Что может вызвать «Не удалось найти основной класс» при упаковке банки? - PullRequest
1 голос
/ 03 ноября 2011

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

За последние пару месяцев я добавил новые функции, всегда тестируя их из затмения. Теперь, когда все готово, я хотел сделать релиз, собрал установщик Windows с помощью скрипта ant, который всегда создавал работающий установщик, но после установки при запуске приложения сразу отображается информационное окно с этим сообщением.

Средство запуска виртуальной машины Java Не удалось найти основной класс: net.pms.PMS. Программа будет закрыта. OK

Я не могу понять, какие изменения были сделаны, чтобы сломать упаковку.

Некоторые факты:

  • Для сборки установщика ANT-скрипт , вызывающий два NSIS-скрипта, находится в процессе используемый. Это скрипт ANT, который упаковывает банку. Эти сценарии не изменились между двумя версиями. Манифест для основного метода (net.pms.PMS) устанавливается в сценарии ANT.
  • Довольно большой объем кода изменился между двумя версиями; так как ошибка основного класса не обнаруживается сразу при запуске приложения, я склонен думать, что ни измененный код, ни измененный импорт для jar-файлов не могут это спровоцировать!?
  • Файлы классов, связанные с основным классом, включены в пакет, и я обещаю, что PMS.java содержит метод main pms-mlx jar content
  • Неважно, как запускается приложение; exe launcher, командный файл или командная строка, основной класс не найден всегда отображается.
  • Я установил jdk7. Поскольку это могло конфликтовать с jdk6, я удалил все, что связано с 7, и в настоящий момент запускаю jdk6_29
  • В приложении доступна система плагинов, в которой плагины загружаются из папки динамически во время выполнения ExternalFactory . То, как это делается, немного изменилось. Опять же, как и во время выполнения, я не могу себе представить, что что-то там может спровоцировать проблему.
  • Я не могу найти никакой информации в журнале событий Windows, не нашел журналы Java, и журналы приложений, очевидно, вообще не инициализируются.

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

Спасибо, Филипп

[редактировать] Некоторые дополнения, связанные с размещенными комментариями:

Содержимое MANIFEST.MF:
Манифест-версия: 1.0
Ant-версия: Apache Ant 1.8.2
Создано: 1.6.0_29-b11 (Sun Microsystems Inc.)
Основной класс: net.pms.PMS

Как запускается приложение:
При запуске с пакетом: javaw -Xmx768M -Djava.net.preferIPv4Stack = true -Dfile.encoding = UTF-8 -classpath update.jar; pms.jar net.pms.PMS
exe, сгенерированный с помощью NSIS: -classpath update.jar; pms.jar -Xmx1024M -Dsun.java2d.d3d = false -Djava.net.preferIPv4Stack = true -Dfile.encoding = UTF-8 $ {CLASS} $ 1

При попытке запустить его с помощью 'java -cp pms.jar net.pms.PMS' появляется интересная трассировка стека
C:\Program Files (x86)\PS3 Media Server MLX>java -cp pms.jar net.pms.PMS Exception in thread "main" java.lang.SecurityException: Invalid signature file digest for Manifest main attributes at sun.security.util.SignatureFileVerifier.processImpl(Unknown Source) at sun.security.util.SignatureFileVerifier.process(Unknown Source) at java.util.jar.JarVerifier.processEntry(Unknown Source) at java.util.jar.JarVerifier.update(Unknown Source) at java.util.jar.JarFile.initializeVerifier(Unknown Source) at java.util.jar.JarFile.getInputStream(Unknown Source) at sun.misc.JarIndex.getJarIndex(Unknown Source) at sun.misc.URLClassPath$JarLoader$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at sun.misc.URLClassPath$JarLoader.ensureOpen(Unknown Source) at sun.misc.URLClassPath$JarLoader.(Unknown Source) at sun.misc.URLClassPath$3.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at sun.misc.URLClassPath.getLoader(Unknown Source) at sun.misc.URLClassPath.getLoader(Unknown Source) at sun.misc.URLClassPath.getResource(Unknown Source) 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) Could not find the main class: net.pms.PMS. Program will exit.

Ответы [ 4 ]

3 голосов
/ 04 ноября 2011

Хорошо, я проведу вас через процесс, который я прошел, чтобы проанализировать проблему:

  • Я взял тебе банку и попытался запустить ее через java -jar pms.jar. Действительно, это не удалось с вышеупомянутыми сообщениями об ошибках.
  • Я создал в вашем пакете быстрый тестовый класс, который просто печатает сообщение в system.out и помещает его в файл jar в папке net.pms.
  • Я вручную изменил атрибут Main-Class в Манифесте, чтобы вызвать этот класс (таким образом: net.pms.Test).
  • Я перезапустил java -jar pms.jar и получил те же сообщения об ошибках.
  • Я удалил все дополнительные папки из корня фляги и перезапустил java -jar pms.jar. Он выдал те же сообщения об ошибках.
  • Я удалил все дополнительные папки из META-INF и перезапустил java -jar pms.jar. Он по-прежнему выдавал те же сообщения об ошибках.
  • Я удалил все дополнительные файлы из META-INF и повторно запустил java -jar pms.jar. Приложение работало нормально.
  • Я начал со свежей копии банки, удалил только все дополнительные файлы из META-INF и перезапустил java -jar pms.jar. Приложение работало нормально.
  • Я начал со свежей копии фляги и один за другим я удалил дополнительные файлы из META-INF, повторно запустив java -jar pms.jar, когда я пошел дальше. Это дало мне следующие результаты:

Если в каталоге META-INF содержится один из файлов NB_IDE.DSA или NB_IDE.SF, Java не может найти основной класс вашего приложения. Похоже, что информация в этих файлах каким-то образом влияет на механизм определения местоположения загрузчика классов.

Я посмотрел на файлы, и кажется, что это какой-то специфический информационный файл Netbeans. Google действительно не дал мне никаких результатов по этому поводу, и моя сеть коллег не имела никаких подсказок по этому поводу. На этом этапе я обычно обращаюсь к StackOverflow за помощью, но, учитывая, что файлы касаются только информации о зависимостях Netbeans, я предполагаю, что файлы используются только в вашей IDE. Кроме того, поскольку эта информация необходима во время сборки, а не во время выполнения, я предполагаю, что безопасно удалить файлы из окончательной версии.

Все, что вам нужно сделать сейчас, это исключить файлы из окончательной сборки через ваш build.xml. Я оставлю это на ваше усмотрение, так как в Интернете много документации по Ant. :)

Теперь, почему я так подробно рассказал об этом?
Ну, это типичный процесс, которому я следую, если сталкиваюсь с такой проблемой. Во-первых, я исключаю все мешающие параметры, чтобы точно определить проблему. Затем я анализирую результат - возможно, используя Интернет, чтобы прояснить моменты, с которыми я не знаком, - чтобы устранить не симптомы, а причину. Тогда я устраню причину.

Лично я считаю, что этот процесс является отличным инструментом в каждом наборе инструментов для разработчиков, чтобы быстро решать проблемы, подобные той, с которой вы столкнулись. Я надеюсь, что вы сможете использовать его когда-нибудь в будущем, и вам не придется ждать дни и дни, пока моя ленивая задница наконец-то взглянет на это. :)

Удачи в вашем программном обеспечении!

0 голосов
/ 03 ноября 2011

Ну, во-первых, я предполагаю, что MANIFEST.MF находится в папке META-INF - иначе вы, вероятно, давно бы нашли решение через Google. :)

То, что вы говорите, это то, что вы обещаете, что PMS.java содержит основной класс [sic]. Если вы не сделали там опечатку и не имеете в виду основной «метод», я думаю, у вас есть внутренний класс, который вы хотели бы использовать в качестве основной точки входа для вашего приложения. Структура jar в вашем посте дает нам дополнительные доказательства этого, поскольку показывает, что в вашем основном классе действительно есть несколько внутренних классов.

Я должен сказать, что это довольно странная конструкция - запускать ваше приложение через внутренний класс, и, честно говоря, я не уверен, возможно ли это вообще или нет. Я настоятельно рекомендую вам переместить основной метод непосредственно в PMS.java.

Если вы действительно хотите использовать внутренний класс в качестве точки входа, попробуйте что-то вроде этого как свойство Main-Class в своем манифесте:

Main-Class: net.pms.PMS$1

Где $1 - класс, который фактически содержит метод main.

Опять же, поскольку я не знаю, требуют ли ваши внутренние классы экземпляра внешнего класса и поддерживает ли Java на самом деле внутренние классы в качестве отправной точки для вашего приложения, это может не сработать вообще. Мой совет по-прежнему заключается в том, чтобы перенести основной метод в PMS.java.

Удачи!

0 голосов
/ 03 ноября 2011

Хорошо, я думаю, что знаю, что может происходить: команды, которые вы используете для запуска приложения, действительно помещают ваш файл jar в путь к классам, но они не сообщают Java, где найти основной класс!

javaw -Xmx768M -Djava.net.preferIPv4Stack=true -Dfile.encoding=UTF-8 -classpath update.jar;pms.jar net.pms.PMS

Это говорит Java использовать pms.jar в classpath и перейти в папку net/pms в текущей структуре для запуска класса PMS.

Попробуйте просто:

java -jar pms.jar

как предложено AlexR, пожалуйста, и дайте нам знать, что это показывает вам ...

0 голосов
/ 03 ноября 2011

Вы когда-нибудь запускали собранный пакет раньше?На одной машине?Вы запускали его из командной строки или пытались?

В настоящее время вы запускаете его двойным щелчком мыши?Я предполагаю, что мы предполагаем, что вы находитесь в Windows, так как вы используете WinRAR.

Вы сосредоточены на предполагаемом «изменении ... сделанном, чтобы сломать упаковку»;Как вы уверены, что ваша среда правильно настроена для запуска программы?Вы не перечисляете подробную информацию о библиотеках, каталогах и т. Д., Которые необходимы.

Вы показываете нам, что класс находится в файле jar, но вы не показываете, по какому пути он идет.И я согласен, что манифест был бы полезен.

Если мы действительно смотрим на проблему с муравьями, вы можете пометить этот вопрос для Ant.

...