user606521
user606521

Reputation: 15454

main class not found in jar file despite manifest

I have Maven project in netbeans. My POM looks like this:

<project xmlns="http://maven.apache.org/POM/4.0.0" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>myproject</groupId>
  <artifactId>Myproject</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>Slave</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <build>
    <plugins>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
              <mainClass>myproject.slave.App</mainClass>
            </manifest>
          </archive>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>
        <executions>
          <execution>
            <id>make-my-jar-with-dependencies</id>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.6</version>
    </dependency> 
    <dependency>
      <groupId>org.jsoup</groupId>
      <artifactId>jsoup</artifactId>
      <version>1.7.1</version>
    </dependency>
    <dependency>
      <groupId>org.apache.pdfbox</groupId>
      <artifactId>pdfbox</artifactId>
      <version>1.7.1</version>
    </dependency>
    <dependency>
      <groupId>com.googlecode.json-simple</groupId>
      <artifactId>json-simple</artifactId>
      <version>1.1</version>
    </dependency>
  </dependencies>
</project>

It worked fine, I could execute Myproject-1.0-SNAPSHOT-jar-with-dependencies.jar and Java found main class and it executed correctly - Until some moment. Suddenly when I wanted to execute jar file I got exception:

java -jar Myproject-1.0-SNAPSHOT-jar-with-dependencies.jar

Exception in thread "main" java.lang.NullPointerException
        at sun.launcher.LauncherHelper.getMainClassFromJar(Unknown Source
        at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)

java -cp Myproject-1.0-SNAPSHOT-jar-with-dependencies.jar myproject.slave.App

Exception in thread "main" java.lang.NoClassDefFoundError: org/jsoup/nodes/Eleme
nt
        at myproject.slave.Worker.<init>(Worker.java:29)
        at myproject.slave.App.main(App.java:26)
Caused by: java.lang.ClassNotFoundException: org.jsoup.nodes.Element
        at java.net.URLClassLoader$1.run(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)

When I click "Run" in Netbeans it executes correctly.

So the problem is that jar with dependencies is build incorrectly, I just wonder why? I was like 2 hours ago and now it's not working...

Upvotes: 2

Views: 1512

Answers (1)

Stephen C
Stephen C

Reputation: 719299

OK, so the problem is NOT that the JVM can't find the main class. The class that it cannot find is "org.jsoup.nodes.Element". (The stack trace says so ...)

But why? After all you have included jsoup as a dependency in the POM file ...

The reason is that that the JVM's class loader cannot find classes in nested JARs. If you want to create an executable JAR that is self-contained (i.e. that contains all of the dependent classes it needs), you need to use the maven-shade-plugin to create a so-called "uber-jar".


When you are running from Netbeans, the command launcher is setting up the classpath ... and not using the -jar option to launch the JVM.

Upvotes: 1

Related Questions