سؤال

أنا أحصل على NoSuchMethodError خطأ عند تشغيل برنامج جافا الخاص بي.ما هو الخطأ وكيف يمكنني إصلاحه؟

هل كانت مفيدة؟

المحلول

من الصعب تحديد المشكلة دون مزيد من المعلومات، ولكن السبب الجذري هو أنك على الأرجح قمت بتجميع فئة مقابل إصدار مختلف من الفئة التي تفتقد طريقة، غير تلك التي تستخدمها عند تشغيلها.

انظر إلى أثر المكدس ...إذا ظهر الاستثناء عند استدعاء أسلوب على كائن في مكتبة، فمن المرجح أنك تستخدم إصدارات منفصلة من المكتبة عند التجميع والتشغيل.تأكد من أن لديك الإصدار الصحيح في كلا المكانين.

إذا ظهر الاستثناء عند استدعاء طريقة على كائنات تم إنشاء مثيل لها بواسطة الفئات أنت مصنوعة، فإن عملية الإنشاء الخاصة بك تبدو معيبة.تأكد من تحديث ملفات الفئة التي تقوم بتشغيلها بالفعل عند التحويل البرمجي.

نصائح أخرى

كنت أواجه مشكلتك، وهذه هي الطريقة التي أصلحتها.الخطوات التالية هي طريقة عمل لإضافة مكتبة.لقد قمت بتنفيذ الخطوتين الأوليين بشكل صحيح، لكنني لم أقم بالخطوة الأخيرة عن طريق سحب الملف ".jar" مباشرة من نظام الملفات إلى المجلد "lib" في مشروع Eclipse الخاص بي.بالإضافة إلى ذلك، اضطررت إلى إزالة الإصدار السابق من المكتبة من كل من مسار البناء والمجلد "lib".

الخطوة 1 - أضف .jar لبناء المسار

enter image description here

الخطوة 2 - ربط المصادر وjavadocs (اختياري)

enter image description here

الخطوة 3 - اسحب ملف .jar فعليًا إلى مجلد "lib" (ليس اختياريًا)

enter image description here

لاحظ أنه في حالة الانعكاس، تحصل على NoSuchMethodException, ، بينما تحصل على رمز غير عاكس NoSuchMethodError.أميل إلى البحث في أماكن مختلفة جدًا عندما أواجه أحدهما مقابل الآخر.

إذا كان لديك حق الوصول لتغيير معلمات JVM، فإن إضافة مخرجات مطولة يجب أن تسمح لك برؤية الفئات التي يتم تحميلها من ملفات JAR.

java -verbose:class <other args>

عند تشغيل البرنامج الخاص بك، يجب أن يقوم JVM بتفريغ المعلومات القياسية مثل:

...

[تم تحميل junit.framework.Assert من الملف:/C:/Program%20Files/junit3.8.2/junit.jar]

...

يحدث هذا عادةً عند استخدام نظام بناء مثل نملة أباتشي يقوم بتجميع ملفات جافا فقط عندما يكون ملف جافا أحدث من ملف الفئة.إذا كانت التغييرات في توقيع الطريقة والفئات تستخدم الإصدار القديم، فقد لا يتم تجميع الأشياء بشكل صحيح.الحل المعتاد هو إجراء إعادة بناء كاملة (عادة "تنظيف النمل" ثم "النمل").

في بعض الأحيان يمكن أن يحدث هذا أيضًا عند التجميع مقابل إصدار واحد من المكتبة ولكن عند التشغيل مقابل إصدار مختلف.

في حالة استخدام مخضرم أو إطار عمل آخر، ويصلك هذا الخطأ بشكل عشوائي تقريبًا، حاول تثبيتًا نظيفًا مثل...

clean install

من المرجح أن ينجح هذا بشكل خاص إذا كنت قد كتبت الكائن وأنت تعلم أن لديه الطريقة.عملت بالنسبة لي.

يمكن أن يكون هذا أيضًا نتيجة لاستخدام الانعكاس.إذا كان لديك رمز ينعكس على الفصل الدراسي ويستخرج طريقة بالاسم (على سبيل المثال:مع Class.getDeclaredMethod("someMethodName", .....)) ثم في أي وقت يتغير فيه اسم الطريقة، كما هو الحال أثناء عملية إعادة البناء، ستحتاج إلى تذكر تحديث المعلمات إلى طريقة الانعكاس لمطابقة توقيع الطريقة الجديدة، أو getDeclaredMethod سيتم رمي المكالمة أ NoSuchMethodException.

إذا كان هذا هو السبب، فيجب أن يُظهر تتبع المكدس النقطة التي يتم فيها استدعاء طريقة الانعكاس، وستحتاج فقط إلى تحديث المعلمات لمطابقة توقيع الطريقة الفعلية.

في تجربتي، يظهر هذا أحيانًا عند اختبار الوحدة للطرق/الحقول الخاصة، واستخدام ملف TestUtilities فئة لاستخراج الحقول للتحقق من الاختبار.(بشكل عام مع التعليمات البرمجية القديمة التي لم يتم تصميمها مع وضع اختبار الوحدة في الاعتبار.)

إذا كنت تكتب تطبيق ويب، فتأكد من عدم وجود إصدارات متعارضة من الجرة في دليل المكتبة العامة للحاوية الخاصة بك وفي تطبيقك أيضًا.قد لا تعرف بالضرورة الجرة التي يستخدمها مُحمل الفصل.

على سبيل المثال

  • القط/المشترك/lib
  • mywebapp/WEB-INF/lib

سبب هذه المشاكل هو استخدام نفس الكائن في نفس الفئتين.الكائنات المستخدمة لا تحتوي على تمت إضافة طريقة جديدة تحتوي عليها فئة الكائن الجديدة.

السابق:

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$ 

سبب هذه المشاكل هو الفئة المماثلة 02 المصاحبة (1 في src، 1 في ملف jar هنا هو gate.jar)

وهذا يعني أن الطريقة المعنية غير موجودة في الفصل:

  1. إذا كنت تستخدم jar، فقم بفك الترجمة وتحقق مما إذا كان الإصدار المعني من jar يحتوي على فئة مناسبة.
  2. تحقق مما إذا كنت قد قمت بتجميع الفصل المناسب من المصدر الخاص بك.

حدث ذلك بالنسبة لي لأنني قمت بتغيير نوع الوسيطة في الوظيفة، من الكائن أ، إلى السلسلة أ.يمكنني حل المشكلة بالتنظيف والبناء مرة أخرى

لقد قمت للتو بحل هذا الخطأ عن طريق إعادة تشغيل Eclipse وتشغيل التطبيق.قد يكون سبب حالتي هو أنني استبدلت ملفاتي المصدرية دون إغلاق مشروعي أو Eclipse.مما تسبب في إصدار مختلف للفصول التي كنت أستخدمها.

جرب هذه الطريقة:قم بإزالة جميع ملفات .class الموجودة ضمن أدلة مشروعك (وبالطبع جميع الدلائل الفرعية).إعادة بناء.

أحيانا mvn clean (إذا كنت تستخدم maven) لا يقوم بتنظيف ملفات .class التي تم إنشاؤها يدويًا بواسطة javac.وتلك الملفات القديمة تحتوي على توقيعات قديمة تؤدي إلى NoSuchMethodError.

مجرد إضافة إلى الإجابات الموجودة.كنت أواجه هذه المشكلة مع Tomcat في Eclipse.لقد قمت بتغيير فصل واحد وقمت بالخطوات التالية،

  1. تنظيف وبناء المشروع في الكسوف

  2. تثبيت mvn النظيف

  3. إعادة تشغيل القط

ما زلت أواجه نفس الخطأ.ثم لقد قمت بتنظيف Tomcat، وتنظيف دليل عمل Tomcat وأعدت تشغيل الخادم وانتهت مشكلتي.أمل أن هذا يساعد شخصاما

لقد أصلحت هذه المشكلة في Eclipse عن طريق إعادة تسمية ملف اختبار Junit.
في مساحة عمل Eclipse الخاصة بي، لدي مشروع تطبيق ومشروع اختباري.
يحتوي المشروع الاختباري على مشروع التطبيق كمشروع مطلوب على مسار الإنشاء.

بدأت في الحصول على NoSuchMethodError.
ثم أدركت أن الفصل في مشروع الاختبار له نفس اسم الفصل في مشروع التطبيق.

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

بعد إعادة تسمية الاختبار إلى الاسم الصحيح "ProjectionTest.java"، اختفى الاستثناء.

لقد واجهت مشكلة مماثلة عندما كنت أقوم بتغيير توقيعات الطريقة في طلبي.أدى تنظيف مشروعي وإعادة بنائه إلى حل مشكلة "NoSuchMethodError".

توضح الإجابة أعلاه جيدًا .. فقط لإضافة شيء واحد إذا كنت تستخدم Eclipse استخدم Ctrl+Shift+T وأدخل بنية فئة الحزمة (على سبيل المثال:gate.smpp.PDUEventListener )، ستجد جميع الجرار/المشاريع حيثما تكون موجودة.قم بإزالة الجرار غير الضرورية من مسار الفصل أو أضفها أعلاه في مسار الفصل.الآن سوف تلتقط الصحيح.

واجهت مشكلة مماثلة.

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

أخيرًا حددت السبب الجذري وهو تغيير نوع بيانات المتغير.

  1. Employee.java --> يحتوي على المتغير (EmpId) الذي تم تغيير نوع البيانات منه int ل String.
  2. ReportGeneration.java --> استرداد القيمة باستخدام getter، getEmpId().

من المفترض أن نقوم بإعادة تجميع الجرة من خلال تضمين الفئات المعدلة فقط.كما لم يكن هناك أي تغيير في ReportGeneration.java كنت فقط بما في ذلك Employee.class في ملف جرة.كان علي أن أدرج ReportGeneration.class ملف في الجرة لحل المشكلة.

لقد واجهت نفس المشكلة.يحدث هذا أيضًا عندما يكون هناك غموض في الفصول الدراسية.كان برنامجي يحاول استدعاء طريقة كانت موجودة في ملفين JAR موجودين في نفس مسار الموقع/الفئة.احذف ملف JAR واحدًا أو قم بتنفيذ التعليمات البرمجية الخاصة بك بحيث يتم استخدام ملف JAR واحد فقط.تأكد من أنك لا تستخدم نفس JAR أو إصدارات مختلفة من نفس JAR التي تحتوي على نفس الفئة.

DISP_E_EXCEPTION [الخطوة] [] [استثناء Java Z-JAVA-105 java.lang.NoSuchMethodError(com.example.yourmethod)]

للإجابة على السؤال الأصلي.وفقا لمستندات جافا هنا:

يتم طرح "NoSuchMethodError" إذا حاول أحد التطبيقات استدعاء طريقة محددة لفئة ما (سواء كانت ثابتة أو مثيل)، ولم يعد لدى هذه الفئة تعريف لهذه الطريقة.

عادةً، يتم اكتشاف هذا الخطأ بواسطة المحول البرمجي؛يمكن أن يحدث هذا الخطأ فقط في وقت التشغيل إذا تم تغيير تعريف الفئة بشكل غير متوافق.

  1. إذا حدث ذلك في وقت التشغيل، فتحقق من أن الفئة التي تحتوي على الطريقة موجودة في مسار الفئة.
  2. تحقق مما إذا كنت قد أضفت إصدارًا جديدًا من JAR وأن الطريقة متوافقة.

في معظم الأوقات يتم اكتشاف java.lang.NoSuchMethodError كمترجم ولكن في بعض الأحيان يمكن أن يحدث ذلك في وقت التشغيل.إذا حدث هذا الخطأ في وقت التشغيل، فقد يكون السبب الوحيد هو التغيير في بنية الفصل الذي جعله غير متوافق.

أفضل تفسير: https://www.journaldev.com/14538/Java-lang-no suchmethoderror

لقد واجهت هذا الخطأ أيضا.

كانت مشكلتي أنني قمت بتغيير توقيع الطريقة، شيء من هذا القبيل

void invest(Currency money){...}

داخل

void invest(Euro money){...}

تم استدعاء هذه الطريقة من سياق مشابه لـ

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

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

لقد التزم المترجم الصمت فيما يتعلق بالتحذيرات/الأخطاء، حيث أن رأس المال هو العملة وكذلك اليورو.

ظهرت المشكلة لأنني قمت فقط بتجميع الفئة التي تم تعريف الطريقة فيها - البنك، ولكن ليس الفئة التي يتم استدعاء الطريقة منها، والتي تحتوي على الطريقة الرئيسية ().

هذه المشكلة ليست شيئًا قد تواجهه كثيرًا، حيث أنه في أغلب الأحيان يتم إعادة بناء المشروع يدويًا أو يتم تشغيل إجراء الإنشاء تلقائيًا، بدلاً من مجرد تجميع فئة واحدة معدلة.

كانت حالة الاستخدام الخاصة بي هي أنني قمت بإنشاء ملف .jar والذي كان من المقرر استخدامه كإصلاح عاجل، ولم يحتوي على App.class لأنه لم يتم تعديله.كان من المنطقي بالنسبة لي عدم تضمينه لأنني احتفظت بالطبقة الأساسية للوسيطة الأولية من خلال الميراث.

الأمر هو أنه عندما تقوم بتجميع فصل دراسي، فإن الكود الثانوي الناتج يكون نوعًا ما ثابتة, ، وبعبارة أخرى، انها مرجع صعب.

يبدو رمز البايت الأصلي المفكك (الذي تم إنشاؤه باستخدام أداة javap) كما يلي:

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

بعد أن يقوم ClassLoader بتحميل Bank.class المترجم الجديد، لن يجد مثل هذه الطريقة، ويبدو كما لو تمت إزالته ولم يتغير، وبالتالي الخطأ المسمى.

أتمنى أن يساعدك هذا.

كانت المشكلة في حالتي هي وجود نسختين من نفس المكتبة في مسار الإنشاء.الإصدار الأقدم من المكتبة لم يكن لديه هذه الوظيفة، بينما الإصدار الأحدث كان لديه هذه الوظيفة.

واجهت مشكلة مماثلة مع مشروع Gradle الخاص بي باستخدام Intelij.لقد قمت بحل المشكلة عن طريق حذف حزمة .gradle (انظر لقطة الشاشة أدناه) وإعادة بناء المشروع.حزمة .gradle

لا هذا خطأ الطريقة :لقد أمضيت بضع ساعات في إصلاح هذه المشكلة، وأخيراً أصلحتها بمجرد إعادة تسمية اسم الحزمة والتنظيف والبناء ...جرب البناء النظيف أولاً إذا لم ينجح، فحاول إعادة تسمية اسم الفئة أو اسم الحزمة والبناء النظيف...يجب إصلاحه.حظ سعيد.

واجهت نفس الخطأ:

  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)

لحلها راجعت، أولا، مخطط تبعية الوحدة النمطية (click in your POM the combination -> Ctrl+Alt+Shift+U أو right click in your POM -> Maven -> Show dependencies) لفهم أين كان الصراع بين المكتبات بالضبط (Intelij IDEA).في حالتي الخاصة، كان لدي إصدارات مختلفة من تبعيات جاكسون.

enter image description here enter image description here

1) لذلك، أضفت مباشرة في دليل عمليات المشروع الخاص بي للمشروع بوضوح أعلى إصدار - 2.8.7 من هذين الإصدارين.

في الخصائص:

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

وكما التبعية:

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

2) ولكن أيضًا يمكن حلها باستخدام استثناءات التبعية.

بنفس المبدأ كما هو موضح أدناه في المثال:

  <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>

سيتم استبعاد التبعية ذات الإصدار غير المرغوب فيه من مشروعك.

إذا كان اسم الملف الخاص بك مختلفًا عن اسم الفئة الذي يحتوي على الطريقة الرئيسية، فمن المحتمل أن يحدث هذا الخطأ.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top