44

I have a single maven project that has multiple main classes. I want to generate runnable Jars (that include all dependencies) out of these project. I currently have the following build configuration (using maven.assembly):

<build>
<plugins>
    <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <configuration>
            <archive>
                <manifest>
                    <mainClass>classpath.to.my.mainClass</mainClass>
                </manifest>
            </archive>
            <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
            </descriptorRefs>
        </configuration>
    </plugin>
</plugins>
</build>

Is their a way to achive this with maven-assembly? If not, what is the simplest way to achive my goal?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Martin Thurau
  • 7,564
  • 7
  • 43
  • 80
  • Have you tried to create several `` entries for `maven-assembly-plugin` with different configurations? This will trigger this plugin twice and create two JAR files hopefully... – dma_k Jan 04 '12 at 14:51
  • @dma_k Following your suggestion, trying to generate three JARs, the first two get overwritten by the last `` configuration. – anon Jan 14 '13 at 18:19
  • Try to play with `` configuration option (check [here](http://maven.apache.org/plugins/maven-assembly-plugin/howto.html)). – dma_k Jan 15 '13 at 15:08

4 Answers4

32

You can do it. You'll need a separate execution for each artifact that you're building (i.e., give each its own id but you can leave the phase as default), and you'll need to specify the finalName and archive/manifest/mainClass for each.

<build>
<plugins>
    <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <executions>
          <execution>
            <id>build-a</id>
            <configuration>
              <archive>
                <manifest>
                  <mainClass>foobar.Aclass</mainClass>
                </manifest>
              </archive>
              <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
              </descriptorRefs>
              <finalName>foobar_a.jar</finalName>
            </configuration>
          </execution>
          <execution>
            <id>build-b</id>
            <configuration>
              <archive>
                <manifest>
                  <mainClass>foobar.Bclass</mainClass>
                </manifest>
              </archive>
              <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
              </descriptorRefs>
              <finalName>foobar_b.jar</finalName>
            </configuration>
          </execution>
        </executions>
    </plugin>
</plugins>
</build>
Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
24

I wasn't able to solve this problem with the maven-assembly-plugin in a satisfying way, so I went for a different solution. I used the onejar-maven-plugin:

<build>
  <plugins>
  <plugin>
    <groupId>org.dstovall</groupId>
    <artifactId>onejar-maven-plugin</artifactId>
    <version>1.4.4</version>
    <executions>
      <execution>
        <id>build-first</id>
          <configuration>
            <mainClass>classpath.to.first.Main</mainClass>
            <attachToBuild>true</attachToBuild>
            <classifier>onejar</classifier>
            <filename>first-runnable.jar</filename>
          </configuration>
          <goals>
            <goal>one-jar</goal>
          </goals>
        </execution>
      <execution>
        <id>build-second</id>
          <configuration>
            <mainClass>classpath.to.second.Main</mainClass>
            <attachToBuild>true</attachToBuild>
            <classifier>onejar</classifier>
            <filename>second-runnable.jar</filename>
          </configuration>
          <goals>
            <goal>one-jar</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

<pluginRepositories>
  <pluginRepository>
     <id>onejar-maven-plugin.googlecode.com</id>
     <url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
  </pluginRepository>
</pluginRepositories>
Tombart
  • 30,520
  • 16
  • 123
  • 136
Martin Thurau
  • 7,564
  • 7
  • 43
  • 80
19

The top answer works if you are not using any configuration (or any resource, for that matter) that gets bundled into your jar file (e.g., configuration for Spring Framework auto-bindings).

Fortunately, this solution also works with maven-shade-plugin and you don't have that aforementioned issue with onejar-maven-plugin.

Also, maven-shade-plugin is actively being maintained as opposed to onejar-maven-plugin which is in the purgatory that is googlecode.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <version>2.4.1</version>
  <executions>
    <execution>
      <id>build-first</id>
      <phase>package</phase>
      <goals>
         <goal>shade</goal>
      </goals>   
      <configuration>
        <transformers>
          <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">                        
            <mainClass>classpath.to.first.Main</mainClass>
          </transformer>
        </transformers>
        <finalName>first-runnable</finalName>
      </configuration>        
    </execution>
    <execution>
      <id>build-second</id>
      <phase>package</phase>
      <goals>
         <goal>shade</goal>
      </goals>   
      <configuration>
        <transformers>
          <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">                        
            <mainClass>classpath.to.second.Main</mainClass>
          </transformer>
        </transformers>
        <finalName>second-runnable</finalName>
      </configuration>  
    </execution>
  </executions>
</plugin>
Community
  • 1
  • 1
Dexter Legaspi
  • 3,192
  • 1
  • 35
  • 26
  • This works but it also seems to backup the target JAR if it already exists, e.g. it creates original-first-runnable.jar and original-second-runnable.jar (using your example). – Mike Stoddart Aug 18 '23 at 13:35
5

To specify a little more previous answer that was very helpful to me, you need to add phase package and goal assembly and run mvn run clean package, pom is as follows :

<plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <executions>
                <execution>
                    <id>build-a</id>
                    <configuration>
                        <archive>
                            <manifest>
                                <mainClass>firstMainClass</mainClass>
                            </manifest>
                        </archive>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                        <finalName>a.jar</finalName>
                    </configuration>
                    <phase>package</phase>
                    <goals>
                        <goal>assembly</goal>
                    </goals>
                </execution>
                <execution>
                    <id>build-b</id>
                    <configuration>
                        <archive>
                            <manifest>
                                <mainClass>SecondMainClass</mainClass>
                            </manifest>
                        </archive>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                        <finalName>b.jar</finalName>
                    </configuration>
                    <phase>package</phase>
                    <goals>
                        <goal>assembly</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
Legwann
  • 71
  • 1
  • 7
  • 2
    Goal `assembly` is deprecated. See [plugin information](https://maven.apache.org/plugins/maven-assembly-plugin/plugin-info.html). Better to use `single` instead. – Gabriel Apr 09 '15 at 07:43