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

122

Я пытаюсь создать исполняемый файл 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>
RMorrisey
источник

Ответы:

244

На самом деле, я думаю, что ответ, данный в упомянутом вами вопросе , просто неверен ( ОБНОВЛЕНИЕ - 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). Сосуд на самом деле не исполняемый файл, который снова не то , что вы хотите.


Итак, я предлагаю удалить 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>
Паскаль Тивент
источник
4
Спасибо за ваши комментарии! Я изменил свой pom.xml, как вы указали. Когда я запускаю mvn clean install, я получаю кучу ошибок компиляции из своего кода, говоря, что аннотации и т. Д. Не поддерживаются в -source 1.3. Я использую jdk1.6, и он компилируется в eclipse; Не знаю, как появилась версия 1.3. Может быть, одна из версий библиотеки в фрагменте pom более старая?
RMorrisey
Спасибо! Я прошел через проблему 1.3. Мне также пришлось добавить зависимость junit4 к моему POM. Я работаю над устранением других проблем; если застряну, опубликую еще раз! Если у меня запущена банка, я отмечу это как ответ. Мой текущий POM обновлен в вопросе выше.
RMorrisey
Есть ли способ исключить ресурсы из сгенерированного файла jar?
2
Возможно ли, чтобы итоговая банка имела "нормальное" имя?
Даниил Шевелев
1
Я также нашел этот пост в блоге Sonatype полезным
15

Мне тоже помог ответ Паскаля Тивента . Но если вы управляете своими плагинами внутри <pluginManagement>элемента, вам нужно снова определить сборку вне управления плагинами, иначе зависимости не будут упакованы в 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>
Майк
источник
1
Спасибо, Майк, мне это помогло. Первоначально мой пакет создавался без использования <pluginManagement>. Но Eclipse выдавал ошибку в pom.xml «maven - выполнение плагина не охвачено жизненным циклом». Что меня отвлекает. Чтобы решить эту проблему, я добавил <pluginManagement>, теперь ошибка eclipse исчезла, но мой пакет перестал строиться. Ваш приведенный выше фрагмент pom сработал для меня. :)
shashaDenovo 01
2
Это было полезно ... при использовании <pluginManagement> верхний ответ не сработает.
ininprsr
5

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

mvn package assembly:single

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

leonidv
источник
-1

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

кукла-кукла
источник