2

I am creating a maven project from scratch, first just learn how to use maven. The main project contains no source code file, but it has two modules (app, and util). App depends on util. I would like to have a .jar from app, and have no manifest file if possible. I am able to compile the whole project with mvn clean install, but can not run the app from console.

The main project .pom is

<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>com.proba</groupId>
  <artifactId>myproject</artifactId>
  <version>0.0.1</version>
<packaging>pom</packaging>


<modules>
  <module>util</module>
  <module>app</module>
</modules>
</project>

Util .pom is

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

  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.proba</groupId>
    <artifactId>myproject</artifactId>
    <version>0.0.1</version>
  </parent>
  <artifactId>util</artifactId>


 <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
     </dependency>
 </dependencies>

</project>

app pom is

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.proba</groupId>
        <artifactId>myproject</artifactId>
        <version>0.0.1</version>
    </parent>
    <artifactId>app</artifactId>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.proba</groupId>
            <artifactId>util</artifactId>
            <version>0.0.1</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>com.proba.app.App</mainClass>
                            <addClasspath>true</addClasspath>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.1.1</version>
                <executions>
                    <execution>
                        <phase>site-deploy</phase>
                        <goals>
                            <goal>java</goal>
                        </goals>
                        <configuration>
                            <mainClass>com.proba.app.App</mainClass>
                            <!--<arguments> <argument>myArg1</argument> <argument>myArg2</argument> 
                                </arguments> -->
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

The code doesn't do too much. App.java (that inside the app module) is package com.proba.app;

import com.proba.util.UtilClass;
public class App 
{
    public static void main( String[] args )
    {
        System.out.println( "Hello World!" );
        UtilClass uc = new UtilClass(); 
        System.out.println( "QQQQQ: " + uc.print() );
    }
}

I compile it with

mvn clean install
[INFO] Reactor Summary:
[INFO]
[INFO] myproject .......................................... SUCCESS [  0.406 s]
[INFO] util ............................................... SUCCESS [  2.074 s]
[INFO] app ................................................ SUCCESS [  0.535 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

myproject, util, app is SUCCESS.

I try to run it with

java -jar app/target/app-0.0.1.jar
Hello World!
Exception in thread "main" java.lang.NoClassDefFoundError: com/proba/util/UtilClass
        at com.proba.app.App.main(App.java:17)
Caused by: java.lang.ClassNotFoundException: com.proba.util.UtilClass
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        ... 1 more

As you can see, Hello World! is printed out, but UtilClass is not found. I am able to run the build from eclipse, but not from the console. What I am doing wrong? Do you have any idea?

Gimby
  • 5,095
  • 2
  • 35
  • 47
thamas
  • 183
  • 2
  • 9
  • What happens if you run the build from the console? – J Fabian Meier Sep 02 '16 at 07:23
  • Try running the jar directly from the target directory - I'm going to guess it has to do with where the util jar is in relation to the current working directory. – Gimby Sep 02 '16 at 07:23
  • Gimby: for that I get the same result: cd util/target/ then java -jar ../../app/target/app-0.0.1.jar Hello World! Exception in thread "main" java.lang.NoClassDefFoundError: com/proba/util/UtilClass – thamas Sep 02 '16 at 07:47
  • JF Meier: I run it from console, that is when I see the NoClassDefFoundError – thamas Sep 02 '16 at 07:48
  • have a look here http://stackoverflow.com/questions/1729054/including-dependencies-in-a-jar-with-maven/1729094#1729094 – user902383 Sep 02 '16 at 08:17
  • As app depends on util, add the util dependency to the app pom. See http://books.sonatype.com/mvnex-book/reference/multimodule.html for an example multi module maven project – Michel Feldheim Sep 02 '16 at 08:19
  • user902383: Copied the plugin part into the pom of app. Compiled it with mvn clean install and mvn clean install package. But running gives the same result. – thamas Sep 02 '16 at 08:27
  • Michel Feldheim: As it is in the original post it is already done, app depends on util, it is in app's pom file. – thamas Sep 02 '16 at 08:28

3 Answers3

1

What you missing is the jar of UtilClass. You just need to add shade plugin in your pom. As reference: maven-shade-plugin

lege
  • 158
  • 11
  • Could you please be more specific? Should I add it in which pom? Util or app or the main project. – thamas Sep 02 '16 at 08:12
  • @thamas main project – lege Sep 02 '16 at 08:20
  • Great! This solved it. Now I got the expected print out in console: "java -jar app/target/app-0.0.1.jar Hello World! QQQQQ: Hello World from Module Util!" Many Thanks! (Accepted this answer.) – thamas Sep 02 '16 at 08:32
-1

In the pom.xml of app module,You have writtent the compile thats why at runtime your jar is not getting into the classpath.Remove the compile line.And it will work.

Sakalya
  • 568
  • 5
  • 15
-1

Util.jar is added to your app pom.xml as dependency but the scope is compile. So it is not getting added to your Manifest as classpath entry. Remove scope element and then try.

Ritesh
  • 1,053
  • 5
  • 16
  • 29
  • java -cp util/target/util-0.0.1.jar -jar app/target/app-0.0.1.jar gives the same result unfortunatelly. As I know java ignores "-cp" is "-jar" is used. – thamas Sep 02 '16 at 08:15
  • Its widely documented that -cp has no effect when running an application with -jar. The classpath is defined in the jar's manifest so it can also work when you just double click the runnable jar. – Gimby Sep 02 '16 at 08:24