将 maven-bundle-plugin 与 maven-shade-plugin 一起使用
Posted
技术标签:
【中文标题】将 maven-bundle-plugin 与 maven-shade-plugin 一起使用【英文标题】:Using maven-bundle-plugin with the maven-shade-plugin 【发布时间】:2013-08-19 06:58:29 【问题描述】:我正在使用 maven-shade-plugin 在构建的打包阶段重新定位一些包。我还使用 maven-bundle-plugin 来生成清单。问题是捆绑插件在阴影插件之前运行(在进程类阶段),并且在生成的清单的导出中不包含我的任何阴影包。
我怎样才能让这两个插件相互配合,以便我重新定位的包被捆绑插件视为任何其他包?
--
根据要求,我的 POM 的 Shade 和 bundle 部分:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<filters>
<filter>
<artifact>cglib:cglib</artifact>
<includes>
<include>net/sf/cglib/core/**</include>
<include>net/sf/cglib/proxy/**</include>
</includes>
</filter>
</filters>
<relocations>
<relocation>
<pattern>net.sf.cglib</pattern>
<shadedPattern>org.modelmapper.internal.cglib</shadedPattern>
</relocation>
<relocation>
<pattern>org.objectweb.asm</pattern>
<shadedPattern>org.modelmapper.internal.asm</shadedPattern>
</relocation>
</relocations>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.3.7</version>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
<configuration>
<instructions>
<Bundle-SymbolicName>$project.artifactId</Bundle-SymbolicName>
<Export-Package>
org.modelmapper,
org.modelmapper.builder,
org.modelmapper.config,
org.modelmapper.convention,
org.modelmapper.spi
</Export-Package>
<Private-Package>
org.modelmapper.internal.**
</Private-Package>
<Import-Package>
*
</Import-Package>
<Include-Resource>
maven-resources,
maven-dependencies
</Include-Resource>
</instructions>
</configuration>
</plugin>
拍摄from here
【问题讨论】:
请发布您的 pom.xml 的相关部分,包括<Export-Package>
和 <relocations>
部分。
这与 osgi 和/或 fuse ESB 有关吗?值得添加这些标签吗?
@AnthonyAccioly - 已发布。
@vikingsteve - 是的,OSGI。你指的是哪些标签?
@Jonathan 我的意思是建议将 osgi 标签添加到您的问题中,看起来已经完成:)
【参考方案1】:
另一种选择是完全转储 maven bundle 插件并使用 Maven Shade Plugin ManifestResourceTransformer 将所需的 OSGI 元数据添加到清单中。
以xbean-asm-shaded/pom.xml 为例。
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Bundle-SymbolicName>$project.artifactId</Bundle-SymbolicName>
<Export-Package>
org.apache.xbean.asm;org.modelmapper.builder; ...
</Export-Package>
<Import-Package>*</Import-Package>
<Private-Package>org.modelmapper.internal ...</Private-Package>
</manifestEntries>
</transformer>
【讨论】:
【参考方案2】:解决方案非常简单。您仍然可以同时使用 maven-bundle-plugin 和 maven-shade-plugin。你只需要记住订单。如果您使用捆绑包打包,maven 捆绑插件将在 maven-shade 之前的打包阶段执行。但这并没有错。
这是交易。
使用私有包:pkg.name.before.shading 用一个你可能会看到这个技巧在 FasterXML jackson-module-paranamer 中起作用
【讨论】:
这非常有效,除非您想自己导出阴影包。这里提出的解决方案将只包含来自 src/main/java 的包。【参考方案3】:我假设在compile
阶段完成后,您想要:
-
使用 shade 插件重新定位一些类
使用捆绑插件创建清单
使用 jar 插件打包
问题是bundle插件在shade插件之前运行
捆绑插件绑定到 process-classes
阶段,该阶段来自 before 与阴影插件绑定的 package
阶段。
我建议您也将阴影插件绑定到process-classes
阶段。像这样更改阴影插件配置:
<phase>process-classes</phase>
由于在 pom 文件中 shade 插件定义在 bundle 插件定义之前,所以在 process-classes
阶段,shade 插件将在 bundle 插件之前运行。
【讨论】:
不幸的是,这不起作用。它失败了,像这样Failed to execute goal org.apache.maven.plugins:maven-shade-plugin:2.1:shade (default) on project modelmapper: Failed to create shaded artifact, project main artifact does not exist.
【参考方案4】:
有一个简洁的 transformer
实现了来自 Hazelcast 的这个功能 - HazelcastManifestTransformer (ver 3.9)。它所做的是精心合并Import-Package
和Export-Package
属性,使用户能够排除扩展/缩减默认合并结果。
如何在你的pom.xml
中使用它:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<dependencies>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast-build-utils</artifactId>
<version>3.9</version>
</dependency>
</dependencies>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="com.hazelcast.buildutils.HazelcastManifestTransformer">
<mainClass>...</mainClass>
<!-- the tag below is required due to a missing null-check it seems -->
<overrideInstructions></overrideInstructions>
</configuration>
</executions>
</plugin>
覆盖指令 (Export/Import-Package
) 是逗号分隔的包名称,当我们想要从列表中排除这些特定的包时,前面带有一个感叹号。
希望这会有所帮助!我确实意识到这是一个老问题,但似乎 Hazelcast 的变压器并没有获得太多宣传。
【讨论】:
以上是关于将 maven-bundle-plugin 与 maven-shade-plugin 一起使用的主要内容,如果未能解决你的问题,请参考以下文章
带有 maven-bundle-plugin 的 OSGI JAR 包
<Export-Package> 用于使用 maven-bundle-plugin 的所有资源
如何使用来自 maven-bundle-plugin 的 bnd 指令?
使用 maven-bundle-plugin 安装 OSGi 依赖项