NoClassDefFoundError при запуске из jar - PullRequest
3 голосов
/ 14 сентября 2009

Я получаю исключение "не найдено определение класса" при попытке запустить мое приложение в Windows (оно нормально работает в OS X). Классы, на которые жалуется JVM, являются моими классами (сторонние банки не требуются). Когда я распаковываю файлы внутри фляги, присутствуют все файлы, включая те, на которые жалуется JVMm.

Баночка создается с помощью следующей задачи:

<target name="jar" depends="">
<jar destfile="build/app.jar" > 
  <manifest>
    <attribute name="Built-By" value="hamza"/>
    <attribute name="Main-Class" value="com.hamza.driver.ui"/>
<attribute name="Class-Path" value="./"/>
  </manifest>
  <fileset dir="build">
    <include name="**/*.class"/>
<include name="**/*.png"/>
<include name="**/*.xpi"/>
<include name="**/*.html"/>
<exclude name="**/*.jar"/>
  </fileset>
</jar>

Я не могу понять, в чем причина проблемы. Если я разархивирую банку и запускаю банку из каталога, в который разархивировал класс, все работает нормально. Итак, я предполагаю, что все необходимые файлы находятся внутри банки.

EDIT: com.hamza.driver.ui - это класс в пакете с именем com.hamza.driver, который имеет main.

После сборки я получаю один jar "app.jar" и запускаю его, используя "java -jar app.jar", который отлично работает в OS X, но не в Windows.

Если я разархивирую app.jar в отдельном каталоге и запускаю «java -jar app.jar», это оправдывает себя.

РЕДАКТИРОВАТЬ 2: исключение:

Exception in thread "main" java.lang.NoClassDefFoundError: com/hamza/gui/tr
ansfer/ClipboardTransferHandle
        at com.hamza.driver.ui.main(Unknown Source)
Caused by: java.lang.ClassNotFoundException: com.hamza.gui.transfer.Clipboa
rdTransferHandle
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClassInternal(Unknown Source)
        ... 1 more

Файлы ClipboardTransferHandle .class присутствуют в банке.

РЕДАКТИРОВАТЬ 3: импорт для класса буфера обмена:

import java.util.logging.Logger;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.Toolkit;
import java.io.IOException;

Во время игры с ним я обнаружил, что если я пытаюсь объявить ClipboardTransferHandle как статическую переменную в драйвере, она работает, но каждый объект, который не является статическим, не найден. Все основные элементы GUI являются статическими переменными, поэтому GUI построен, а другие элементы нет; все, что создано не статично, вызывает NoClassDefFound, но если я объявлю их статичными для тестирования, они будут работать.

Ответы [ 4 ]

2 голосов
/ 05 сентября 2012

Это проблема, которая возникает,

если файл 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. Выберите правильные параметры и в разделе «Обработка библиотек» выберите третий вариант, т. Е. (Скопируйте необходимые библиотеки в подпапку рядом с сгенерированным JAR).
  4. Нажмите "Готово", и ваш JAR будет создан в указанной позиции вместе с папкой, содержащей JARS, упомянутый в файле манифеста.
  5. откройте терминал, укажите правильный путь к вашему банку и запустите его с помощью этой команды java -jar abc.jar

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

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

1 голос
/ 14 сентября 2009

Какой класс отсутствует? Ваш атрибут Main-Class выглядит немного подозрительно - это com.hamza.driver.ui класс или пакет?

1 голос
/ 14 сентября 2009

Есть вероятность, что NoClassDefFoundError (я действительно ненавижу эту ошибку - всегда сводит меня с ума ...) не брошен, потому что он не находит класс, который говорит вам (-> ваш класс), а потому, что Java не удается найти один из классов, которые используются для создания экземпляра этого класса.

Однажды у меня возникла эта проблема, когда класс импортировал другой класс из другого jar-файла (в моем случае - пакета OSGi), который не был должным образом экспортирован. Хотя это была специфическая проблема OSGi - у вас могут быть такие же проблемы в вашей среде. Возможно, ваше приложение зависит от некоторых классов, которые присутствуют в вашей реальной среде OS-X, но не в реальной среде Windows. Я смотрю не на сторонние библиотеки, а на саму реализацию Java.

Удачи!

Редактировать

Есть еще два довольно похожих вопроса о SO, к сожалению, без принятого решения, но, возможно, один из советов может помочь в вашем случае:

NoClassDefFound при запуске баночки

NoClassDefFoundError в банке

Редактировать 2

Вот аналогичная проблема, что имеет принятый ответ. Надеюсь, что это поможет:

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

0 голосов
/ 14 сентября 2009

Вы указали новый jar в своем пути к классам (java -cp.; New.jar MainClass.class)?

...