NoClassDefFoundError أثناء محاولة تشغيل الجرة الخاصة بي باستخدام java.exe -jar...ما المشكلة؟
-
05-07-2019 - |
سؤال
لدي تطبيق أحاول تغليفه في وعاء لتسهيل النشر.يتم تجميع التطبيق وتشغيله بشكل جيد (في نافذة Windows cmd) عند تشغيله كمجموعة من الفئات التي يمكن الوصول إليها من CLASSPATH.ولكن عندما أقوم بتجميع فصولي وأحاول تشغيلها باستخدام Java 1.6 في نفس نافذة cmd، أبدأ في الحصول على استثناءات:
C:\dev\myapp\src\common\datagen>C:/apps/jdk1.6.0_07/bin/java.exe -classpath C:\myapp\libs\commons -logging-1.1.jar -server -jar DataGen.jar
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
at com.example.myapp.fomc.common.datagen.DataGenerationTest.<clinit>(Unknown Source)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
... 1 more
الشيء المضحك هو أن LogFactory المخالف يبدو أنه موجود في commons-logging-1.1.jar، الموجود في مسار الفئة المحدد.ملف jar (نعم، إنه موجود بالفعل):
C:\dev\myapp\src\common\datagen>dir C:\myapp\libs\commons-logging-1.1.jar
Volume in drive C is Local Disk
Volume Serial Number is ECCD-A6A7
Directory of C:\myapp\libs
12/11/2007 11:46 AM 52,915 commons-logging-1.1.jar
1 File(s) 52,915 bytes
0 Dir(s) 10,956,947,456 bytes free
محتويات الملف commons-logging-1.1.jar:
C:\dev\myapp\src\common\datagen>jar -tf C:\myapp\libs\commons-logging-1.1.jar
META-INF/
META-INF/MANIFEST.MF
org/
org/apache/
org/apache/commons/
org/apache/commons/logging/
org/apache/commons/logging/impl/
META-INF/LICENSE.txt
META-INF/NOTICE.txt
org/apache/commons/logging/Log.class
org/apache/commons/logging/LogConfigurationException.class
org/apache/commons/logging/LogFactory$1.class
org/apache/commons/logging/LogFactory$2.class
org/apache/commons/logging/LogFactory$3.class
org/apache/commons/logging/LogFactory$4.class
org/apache/commons/logging/LogFactory$5.class
org/apache/commons/logging/LogFactory.class
... (more classes in commons-logging-1.1 ...)
نعم، يحتوي تسجيل المشاعات على فئة LogFactory.وأخيرًا، محتويات بيان الجرة الخاص بي:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.6.5
Created-By: 10.0-b23 (Sun Microsystems Inc.)
Main-Class: com.example.myapp.fomc.common.datagen.DataGenerationTest
Class-Path: commons-logging-1.1.jar commons-lang.jar antlr.jar toplink
.jar GroboTestingJUnit-1.2.1-core.jar junit.jar
لقد أزعجني هذا الأمر وأزعجني أي زملائي في العمل الذين قمت بالتنصت عليهم منذ أكثر من يوم.فقط لتصفية الإجابات، في الوقت الحالي على الأقل، من المحتمل أن تكون حلول الطرف الثالث لهذا الأمر غير موجودة بسبب قيود الترخيص وسياسات الشركة (على سبيل المثال:أدوات لإنشاء ملفات exe أو تعبئة الجرار).الهدف النهائي هو إنشاء جرة يمكن نسخها من صندوق Windows الخاص بالتطوير إلى خادم Linux (مع أي جرة تابعة) واستخدامها لملء قاعدة بيانات (لذلك قد ينتهي الأمر بمسارات الفصل إلى أن تكون مختلفة بين بيئات التطوير والنشر).أي أدلة على هذا اللغز سيكون موضع تقدير كبير!
المحلول
الخيار -jar يستبعد الآخر من -classpath.انظر الوصف القديم هنا
-إناء
تنفيذ برنامج مغلف في ملف JAR.الوسيطة الأولى هي اسم ملف JAR بدلاً من اسم فئة بدء التشغيل.لكي يعمل هذا الخيار، يجب أن يحتوي بيان ملف JAR على سطر من النموذج Main-Class:اسم الفئة.هنا، يحدد اسم الفئة الفئة التي تحتوي على الطريقة العامة static void main(String[] args) التي تعمل كنقطة بداية لتطبيقك.
راجع الصفحة المرجعية لأداة Jar ومسار Jar الخاص ببرنامج Java التعليمي للحصول على معلومات حول العمل مع ملفات Jar وبيانات ملف Jar.
عند استخدام هذا الخيار، يكون ملف JAR هو مصدر جميع فئات المستخدمين، ويتم تجاهل إعدادات مسار فئة المستخدم الأخرى.
الاختراق السريع والقذر هو إلحاق مسار الفصل الدراسي الخاص بك بمسار الفصل التمهيدي:
-Xbootclasspath/أ:طريق
حدد مسارًا مفصولاً بالنقطتين للمخرجات وأرشيفات JAR وأرشيفات ZIP لإلحاقها بمسار فئة التمهيد الافتراضي.
ولكن كما @ دان يقول بحق، الحل الصحيح هو التأكد من أن بيان JAR الخاص بك يحتوي على مسار الفصل لجميع ملفات JAR التي سيحتاجها.
نصائح أخرى
ويمكنك حذف الخيار -jar
والبدء في ملف جرة مثل هذا:
وjava -cp MyJar.jar;C:\externalJars\* mainpackage.MyMainClass
هذه هي المشكلة التي تحدث،
إذا تم تحميل ملف JAR من "C:\java\apps\appli.jar"، وكان ملف البيان الخاص بك يحتوي على مسار الفئة:مرجع "lib/other.jar"، سيبحث مُحمل الفئة في "C:\Java\apps\lib\" عن "other.jar".لن ينظر إلى إدخال ملف JAR "lib/other.jar".
حل:-
- انقر بزر الماوس الأيمن على المشروع، وحدد تصدير.
- حدد مجلد Java وفيه حدد ملف JAR القابل للتشغيل بدلاً من ملف JAR.
- حدد الخيارات المناسبة وفي قسم التعامل مع المكتبة حدد الخيار الثالث، أي.(انسخ المكتبات المطلوبة إلى مجلد فرعي بجوار JAR الذي تم إنشاؤه).
[ يحرر = الخيار الثالث ينشئ مجلدًا بالإضافة إلى الجرة، ويمكن أيضًا استخدام الخيار الثاني ("حزم المكتبات المطلوبة في JAR المُنشأ") عندما يكون لديك الجرة.]
- انقر فوق "إنهاء" وسيتم إنشاء JAR الخاص بك في الموضع المحدد مع مجلد يحتوي على JARS المذكورة في ملف البيان.
افتح الوحدة الطرفية، ثم أعط المسار الصحيح للجرة الخاصة بك وقم بتشغيلها باستخدام هذا الأمر java -jar abc.jar
ما سيحدث الآن هو أن مُحمل الفئة سيبحث في المجلد الصحيح عن JARS المشار إليه نظرًا لأنه موجود الآن في نفس المجلد الذي يحتوي على تطبيق JAR الخاص بك.. لا يوجد استثناء "java.lang.NoClassDefFoundError" الذي تم طرحه الآن.
هذا عملت بالنسبة لي...أتمنى أن تعمل معك أيضا!!!
وإذا كنت تستخدم المكتبات الخارجية في البرنامج وحاولت أن حزمة كل ذلك معا في ملف جرة انها ليست بهذه البساطة، لأن من القضايا CLASSPATH الخ.
وكنت تفضل استخدام OneJar للحصول على هذه المسألة.
واجهت نفس المشكلة مع جرة الحل
- قم بإنشاء ملف MANIFEST.MF:
نسخة البيان:1.0
مختوم:حقيقي
مسار الفصل:.lib/jarX1.jar lib/jarX2.jar lib/jarX3.jar
الفئة الرئيسية:com.MainClass
- انقر بزر الماوس الأيمن على المشروع، وحدد تصدير.
حدد تصدير جميع مجلدات الإخراج للمشروع المحدد
- حدد استخدام البيان الموجود من مساحة العمل وحدد ملف MANIFEST.MF
هذا عملت بالنسبة لي :)
ولقد وجدت وأنا عندما باستخدام الظاهر أن إدراج الجرار لCLASSPATH الحاجة إلى وجود مسافة بعد إدراج كل جرة على سبيل المثال "required_lib / الشمس / pop3.jar required_lib / الشمس / smtp.jar". حتى لو كان هو الأخير في القائمة.