升级至WildFly 23后Arquillian静态变量为null的问题排查与解决
根据你的描述,升级到WildFly 23后测试代码里的静态数据类UserInfo的静态UUID变量变为null,这大概率是类加载器隔离或ShrinkWrap打包不完整导致的,毕竟WildFly从8到23的类加载机制(模块化架构)发生了巨大变化。下面是具体的排查和解决步骤:
一、先排查最可能的原因:ShrinkWrap是否正确打包了静态数据类
虽然你用了addPackages(true, "org.<company>.crs")递归添加包,但WildFly 23的模块化环境下,有时候递归打包会因为类的归属(比如是否是测试类、是否有特殊访问修饰符)出现遗漏。建议你显式指定添加utils包或UserInfo类:
public static Archive<?> createBasicShrinkWrappedDeployment() { File[] mavenImports = Maven.resolver() .loadPomFromFile("pom.xml") .importRuntimeDependencies() .resolve() .withTransitivity() .asFile(); return ShrinkWrap.create(WebArchive.class, "<project>-tests.war") .addAsLibraries(mavenImports) .addPackages(true, "org.<company>.crs") // 显式添加utils包,确保静态数据类被打包 .addPackages(true, "org.<company>.crs.utils") // 或者直接指定UserInfo类,更稳妥 .addClass(org.<company>.crs.utils.UserInfo.class) .addAsResource("jbossas-managed/test-persistence.xml", "META-INF/persistence.xml") .addAsResource("jbossas-managed/test-orm.xml", "META-INF/orm.xml") .addAsResource("templates/email/template1.vm") .addAsResource("templates/email/template2.vm") .addAsResource("templates/email/template3.vm") .addAsResource("templates/email/template4.vm") .addAsResource("templates/pdf/template5.vm") .addAsWebInfResource("beans.xml", "beans.xml"); }
二、验证类加载器是否一致
WildFly 23的模块化类加载会严格隔离不同模块的类,如果测试代码的类加载器和部署归档的类加载器不是同一个,就会出现UserInfo被加载两次的情况:测试代码引用的是未初始化的类实例,而部署应用里的是另一个实例。
你可以在测试代码和部署的业务代码中分别打印类加载器信息,确认是否一致:
// 测试代码中打印 System.out.println("测试类加载器: " + UserInfo.class.getClassLoader()); // 部署应用的某个Bean中打印 System.out.println("部署应用类加载器: " + UserInfo.class.getClassLoader());
如果两者输出不同,说明类被重复加载。此时需要确保测试代码和部署归档共享同一个类加载器,或者将静态数据类完全打包到部署归档中,让测试代码引用归档内的类。
三、检查静态初始化是否执行
有时候模块化环境会延迟类的静态初始化,你可以给UserInfo和内部类Id添加静态初始化日志,确认代码是否被执行:
package org.<company>.crs.utils; public class UserInfo{ static { System.out.println("UserInfo 静态初始化块执行"); } public static class Id { static { System.out.println("UserInfo.Id 静态初始化块执行"); } public static UUID Steve = UUID.fromString("..."); public static UUID TestPerson = UUID.fromString("..."); public static UUID Anonymous = UUID.fromString("..."); } }
如果日志没有打印,说明静态初始化根本没触发,这时候需要排查是否有类加载权限问题,或者Arquillian容器配置阻止了初始化。
四、确认Arquillian适配器版本匹配
WildFly 23需要对应版本的Arquillian容器适配器,版本不兼容会导致各种类加载异常。检查你的pom.xml,确保arquillian-wildfly-container的版本和WildFly 23匹配(比如使用2.2.0.Final或更高版本)。
五、排除依赖冲突
用mvn dependency:tree命令查看依赖树,确认是否有重复的org.<company>.crs.utils类被多个依赖引入,导致类加载冲突。如果有,通过<exclusions>标签排除重复依赖。
内容的提问来源于stack exchange,提问作者Tabs

