什么会导致“无法找到主类”?包装罐子时?

发布于 2024-12-13 10:37:40 字数 3351 浏览 0 评论 0原文

我正在参与一个开源项目,其中我有自己的存储库用于我正在进行的修改。

在过去的几个月里,我添加了新功能,同时始终在 Eclipse 中测试功能。现在一切都准备好了,我想发布一个版本,用 ant 脚本构建 Windows 安装程序,该脚本总是生成一个可用的安装程序,但安装后,启动应用程序时,会立即显示带有此消息的信息窗口。

Java 虚拟机启动器 找不到主类:net.pms.PMS。程序将退出。 好吧,

我不知道做了什么改变来破坏包装。

一些事实:

  • 要构建安装程序,需要 ANT 脚本 正在调用两个 NSIS scipt 用过的。这是打包 jar 的 ANT 脚本。这些脚本在两个版本之间没有变化。主方法 (net.pms.PMS) 的清单正在 ANT 脚本中设置。
  • 两个版本之间有相当多的代码发生了变化;由于启动应用程序时立即显示未找到主类错误,我倾向于认为更改的代码和更改的 jar 导入都不会引起这种情况!?
  • 包含主类的类文件包含在包中,我保证 PMS.java 包含一个主要方法 pms-mlx jar content
  • 应用程序如何启动并不重要; exe 启动器,批处理文件或命令行,总是显示找不到主类。
  • 我已经安装了jdk7。由于它可能与 jdk6 冲突,我已经卸载了与 7 相关的所有内容,并且当前运行 jdk6_29
  • 应用程序中提供了一个插件系统,其中插件在运行时从文件夹动态加载 外部工厂。这样做的方式已经发生了很大变化。同样,由于是在运行时,我无法想象其中的某些内容可能会引发问题。
  • 我在 Windows 事件日志中找不到任何信息,也没有找到任何 java 日志,并且应用程序日志显然根本没有初始化。

我目前不知道我所做的更改会引发此主类未找到错误。如果有人能通过一些线索为我指明正确的方向,我将非常感激,我可以从中获得一些有用的信息或实际发生的情况。

谢谢,Philippe

[编辑]与发布的评论相关的一些补充:

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
使用 NSIS 生成的 exe: -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 线程“main”中出现异常 java.lang.SecurityException:Manifest 主要属性的签名文件摘要无效 在 sun.security.util.SignatureFileVerifier.processImpl(来源未知) 在 sun.security.util.SignatureFileVerifier.process(来源未知) 在 java.util.jar.JarVerifier.processEntry(来源未知) 在 java.util.jar.JarVerifier.update(来源未知) 在 java.util.jar.JarFile.initializeVerifier(来源未知) 在 java.util.jar.JarFile.getInputStream(来源未知) 在 sun.misc.JarIndex.getJarIndex(来源未知) 在 sun.misc.URLClassPath$JarLoader$1.run(来源未知) 在 java.security.AccessController.doPrivileged(本机方法) 在 sun.misc.URLClassPath$JarLoader.ensureOpen(来源未知) 在 sun.misc.URLClassPath$JarLoader。(来源未知) 在 sun.misc.URLClassPath$3.run(来源未知) 在 java.security.AccessController.doPrivileged(本机方法) 在 sun.misc.URLClassPath.getLoader(来源未知) 在 sun.misc.URLClassPath.getLoader(来源未知) 在 sun.misc.URLClassPath.getResource(来源未知) 在 java.net.URLClassLoader$1.run(来源未知) 在 java.security.AccessController.doPrivileged(本机方法) 在 java.net.URLClassLoader.findClass(来源未知) 在 java.lang.ClassLoader.loadClass(来源未知) 在 sun.misc.Launcher$AppClassLoader.loadClass(来源未知) 在 java.lang.ClassLoader.loadClass(来源未知) 找不到主类:net.pms.PMS。程序将退出。

I'm participating in an open source project, where I've got my own repo for the modification I'm working on.

I've added new features over the last couple of months while always testing the functionalities from within eclipse. Now that everything is ready, I wanted to make a release, built the windows installer with the ant script which always produced a working installer, but after installation, when launching the application a information window with this message is being displayed right away.

Java Virtual Machine Launcher
Could not find the main class: net.pms.PMS. Program will exit.
OK

I can't figure out what change has been made to break the packaging.

Some facts:

  • To build the installer, an ANT script calling two NSIS scipts is being
    used. It's the ANT script which is packaging the jar. These scripts haven't changed between the two versions. The manifest for the main method (net.pms.PMS) is being set in the ANT script.
  • Quite a big amount of code has changed between the two versions; as the main class not found error is being shown right away when starting the application I tend to think neither the changed code nor changed imports for jars can provoke that!?
  • The class files containg the main class are included in the package and I promise PMS.java contains a main method pms-mlx jar content
  • It doesn't matter how the application is being started; exe launcher, batch file or command line, the main class not found always shows up.
  • I had installed the jdk7. As it might have been conflicting with jdk6, I've uninstalled everyting related to 7 and currently run jdk6_29
  • A plugin system is available in the application, where plugins get loaded from a folder dynamically on runtime ExternalFactory. The way this being done has changed quite a bit. Again, as it is during runtime, I can't imagine something in there could provoke the problem.
  • I can't find any information either in the windows event log, haven't found any java logs and the application logs obviously aren't initialized at all.

I'm currently clueless what change I've made provokes this main class not found error. I'd be really grateful if someone could point me into the right direction with some clues where I could get some useful information from or what is actually going on.

Thanks, Philippe

[edit] Some additions related to the posted comments:

Contents of MANIFEST.MF:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.8.2
Created-By: 1.6.0_29-b11 (Sun Microsystems Inc.)
Main-Class: net.pms.PMS

How is the application started:
If launched with the batch: javaw -Xmx768M -Djava.net.preferIPv4Stack=true -Dfile.encoding=UTF-8 -classpath update.jar;pms.jar net.pms.PMS
exe generated with NSIS: -classpath update.jar;pms.jar -Xmx1024M -Dsun.java2d.d3d=false -Djava.net.preferIPv4Stack=true -Dfile.encoding=UTF-8 ${CLASS} $1

When trying to launch it with 'java -cp pms.jar net.pms.PMS' an intersting stack trace shows up
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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

吃素的狼 2024-12-20 10:37:40

好的,我将引导您完成分析问题的过程:

  • 我拿了您的 jar 并尝试通过 java -jar pms.jar 运行它。事实上,上面提到的错误消息失败了。
  • 我在您的包中创建了一个快速测试类,它只是将消息打印到 system.out 并将其放入 net.pms 文件夹中的 jar 文件中。
  • 我手动更改了清单中的 Main-Class 属性来调用该类(因此:net.pms.Test)。
  • 我重新运行 java -jar pms.jar 并收到相同的错误消息。
  • 我从 jar 根目录中删除了所有其他文件夹并重新运行 java -jar pms.jar。它产生了相同的错误消息。
  • 我从 META-INF 中删除了所有其他文件夹,并重新运行 java -jar pms.jar。它仍然产生相同的错误消息。
  • 我从 META-INF 中删除了所有其他文件,并重新运行 java -jar pms.jar。该应用程序运行良好。
  • 我从 jar 的新副本开始,仅删除了 META-INF 中的所有其他文件,然后重新运行 java -jar pms.jar 。该应用程序运行良好。
  • 我从 jar 的新副本开始,逐个删除了 META-INF 中的附加文件,然后重新运行 java -jar pms.jar沿着。这给了我以下结果:

如果您的 META-INF 目录包含文件 NB_IDE.DSANB_IDE.SF 之一,则主Java 无法找到您的应用程序的类。看来这些文件中的信息在某种程度上影响了类加载器的位置机制。

我查看了这些文件,似乎是一些 Netbeans 特定的信息文件。 Google 并没有真正给我任何信息对此结果,我的同事网络也没有任何线索。此时,我通常会向 StackOverflow 寻求帮助,但看到这些文件只涉及 Netbeans 依赖信息,我假设这些文件仅在您的 IDE 中使用。另外,由于这是构建时所需的信息,而不是运行时所需的信息,因此我认为从最终版本 jar 中删除这些文件是安全的。

您现在要做的就是通过 build.xml 从最终构建中排除这些文件。我将把这个问题留给您,因为互联网上有大量有关 Ant 的文档。 :)

现在,为什么我要详细介绍这一点?
好吧,如果我遇到这样的问题,这是我遵循的典型流程。首先,我排除所有干扰参数以查明问题。然后,我分析结果——可能会利用互联网来澄清我不熟悉的地方——不是解决症状而是解决原因。然后我消除原因。

就我个人而言,我认为这个过程是每个开发人员工具箱中的一个很好的工具,可以快速解决您所面临的问题。我希望您将来可以重新使用它,而不必等待几天又几天让我这个懒蛋终于看到它。 :)

祝您的软件好运!

Okay, I will walk you through the process I went through to analyse the issue:

  • I took you jar and tried to run it via java -jar pms.jar. Indeed, that failed with the above mentioned error messages.
  • I created a quick test class in your package that simply prints a message to system.out and put it in the jar file in the folder net.pms.
  • I manually changed the Main-Class attribute in the Manifest to call that class (thus: net.pms.Test).
  • I re-ran java -jar pms.jar and got the same error messages.
  • I deleted all additional folders from the root of the jar and re-ran java -jar pms.jar. It yielded the same error messages.
  • I deleted all the additional folders from META-INF and re-ran java -jar pms.jar. It still yielded the same error messages.
  • I deleted all additional files from META-INF and re-ran java -jar pms.jar. The application worked fine.
  • I started with a fresh copy of the jar, deleted only all additional files from META-INF and re-ran java -jar pms.jar. The application worked fine.
  • I started with a fresh copy of the jar and one by one, I deleted the additional files from META-INF, re-running java -jar pms.jar as I went along. This gave me the following results:

If your META-INF directory contains either one of the files NB_IDE.DSA or NB_IDE.SF, the main class of your application cannot be found by Java. It appears that the information in those files somehow influences the location mechanism of the classloader.

I had a look at the files and it seems that it is some Netbeans specific information file. Google did not really give me any results on this, neither did my network of colleagues have any clues on it. At this point, I would usually ask StackOverflow for help, but seeing that the files only concern Netbeans dependency information, I assume that the files are only used in your IDE. Also, since this is information that is needed at build time, but not at runtime, I assume that it is safe to remove the files from your final release jar.

All you have to do now is exclude the files from the final build through your build.xml. I'll leave this up to you, as there is plenty of documentation on Ant on the internet. :)

Now, why did I go through this in so much detail?
Well, this is the typical process that I follow if I am facing a problem like this. First, I exclude all interfering parameters to pinpoint the problem. Then, I analyze the result - potentially using the internet to clarify points that I am not familiar with - to not resolve the symptoms but the cause. Then I eliminate the cause.

Personally, I think that this process is a great tool in every developers toolbox to quickly resolve issues like the one you were facing. I hope that you can re-use it sometime in the future and don't have to wait days and days for my lazy-ass to finally have a look at it. :)

Good luck with your software!

左岸枫 2024-12-20 10:37:40

您以前运行过构建的包吗?在同一台机器上?您是否从命令行运行它,或者尝试这样做?

您当前是否通过双击运行它?我想我们会假设您使用的是 Windows,因为您使用 WinRAR。

您正在关注所谓的“改变......旨在打破包装”;您如何确定您的环境已正确设置以运行该程序?您没有列出必要的库、目录等详细信息。

您向我们显示该类位于 jar 文件中,但没有向我们显示它所在的路径。我同意清单会很有用。

如果我们确实正在研究 ant 问题,您可以将此问题标记为 Ant。

Have you ever run the built package before? On the same machine? Did you run it from a command line, or try to?

Are you currently running it by a double-click? I guess we'll assume you're in Windows, since you use WinRAR.

You are focusing on a supposed "change ... made to break the packaging"; how sure are you that your environment is set up properly for running the program? You don't list details of libraries, directories, etc. that are necessary.

You show us that the class is in the jar file, but you don't show us what path it is on. And I agree the manifest would be useful.

If we really are looking at an ant problem, you might tag this question for Ant.

月亮邮递员 2024-12-20 10:37:40

好吧,首先,我假设 MANIFEST.MF 位于 META-INF 文件夹中 - 否则你可能很久以前就通过 google 找到了解决方案。 :)

你所说的是你承诺 PMS.java 包含一个主类 [原文如此]。
除非您在那里犯了一个拼写错误并且您实际上指的是主要“方法”,否则我猜您有一个内部类,您希望将其用作应用程序的主要入口点。您帖子中的 jar 结构为我们提供了进一步的证据,因为它向我们表明您的主类中确实有多个内部类。

我必须说,通过内部类启动应用程序是一个非常奇怪的构造,坦率地说,我不确定这是否可能。我强烈建议您直接将 main 方法移至 PMS.java 中。

如果您真的非常想使用内部类作为入口点,请在清单中尝试类似的 Main-Class 属性:

Main-Class: net.pms.PMS$1

其中 $1 是该类实际上包含了main方法。

同样,由于我不知道您的内部类是否需要外部类的实例,也不知道 Java 是否实际上支持内部类作为您的应用程序的起点,所以这可能根本不起作用。我的建议仍然是将 main 方法移至 PMS.java 中。

祝你好运!

Well, first of all, I assume that the MANIFEST.MF is located in the META-INF folder - otherwise you would have probably found a solution through google a long time ago. :)

What you say is that you promise that PMS.java contains a main class [sic].
Unless you made a typo there and you actually mean main 'method', I guess that you have an inner class that you would like to serve as the main entry point for your application. The jar structure in your post gives us further evidence to this, since it shows us that there are indeed multiple inner classes in your main class.

I must say that it is a pretty weird construct to start your application through an inner class and quite frankly, I am not sure whether this is even possible or not. I would strongly suggest you move the main method into PMS.java directly.

If you really, really want to use an inner class as the entry point, try something like this as the Main-Class property in your manifest:

Main-Class: net.pms.PMS$1

Where $1 is the class that actually contains the main method.

Again, since I don't know whether your inner classes require an instance of the outer class and whether Java actually supports inner classes as starting point for your application, this might not work at all. My advice still is to move the main method up into PMS.java.

Good luck!

固执像三岁 2024-12-20 10:37:40

好吧,我想我知道可能发生了什么:您用于运行应用程序的命令确实将您的 jar 文件放在类路径上,但它们没有告诉 Java 在哪里可以找到主类!

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

这告诉 Java 使用类路径中的 pms.jar 并转到当前结构中的文件夹 net/pms 来运行类 PMS

尝试简单的方法:

java -jar pms.jar

按照 AlexR 的建议,请让我们知道这向您展示了什么......

Alright, I think I know what might be going on: the commands you are using for running the application do indeed place your jar file on the classpath, but they do not tell Java where to find the main class!

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

This tells Java to use pms.jar in the classpath and to go to the folder net/pms in the current structure to run a class PMS.

Try the simple:

java -jar pms.jar

as suggested by AlexR, please and let us know what that shows you...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文