NoClassDefFoundError при попытке запустить мою банку с java.exe-jar...что случилось?
у меня есть приложение, которое я пытаюсь завернуть в банку для более легкого развертывания. Приложение компилируется и работает нормально (в окне cmd Windows) при запуске как набор классов, доступных из пути к классам. Но когда я поднимаю свои классы и пытаюсь запустить его с java 1.6 в том же окне cmd, я начинаю получать исключения:
C:devmyappsrccommondatagen>C:/apps/jdk1.6.0_07/bin/java.exe -classpath C:myapplibscommons -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.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:devmyappsrccommondatagen>dir C:myapplibscommons-logging-1.1.jar
Volume in drive C is Local Disk
Volume Serial Number is ECCD-A6A7
Directory of C:myapplibs
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
содержание общего-ведение журнала-1.1.jar-файл:
C:devmyappsrccommondatagen>jar -tf C:myapplibscommons-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.class
org/apache/commons/logging/LogFactory.class
org/apache/commons/logging/LogFactory.class
org/apache/commons/logging/LogFactory.class
org/apache/commons/logging/LogFactory.class
org/apache/commons/logging/LogFactory.class
... (more classes in commons-logging-1.1 ...)
да, commons-logging имеет класс 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 или упаковка банок). Конечная цель-создать jar, который можно скопировать из окна моей разработки Windows на сервер Linux (с любыми зависимыми jar) и использовать для заполнения базы данных (поэтому пути к классам могут отличаться между средами разработки и развертывания). Любые подсказки к этой тайне будут очень признательны!
6 ответов:
параметр-jar является взаимоисключающим из-classpath. Смотрите старое описание здесь
-jar
выполнить программу, инкапсулированную в файл JAR. Первый аргумент - это имя файла JAR вместо имени класса запуска. Для того, чтобы эта опция работала, манифест jar-файл должен содержать строку из главных-форма класса: имя_класса. Здесь classname определяет класс, имеющий метод public static void main (String[] args это служит отправной точкой вашего приложения.
см. справочную страницу инструмента Jar и след Jar учебника Java для получения информации о работе с файлами Jar и манифестами Jar-файлов.
при использовании этого параметра файл JAR является источником всех пользовательских классов, а другие параметры пути к пользовательскому классу игнорируются.
быстрый и грязный хак, чтобы добавить свой classpath к bootstrap путь к классу:
, а @Dan правильно говорит, правильное решение-обеспечить, чтобы ваш манифест JARs содержал путь к классам для всех банок, которые ему понадобятся.- Xbootclasspath/a:путь
укажите разделенный двоеточием путь к директориям, архивам JAR и архивам ZIP для добавления к пути класса начальной загрузки по умолчанию.
вы можете опустить
-jar
опция и запустите файл jar следующим образом:
java -cp MyJar.jar;C:\externalJars\* mainpackage.MyMainClass
Это проблема, которая происходит,
Если файл JAR был загружен из "C:\java\apps\appli.jar", и ваш файл манифеста имеет путь к классу: ссылка " lib/other.jar", загрузчик классов будет смотреть в "C:\java\apps\lib\" для " других.сосуд." Он не будет смотреть на запись файла JAR "lib/other.сосуд."
решение:-
- щелкните правой кнопкой мыши проект, выберите Экспорт.
- выберите папку Java и в ней выберите запускаемый файл JAR вместо файла JAR.
- выберите нужные параметры и в разделе обработка библиотек выберите 3-й вариант, т. е. (скопируйте необходимые библиотеки в подпапку рядом с сгенерированной JAR).
[ EDIT = 3-й вариант генерирует папку в дополнение к jar, 2-й вариант ("пакет необходимых библиотек в сгенерированный JAR") также может быть использован, как у вас есть jar. ]
- Нажмите кнопку Готово и ваша банка будет создана на указанная позиция вместе с папкой, содержащей банки, упомянутые в файле манифеста.
откройте терминал, укажите правильный путь к вашему jar и запустите его с помощью этой команды java-jar abc.банку
теперь произойдет то, что загрузчик классов будет искать в правильной папке для указанных банок, так как теперь они присутствуют в той же папке, которая содержит вашу банку приложения..Нет "на Java.ленг.Noclassdeffounderror " исключение брошено сейчас.
Это работает для меня... Надеюсь, что это работает и для вас тоже!!!
Если вы используете внешние библиотеки в своей программе, и вы пытаетесь упаковать все вместе в файл jar, это не так просто, из-за проблем с classpath и т. д.
Я бы предпочел использовать OneJar по этому вопросу.
У меня была такая же проблема с моим фляги решение
- создать манифест.Файл MF:
Манифест-Версия: 1.0
опечатался: правда
Class-Path: . lib / jarX1.jar lib / jarX2.jar lib / jarX3.банку
основной класс: com.MainClass
- щелкните правой кнопкой мыши проект, выберите Экспорт.
выберите экспортировать все папки вывода для проверки проект
- выберите использование существующего манифеста из рабочей области и выберите манифест.MF file
Это сработало для меня :)