Frank Harris
Frank Harris

Reputation: 655

pom.xml for single jar with multiple main classes

I have a Java project with multiple executables using the same classes. I currently have maven install set up to create a standalone executable jar for each main class, with all dependencies contained. I would like to instead have it all in one jar, as there's a huge amount of reuse. When I tried to do this previously, I got a complaint about a lack of a manifest file, so I tried this approach instead.

How do I need to set up my pom.xml, and how would I then specify which main class to use when launching in java on command line?

Ideally the user of the jar would only be able to specify the explicitly allowed main classes, as there are test main classes I have I don't want them to be able to use.

Another solution that would work would be to have all of the classes contained in a non-executable jar, and then to have a bunch of executable jars that each have a specified main class, but they all have access to the non-executable jar.

The relevant part of my pom.xml looks like this:

<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <executions>
        <execution>
            <id>build-a</id>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>path.to.MainClassA</mainClass>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <finalName>MainClassA</finalName>
                </configuration>
                <phase>package</phase>
                <goals>
                    <goal>single</goal>
                </goals>
        </execution>
        <execution>
            <id>build-b</id>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>path.to.MainClassB</mainClass>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <finalName>MainClassB</finalName>
                </configuration>
                <phase>package</phase>
                <goals>
                    <goal>single</goal>
                </goals>
        </execution>
    </executions>
</plugin>

Upvotes: 2

Views: 2472

Answers (1)

erosb
erosb

Reputation: 3141

How do I need to set up my pom.xml, and how would I then specify which main class to use when launching in java on command line?

Essentially, you can't declare more that one main class in a jar file. The main class is declared in the Main-Class attribute of the META-INF/MANIFEST.MF file in a jar, and this is what the JVM is looking for when you run java -jar my-main.jar (regardless what build tool you used).

But at any time you can explicitly specify your main class when you start the java executable, you just need to make sure you put the jar file containing it to the classpath (and you don't need -jar for this). You don't even need any maven magic to do that. So if you delete the manifest/mainClass declarations from the above pom, and have only one execution of maven-assembly-plugin, and build your project, you can run it with different main classes like

java -cp target/my-main.jar path.to.MainClassA

or

java -cp target/my-main.jar path.to.MainClassB

Upvotes: 3

Related Questions