Jira插件启动报错:找不到ModuleFactoryBean类求助
开发Jira插件时,使用Quick Reload后执行atlas-mvn package更新JAR出现异常。最初仅打包步骤报错,删除target目录并通过atlas-run重新构建项目后问题依旧:项目编译成功,但服务器无法启动,错误日志提示找不到com.atlassian.plugins.osgi.javaconfig.configs.beans.ModuleFactoryBean类。
错误日志
org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from URL [bundle://3a20f3ef-c74d-403e-ab58-ca9d1f222d58_187.0:0/META-INF/spring/plugin-context.xml]; nested exception is java.lang.IllegalArgumentException: Could not find class [com.atlassian.plugins.osgi.javaconfig.configs.beans.ModuleFactoryBean] ... 2025-01-09 23:35:55,544+0500 ThreadPoolAsyncTaskExecutor::Thread 28 ERROR [o.e.g.b.e.internal.support.ExtenderConfiguration] Application context refresh failed (NonValidatingOsgiBundleXmlApplicationContext(bundle=com.i2c.jira.timesheet, config=osgibundle:/META-INF/spring/*.xml)) org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from URL [bundle://3a20f3ef-c74d-403e-ab58-ca9d1f222d58_187.0:0/META-INF/spring/plugin-context.xml]; nested exception is java.lang.IllegalArgumentException: Could not find class [com.atlassian.plugins.osgi.javaconfig.configs.beans.ModuleFactoryBean] at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:417)
配置类代码
package com.i2c.jira.timesheet.config; import com.i2c.jira.timesheet.api.MyPluginComponent; import com.i2c.jira.timesheet.impl.MyPluginComponentImpl; import com.atlassian.plugins.osgi.javaconfig.configs.beans.ModuleFactoryBean; import com.atlassian.plugins.osgi.javaconfig.configs.beans.PluginAccessorBean; import com.atlassian.sal.api.ApplicationProperties; import org.osgi.framework.ServiceRegistration; import org.springframework.beans.factory.FactoryBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import static com.atlassian.plugins.osgi.javaconfig.OsgiServices.exportOsgiService; import static com.atlassian.plugins.osgi.javaconfig.OsgiServices.importOsgiService; @Configuration @Import({ ModuleFactoryBean.class, PluginAccessorBean.class }) public class MyPluginJavaConfig { @Bean public ApplicationProperties applicationProperties() { return importOsgiService(ApplicationProperties.class); } @Bean public MyPluginComponent myPluginComponent(ApplicationProperties applicationProperties) { return new MyPluginComponentImpl(applicationProperties); } @SuppressWarnings("rawtypes") @Bean public FactoryBean<ServiceRegistration> registerMyDelegatingService( final MyPluginComponent mypluginComponent) { return exportOsgiService(mypluginComponent, null, MyPluginComponent.class); } }
plugin-context.xml代码
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.i2c.jira.timesheet.config" /> </beans>
构建环境信息
- SDK版本:8.2.7
- Maven版本:3.5.4
- AMPS版本:8.1.2
- Spring版本:5.3.39
已验证的OSGi依赖
<dependency> <groupId>com.atlassian.plugins</groupId> <artifactId>atlassian-plugins-osgi-javaconfig</artifactId> <version>${osgi.javaconfig.version}</version> <scope>provided</scope> </dependency>
已尝试的OSGi版本
- 0.2.0
- 0.2.1
- 0.6.0
解决思路
确认依赖包的OSGi导出
provided范围的依赖需要Jira运行环境中已包含对应类。检查Jira系统插件中atlassian-plugins-osgi-javaconfig是否导出了com.atlassian.plugins.osgi.javaconfig.configs.beans包,可通过Jira插件管理页面查看系统插件的包导出详情。匹配AMPS与OSGi JavaConfig的兼容版本
AMPS版本8.1.2对atlassian-plugins-osgi-javaconfig有版本兼容要求,不要随意尝试版本。查看AMPS 8.1.2的官方依赖文档,使用推荐的对应版本。替换为Atlassian推荐的服务绑定方式
弃用@Import(ModuleFactoryBean.class)的方式,改用atlassian-spring-scanner实现服务导入导出:- 引入
atlassian-spring-scanner-annotation和atlassian-spring-scanner-runtime依赖 - 配置类中用
@Component标记Bean,用@OsgiService导入ApplicationProperties,用@OsgiServiceProvider导出MyPluginComponent
- 引入
临时调整依赖范围测试
将atlassian-plugins-osgi-javaconfig的依赖范围改为compile(仅测试用),重新构建启动,确认是否能找到类。测试通过后需改回provided,避免与Jira内置包冲突。清理SDK缓存并重建
执行atlas-clean,删除本地Maven缓存中com/atlassian/plugins/atlassian-plugins-osgi-javaconfig目录,重新拉取依赖后执行atlas-run。
内容的提问来源于stack exchange,提问作者Azhak Anwar

