Будівництво виконуваної банки з maven?


122

Я намагаюся генерувати виконувану банку для невеликого домашнього проекту під назвою "logmanager", використовуючи maven, саме так:

Як я можу створити виконуваний JAR із залежностями за допомогою Maven?

Я додав показаний там фрагмент до pom.xml і запустив mvn Assembly: Assembly. Він генерує два jar-файли в logmanager / target: logmanager-0.1.0.jar та logmanager-0.1.0-jar-with-зависимостtions.jar. Я отримую помилку, коли двічі клацну на першій банці:

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

Трохи інша помилка, коли я двічі клацнув jar-with-зависимоtions.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>

Відповіді:


244

Насправді, я вважаю, що відповідь на вказане вами запитання просто неправильна ( ОНОВЛЕННЯ - 20101106: хтось виправив її, ця відповідь посилається на версію, що передувала редагуванню ), і це, принаймні частково, пояснює, чому ви стикаєтеся з проблемами.


Він генерує два jar-файли в logmanager / target: logmanager-0.1.0.jar та logmanager-0.1.0-jar-with-зависимостtions.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-зависимоtions.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 і налаштувати плагін 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. Потім введіть CD у 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

щоб продемонструвати, що це добре працює в командному рядку (незалежно від того, що говорить затемнення).

EDIT: Для Java 6 вам потрібно налаштувати плагін maven-компілятор. Додайте це до свого 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, і він збирається в затемнення; Я не впевнений, як 1.3 ввели. Можливо, одна з версій бібліотеки у фрагменті пам’яті є старшою?
RMorrisey

Дякую! Я пройшов минулий випуск 1.3. Я також повинен був додати залежність junit4 до мого POM. Я працюю над вирішенням інших проблем; якщо я застряг, я ще раз напишу! Якщо я зроблю баночку, я позначу це як відповідь. Мій поточний POM оновлений у вищезазначеному питанні.
RMorrisey

Чи є спосіб виключити ресурси із створеного файлу jar?

2
Чи можливо, щоб в результаті баночка мала "звичайне" ім'я?
Даніїл Шевельов

1
Я також вважаю корисною цю публікацію в блозі

15

Відповідь Паскаля Тівента допомогла і мені. Але якщо ви керуєте своїми плагінами всередині <pluginManagement>елемента, вам доведеться знову визначити збірку за межами управління плагінами, інакше залежності не запакуються в банку, якщо ви запустите 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>, тепер помилка затемнення пішла, але мій пакунок перестав бути створений. Ваш вище фрагмент помпону працював на мене. :)
shashaDenovo

2
Це було корисно .. під час використання <pluginManagement> верхня відповідь не працюватиме.
ininprsr

5

Якщо ви не хочете виконати ціль складання в пакеті, ви можете використовувати наступну команду:

mvn package assembly:single

Тут пакет - це ключове слово.


-1

Клацніть правою кнопкою миші проект і дайте Maven build, maven clean, maven генерує ресурс та Maven install.Бар-файл автоматично генерується.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.