NoSuchMethodError'u nasıl düzeltirim?


178

NoSuchMethodErrorJava programımı çalıştırırken bir hata alıyorum . Sorun nedir ve nasıl düzeltebilirim?


11
Netbeans: Projeler sekmesinde projeye sağ tıklayın, "Temizle ve Oluştur" seçeneğini kullanın. Benim için çözdüm.
Ocak'ta Heinzlmaen

3
Ayrıca Intellij Idea'da, yeniden inşa bazen sorunu çözer
Hawk

1
Bu makale bu sorun için çok faydalıdır reflectoring.io/nosuchmethod
Michael Smith

Yanıtlar:


228

Daha fazla bilgi olmadan sorunu saptamak zordur, ancak kök neden, büyük olasılıkla, bir yöntemi eksik olan sınıfın farklı bir sürümüne karşı, sınıfı çalıştırırken kullandığınızdan derlemiş olmanızdır.

Yığın izine bakın ... Kitaplıktaki bir nesnede yöntem çağrılırken kural dışı durum görünürse, büyük olasılıkla derleme ve çalıştırma sırasında kitaplığın ayrı sürümlerini kullanıyorsunuzdur. Her iki yerde de doğru sürüme sahip olduğunuzdan emin olun.

Yaptığınız sınıflarla somutlaştırılan nesneler için bir yöntem çağrılırken kural dışı durum görünürse , oluşturma işleminiz hatalı görünüyor. Derlerken çalıştırdığınız sınıf dosyalarının güncellendiğinden emin olun.


3
Son zamanlarda bunlardan birinin nedenini keşfettik ve derleme işleminin, java sunucusu kapatılmadan önce sınıf dosyalarını yerine koyduğu ortaya çıktı ve java sunucusu bazı sınıflar yüklemediğinden buna değindik ve bazı ama bu yenilerini aldı ve yeni kod eski sınıfların sahip olmadığı yöntemlere atıfta beri ... bingo, NoSuchMethodError
vazor

"Yığın izine bak ..." - Eh, neredeyse her zaman gidip Caused byyığın izinde son bölümü kontrol suçlu sınıfı / kavanoz bulmak için
KrishPrabakar

108

Ben senin problemini yaşıyordum, ve ben böyle düzelttim. Aşağıdaki adımlar kitaplık eklemenin çalışan bir yoludur. İlk iki adımı doğru yapmıştım, ancak son adımı ".jar" dosyasını doğrudan dosya sisteminden tutulma projemdeki "lib" klasörüne sürükleyerek yapmamıştım. Ayrıca, kitaplığın önceki sürümünü hem yapı yolundan hem de "lib" klasöründen kaldırmak zorunda kaldım.

Adım 1 - Yol oluşturmak için .jar ekleyin

resim açıklamasını buraya girin

2. Adım - Kaynakları ve javadokları ilişkilendirme (isteğe bağlı)

resim açıklamasını buraya girin

Adım 3 - Aslında .jar dosyasını "lib" klasörüne sürükleyin (isteğe bağlı değil)

resim açıklamasını buraya girin


75
+1 "Herkes sizden nasıl kullanılacağını bilmenizi bekliyor ve eğer yapmazsanız sorunuzu küçümsüyor."
Vikram

73

Yansıtma durumunda, yansıtıcı NoSuchMethodExceptionolmayan bir kodla bir alırsınız NoSuchMethodError. Biriyle karşı karşıya geldiğinde çok farklı yerlere bakma eğilimindeyim.


Başka bir deyişle, sınıfta bir yöntem almak için yansıma kullanıyorsanız ve yöntem bulunamazsa, bir NoSuchMethodException alıyorsunuz demektir. Bazı senaryolara karşı kodunuzu derlediğinizde ve sunucuda bir senaryoda iseniz ve başka libs (belki daha yeni belki daha eski) varsa o zaman NoSuchMethodError alırsınız. Yanlışsam düzelt.
Victor

Doğru, @Victor
KrishPrabakar

51

JVM parametrelerini değiştirme erişiminiz varsa, ayrıntılı çıktı eklemek hangi JAR dosyalarından hangi sınıfların yüklendiğini görmenizi sağlar.

java -verbose:class <other args>

Programınız çalıştırıldığında, JVM aşağıdaki gibi standart çıkış bilgilerine dökülmelidir:

...

[Junit.framework.Aedert dosyadan yüklendi: / C: /Program%20Files/junit3.8.2/junit.jar]

...


3
+1 Mükemmel! Bu yöntemi kullanarak kötü küçük bir sorunu çözdüm, teşekkürler. Bu, sınıfların bir şekilde bir sınıf yoluna gizlice girdiklerini keşfetmenin mükemmel bir yoludur.
Duncan Jones

1
+1 Günümü kurtardın! Aynı isimlere sahip eski sınıfları kaynaklarına dahil eden sadece bir kütüphane idi.
Andrii Nemchenko

12

Bunun nedeni genellikle , yalnızca java dosyası sınıf dosyasından daha yeni olduğunda java dosyalarını derleyen Apache Ant gibi bir derleme sistemi kullanıldığında ortaya çıkar . Bir yöntem imzası değişirse ve sınıflar eski sürümü kullanıyorsa, işler doğru şekilde derlenmeyebilir. Genel düzeltme tam bir yeniden oluşturma (genellikle "karınca temiz" sonra "karınca").

Bazen bu, bir kütüphanenin bir sürümüne karşı derlenirken, ancak farklı bir sürümle çalışırken de oluşabilir.


1
Aslında, bu daha çok herhangi bir Java geliştirme çerçevesi kullanan Java programcıları için ortaya çıkan bir sorun gibi geliyor: Maven, NetBeans ve Apache Ant, burada tüm cevaplardan görebileceğiniz gibi.
HoldOffHunger

8

Maven veya başka bir çerçeve kullanıyorsanız ve bu hatayı neredeyse rastgele alırsanız, ...

clean install

Bu, özellikle nesneyi yazdıysanız ve yöntemini bildiğinizde işe yarayacaktır. Benim için çalıştı.


Gradle yapıları için de durum budur.
Jonathan Landrum

4

Bu aynı zamanda yansıma kullanmanın bir sonucu olabilir. Bir sınıfa yansıyan ve bir yöntemi ada göre (örneğin: ile Class.getDeclaredMethod("someMethodName", .....)) ayıklayan kodunuz varsa, bu yöntem adı değiştiğinde, örneğin bir refactor sırasında, parametreleri yansıma yöntemiyle eşleştirmek için hatırlamanız gerekir. yeni yöntem imzası, yoksa getDeclaredMethodçağrı atar NoSuchMethodException.

Nedeni bu ise, yığın izlemesi yansıma yönteminin çağrıldığı noktayı göstermelidir ve parametreleri yalnızca gerçek yöntem imzasına uyacak şekilde güncellemeniz gerekir.

Deneyimlerime göre, bu, zaman zaman özel yöntemleri / alanları birim test ederken ve TestUtilitiestest doğrulaması için alanları ayıklamak için bir sınıf kullanırken ortaya çıkar . (Genellikle birim testi göz önünde bulundurularak tasarlanmamış eski kodla.)


3

Bir web uygulaması yazıyorsanız, kapsayıcınızın genel kütüphane dizininde ve uygulamanızda bir kavanozun çakışan sürümlerine sahip olmadığınızdan emin olun. Sınıf doldurucu tarafından hangi kavanozun kullanıldığını bilmeniz gerekmeyebilir.

Örneğin

  • tomcat / ortak / lib
  • myWebApp / WEB INF / lib

2

Bu sorunlara aynı nesnenin aynı iki sınıfta kullanılması neden olmaktadır. Kullanılan nesneler yeni nesne sınıfını içermeyen yeni bir yöntem içermiyor.

örn:

filenotnull=/DayMoreConfig.conf
16-07-2015 05:02:10:ussdgw-1: Open TCP/IP connection to SMSC: 10.149.96.66 at 2775
16-07-2015 05:02:10:ussdgw-1: Bind request: (bindreq: (pdu: 0 9 0 [1]) 900 900 GEN 52 (addrrang: 0 0 2000) ) 
Exception in thread "main" java.lang.NoSuchMethodError: gateway.smpp.PDUEventListener.<init>(Lgateway/smpp/USSDClient;)V
        at gateway.smpp.USSDClient.bind(USSDClient.java:139)
        at gateway.USSDGW.initSmppConnection(USSDGW.java:274)
        at gateway.USSDGW.<init>(USSDGW.java:184)
        at com.vinaphone.app.ttn.USSDDayMore.main(USSDDayMore.java:40)

-bash-3.00$ 

Bu sorunların eşlik eden 02 benzer sınıf (src içinde 1, jar dosyasında 1 burada gateway.jar) neden olur


2

Sınıfta ilgili yöntemin mevcut olmadığı anlamına gelir:

  1. Kavanoz kullanıyorsanız, koda dönüştürün ve ilgili kavanoz versiyonunun uygun sınıfa sahip olup olmadığını kontrol edin.
  2. Kaynağınızdan uygun sınıfı derleyip derlemediğinizi kontrol edin.

2

Benim için oldu, çünkü fonksiyonda argüman türünü Object a'dan String a'ya değiştirdim. Temiz ve tekrar inşa ile çözebilirim


2

Eclipse'imi yeniden başlatarak ve uygulamayı çalıştırarak bu hatayı çözdüm. Benim durumumun nedeni, kaynak dosyalarımı projemi veya Eclipse'i kapatmadan değiştirmemden kaynaklanıyor olabilir. Hangi kullandığım sınıfların farklı sürümüne neden oldu.


2

Bu şekilde deneyin: proje dizinleriniz (ve elbette tüm alt dizinler) altındaki tüm .class dosyalarını kaldırın. Yeniden oluşturun.

Bazen mvn clean(maven kullanıyorsanız) tarafından oluşturulan .class dosyalarını temizlemez javac. Ve bu eski dosyalar eski imzalar içeriyor NoSuchMethodError.


2

Sadece mevcut cevaplara ekliyoruz. Tutulmadaki tomcat ile bu sorunla karşı karşıyaydım. Bir sınıfı değiştirdim ve aşağıdaki adımları uyguladım,

  1. Temizlenen ve projeyi eklenti içinde inşa etti

  2. mvn temiz kurulum

  3. Tomcat yeniden başlatıldı

Yine de aynı hatayla karşı karşıyaydım. Sonra tomcat'i temizledim, tomcat çalışma dizinini temizledim ve sunucuyu yeniden başlattım ve sorunum gitti. Umarım bu birine yardımcı olur


1

Orijinal soruyu cevaplamak için. Java Docs göre burada :

"NoSuchMethodError" Bir uygulama bir sınıfın (statik veya örnek) belirli bir yöntemini çağırmaya çalışırsa ve o sınıfın artık bu yöntemin bir tanımı yoksa atılır.

Normalde, bu hata derleyici tarafından yakalanır; bu hata, yalnızca bir sınıfın tanımı uyumsuzca değiştiğinde çalışma zamanında oluşabilir.

  1. Çalışma zamanında gerçekleşirse, yöntemi içeren sınıfın sınıf yolunda olduğunu kontrol edin.
  2. JAR'ın yeni sürümünü ekleyip eklemediğinizi ve yöntemin uyumlu olup olmadığını kontrol edin.

1

Eclipse bu sorunu bir Junit test dosyasını yeniden adlandırarak giderdim.
Eclipse çalışma alanımda bir App projesi ve Test projesi var.
Test projesi, uygulama yolunda gerekli bir proje olarak App projesine sahiptir.

NoSuchMethodError almaya başladı.
Daha sonra Test projesindeki sınıfın App projesindeki sınıfla aynı ada sahip olduğunu fark ettim.

App/  
  src/
     com.example/  
       Projection.java
Test/  
  src/
     com.example/
       Projection.java

Testi doğru adı "ProjectionTest.java" olarak yeniden adlandırdıktan sonra istisna gitti.


Benzer bir sorunum vardı. Aynı kanonik isimle aynı bağımlılık sınıfım vardı. Yeniden adlandırdıktan sonra istisna gitti.
moralejaSinCuentoNiProverbio

1

Aynı hatayla karşılaştım:

  Exception in thread "main" java.lang.NoSuchMethodError: com.fasterxml.jackson.core.JsonGenerator.writeStartObject(Ljava/lang/Object;)V
        at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:151)
        at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:292)
        at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:3681)
        at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3057)

Bunu çözmek için öncelikle kütüphaneler arasındaki çatışmanın (Intelij IDEA) tam olarak nerede olduğunu anlamak için Modül Bağımlılık Şemasını ( click in your POM the combination -> Ctrl+Alt+Shift+Uveya right click in your POM -> Maven -> Show dependencies) kontrol ettim . Benim özel durumumda, Jackson bağımlılıklarının farklı versiyonları vardı.

resim açıklamasını buraya girin resim açıklamasını buraya girin

1) Bu yüzden, doğrudan projenin POM'una bu en yüksek sürümü olan 2.8.7'yi ekledim.

Özelliklerde:

<jackson.version>2.8.7</jackson.version>

Ve bağımlılık olarak:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>${jackson.version}</version>
</dependency>

2) Ama aynı zamanda Bağımlılık Dışlamaları kullanılarak çözülebilir .

Örnekte aşağıdaki ile aynı prensibe göre:

  <dependency>
      <groupId>group-a</groupId>
      <artifactId>artifact-a</artifactId>
      <version>1.0</version>
          <exclusions>
             <exclusion>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
             </exclusion>
         </exclusions>
  </dependency>

İstenmeyen versiyona bağımlılık projenizden hariç tutulacaktır.


1

Benim durumumda çok modüllü bir projem vardı ve senaryo com.xyz.TestClassmodülde Aolduğu gibi modül Bve modülde Ade modüle bağlıydı B. Bir montaj kavanozu oluştururken, eğer çağrılmış yöntem yoksa sınıfın sadece bir versiyonunun korunduğunu düşünüyorumNoSuchMethodError çalışma istisnası , ancak derleme iyiydi .

İlgili: https://reflectoring.io/nosuchmethod/


0

Uygulamamda yöntem imzalarını değiştirirken de benzer bir sorunla karşılaştım. Projemi temizleme ve yeniden oluşturma "NoSuchMethodError" sorununu çözdü.


0

Yukarıdaki cevap çok iyi açıklıyor .. sadece bir şey eklemek için eclipse kullanarak ctrl + shift + T kullanın ve sınıfın paket yapısını girin (örn: gateway.smpp.PDUEventListener), mevcut tüm kavanozları / projeleri bulacaksınız . Sınıf yolundan gereksiz kavanozları kaldırın veya sınıf yoluna yukarı ekleyin. Şimdi doğru olanı alacak.


0

Benzer bir sorunla karşılaştım.

Caused by: java.lang.NoSuchMethodError: com.abc.Employee.getEmpId()I

Sonunda kök neden değişkenin veri türünü değiştirdiğini tespit ettim.

  1. Employee.java-> Değişken (İçeriyor EmpId) olan Veri Türü olarak değiştirildi intiçin String.
  2. ReportGeneration.java-> Alıcıyı kullanarak değeri alır getEmpId(),.

Kavanozu sadece değiştirilmiş sınıfları dahil ederek yeniden birleştirmemiz gerekiyor. ReportGeneration.javaBen hiçbir değişiklik olmadığı için sadece Employee.classJar dosyası dahil edildi . ReportGeneration.classSorunu çözmek için dosyayı kavanoza dahil etmek zorunda kaldım .


0

Aynı sorunu yaşadım. Bu, sınıflarda bir belirsizlik olduğunda da ortaya çıkar. Programım, aynı konum / sınıf yolunda bulunan iki JAR dosyasında bulunan bir yöntemi çağırmaya çalışıyordu. Bir JAR dosyasını silin veya kodunuzu yalnızca bir JAR dosyası kullanılacak şekilde yürütün. Aynı JAR'ı veya aynı JAR'ın aynı sınıfı içeren farklı sürümlerini kullanmadığınızı kontrol edin.

DISP_E_EXCEPTION [adım] [] [Z-JAVA-105 Java istisnası java.lang.NoSuchMethodError (com.example.yourmethod)]



0

Bu hatayla da karşılaştım.

Benim sorunum bir yöntemin imzasını değiştirmiş olmamdı.

void invest(Currency money){...}

içine

void invest(Euro money){...}

Bu yöntem, aşağıdakine benzer bir bağlamdan çağrıldı:

public static void main(String args[]) {
    Bank myBank = new Bank();

    Euro capital = new Euro();
    myBank.invest(capital);
}

Derleyici, sermaye hem Para Birimi hem de Euro olduğu için uyarılar / hatalar konusunda sessiz kaldı.

Sorun, yalnızca yöntemin tanımlandığı sınıfı derlediğim için ortaya çıktı - Banka, ancak yöntemin çağrıldığı sınıfı değil, main () yöntemini içeriyor.

Bu sorun, çok sık karşılaşabileceğiniz bir şey değildir, çünkü çoğu zaman proje tek tek yeniden oluşturulur veya yalnızca bir değiştirilmiş sınıfı derlemek yerine otomatik olarak bir Derleme eylemi tetiklenir.

Benim usecase, bu değiştirilmedi olarak App.class içermeyen bir düzeltme olarak kullanılacak bir .jar dosyası oluşturdu oldu. İlk argümanın temel sınıfından kalıtımla devam ettiğim için bunu dahil etmem bana mantıklı geldi.

Mesele şu ki, bir sınıfı derlediğinizde ortaya çıkan bayt kodu bir tür statik , başka bir deyişle, zor bir referanstır .

Sökülen orijinal bayt kodu (javap aracıyla oluşturulur) şöyle görünür:

 #7 = Methodref          #2.#22         // Bank.invest:(LCurrency;)V

ClassLoader yeni derlenmiş Bank.class'ı yükledikten sonra, böyle bir yöntem bulamaz, kaldırılmış ve değiştirilmemiş gibi görünür, bu nedenle adlandırılan hata.

Bu yardımcı olur umarım.


0

Benim durumumda derleme yolunda aynı kütüphanenin iki sürümü olmasıydı. Kütüphanenin eski sürümü bu işleve sahip değildi ve daha yeni olanı vardı.


0

Intelij kullanan Gradle Projemde de benzer bir sorun yaşadım. .Gradle (aşağıdaki ekran görüntüsüne bakın) Paketini silerek ve Projeyi yeniden inşa ederek çözdüm. .gradle Paketi


0

NoSuchMethodError: Bu sorunu düzeltmek için birkaç saat harcadım, sonunda paket adını yeniden adlandırarak temizledim ve temizleyin ... Çalışmıyorsa önce temiz derlemeyi deneyin, sınıf adını veya paket adını ve temiz derlemeyi yeniden adlandırmayı deneyin .. sabit olmalıdır. İyi şanslar.


-2

Dosya adınız ana yöntemi içeren sınıf adından farklıysa, bu hatanın neden olma olasılığı olabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.