NoClassDefFoundError при попытке запустить мой jar с помощью java.exe -jar ... что не так?

StackOverflow https://stackoverflow.com/questions/250166

Вопрос

У меня есть приложение, которое я пытаюсь обернуть в jar для упрощения развертывания.Приложение компилируется и работает нормально (в окне Windows cmd) при запуске как набор классов, доступных по пути к КЛАССАМ.Но когда я запускаю свои классы и пытаюсь запустить их с 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 ...)

Да, в 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

Это поставило в тупик меня и всех коллег, которых я прослушивал уже больше дня.Просто чтобы отбросить ответы, по крайней мере, на данный момент, сторонние решения для этого, вероятно, недоступны из-за лицензионных ограничений и политики компании (например:инструменты для создания исполняемых файлов или упаковки банок).Конечная цель - создать jar, который можно скопировать из моего окна Windows для разработки на сервер Linux (с любыми зависимыми jar) и использовать для заполнения базы данных (поэтому пути к классам могут отличаться в средах разработки и развертывания).Мы были бы очень признательны за любые подсказки к этой тайне!

Это было полезно?

Решение

Параметр -jar взаимоисключает параметр -classpath.Смотрите старое описание здесь

-банка

Запустите программу, инкапсулированную в JAR-файл.Первым аргументом является имя файла JAR вместо имени класса startup.Чтобы эта опция работала, манифест файла JAR должен содержать строку вида Main-Class:имя класса.Здесь classname идентифицирует класс, имеющий открытый статический метод void main(String[] args), который служит отправной точкой вашего приложения.

Смотрите справочную страницу Jar tool и Jar trail руководства по Java для получения информации о работе с файлами Jar и манифестами Jar-файлов.

Когда вы используете этот параметр, файл JAR является исходным кодом всех пользовательских классов, а другие параметры пути к пользовательскому классу игнорируются.

Быстрый и грязный способ - добавить ваш classpath к bootstrap classpath:

-Путь к Xbootclasspath/a:путь

Укажите разделенный двоеточием путь к directires, JAR-архивам и ZIP-архивам для добавления к пути к классу начальной загрузки по умолчанию.

Однако, поскольку @Dan правильно сказано, правильное решение - убедиться, что ваш манифест JARs содержит путь к классу для всех JARS, которые ему понадобятся.

Другие советы

Вы можете опустить опцию -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".

Решение:-

  1. Щелкните правой кнопкой мыши на проекте, выберите пункт Экспортировать.
  2. Выберите папку Java и в ней выберите Runnable JAR File вместо JAR-файла.
  3. Выберите соответствующие параметры и в разделе Обработка библиотеки выберите 3-й вариант, т.е.(Скопируйте необходимые библиотеки во вложенную папку рядом с созданным JAR).

[ Редактировать = 3-й вариант создает папку в дополнение к jar, 2-й вариант ("Упакуйте необходимые библиотеки в сгенерированный JAR") также можно использовать, поскольку у вас есть jar.]

  1. Нажмите кнопку готово, и ваш JAR будет создан в указанном месте вместе с папкой, содержащей JAR, упомянутые в файле манифеста.
  2. откройте терминал, укажите правильный путь к вашему jar и запустите его, используя эту команду java -jar abc.jar

    Теперь произойдет то, что загрузчик классов будет искать в правильной папке указанные банки, поскольку теперь они присутствуют в той же папке, которая содержит ваше приложение JAR .. Там нет "java.lang.Сейчас генерируется исключение NoClassDefFoundError".

У меня это сработало...Надеюсь, у вас это тоже сработает!!!

если вы используете в своей программе внешние библиотеки и пытаетесь упаковать все вместе в файл jar, это не так просто из-за проблем с classpath и т. д.

Я бы предпочел использовать OneJar для этой проблемы.

у меня была та же проблема с моей банкой решение

<Ол>
  • Создайте файл MANIFEST.MF:
  •   

    Manifest-Version: 1.0

         

    Запечатано: правда

         

    Class-Path:. lib / jarX1.jar lib / jarX2.jar lib / jarX3.jar

         

    Основной класс: com.MainClass

    1. Щелкните правой кнопкой мыши проект, выберите "Экспорт".
    2.   

      выберите экспорт всех выходных папок для проверенного проекта

      1. выберите с помощью существующего манифеста из рабочей области и выберите файл MANIFEST.MF
      2. Это сработало для меня :)

    Я обнаружил, что когда я использую манифест, в списке банок для пути к классам должен быть пробел после списка каждой банки, например, " required_lib / sun / pop3.jar required_lib / sun / smtp.jar " ;. Даже если это последний в списке.

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top