6

I can make a executable jar file with Eclipse. Let's say it is called ast.jar, and the Main class is ASTExplorer. I can verify that this works with java -jar ast.jar.

Then, I unzip the jar file in a separate directory and verify that the ASTExplorer is in astexplorer directory. But when I executed this command java -cp . astexplorer.ASTExplorer I get this error.

java -cp . astexplorer/ASTExplorer
Exception in thread "main" java.lang.NoClassDefFoundError: org/eclipse/swt/widgets/Composite
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
at java.lang.ClassLoader.defineClass(ClassLoader.java:615)

The thing is that there is no org/eclipse/swt directory in the jar file.

Directory screenshot

What's the magic behind the executable jar file? Why doesn't it run when unzipped?

prosseek
  • 182,215
  • 215
  • 566
  • 871
  • You should try creating your JAR with ant, without the eclipse black magic. – Gilberto Torrezan Sep 24 '12 at 21:53
  • What is your classpath when you run `java -jar ast.jar`. When you unpack the jar file your classpath is `.`. I'm guessing that there is an environment variable CLASSPATH set to something that allows the `java -jar ast.jar` to work. – km1 Sep 24 '12 at 21:57

1 Answers1

2

When Eclipse packages a runnable jar, it includes the dependencies as nested jar files, and also includes a special classloader that understands how to find classes in nested jars. It works only with nested jars and when you extract everything you prevent it from working.

I've looked in an Eclipse-produced runnable jar, and here's what I think you'd need to do:

  1. Extract everything to a directory. The dependency jars are extracted at the top level directory
  2. Delete the org/eclipse/jdt/internal directory
  3. Run your main class from the top level directory with

    java -cp .;dep-jar;dep-jar;... your.main.class

I tried this with a runnable jar I happen to have lying around and it works. Step 2 isn't strictly necessary.

Jim Garrison
  • 85,615
  • 20
  • 155
  • 190
  • I could make it execute using -cp .:ALL THE JAR FILES FROM ECLIPSE main.class. I think there seems to be no big magic behind the eclipse generated executable jar file other than wrapping it up and make a reference to the jar files automatically – prosseek Sep 24 '12 at 22:21
  • 1
    Plus substituting the "jarinjar" classloader in the mainfest file. – Jim Garrison Sep 24 '12 at 22:40