是否可以创建一个包含项目类和项目依赖项的“uber”jar 作为带有自定义清单文件的 jar?

Posted

技术标签:

【中文标题】是否可以创建一个包含项目类和项目依赖项的“uber”jar 作为带有自定义清单文件的 jar?【英文标题】:Is it possible to create an "uber" jar containing the project classes and the project dependencies as jars with a custom manifest file? 【发布时间】:2010-12-22 09:59:18 【问题描述】:

我正在尝试创建一个可执行 jar(使用 maven),其中包含项目类及其依赖项,其中包含一个清单文件,该清单文件具有主类的条目和指向根中打包的依赖项的类路径条目罐子的;像这样的:

清单文件:

...... 主类:com.acme.MainClass 类路径:dependecy1.jardependecy2.jar ......

罐子:

jar 根 |-- .... |-- com/acme/../*.class |-- 依赖1.jar `--dependecy2.jar

我使用 maven-jar-plugin 创建清单文件,使用 maven-shade-plugin 创建“uber” jar,但依赖项已解压缩并作为类添加到我的 jar。

【问题讨论】:

【参考方案1】:

实际上,我没有检查 maven-shade-plugin 正在做什么(或任何其他插件),因为 maven 2 内置了所有东西来创建一个 megajar 或 uberjar。您只需使用带有预定义 jar-with-dependencies 描述符的 maven-assembly-plugin。

只需将此 sn-p 添加到您的 pom.xml 即可自定义清单:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <configuration>
    <archive>
      <manifest>
        <mainClass>my.package.to.my.MainClass</mainClass>
      </manifest>
    </archive>
  </configuration>
</plugin>

以下命令将生成您的 uberjar:

mvn assembly:assembly -DdescriptorId=jar-with-dependencies

但是,同样,此描述符的默认行为是解压缩依赖项(如 maven-shade-plugin)。老实说,我不明白为什么这是个问题,但是,如果这真的不是您想要的,您可以使用您自己的自定义程序集描述符。

为此,首先,创建您的程序集描述符,比如src/assembly/uberjar.xml,并包含以下内容:

<assembly>
  <id>uberjar</id>
  <formats>
    <format>jar</format>
  </formats>
  <includeBaseDirectory>false</includeBaseDirectory>
  <dependencySets>
    <dependencySet>
      <unpack>false</unpack>
      <scope>runtime</scope>
      <useProjectArtifact>false</useProjectArtifact>
    </dependencySet>
  </dependencySets>
  <fileSets>
    <fileSet>
      <directory>$project.build.outputDirectory</directory>
      <outputDirectory>/</outputDirectory>
    </fileSet>
  </fileSets>
</assembly>

然后,配置 maven-assembly-plugin 以使用此描述符并将依赖项添加到清单的 Class-Path 条目:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <configuration>
    <descriptors> 
      <descriptor>src/assembly/uberjar.xml</descriptor>
    </descriptors>
    <archive>
      <manifest>
        <mainClass>my.package.to.my.MainClass</mainClass>
        <addClasspath>true</addClasspath>
      </manifest>
    </archive>
  </configuration>
  <!--
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
    </execution>
  </executions>
  -->
</plugin>

最后运行 mvn assembly:assembly 来生成你的 uberjar。

或者,取消注释executions 元素以在package 阶段绑定程序集插件(并将程序集作为正常构建的一部分生成)。

【讨论】:

+1,非常有用的答案。我可以想象,一些软件生产商,尤其是操作系统之外的软件生产商,可能会禁止“反汇编/逆向工程”他们的产品,或者坚持按原样维护他们的包装,包括文件名等。 assembly:assembly 最近已替换为 assembly:single。 (我在组装插件版本 2.3) 组装插件和shade插件一样是一个插件,所以不是“内置”【参考方案2】:

OneJar 有一个maven2 plugin。

【讨论】:

【参考方案3】:

我过去曾为此使用过 FatJar。 http://fjep.sourceforge.net/

我创建了一个相对简单的应用程序,客户想要双击一个可执行文件并让它正常工作。安装程序或依赖项是不可能的。 Fatjar 将 Eclipse 中的项目库和引用文件捆绑到一个数兆字节的可执行 jar 中。完美无瑕。

【讨论】:

这是一个 Eclipse 插件吗?如果是这样,我看不出它是如何回答这个问题的。 OP 要求一个 Maven 解决方案... 你说得对,我看错了那部分。我想我认为它可以应用于其他领域,因为所有 IDE 都只不过是脚本包装器的包装器。【参考方案4】:
task uberJar(type: Jar) 
    manifest 
        attributes 'Main-Class': 'main.RunTest'
    
    dependsOn configurations.runtimeClasspath
    from sourceSets.main.output
    from sourceSets.test.output
    from sourceSets.main.resources
    from sourceSets.test.resources
    from 
        configurations.runtimeClasspath.findAll  it.name.endsWith('jar') .collect  zipTree(it) 
    
    from 
        project(':someothermoudule').sourceSets.main.resources // If current project depends on some other modules
        project(':someothermoudule').sourceSets.test.resources // If current project depends on some other modules
    
    exclude 'META-INF/*.RSA'
    exclude 'META-INF/*.SF'
    exclude 'META-INF/*.DSA'

如果上面的 gradle 可以提供帮助。注意from project('') 行,仅当当前项目依赖于其他一些子项目或模块时才需要。

【讨论】:

我也有同样的问题。我想用 Eclipse 构建 Maven 项目。我的问题是:在哪个文件中以及在哪里保存以下内容:``` org.apache.maven.pluginsmaven-assembly-plugin ... --> ``` 我也在尝试生成uberjar.xml 文件。 这是我在 githib 上的问题:github.com/tensorflow/java/issues/273 经过多次尝试;它必须在pom.xml 文件中的&lt;build&gt;&lt;plugins&gt; ... &lt;/plugins&gt;&lt;/build&gt; 之间

以上是关于是否可以创建一个包含项目类和项目依赖项的“uber”jar 作为带有自定义清单文件的 jar?的主要内容,如果未能解决你的问题,请参考以下文章

具有依赖项的 Maven2 + JMeter + JUnit

如何在另一个具有更高Spring版本的Spring项目中使用具有Spring作为打包依赖项的jar?

在android中创建一个具有依赖项的库

重新创建没有依赖项的GitHub项目(Java)

如何在不是Visual Studio c中的依赖项的构建中包含项目#

为啥使用 jasmine 对 Node typescript 项目进行 Karma 单元测试会显示包含依赖项的覆盖范围?