Как создать исполняемый файл jar на основе spring с помощью maven?

У меня есть клиентский проект Spring-WS на основе Maven, который я хочу упаковать как одну банку. В eclipse все работает нормально. Когда я пытаюсь упаковать его как исполняемый jar-файл, я получаю исключения ClassNotFound, поскольку jar-файлы Spring не включены в jar-файл моего приложения.

Поэтому я добавил maven-shade-plugin, чтобы включить все мои зависимости в банку приложения. . Когда я смотрю на свою банку приложения, я вижу все файлы классов из всех включенных зависимостей (все библиотеки jar взорваны).

<build>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <mainClass>com.cws.cs.Client</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>1.7</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                </execution>
            </executions>

        </plugin>
    </plugins>
</build>

Моя проблема в том, что в процессе упаковки мои многочисленные зависимости Spring имеют разные META-INF/spring.schemas, которые переопределяют друг друга. Следовательно, в моей последней банке есть неполный файл spring.schemas.

Поэтому, когда я пытаюсь запустить свой исполняемый файл jar, я получаю сообщения об ошибках Spring о том, что файлы не могут быть найдены, поскольку файл spring.schemas неполный (файл jar Spring-WS переопределяет файл spring.schemas Spring-core).

Моя исполняемая банка META-INF/spring.schemas:

http\://www.springframework.org/schema/web-services/web-services-1.5.xsd=/org/springframework/ws/config/web-services-1.5.xsd
http\://www.springframework.org/schema/web-services/web-services-2.0.xsd=/org/springframework/ws/config/web-services-2.0.xsd
http\://www.springframework.org/schema/web-services/web-services.xsd=/org/springframework/ws/config/web-services-2.0.xsd

Вместо Spring-beans.jar META-INF/spring.schemas:

http\://www.springframework.org/schema/beans/spring-beans-2.0.xsd=org/springframework/beans/factory/xml/spring-beans-2.0.xsd
http\://www.springframework.org/schema/beans/spring-beans-2.5.xsd=org/springframework/beans/factory/xml/spring-beans-2.5.xsd
http\://www.springframework.org/schema/beans/spring-beans-3.0.xsd=org/springframework/beans/factory/xml/spring-beans-3.0.xsd
http\://www.springframework.org/schema/beans/spring-beans-3.1.xsd=org/springframework/beans/factory/xml/spring-beans-3.1.xsd
http\://www.springframework.org/schema/beans/spring-beans.xsd=org/springframework/beans/factory/xml/spring-beans-3.1.xsd
http\://www.springframework.org/schema/tool/spring-tool-2.0.xsd=org/springframework/beans/factory/xml/spring-tool-2.0.xsd
http\://www.springframework.org/schema/tool/spring-tool-2.5.xsd=org/springframework/beans/factory/xml/spring-tool-2.5.xsd
http\://www.springframework.org/schema/tool/spring-tool-3.0.xsd=org/springframework/beans/factory/xml/spring-tool-3.0.xsd
http\://www.springframework.org/schema/tool/spring-tool-3.1.xsd=org/springframework/beans/factory/xml/spring-tool-3.1.xsd
http\://www.springframework.org/schema/tool/spring-tool.xsd=org/springframework/beans/factory/xml/spring-tool-3.1.xsd
http\://www.springframework.org/schema/util/spring-util-2.0.xsd=org/springframework/beans/factory/xml/spring-util-2.0.xsd
http\://www.springframework.org/schema/util/spring-util-2.5.xsd=org/springframework/beans/factory/xml/spring-util-2.5.xsd
http\://www.springframework.org/schema/util/spring-util-3.0.xsd=org/springframework/beans/factory/xml/spring-util-3.0.xsd
http\://www.springframework.org/schema/util/spring-util-3.1.xsd=org/springframework/beans/factory/xml/spring-util-3.1.xsd
http\://www.springframework.org/schema/util/spring-util.xsd=org/springframework/beans/factory/xml/spring-util-3.1.xsd

Я в тупике. Я не уверен, могу ли/как я могу упаковать все как один исполняемый файл jar. Я не знаю, проблема ли это в конфигурации плагина тени или я пытаюсь сделать что-то невозможное. Было бы неправильно, если бы мне пришлось вручную создавать свой собственный файл spring.schemas (объединение других).

Возможно, я немного поторопился. В поисках дополнительной информации о плагине тени я заметил AppendingTransformer то, что я раньше пропустил. Однако меня беспокоит, как узнать, какие другие файлы имеют те же проблемы? Я обнаружил/обнаружил эту конкретную проблему Spring. Я понятия не имею о каких-либо других библиотеках, которые могут делать что-то подобное...

Мы ценим любые предложения.


person Eric B.    schedule 22.06.2012    source источник
comment
Альтернативный подход, который отлично работает, заключается в том, чтобы поместить банки Spring в отдельную папку lib и добавить эту папку lib в путь к классу в манифесте - см. ответ Андре Аронсена stackoverflow.com/a/4323501/241986   -  person Boris Treukhov    schedule 09.05.2015


Ответы (5)


Вместо maven-shade-plugin используйте onejar-maven-plugin. One-JAR позволяет упаковать приложение Java вместе с зависимыми JAR-файлами в один исполняемый файл JAR.

person amra    schedule 22.06.2012
comment
Моя проблема с плагином one-jar заключается в том, что он создает вторую банку в целевой папке с расширением one-jar.jar. Следовательно, когда я пытаюсь развернуть артефакт, он развертывает исходную банку, а не одну банку. Знаете ли вы, есть ли правильный способ настроить pom, чтобы избежать этой проблемы? - person Eric B.; 26.06.2012
comment
one-jar — это классификатор по умолчанию, добавленный плагином one-jar. См. onejar-maven-plugin.googlecode.com/svn/mavensite/usage. .html Настройте развертывание для использования этого классификатора stackoverflow.com/questions/9743574/ - person amra; 27.06.2012

Вы можете добавить следующую конфигурацию, чтобы содержимое файлов .schema из всех банок было добавлено вместе.

<configuration>
  <transformers>
    <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
      <resource>META-INF/spring.handlers</resource>
    </transformer>
    <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
      <resource>META-INF/spring.schemas</resource>
    </transformer>
  </transformers>
</configuration>
person gkamal    schedule 22.06.2012
comment
Спасибо - я видел то же самое и только что отредактировал свой вопрос, чтобы включить эту информацию. Мой вопрос/проблема заключается в том, как узнать, есть ли какие-либо другие библиотеки, которые могут испытывать подобные проблемы? Я не могу ожидать, что буду знать содержимое всех папок META-INF для всех библиотек, которые я использую... - person Eric B.; 22.06.2012
comment
Анализом, наверное, не определить. Единственный практический вариант — выполнить несколько тестов, убедиться, что он работает, и исправить все, что не работает. - person gkamal; 23.06.2012
comment
@gkamal что это значит get appended together разве файлы с одинаковыми именами не переопределяют друг друга при упаковке в jar? как разные файлы с одинаковым именем не могли столкнуться в банке? - person Jas; 10.02.2015
comment
@Jas - плагин maven Shade добавляет файлы вместе, если добавлена ​​вышеуказанная конфигурация. - person gkamal; 02.04.2015
comment
@gkamal Спасибо! Наконец это сработало. +1 - person Sahil Gulati; 17.02.2021

Вчера тоже столкнулся с этой проблемой.

Решение заключалось в том, чтобы подготовить необходимые файлы путем ручной конкатенации и настройки плагина сборки следующим образом:

  <files>
    <file>
        <source>src/META-INF/spring.schemas</source>
        <outputDirectory>META-INF</outputDirectory>
    </file>
    <file>
        <source>src/META-INF/spring.handlers</source>
        <outputDirectory>META-INF</outputDirectory>
    </file>
  </files>
  <dependencySets>
    <dependencySet>
      <outputDirectory>/</outputDirectory>
      <useProjectArtifact>true</useProjectArtifact>
      <unpack>true</unpack>
      <scope>runtime</scope>
      <unpackOptions>
        <excludes>
            <exclude>META-INF/spring.handlers</exclude>
            <exclude>META-INF/spring.schemas</exclude>
        </excludes>
      </unpackOptions>  
    </dependencySet>
  </dependencySets>

ПРИМЕЧАНИЕ: использование одного подхода jar недостаточно хорошо - вы не можете быть уверены в ручных смешанных файлах, попробуйте сохранить экспорт всех зависимостей как есть...

person Mikhail Tsaplin    schedule 02.08.2012

Вы пробовали использовать maven-assembly-plugin?

Он создаст для вас одну банку с зависимостями и, более того, может сделать эту банку исполняемой:

Используйте mainClass, чтобы указать класс, который вы хотите выполнить.

<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.3</version>
    <configuration>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
      <archive>
        <manifest>
          <mainClass>org.sample.App</mainClass>
        </manifest>
      </archive>
    </configuration>
    <executions>
      <execution>
        <id>make-assembly</id> <!-- this is used for inheritance merges -->
        <phase>package</phase> <!-- bind to the packaging phase -->
        <goals>
          <goal>single</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
person Jean-Philippe Briend    schedule 26.06.2012
comment
Плагины Shade и Assembly — это одна и та же концепция. Они оба взорвут зависимости и попытаются включить их в одну и ту же область. Оба сталкиваются с проблемами, когда несколько зависимостей имеют файлы по одному и тому же пути (например: META-INF/spring.schemas) - person Eric B.; 26.06.2012

Для людей, которые надеялись найти ответ для приложений Spring Boot, все, что вам нужно, это:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
person Koray Tugay    schedule 25.06.2020