从基于 Spring 的 Java 应用程序创建单个可执行 JAR

Create a single executable JAR from a Spring Based Java Application

我有一个基于 spring 的应用程序,它执行 component/package 扫描以查找特定命名空间中的包。应用程序 运行 在 Eclipse 中完美运行,我想创建一个可执行 JAR 以部署到我们的各种环境。

我已经尝试了各种方法来让它工作,但唯一有效的是如果我将依赖项包含在 JAR 之外的文件夹中。这是我到目前为止尝试过的 -

  1. Maven Compile to a single jar from here ,使用这种方法创建单个 JAR,其中包含的依赖项为 类.当 运行 使用 -

    连接 JAR 时

    “java –jar jarName.jar”

    我收到一条错误消息 - "Error: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace http://www.springframework.org/schema/context]"

  2. 使用 Eclipse 中的“作为可运行的 JAR 文件”导出,然后选择“将需要的库提取到生成的 JAR 中” 在库处理部分。

    这还会构建一个 jar,其中包含 类 的依赖项。当 运行 安装 jar 时,我得到相同的“错误:配置问题:无法找到 Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/context]

  3. 使用 Eclipse 中的“作为可运行的 JAR 文件” 导出,然后选择“将需要的库打包到生成的 JAR 中” 在图书馆处理部分。

    这将构建一个 jar,其中包含作为 JAR 的依赖项(不是 类)。当我 运行 这个 JAR 我得到以下错误 –

    “无法在URL[rsrc:com/company/]下搜索匹配文件,因为它不对应文件系统中的目录java.io.FileNotFoundException:URL [rsrc:com/company/] 无法解析为绝对文件路径,因为它不驻留在文件系统中:rsrc:com/company/ at org.springframework.util.ResourceUtils.getFile(ResourceUtils.java:210”

    所以 JAR 运行 但无法扫描我要求它查找的组件。

  4. 使用 Eclipse 中的 Export 'As Runnable JAR file',然后选择 'Copy required libraries into a sub-folder next to the在库处理部分生成了 JAR'

    这会创建一个小 JAR,旁边有一个文件夹,其中包含所有作为 JAR 的依赖项。当我运行这个的时候,一切正常!

因此我认为这不是我的代码的问题,似乎是打包 spring 在单个 JAR 中进行扫描的问题。这样对吗?

有没有人对如何构建一个基于 spring 的应用程序执行 package/component 扫描到单个 运行 可用 JAR 有任何建议?

答案:

我将以下 XML 添加到我的 POM 文件中,并且只使用了 "mvn package",它创建了一个有效的可执行 jar。为什么它起作用仍然是个谜。

      <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>2.3</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <transformers>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                <mainClass>com.company.project.MainApp</mainClass>
                            </transformer>
                            <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>
                </execution>
            </executions>
        </plugin>

使用 Maven Shade Plugin 创建 uberjar。 This 也能帮到你。

我今天遇到的问题和你完全一样,步骤完全一样:)

非常感谢您的留言,这让我节省了一些时间,此外,我只想快速回答您的 "Why it worked is still a mystery." 句子:

"This is because I have several Spring Jar in my dependencies. Some of the spring jars contain meta info files with the same name. To avoid that some meta files are overridden you have to merge it"

所以这就是为什么您需要将这两个转换器添加到 Maven Shade 插件文档中给出的 Maven 片段中的原因:

<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

来源:http://robert-reiz.com/2011/11/14/832/

希望对理解有所帮助;)

在 eclipse 中试试这个: 在菜单中选择 File -> Export -> Runnable JAR file

在规范中 window:(正确填写其他空白后)库处理 : Select the second one

完成

现在在 cmd 或终端中尝试以下命令: java -jar [你的项目名称]

希望对您有所帮助

您可以使用您的选项 1 Maven 编译成一个带有额外目标参数的 jar

mvn clean package spring-boot:repackage

它将创建具有 Spring 自动加载功能的独立 jar 文件。