NoClassDefFoundError while trying to run my jar with java.exe -jar...what's wrong?

144,971

Solution 1

The -jar option is mutually exclusive of -classpath. See an old description here

-jar

Execute a program encapsulated in a JAR file. The first argument is the name of a JAR file instead of a startup class name. In order for this option to work, the manifest of the JAR file must contain a line of the form Main-Class: classname. Here, classname identifies the class having the public static void main(String[] args) method that serves as your application's starting point.

See the Jar tool reference page and the Jar trail of the Java Tutorial for information about working with Jar files and Jar-file manifests.

When you use this option, the JAR file is the source of all user classes, and other user class path settings are ignored.

A quick and dirty hack is to append your classpath to the bootstrap classpath:

-Xbootclasspath/a:path

Specify a colon-separated path of directires, JAR archives, and ZIP archives to append to the default bootstrap class path.

However, as @Dan rightly says, the correct solution is to ensure your JARs Manifest contains the classpath for all JARs it will need.

Solution 2

You can omit the -jar option and start the jar file like this:

java -cp MyJar.jar;C:\externalJars\* mainpackage.MyMainClass

Solution 3

This is the problem that is occurring,

if the JAR file was loaded from "C:\java\apps\appli.jar", and your manifest file has the Class-Path: reference "lib/other.jar", the class loader will look in "C:\java\apps\lib\" for "other.jar". It won't look at the JAR file entry "lib/other.jar".

Solution:-

  1. Right click on project, Select Export.
  2. Select Java Folder and in it select Runnable JAR File instead of JAR file.
  3. Select the proper options and in the Library Handling section select the 3rd option i.e. (Copy required libraries into a sub-folder next to the generated JAR).

[ EDIT = 3rd option generates a folder in addition to the jar, 2nd option ("Package required libraries into generated JAR") can also be used as you have the jar. ]

  1. Click finish and your JAR is created at the specified position along with a folder that contains the JARS mentioned in the manifest file.
  2. open the terminal,give the proper path to your jar and run it using this command java -jar abc.jar

    Now what will happen is the class loader will look in the correct folder for the referenced JARS since now they are present in the same folder that contains your app JAR..There is no "java.lang.NoClassDefFoundError" exception thrown now.

This worked for me... Hope it works for you too!!!

Solution 4

if you use external libraries in your program and you try to pack all together in a jar file it's not that simple, because of classpath issues etc.

I'd prefer to use OneJar for this issue.

Solution 5

i had the same problem with my jar the solution

  1. Create the MANIFEST.MF file:

Manifest-Version: 1.0

Sealed: true

Class-Path: . lib/jarX1.jar lib/jarX2.jar lib/jarX3.jar

Main-Class: com.MainClass

  1. Right click on project, Select Export.

select export all outpout folders for checked project

  1. select using existing manifest from workspace and select the MANIFEST.MF file

This worked for me :)

Share:
144,971
Ogre Psalm33
Author by

Ogre Psalm33

The way of a foolish programmer seems right to him, but a wise man listens to advice of his fellow coders!   -Proverbs 12:15 (Paraphrased :-) #SOreadytohelp

Updated on July 05, 2022

Comments

  • Ogre Psalm33
    Ogre Psalm33 almost 2 years

    I have an application that I'm trying to wrap into a jar for easier deployment. The application compiles and runs fine (in a Windows cmd window) when run as a set of classes reachable from the CLASSPATH. But when I jar up my classes and try to run it with java 1.6 in the same cmd window, I start getting exceptions:

    C:\dev\myapp\src\common\datagen>C:/apps/jdk1.6.0_07/bin/java.exe -classpath C:\myapp\libs\commons -logging-1.1.jar -server -jar DataGen.jar
    Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
        at com.example.myapp.fomc.common.datagen.DataGenerationTest.<clinit>(Unknown Source)
    Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
        at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
        ... 1 more
    

    The funny thing is, the offending LogFactory seems to be in commons-logging-1.1.jar, which is in the class path specified. The jar file (yep, it's really there):

    C:\dev\myapp\src\common\datagen>dir C:\myapp\libs\commons-logging-1.1.jar
     Volume in drive C is Local Disk
     Volume Serial Number is ECCD-A6A7
    
     Directory of C:\myapp\libs
    
    12/11/2007  11:46 AM            52,915 commons-logging-1.1.jar
               1 File(s)         52,915 bytes
               0 Dir(s)  10,956,947,456 bytes free
    

    The contents of the commons-logging-1.1.jar file:

    C:\dev\myapp\src\common\datagen>jar -tf C:\myapp\libs\commons-logging-1.1.jar
    META-INF/
    META-INF/MANIFEST.MF
    org/
    org/apache/
    org/apache/commons/
    org/apache/commons/logging/
    org/apache/commons/logging/impl/
    META-INF/LICENSE.txt
    META-INF/NOTICE.txt
    org/apache/commons/logging/Log.class
    org/apache/commons/logging/LogConfigurationException.class
    org/apache/commons/logging/LogFactory$1.class
    org/apache/commons/logging/LogFactory$2.class
    org/apache/commons/logging/LogFactory$3.class
    org/apache/commons/logging/LogFactory$4.class
    org/apache/commons/logging/LogFactory$5.class
    org/apache/commons/logging/LogFactory.class
    ... (more classes in commons-logging-1.1 ...)
    

    Yep, commons-logging has the LogFactory class. And finally, the contents of my jar's manifest:

    Manifest-Version: 1.0
    Ant-Version: Apache Ant 1.6.5
    Created-By: 10.0-b23 (Sun Microsystems Inc.)
    Main-Class: com.example.myapp.fomc.common.datagen.DataGenerationTest
    Class-Path: commons-logging-1.1.jar commons-lang.jar antlr.jar toplink
     .jar GroboTestingJUnit-1.2.1-core.jar junit.jar
    

    This has stumped me, and any coworkers I've bugged for more than a day now. Just to cull the answers, for now at least, third party solutions to this are probably out due to licensing restrictions and company policies (e.g.: tools for creating exe's or packaging up jars). The ultimate goal is to create a jar that can be copied from my development Windows box to a Linux server (with any dependent jars) and used to populate a database (so classpaths may wind up being different between development and deployment environments). Any clues to this mystery would be greatly appreciated!

  • Dan Dyer
    Dan Dyer over 15 years
    It would be better to specify a classpath in the JAR's manifest. The bootclasspath is intended for replacing system classes.
  • toolkit
    toolkit over 15 years
    True -- will edit it make it clear this is only a workaround.
  • Ogre Psalm33
    Ogre Psalm33 over 15 years
    Aha! That's it! I knew there must be something simple that I was missing. Just nobody around here has worked with jars enough to notice my error!
  • Ogre Psalm33
    Ogre Psalm33 over 15 years
    I looked at OneJar a little bit. That might be a possibility--the license appears to be pretty straight-forward. But I'd still have to get it "approved" where I work in order to use it.
  • kanzure
    kanzure over 11 years
    Thank you, you saved me from recompiling a massive jar that forgot to include its dependencies. Everyone else on the web keeps saying that you can't use both -classpath and -jar but you clearly are doing that there.
  • Qix - MONICA WAS MISTREATED
    Qix - MONICA WAS MISTREATED over 11 years
    Holy crap this is awesome. Thank you!
  • maxivis
    maxivis over 10 years
    your answer it is correct, but with the 3rd option it generates a folder in addition to the jar, I think is a better option the 2nd one ("Package required libraries into generated JAR") because you only have the jar. Nevertheless, you have my vote ;)
  • Hazok
    Hazok over 9 years
    Just to clarify, the -jar option and the -classpath option are not both used here. Rather, the -classpath option accepts jars and wildcards: -cp <class search path of directories and zip/jar files> -classpath <class search path of directories and zip/jar files> A : separated list of directories, JAR archives, and ZIP archives to search for class files.
  • kopos
    kopos over 5 years
    Found this after I was done wrecking my brains. Thank you!
  • aderchox
    aderchox over 2 years
    Thank you. In my case, I had to wrap the paths in double quotes or else it didn't work. Example: java -cp "lib\jcommander-1.81.jar;bin" com.aderchox.App --length 512 -p 2