You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为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部署。

配置步骤

  1. 确保Gradle构建产物路径:确认你的Gradle模块构建后,class文件在build/classes/java/main,资源文件(包括正确的META-INF/MANIFEST.MF)在build/resources/main,或者直接生成了完整的JAR在build/libs/。

  2. 修改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:

  1. 确认META-INF/MANIFEST.MF的关键头信息完全一致(方案1)或核心字段匹配(方案2)
  2. 确认OSGI-INF目录存在且包含组件描述符
  3. 部署到Liferay后,查看日志是否出现Bundle your.module.symbolic.name [xxx] STARTED,表示部署成功

内容的提问来源于stack exchange,提问作者Manticore

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:39:53