Forums Register Login

JAR file compile and execution error - NoClassDefFoundError

+Pie Number of slices to send: Send
Hi,

I have created an executable JAR file testapp.jar that contains a properties file. The folder structure is as follows:

TestApp (folder name)
testapp.jar
testapp_prop.properties

When I execute the jar file: "java -jar testapp.jar", I get a "NoClassDefFoundError".

The jar file in the TestApp folder was compiled beforehand and contains the META-INF manifest file and all other classes.

Why is this not working? Advice much appreciated.

Thanks.


+Pie Number of slices to send: Send
What's the internal structure of the jar file?

What are the contents of the manifest file?
+Pie Number of slices to send: Send
 

Ulf Dittmer wrote:What's the internal structure of the jar file?

What are the contents of the manifest file?



Hi there,

Internal structure of JAR is as follows:

testapp.jar ->

ar/mq/mqBrowse.java
META-INF/MANIFEST.MF
jndi.jar
connector.jar
com.ibm.mq.jar

MANIFEST.MF contents:

Manifest-Version: 1.0
Class-Path: com.ibm.mq.jar jndi.jar testapp.jar connector.jar c
onfig/
Sealed: true
Main-Class: ar.mq.mqBrowse.java


The weird thing is, if I copy all of these files into the SAME folder as the JAR file, then it works. I would like to just have a single JAR, however and be able to execute it by itself.

Thanks!
+Pie Number of slices to send: Send
 

testapp.jar ->

ar/mq/mqBrowse.java
META-INF/MANIFEST.MF
jndi.jar
connector.jar
com.ibm.mq.jar


You can't include jar files inside other jar files.
Your manifest file should have a Class-Path entry listing each of the jar files you need to reference, see the Sun Tutorial.

+Pie Number of slices to send: Send
 


testapp.jar ->

ar/mq/mqBrowse.java
META-INF/MANIFEST.MF
jndi.jar
connector.jar
com.ibm.mq.jar


The jar file needs to contain .class files, not .java files. And more importantly, jar files that are inside of other jar files can't be used for the classpath.


MANIFEST.MF contents:

Class-Path: com.ibm.mq.jar jndi.jar testapp.jar connector.jar config/
Main-Class: ar.mq.mqBrowse.java


Main-Class refers to a *class*, so it should read "ar.mq.mqBrowse"

The weird thing is, if I copy all of these files into the SAME folder as the JAR file, then it works.


That's actually not weird at all - jar files specified like that *always* refer to jar files that are in the same directory as the main jar file.

I would like to just have a single JAR, however and be able to execute it by itself.


Then you need to un-jar all those jar files into loose class files, and mix them with your class files into a single jar.
+Pie Number of slices to send: Send
 

Tony Docherty wrote:

testapp.jar ->

ar/mq/mqBrowse.java
META-INF/MANIFEST.MF
jndi.jar
connector.jar
com.ibm.mq.jar


You can't include jar files inside other jar files.
Your manifest file should have a Class-Path entry listing each of the jar files you need to reference, see the Sun Tutorial.



Interesting. I compiled the JAR file using the following:

jar cfvm testapp.jar META-INF\MANIFEST.MF *.jar ar/mq/*.class

It generates the testapp.jar file places the jar and class files into that jar. I now deleted the files and folders that I don't need to execute the jar and my folder now contains the following:

testapp.jar
com.ibm.mq.jar
jndi.jar
connector.jar
testapp_prop.properties

Executing testapp.jar now works! However, if I remove the other jar files from the folder and execute it, I get a missing class error, presumably because it requires the jar files.

One last question. I think I understand what is happening, however, why is it the other JAR files (mq.jar etc) are able to be packaged within testapp.jar if they are not reachable? It would be nice to have just one single executable jar file.

Thanks for the assistance.


+Pie Number of slices to send: Send
A jar file is just a zip file with some special properties - as such it can contain any kind of file. There may be other reasons (besides wanting to load classes contained in them) why one might want to keep nested jar files.

Note that it's just the standard URLClassLoader (which the JVM uses by default) that can't look for jar files inside of jar files. Nothing prevents you from writing a classloader that *can* load classes from nested jar files. You can switch that for the standard ClassLoader by using the "java.system.class.loader" property. See the javadocs of the ClassLoader class for more detail.
+Pie Number of slices to send: Send
 

Christopher Frankland wrote:Interesting. I compiled the JAR file using the following:

jar cfvm testapp.jar META-INF\MANIFEST.MF *.jar ar/mq/*.class

It generates the testapp.jar file places the jar and class files into that jar.


Well it would because you've told it to add all jar and all class files.

When I said you can't include jar files in other jar files I was being very simplistic, ie I meant your jar isn't working because the other jars it needs are packaged in it - sorry I didn't explain it in clearer terms. As Ulf has already explained you can put anything into a jar, the problem is the Java classloader won't access jars that are within jars.

If you really want a single executable then there are tools that will package everything up into a single .exe file, but this means they will only run on a Windows platform. I'm not sure if they are also available for other platforms and either way I don't advocate their use, I'm just aware they are available.
There will be plenty of time to discuss your objections when and if you return. The cargo is this tiny ad:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com


reply
reply
This thread has been viewed 2027 times.
Similar Threads
NoClassDefFoundError
NoClassDefFoundError
NoClassDefFoundError
NoClassDefFoundError
NoClassDefFoundError
More...

All times above are in ranch (not your local) time.
The current ranch time is
Mar 28, 2024 02:20:47.