NoSuchMethodError
Java programımı çalıştırırken bir hata alıyorum . Sorun nedir ve nasıl düzeltebilirim?
NoSuchMethodError
Java programımı çalıştırırken bir hata alıyorum . Sorun nedir ve nasıl düzeltebilirim?
Yanıtlar:
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.
Caused by
yığın izinde son bölümü kontrol suçlu sınıfı / kavanoz bulmak için
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.
Yansıtma durumunda, yansıtıcı NoSuchMethodException
olmayan bir kodla bir alırsınız NoSuchMethodError
. Biriyle karşı karşıya geldiğinde çok farklı yerlere bakma eğilimindeyim.
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]
...
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.
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ı.
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 TestUtilities
test 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.)
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
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
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.
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
.
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,
Temizlenen ve projeyi eklenti içinde inşa etti
mvn temiz kurulum
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
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.
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.
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+U
veya right click in your POM -> Maven -> Show dependencies
) kontrol ettim . Benim özel durumumda, Jackson bağımlılıklarının farklı versiyonları vardı.
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.
Benim durumumda çok modüllü bir projem vardı ve senaryo com.xyz.TestClass
modülde A
olduğu gibi modül B
ve modülde A
de 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 .
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.
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.
Employee.java
-> Değişken (İçeriyor EmpId
) olan Veri Türü olarak değiştirildi int
için String
.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.java
Ben hiçbir değişiklik olmadığı için sadece Employee.class
Jar dosyası dahil edildi . ReportGeneration.class
Sorunu çözmek için dosyayı kavanoza dahil etmek zorunda kaldım .
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)]
Çoğu zaman java.lang.NoSuchMethodError derleyici olarak yakalanır ancak bazen çalışma zamanında ortaya çıkabilir. Bu hata çalışma zamanında meydana gelirse, bunun tek nedeni sınıf yapısındaki onu uyumsuz yapan değişiklik olabilir.
En İyi Açıklama: https://www.journaldev.com/14538/java-lang-nosuchmethoderror
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.
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
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.
Dosya adınız ana yöntemi içeren sınıf adından farklıysa, bu hatanın neden olma olasılığı olabilir.