POM添加依赖与JBoss部署结构文件添加模块依赖的差异及类加载疑问
背景说明
在ejb-txn-remote-call快速启动示例中,应用做了两处关联配置:
1. POM文件添加的依赖
<!-- for Mock XAResource recovery we need the dependency to Narayana --> <dependency> <groupId>org.jboss.narayana.jts</groupId> <artifactId>narayana-jts-idlj</artifactId> <version>${version.narayana}</version> <scope>provided</scope> </dependency>
2. jboss-deployment-structure.xml中添加的模块依赖
<jboss-deployment-structure> <deployment> <dependencies> <!-- dependency to Narayana transaction module as the deployment uses internal Narayana classes to work with XAResource and recovery --> <module name="org.jboss.jts" slot="main" export="true" meta-inf="export"/> </dependencies> </deployment> </jboss-deployment-structure>
经确认,两者指向同一Jar包:
>less modules\system\layers\base\org\jboss\jts\main\module.xml <resources> <resource-root path="narayana-jts-idlj-5.11.3.Final-redhat-00001.jar"/> </resources>
疑问解答
问题1:在应用POM中添加依赖,是否会将其加入应用模块的ModuleClassLoader类路径?
不会。该依赖的scope为provided,Maven打包时不会将此Jar包打入应用归档(WAR/EAR等)。JBoss的ModuleClassLoader仅加载应用归档内的资源,以及通过jboss-deployment-structure.xml声明的模块依赖,因此这个POM依赖不会直接进入应用的ModuleClassLoader类路径。问题2:为应用模块添加依赖后,该依赖是否会出现在应用模块的ModuleClassLoader类路径上?
会。当在jboss-deployment-structure.xml中声明对org.jboss.jts模块的依赖后,JBoss模块系统会将该模块包含的所有资源(即对应的narayana-jts-idlj Jar包)纳入应用模块ModuleClassLoader的类搜索路径,应用代码可直接加载该模块内的类。问题3:通过调试查看moduleclassloader.paths.allPaths来确认类路径是否正确?
这种方式并不准确。allPaths通常仅包含应用归档自身携带的资源路径(如WEB-INF/lib下的Jar包),而JBoss模块系统提供的依赖是通过类加载委托机制处理的,不会直接出现在这个集合里。更可靠的验证方式包括:- 在代码中尝试加载目标模块内的类,检查是否加载成功;
- 查看JBoss服务器日志,确认无模块依赖加载失败的报错;
- 使用JBoss自带的
jboss-cli工具,执行module info命令查看模块依赖关系。
问题4:调试中发现allPaths仅显示POM添加的依赖,却看不到部署结构文件中添加的模块依赖,这是否符合预期?
符合预期。如问题3所述,allPaths仅记录应用自身打包携带的资源路径。jboss-deployment-structure.xml声明的模块依赖属于JBoss模块系统提供的外部依赖,这类依赖的资源不会被添加到allPaths中,而是通过类加载器委托机制访问。你看到POM依赖出现在allPaths里,大概率是打包时因插件配置问题误将Jar包纳入了应用归档,或是调试路径显示包含了本地Maven仓库路径,但这并不代表它被ModuleClassLoader实际使用。
内容的提问来源于stack exchange,提问作者ericj

