Arquillian部署EnterpriseArchive时@ArquillianResource注入URL异常如何解决
问题解答
1. 你的假设是否正确
你的假设完全符合Arquillian的官方设计规范。按标准实现,@ArquillianResource(SecurityServlet.class) 注解应当自动返回对应Servlet所在的WAR模块上下文根拼接Servlet路径的完整可访问URL,不需要手动处理部署包的随机命名问题。
2. 异常是否由OpenLiberty容器实现导致
是的,该异常是OpenLiberty官方Arquillian适配器的已知限制导致的。你当前使用的2.x版本适配器对EAR多模块部署场景的元数据扫描支持不完善:当部署EAR包时,适配器无法正确识别EAR内部内嵌的WAR模块的Servlet类信息,也无法关联Servlet类和对应WAR的随机上下文路径,因此URL资源提供者会返回null抛出异常。
你当前的Liberty特性配置、Arquillian依赖配置均无错误,不需要调整这部分内容。
3. 正确获取模块URL的方案
你可以选择以下任意一种可行方案解决问题:
- 方案一:显式指定WAR模块的上下文根
在构建EAR归档时通过ShrinkWrap的API为对应WAR绑定固定上下文根,避免依赖随机生成的路径,示例代码如下:
之后直接通过注入的根URL拼接即可得到Servlet的访问地址:EnterpriseArchive ear = ShrinkWrap.create(EnterpriseArchive.class) .addAsModules(war, jar) // 给SecurityServlet所在的WAR设置固定上下文根 .setWebModuleContextRoot(war.getName(), "/security-test") .addAsManifestResource(ContextTests.class.getPackage(), "sun-ejb-jar.xml", "sun-ejb-jar.xml");@ArquillianResource URL earRootUrl; // 拼接得到Servlet完整路径 URL servletUrl = new URL(earRootUrl, "/security-test/SecurityServlet"); - 方案二:调整部署结构
如果你的测试场景不需要EAR多模块拆分,可以直接将所有测试相关代码打包为单个WAR包部署,这种情况下@ArquillianResource(SecurityServlet.class)注解可以正常工作,返回正确的Servlet访问路径。 - 方案三:获取部署元数据动态解析
你可以在测试类中注入ArchiveDeploymentInfo对象,从该对象中读取所有部署模块的上下文路径映射关系,动态匹配到Servlet所在WAR的上下文路径后拼接访问地址。
内容的提问来源于stack exchange,提问作者KyleAure
相关产品推荐
相关产品推荐

