使用Maven生成部分阴影的可运行jar

时间:2015-04-03 13:21:12

标签: java maven jar

我有一个部署环境,我有以下目录结构:

+--runnable.jar
+--thirdparty_lib
   +-- a.jar
   +-- b.jar
   +-- c.jar

这很好用,因为我们有相当频繁的部署,但不常见的thirdparty_lib更新(其中有很多,需要很长时间)。 [未来,这种结构和部署系统不可行,但它是我们现在所拥有的,并且不想改变它]

runnable.jar中的代码是从多个项目(包括一些共享内部库)的eclipse生成的。

我为每个项目创建了一个Maven模块,以便管理内部和第三方依赖项。我创建了一个初始构建配置(使用maven-jar-plugin和maven-dependency-plugin)生成

+--runnable.jar
+--lib
   +-- a.jar
   +-- b.jar
   +-- c.jar
   +-- internaldependency1.jar
   +-- internaldependency2.jar

运行正常,表示更新部署时的所有内部依赖项。

所以我想在runnable.jar中包含一些.jar文件,以便快速部署,而在thirdparty_lib文件夹中包含其他文件,这些文件不需要经常部署。

我遇到了几个问题,并有一个初步的解决方案,下面给出了答案,但似乎过于复杂。

1 个答案:

答案 0 :(得分:0)

我的解决方案需要三个部分

  • 使用maven-shade-plugin在runnable.jar
  • 中包含内部依赖关系jar
  • 使用maven-dependency-plugin copy-dependencies复制其他依赖项
  • 在runnable.jar的清单中设置正确的类路径

前两部分非常简单。 maven-shade-plugin的配置需要

<configuration>
  ...
  <artifactSet>
    <includes>
      <include>INTERNAL_GROUP</include>
    </includes>
  </artifactSet>
</configuration>

maven-dependency-plugin的配置:copy-dependencies

<configuration>
  <outputDirectory>thirdparty_lib</outputDirectory>
  <excludeGroupIds>INTERNAL_GROUP</excludeGroupIds>
</configuration>

但是设置类路径证明是具有挑战性的。可运行的jar清单中不允许使用通配符。也没有裸文件夹名称。以前,maven-jar-plugin从依赖项生成类路径,但现在......?

我发现maven-dependency-plugin:build-classpath在创建我想要的类路径方面做得很好,但是使用了一个不能为空字符串的pathSeparator(我尝试在生成有效POM时删除空格的所有变体) )。然后我可以将它输出到运行时属性(除了jar清单的错误分隔符,它需要路径之间的空格)。

<configuration>
  <prefix>thirdparty_lib</prefix>
  <pathSeparator>:</pathSeparator>
  <outputProperty>CLASSPATH_WITH_WRONG_SEPARATOR</outputProperty>
  <excludeGroupIds>INTERNAL_GROUP </excludeGroupIds>
</configuration>

我使用gmaven-plugin

解决了这个问题
<configuration>
  <source>
    project.properties.setProperty(
      'CLASSPATH_WITH_SPACES',
      project.properties.CLASSPATH_WITH_WRONG_SEPARATOR.replace(':', ' ')
    )
  </source>
</configuration>

将以下条目添加到maven-shade-plugin配置

<transformers>
  <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
   <manifestEntries>
    <Main-Class>MAIN</Main-Class>
    <Class-Path>${CLASSPATH_WITH_SPACES}</Class-Path>
   </manifestEntries>
  </transformer>
</transformers>