3

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> 
3
  • Why do you need more than one main class? Couldn't you just add parameters to distinguish use cases? Commented Jun 29, 2021 at 18:06
  • Sure, I could have done it that way, but that's not the way the design went. Commented Jun 29, 2021 at 18:55
  • So what hinders you to change the design? Commented Jun 29, 2021 at 19:54

1 Answer 1

4

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

Sign up to request clarification or add additional context in comments.

1 Comment

Awesome, thanks for the answer! I assume I could also just have an additional execution without the manifest/mainClass, in addition to the others? That way I can offer multiple solutions in case somebody only wants to use one of them (it's not really necessary as the whole project is no larger than the individual packages, of course)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.