Создайте несколько исполняемых JAR-файлов (с включенными зависимостями) из одного проекта Maven

У меня есть один проект maven с несколькими основными классами. Я хочу сгенерировать исполняемые Jars (включая все зависимости) из этого проекта. В настоящее время у меня есть следующая конфигурация сборки (с использованием 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>

Это способ добиться этого с помощью maven-assembly? Если нет, то какой самый простой способ достичь моей цели?


person Martin Thurau    schedule 04.01.2012    source источник
comment
Пробовали ли вы создать несколько записей <plugin> для maven-assembly-plugin с разными конфигурациями? Это вызовет этот плагин дважды и, надеюсь, создаст два файла JAR...   -  person dma_k    schedule 04.01.2012
comment
@dma_k Следуя вашему предложению, при попытке создать три JAR-файла первые два перезаписываются последней конфигурацией <plugin>.   -  person Brian Bowman    schedule 14.01.2013
comment
Попробуйте поиграть с параметром конфигурации <finalName> (отметьте здесь).   -  person dma_k    schedule 15.01.2013


Ответы (4)


Ты можешь это сделать. Вам понадобится отдельное выполнение для каждого артефакта, который вы создаете (т.е. дайте каждому свой собственный идентификатор, но вы можете оставить фазу по умолчанию), и вам нужно будет указать finalName и archive/manifest/mainClass для каждого.

<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>
person Donal Fellows    schedule 04.01.2012
comment
Вероятно, также следует явно объявить, что должна использоваться цель single. - person Donal Fellows; 04.01.2012
comment
попробовав это решение и тот, который опубликован здесь, похоже, что нужно также добавить теги <goals> и <phase>? - person Andre Holzner; 25.06.2013
comment
Я отредактировал сообщение (ожидая экспертной оценки), включив в него цели и теги фаз. - person Gabriel; 09.04.2015
comment
Возможно ли установить их оба? добавив суффикс к артефакту? - person Phate; 07.04.2020
comment
Можно ли уменьшить размер этих двух банок с помощью плагина тени? - person ifly6; 21.12.2020

Мне не удалось решить эту проблему с помощью maven-assembly-plugin удовлетворительным образом, поэтому я выбрал другое решение. Я использовал 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>
person Martin Thurau    schedule 03.02.2012
comment
разве два id в двух execution не должны быть разными? Мой maven жалуется, если у меня есть один и тот же идентификатор более одного раза. - person Andre Holzner; 21.02.2012
comment
@AndreHolzner: Да, это была ошибка - person Martin Thurau; 22.02.2012
comment
ИМХО, то же самое возможно и с maven-assembly-plugin. См. ответ @donal-fellows - person Gabriel; 09.04.2015
comment
разные идентификаторы необходимы для уникальной идентификации отдельных банок, - person Ankur Srivastava; 13.04.2017
comment
Вы должны заменить репозиторий плагинов следующим: ‹pluginRepository› ‹id›redhat-earlyaccess-repository‹/id› ‹url›maven.repository.redhat.com/earlyaccess/all/‹/url› ‹/pluginRepository› - person Babajide M. Moibi; 18.09.2018
comment
URL-адрес onejar-maven-plugin.googlecode.com/svn/mavenrepo кажется больше не работать - person Fred_Weitendorf; 20.02.2019

Лучший ответ работает, если вы не используете какую-либо конфигурацию (или какой-либо ресурс, если на то пошло ), который встраивается в ваш jar-файл (например, конфигурация для автопривязки Spring Framework).

К счастью, это решение также работает с maven-shade-plugin, и у вас нет вышеупомянутой проблемы с onejar-maven-plugin.

Кроме того, maven-shade-plugin активно поддерживается, в отличие от onejar-maven-plugin, который находится в чистилище, то есть 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>
person Dexter Legaspi    schedule 05.02.2016

Чтобы указать немного больше предыдущего ответа, который был очень полезен для меня, вам нужно добавить фазовый пакет и целевую сборку и запустить mvn run clean package, pom выглядит следующим образом:

<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>
person Legwann    schedule 11.03.2015
comment
Цель assembly устарела. См. информацию о подключаемом модуле. Вместо этого лучше использовать single. - person Gabriel; 09.04.2015