java.lang.ClassNotFoundException when running java -jar

32,279

Solution 1

Could not find the main class: MyClass

The error seems actually related to your MANIFEST which:

  • may not have a complete classpath Class-Path: see this HowTo

The best solution when you have a jar is to try to include the required jars into the manifest declaration.

Manifest-Version: 1.0 
Class-Path:  
 customer_client.jar  
 mailer_client.jar  
 signon_client.jar 
  • or may not define adequately the MainClass within your 'my_jar.jar'.

See this HowTo:

<target name="jar" depends="compile">
     <delete file="hello.jar"/>
     <delete file="MANIFEST.MF"/>
     <manifest file="MANIFEST.MF">
        <attribute name="Built-By" value="${user.name}"/>
        <attribute name="Main-Class" value="howto.Hello"/>
    </manifest>

      <jar destfile="hello.jar"
           basedir="."
           includes="**/*.class"
           manifest="MANIFEST.MF"
           />
  </target>

the <attribute name="Main-Class" value="howto.Hello"/> needs to specify the full path (packages) of the MainClass, not just MainClass.

If your main class is in the default package (the unnamed package), I am not sure it can be referenced by the loader (see this SO question)
So move your JarRunner into a package, and declare it appropriately in the <attribute name="Main-Class" value="myPackage.JarRunner"/> element.

Solution 2

You need to specify all the other jars that are required in your classpath in the manifest file before you can execute java -jar my-test.jar, here is a copy of one of my manifest files. With all these entries in the manifest I can specify java -jar db_field_cleaner.jar and all the other jars are inlined into the classpath :

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: James B
Build-Jdk: 1.6.0_01
Package: com.blah.dbfieldcleaner
Specification-Title: db_field_cleaner
Specification-Version: 2.5.7-SNAPSHOT
Implementation-Title: db_field_cleaner
Implementation-Version: 2.5.7-SNAPSHOT
Implementation-Vendor-Id: com.blah.dbfieldcleaner
Implementation-Vendor:
Main-Class: com.blah.dbfieldcleaner.main.Main
mode: development
url: ..\..\db_field_cleaner\target\site
Class-Path: log4j-1.2.14.jar cygna_commons-2.5.7-SNAPSHOT.jar mail-1.4
 .jar activation-1.1.jar jdic-0.9.5.jar jdic_native-0.9.5.jar jdic_plu
 s-0.2.2.jar jdic_plus_native-0.2.2.jar jtds-1.2.2.jar xstream-1.3.1.j
 ar xpp3_min-1.1.4c.jar commons-net-2.0.jar text_processing-2.5.7-SNAP
 SHOT.jar

Alternatively, use Maven, it's loads better at this kind of stuff!

Solution 3

You had given answer yourself :-) add all the jars to your runtime classpath.As you said earlier *.jar solved one problem but loggers are not able to find out, so add log4j.jar to the path. Basically the idea is add all the jars required for running in to classpath.

Share:
32,279
Heinrich Schmetterling
Author by

Heinrich Schmetterling

Updated on May 09, 2020

Comments

  • Heinrich Schmetterling
    Heinrich Schmetterling about 4 years

    I'm using ant to build my build.xml file, it compiles ok, but then getting a runtime java.lang.NoClassDefFoundError when running the resulting jar via "java -jar my_jar.jar". It seems like this comes up a lot but none of the related questions' solutions worked for me.

    My classpath for javac contains only "/usr/local/lib/libthrift.jar" and the main .java file imports a bunch of thrift packages such as org.apache.thrift.transport.TTransportException.

    When I try running the program via:

    java -jar MyClass.jar
    

    , I get the error:

    Exception in thread "main" **java.lang.NoClassDefFoundError**: org/apache/thrift/transport/TTransportException
    Caused by: java.lang.ClassNotFoundException: org.apache.thrift.transport.TTransportException
            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:307)
            at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
            at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
    Could not find the main class: **MyClass**. Program will exit.
    

    Here are the things I've tried so far that don't work:

    • adding a flag on the command line like "java -cp /usr/local/lib/libthrift.jar -jar my_jar.jar", the result is the same error as above

    • adding &lt;attribute name="Class-Path" value="./:/usr/local/lib/libthrift.jar"/> inside my jar's manifest> tag, the result is the same error as above

    • adding -Xbootclasspath/a:/usr/local/lib/libthrift.jar:./ to the java command line. it solves the first error but a different error comes up:

      Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/Logger at org.apache.thrift.transport.TServerSocket.<clinit>(TServerSocket.java:36) at MyClass.start(Unknown Source) at MyClass.main(Unknown Source)

    EDIT:

    If I comment out the code that instantiates the missing classes but leave the imports, the code executes fine.

    EDIT:

    I moved my java classes to a server and referenced the MainClass with the server in the manifest attribute, but that didn't fix anything.