26

I'm beginner with maven and do not understand many things. I can build simple executable jar, but how to build multimodule maven project into executable jar is magic for me. So, I have three projects. Parent:

<?xml version="1.0" encoding="UTF-8"?>
<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>org.example</groupId>
    <artifactId>Test</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>Main</module>
        <module>Dep</module>
    </modules>
</project>

And two child projects:

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <parent>
        <artifactId>Test</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>Main</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>Dep</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>

and:

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <parent>
        <artifactId>Test</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>Dep</artifactId>
</project>

Main module has Main class with main method(lol)

public class Main {
    public static void main(String[] args) {
        Hello hello = new Hello();
        System.out.println(hello.sayHello());
    }
}

Class Hello is defined in the Dep module. What should I add into my poms to build executable jar with Main class from Main module as entry point?

Moses
  • 1,243
  • 3
  • 14
  • 21
  • possible duplicate of [How can I create an executable jar with dependencies using Maven?](http://stackoverflow.com/questions/574594/how-can-i-create-an-executable-jar-with-dependencies-using-maven). Read the accepted answer of this question, it should fit your needs as well. – Sean Patrick Floyd Dec 27 '13 at 14:01

1 Answers1

21

You need to change your pom for artifactid Main. You need to add the maven-assembly-plugin

In the configuration of it you have an option to specify the mainClass in the manifest. This should be the fully qualified name of the Main class.

<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>
    <parent>
        <groupId>org.example</groupId>
        <artifactId>Test</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>Main</artifactId>

    <properties>
        <!-- plugins -->
        <maven.assembly.plugin.version>2.4</maven.assembly.plugin.version>
        <!-- dependencies -->
        <dep.version>1.0-SNAPSHOT</dep.version>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
            </plugin>
        </plugins>

        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-assembly-plugin</artifactId>
                    <version>${maven.assembly.plugin.version}</version>
                    <configuration>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                        <archive>
                            <manifest>
                                <mainClass>Main</mainClass>
                            </manifest>
                        </archive>
                    </configuration>
                    <executions>
                        <execution>
                            <id>make-assembly</id>
                            <phase>package</phase>
                            <goals>
                                <goal>single</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>Dep</artifactId>
            <version>${dep.version}</version>
        </dependency>
    </dependencies>
</project>

After you start your build on the parent project, it should create the executable jar in the target subfolder of the module Main. (a jar with the name Main-1.0-SNAPSHOT-jar-with-dependencies.jar was what i got)

y.luis.rojo
  • 1,794
  • 4
  • 22
  • 41
stefaan dutry
  • 1,096
  • 1
  • 10
  • 21
  • Well, it's much better than my attempts because jar is now executable, but now I have this exception:Exception in thread "main" java.lang.NoClassDefFoundError: org/example/dep/Hello at org.example.Main.main(Main.java:7) Caused by: java.lang.ClassNotFoundException: org.example.dep.Hello – Moses Dec 27 '13 at 14:09
  • 1
    I overlooked the missing library on the classpath. The easiest way to get around this is to package your dependencies inside your jar. I just edited my answer so that it does that. An alternative way is to have your dependencies in a seperate directory and refer to that from the Manifest file from within your jar, but that requires you to place that requires you to put the dependencies on the exact spot you specified in the Manifest file. If you want more info on that, leave a comment. – stefaan dutry Dec 27 '13 at 18:36