1

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.

Philippe
  • 1,949
  • 4
  • 31
  • 57
  • Can you show the manifest please? (The one in the jar file, after building.) – Jon Skeet Nov 03 '11 at 08:22
  • The content of MANIFEST.MF is 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 – Philippe Nov 03 '11 at 08:33
  • How are you running the app? `java -jar pms.jar`? What happens if you say `java -cp pms.jar net.pms.PMS`? – AlexR Nov 03 '11 at 08:38
  • I've answered the questions on the bottom of the post – Philippe Nov 03 '11 at 08:58
  • You ARE running the command suggested by AlexR from the folder where the pms.jar is located, right? – LeChe Nov 03 '11 at 09:08
  • @LeChe yes I do, 'C:\Program Files (x86)\PS3 Media Server MLX' is the default installation path for the application. I'll try to dig a bit deeper into what causes 'Exception in thread "main" java.lang.SecurityException: Invalid signature file digest for Manifest main attributes at' – Philippe Nov 03 '11 at 09:17
  • Could you please do a simple `java -jar pms.jar`, too? Cause the way I see it, your are putting the jar on your classpath, but you are not telling java where to find the Main class... – LeChe Nov 03 '11 at 09:27
  • Of course. It results in exactly the same stack trace with the SecurityException as posted above – Philippe Nov 03 '11 at 09:30
  • Damn, and I went through all the trouble of creating an extra post to give some more information on this... ;) – LeChe Nov 03 '11 at 09:33
  • One more try: you DO have a line feed after the last line of the manifest, right? – LeChe Nov 03 '11 at 09:38
  • Actually I've got two. It contains the four lines posted above plus two blank lines at the end. Thanks a lot for taking the time for trying to figure this out!! – Philippe Nov 03 '11 at 09:44
  • Well, I think that without having the actual jar file, this will be hard to solve. :( Is there a way to make the jar available to us? – LeChe Nov 03 '11 at 10:01
  • I've uploaded the jar as well as the zipped sources here http://sourceforge.net/projects/pms-mlx/files/development/tmp/ The sources have been used to build the jar. They do NOT correspond to the checked in ones, I wanted to fix the problem we're discussing before doing the check-in. – Philippe Nov 03 '11 at 10:54

4 Answers4

3

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!

LeChe
  • 1,288
  • 14
  • 18
  • Wow, that's what I call helping out! Calling you a lazy-ass would be the last thing coming to my mind ;) Usually I feel more at home in the .NET world. Coding java goes fine but when it comes to build processes as this one I'm pretty lost in understanding what can go wrong. Reading this thread (http://stackoverflow.com/questions/999489/invalid-signature-file-when-attempting-to-run-a-jar) I had started deleting some references, also the netbeans one you've mentioned, but I still couldn't get it to work. Again, THANKS! – Philippe Nov 04 '11 at 15:15
  • Btw, the netbeans jar had been added because of another issue I'll have to solve (http://stackoverflow.com/questions/7172097/jtable-with-jgoodies-sorting-trouble). If you happen to come through Switzerland you're welcome to grab a beer :) – Philippe Nov 04 '11 at 15:25
  • Thanks a lot, that sounds like a plan! :) Glad I could help. Just note that it is not about the jar, but about the additional files in META-INF! Good luck... – LeChe Nov 04 '11 at 15:35
0

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.

arcy
  • 12,845
  • 12
  • 58
  • 103
  • I've been working for almost three years on this project and never had problems with the packaging before.
    I'm coding on OSX and running it on win7 64bit
    I've been using this application for years without trouble. If the installer is being built from the linked head of the trunk it installs correctly. With the installer built by the version I'm working the problem occurs. The source is NOT checked in this repo yet!
    In winrar the path of the file is being shown as pms.jar\net\pms, that's where it lives.
    Hope this info helps
    – Philippe Nov 03 '11 at 08:56
0

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!

LeChe
  • 1,288
  • 14
  • 18
  • Yep, the MANIFEST.MF file is contained in the META-INF folder. Sorry for the confusion, I ment main method. No funny constructs with inner classes ;) – Philippe Nov 03 '11 at 09:00
  • Alright, one last shot: what is the signature of your main method? You say that you tested the functionality through eclipse - I assume unit tests - but maybe your main method is invalid... – LeChe Nov 03 '11 at 09:06
  • As nothing changed in there, it should be fine 'public static void main(String args[]) throws IOException, ConfigurationException' (http://pms-mlx.svn.sourceforge.net/viewvc/pms-mlx/trunk/ps3mediaserver_mlx/net/pms/PMS.java?revision=48&view=markup) – Philippe Nov 03 '11 at 09:18
  • Apart from some general comments on the structure of the class, I must say that the main method signature seems to be fine, indeed. Bummer... :( – LeChe Nov 03 '11 at 09:23
  • I agree with that, but the general architecture of the code is outside of the scope of this question ;) – Philippe Nov 03 '11 at 09:25
0

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...

LeChe
  • 1,288
  • 14
  • 18