Создание исполняемой банки с maven?

Я пытаюсь создать исполняемый файл jar для небольшого домашнего проекта под названием «logmanager», используя maven, вот так:

Как я могу создать исполняемый JAR с зависимостями, используя Maven?

Я добавил показанный там фрагмент в pom.xml и запустил mvn assembly: assembly. Он генерирует два файла jar в logmanager / target: logmanager-0.1.0.jar и logmanager-0.1.0-jar-with-dependencies.jar. Я получаю сообщение об ошибке при двойном щелчке по первой банке:

Could not find the main class: com.gorkwobble.logmanager.LogManager. Program will exit.

Немного другая ошибка, когда я дважды щелкаю jar-with-dependencies.jar:

Failed to load Main-Class manifest attribute from: C:\EclipseProjects\logmanager\target\logmanager-0.1.0-jar-with-dependencies.jar

Я скопировал и вставил путь и имя класса и проверил орфографию в POM. Мой основной класс отлично запускается из конфигурации запуска eclipse. Может ли кто-нибудь помочь мне понять, почему мой файл jar не запускается? Кроме того, почему для начала нужны две банки? Дайте мне знать, если вам понадобится дополнительная информация.

Вот полный pom.xml для справки:

<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.gorkwobble</groupId>
  <artifactId>logmanager</artifactId>
  <name>LogManager</name>
  <version>0.1.0</version>
  <description>Systematically renames specified log files on a scheduled basis. Designed to help manage MUSHClient logging and prevent long, continuous log files.</description>
  <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.2</version>
            <!-- nothing here -->
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.2-beta-4</version>
            <configuration>
              <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
              </descriptorRefs>
              <archive>
                <manifest>
                  <mainClass>com.gorkwobble.logmanager.LogManager</mainClass>
                </manifest>
              </archive>
            </configuration>
            <executions>
              <execution>
                <phase>package</phase>
                <goals>
                  <goal>single</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
              <source>1.6</source>
              <target>1.6</target>
            </configuration>
          </plugin>
    </plugins>
  </build>
  <dependencies>
    <!-- commons-lang -->
    <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
        <version>2.4</version>
    </dependency> 

    <!-- Quartz scheduler -->
    <dependency>
        <groupId>opensymphony</groupId>
        <artifactId>quartz</artifactId>
        <version>1.6.3</version>
    </dependency>
    <!-- Quartz 1.6.0 depends on commons collections -->
    <dependency>
      <groupId>commons-collections</groupId>
      <artifactId>commons-collections</artifactId>
      <version>3.1</version>
    </dependency>
    <!-- Quartz 1.6.0 depends on commons logging -->
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.1</version>
    </dependency>
    <!-- Quartz 1.6.0 requires JTA in non J2EE environments -->
    <dependency>
      <groupId>javax.transaction</groupId>
      <artifactId>jta</artifactId>
      <version>1.1</version>
      <scope>runtime</scope>
    </dependency>

    <!-- junitx test assertions -->
    <dependency>
        <groupId>junit-addons</groupId>
        <artifactId>junit-addons</artifactId>
        <version>1.4</version>
        <scope>test</scope>
    </dependency>

    <!-- junit dependency; FIXME: make this a separate POM -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.1</version>
    </dependency>

  </dependencies>
  <dependencyManagement>
  </dependencyManagement>
</project>

person RMorrisey    schedule 29.11.2009    source источник


Ответы (4)


На самом деле, я думаю, что ответ, данный в вопрос, который вы упомянули, просто неверен (ОБНОВЛЕНИЕ - 20101106: кто-то исправил его, этот ответ относится к версия, предшествующая редактированию), и это объясняет, по крайней мере частично, почему у вас возникают проблемы.


Он генерирует два файла jar в logmanager / target: logmanager-0.1.0.jar и logmanager-0.1.0-jar-with-dependencies.jar.

Первый - это JAR модуля logmanager, сгенерированный на этапе package пользователем jar:jar (поскольку модуль имеет упаковку типа jar). Вторая - это сборка, созданная assembly:assembly, и она должна содержать классы из текущего модуля и его зависимости (если вы использовали дескриптор jar-with-dependencies).

Я получаю сообщение об ошибке при двойном щелчке по первой банке:

Could not find the main class: com.gorkwobble.logmanager.LogManager. Program will exit.

Если вы применили предложенную конфигурацию ссылки, размещенной в качестве справки, вы настроили плагин jar для создания исполняемого артефакта, примерно так:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
      <archive>
        <manifest>
          <addClasspath>true</addClasspath>
          <mainClass>com.gorkwobble.logmanager.LogManager</mainClass>
        </manifest>
      </archive>
    </configuration>
  </plugin>

Итак, logmanager-0.1.0.jar действительно исполняемый файл, но 1. это не то, что вы хотите (потому что у него нет всех зависимостей) и 2. он не содержит com.gorkwobble.logmanager.LogManager (это то, о чем говорит ошибка, проверьте содержимое jar).

Немного другая ошибка, когда я дважды щелкаю jar-with-dependencies.jar:

Failed to load Main-Class manifest attribute from: C:\EclipseProjects\logmanager\target\logmanager-0.1.0-jar-with-dependencies.jar

Опять же, если вы настроили плагин сборки, как было предложено, у вас будет что-то вроде этого:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
    </configuration>
  </plugin>

При такой настройке logmanager-0.1.0-jar-with-dependencies.jar содержит классы из текущего модуля и его зависимости, но, согласно ошибке, его META-INF/MANIFEST.MF не содержит записи Main-Class (вероятно, не тот же MANIFEST.MF, что и в logmanager-0.1.0.jar). На самом деле jar является не исполняемым файлом, что, опять же, не то, что вам нужно.


Итак, я предлагаю удалить элемент configuration из maven-jar-plugin и настроить maven-assembly-plugin следующим образом:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.2</version>
    <!-- nothing here -->
  </plugin>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.2-beta-4</version>
    <configuration>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
      <archive>
        <manifest>
          <mainClass>org.sample.App</mainClass>
        </manifest>
      </archive>
    </configuration>
    <executions>
      <execution>
        <phase>package</phase>
        <goals>
          <goal>single</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

Конечно, замените org.sample.App классом, который вы хотите выполнить. Небольшой бонус, я привязал assembly:single к фазе package, поэтому вам больше не нужно запускать assembly:assembly. Просто запустите mvn install, и сборка будет произведена во время стандартной сборки.

Итак, обновите свой pom.xml конфигурацией, указанной выше, и запустите mvn clean install. Затем перейдите в каталог target и повторите попытку:

java -jar logmanager-0.1.0-jar-with-dependencies.jar

Если вы получили сообщение об ошибке, обновите свой вопрос и опубликуйте содержание файла META-INF/MANIFEST.MF и соответствующей части вашего pom.xml (части конфигурации плагинов). Также опубликуйте результат:

java -cp logmanager-0.1.0-jar-with-dependencies.jar com.gorkwobble.logmanager.LogManager

чтобы продемонстрировать, что он отлично работает в командной строке (независимо от того, что говорит eclipse).

РЕДАКТИРОВАТЬ: для Java 6 вам необходимо настроить maven-compiler-plugin. Добавьте это в свой pom.xml:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
      <source>1.6</source>
      <target>1.6</target>
    </configuration>
  </plugin>
person Pascal Thivent    schedule 29.11.2009
comment
Спасибо за ваши комментарии! Я изменил свой pom.xml, как вы указали. Когда я запускаю mvn clean install, я получаю кучу ошибок компиляции из моего кода, говоря, что аннотации и т. Д. Не поддерживаются в -source 1.3. Я использую jdk1.6, и он компилируется в eclipse; Я не знаю, как появилась версия 1.3. Может быть, одна из версий библиотеки в фрагменте pom более старая? - person RMorrisey; 29.11.2009
comment
Спасибо! Я прошел через проблему 1.3. Мне также пришлось добавить зависимость junit4 к моему POM. Я работаю над устранением других проблем; если я застряну, я опубликую еще раз! Если у меня запущена банка, я помечу это как ответ. Мой текущий POM обновлен в вопросе выше. - person RMorrisey; 30.11.2009
comment
Есть ли способ исключить ресурсы из сгенерированного файла jar? - person ; 03.11.2010
comment
@HaiMinhNguyen Какая банка? По умолчанию или созданный плагином сборки? В обоих случаях это возможно, но не совсем так. - person Pascal Thivent; 03.11.2010
comment
Тот, который создается плагином сборки. Я нашел способ благодаря вашему ответу здесь stackoverflow.com/questions/2737601/. Спасибо. - person ; 04.11.2010
comment
@Pascal Thivent: Извините, я думаю, что ошибаюсь. Я задал вопрос о своей проблеме (stackoverflow.com/questions/4113697/). Не могли бы вы мне помочь? Большое тебе спасибо. - person ; 06.11.2010
comment
Хороший ответ, но у меня небольшая проблема со сборкой. Когда я переключаю appendAssemblyId на false, мои классы удваиваются в моем файле outpu jar! Есть идеи, как это исправить? Я предполагаю, что плагин сборки обычно создает новый файл jar с суффиксом -jar-with-dependencies, но, поскольку я отключил его, он добавляет зависимости вместе с файлами проекта в существующий jar (созданный с помощью jar: jar) - person Wojtek Owczarczyk; 04.02.2012
comment
@Pascal, согласно вышеупомянутому подходу, зависимые банки находятся в разнесенном формате внутри моей банки. Можно ли сохранить зависимости как банки (в моей банке)? - person saravana_pc; 08.08.2012
comment
Если бы я мог дать по этому поводу более одного голоса, я бы так и поступил. Большое спасибо, потому что другой ответ просто не сработал для меня. - person Adam Parkin; 15.11.2012
comment
Возможно ли, чтобы получившаяся банка имела нормальное имя? - person Daniil Shevelev; 11.02.2014
comment
Чтобы ответить на мой собственный комментарий: использование плагина shade со свойством transformers работает для изменения имени созданного jar. - person Daniil Shevelev; 11.02.2014
comment
Я также нашел этот Сообщение в блоге Sonatype полезно - person ; 13.04.2015

Мне тоже помог ответ Паскаля Тивента. Но если вы управляете своими подключаемыми модулями в <pluginManagement>element, вам необходимо снова определить сборку вне управления подключаемыми модулями, иначе зависимости не будут упакованы в jar-файл, если вы запустите mvn install.

<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>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>


    <build>
        <pluginManagement>
            <plugins>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.1</version>
                    <configuration>
                        <source>1.6</source>
                        <target>1.6</target>
                    </configuration>
                </plugin>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-assembly-plugin</artifactId>
                    <version>2.4</version>
                    <configuration>
                        <archive>
                            <manifest>
                                <mainClass>main.App</mainClass>
                            </manifest>
                        </archive>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                    </configuration>
                    <executions>
                        <execution>
                            <id>make-assembly</id>
                            <phase>package</phase>
                            <goals>
                                <goal>single</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>

            </plugins>

        </pluginManagement>

        <plugins> <!-- did NOT work without this  -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
            </plugin>
        </plugins>

    </build>


    <dependencies>
       <!--  dependencies commented out to shorten example -->
    </dependencies>

</project>
person mike    schedule 04.09.2013
comment
Спасибо, Майк, мне это помогло. Первоначально мой пакет создавался без использования ‹pluginManagement›. Но Eclipse выдавал некоторую ошибку в pom.xml maven - выполнение плагина не охвачено жизненным циклом. Которые меня отвлекают. Чтобы решить эту проблему, я добавил ‹pluginManagement›, теперь ошибка eclipse исчезла, но мой пакет перестал строиться. Ваш приведенный выше фрагмент pom сработал для меня. :) - person shashaDenovo; 01.07.2015
comment
Это было полезно ... при использовании ‹pluginManagement› верхний ответ не сработает. - person ininprsr; 20.07.2015

Если вы не хотите выполнять цель сборки в пакете, вы можете использовать следующую команду:

mvn package assembly:single

Здесь пакет - ключевое слово.

person leonidv    schedule 05.04.2011

Щелкните проект правой кнопкой мыши и дайте maven build, maven clean, maven generate resource и maven install. Jar-файл будет автоматически сгенерирован.

person dolly doll    schedule 22.04.2016