Строить исполняемую банку с мавеном? - PullRequest
118 голосов
/ 29 ноября 2009

Я пытаюсь сгенерировать исполняемый 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. Мой основной класс запускается нормально из конфигурации запуска затмения. Может кто-нибудь помочь мне понять, почему мой файл 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>

Ответы [ 4 ]

239 голосов
/ 29 ноября 2009

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

EDIT: для 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>
14 голосов
/ 04 сентября 2013

Ответ Паскаль Тивент мне тоже помог. Но если вы управляете вашими плагинами в элементе <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>
5 голосов
/ 05 апреля 2011

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

mvn package assembly:single

Здесь package - ключевое слово.

0 голосов
/ 22 апреля 2016

Щелкните правой кнопкой мыши по проекту и выполните сборку maven, очистку maven, создание ресурса maven и установку maven. Файл jar будет создан автоматически.

...