如何为Liferay手动创建可部署的OSGI兼容JAR包?
解决方案:为Liferay TemplateContextContributor模块构建Maven包装器(保留Gradle构建逻辑)
针对你的需求——复用Gradle构建产物,仅用Maven做包装生成可部署的OSGI JAR,这里提供两种可靠方案,优先推荐第一种,完全规避Maven构建逻辑与Gradle的差异:
方案1:直接复用Gradle构建产物打包(推荐)
既然Gradle已经能生成正确的OSGI JAR,Maven只需要"打包Gradle的输出"即可,不需要重新处理代码或生成Manifest。这种方式能确保JAR完全和Gradle输出一致,100%兼容Liferay部署。
配置步骤
确保Gradle构建产物路径:确认你的Gradle模块构建后,class文件在
build/classes/java/main,资源文件(包括正确的META-INF/MANIFEST.MF)在build/resources/main,或者直接生成了完整的JAR在build/libs/。修改pom.xml:添加
exec-maven-plugin自动调用Gradle构建,再用maven-jar-plugin打包Gradle产物:
<properties> <gradle.build.dir>build</gradle.build.dir> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <build> <plugins> <!-- 自动调用Gradle完成构建(可选,也可手动先执行gradlew build) --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.1.0</version> <executions> <execution> <id>gradle-build</id> <phase>process-resources</phase> <goals> <goal>exec</goal> </goals> <configuration> <executable>./gradlew</executable> <arguments> <argument>build</argument> <argument>-x</argument> <argument>test</argument> <!-- 可选:跳过测试环节 --> </arguments> </configuration> </execution> </executions> </plugin> <!-- 用Gradle生成的class、资源和Manifest打包JAR --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.3.0</version> <configuration> <classesDirectory>${gradle.build.dir}/classes/java/main</classesDirectory> <resourcesDirectory>${gradle.build.dir}/resources/main</resourcesDirectory> <!-- 直接复用Gradle生成的Manifest,确保元数据完全一致 --> <archive> <manifestFile>${gradle.build.dir}/resources/main/META-INF/MANIFEST.MF</manifestFile> </archive> </configuration> </plugin> </plugins> </build>
方案2:让Maven生成与Gradle一致的Manifest
如果一定要让Maven独立生成Manifest,需要配置bnd插件模拟Liferay Gradle插件的元数据生成逻辑,确保包含Liferay特定的OSGI头信息。
修改后的pom.xml核心配置
<properties> <bundle.symbolic.name>your.module.symbolic.name</bundle.symbolic.name> <bundle.version>1.0.0</bundle.version> <liferay.plugin.type>module</liferay.plugin.type> <liferay.require.schema.version>1.0.0</liferay.require.schema.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.apache.felix</groupId> <artifactId>org.apache.felix.scr.ds-annotations</artifactId> <version>1.2.10</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.liferay.portal</groupId> <artifactId>com.liferay.portal.kernel</artifactId> <version>2.0.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.service.component.annotations</artifactId> <version>1.3.0</version> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <!-- 生成SCR组件描述符 --> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-scr-plugin</artifactId> <version>1.25.0</version> <executions> <execution> <id>generate-scr-descriptor</id> <goals> <goal>scr</goal> </goals> <configuration> <outputDirectory>${project.build.outputDirectory}/OSGI-INF</outputDirectory> <scanClasses>true</scanClasses> </configuration> </execution> </executions> </plugin> <!-- 用bnd生成符合Liferay要求的Manifest --> <plugin> <groupId>biz.aQute.bnd</groupId> <artifactId>bnd-maven-plugin</artifactId> <version>5.1.1</version> <!-- 与Liferay Gradle插件兼容版本 --> <executions> <execution> <goals> <goal>bnd-process</goal> </goals> </execution> </executions> <dependencies> <dependency> <groupId>biz.aQute.bnd</groupId> <artifactId>biz.aQute.bndlib</artifactId> <version>5.1.1</version> </dependency> <dependency> <groupId>com.liferay</groupId> <artifactId>com.liferay.ant.bnd</artifactId> <version>2.0.48</version> </dependency> </dependencies> <configuration> <bnd> <!-- 基础OSGI配置 --> Bundle-SymbolicName: ${bundle.symbolic.name} Bundle-Version: ${bundle.version} Export-Package: com.yourcompany.module.*;version=${bundle.version} Import-Package: * <!-- Liferay特定元数据 --> Liferay-Plugin-Type: ${liferay.plugin.type} Liferay-Require-SchemaVersion: ${liferay.require.schema.version} <!-- 包含SCR组件描述符 --> Include-Resource: OSGI-INF=${project.build.outputDirectory}/OSGI-INF Service-Component: OSGI-INF/*.xml </bnd> </configuration> </plugin> <!-- 用bnd生成的Manifest打包JAR --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.3.0</version> <configuration> <archive> <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile> </archive> </configuration> </plugin> </plugins> </build>
注意事项
- 替换
your.module.symbolic.name和com.yourcompany.module.*为你实际的模块符号名和包路径 - 使用5.x版本的bnd插件,与Liferay Gradle插件使用的bnd版本更匹配,减少元数据差异
- 确认
OSGI-INF目录下的组件描述符被正确打包,且Manifest中Service-Component头已声明
验证方法
打包后执行jar tf your-module.jar,对比Gradle生成的JAR:
- 确认
META-INF/MANIFEST.MF的关键头信息完全一致(方案1)或核心字段匹配(方案2) - 确认
OSGI-INF目录存在且包含组件描述符 - 部署到Liferay后,查看日志是否出现
Bundle your.module.symbolic.name [xxx] STARTED,表示部署成功
内容的提问来源于stack exchange,提问作者Manticore
相关产品推荐
相关产品推荐

