基础Weld示例搭配Embedded Tomcat无法运行:注入Bean为空、BeanManager查找失败
问题根源
从日志差异能明确看出:Embedded Tomcat环境下Weld没有触发Tomcat专属容器集成逻辑,而是回退到了通用Servlet生命周期管理模式。这直接导致Weld无法把BeanManager正确绑定到JNDI,也没法处理CDI依赖注入,最终出现Bean注入为null、JNDI查找失败的问题。
解决方案
1. 替换Weld依赖,启用Tomcat集成模块
你之前用的weld-servlet-core仅包含核心Servlet支持,缺少Tomcat集成的关键代码。必须替换为完整的weld-servlet依赖:
implementation group: 'org.jboss.weld.servlet', name: 'weld-servlet', version: '5.1.0.Final'
2. 确保Weld能识别Embedded Tomcat环境
Embedded Tomcat的类加载机制和常规Tomcat不同,得让Weld能检测到Tomcat核心类(比如org.apache.catalina.Context):
- 添加Tomcat API依赖(保证Weld能访问到Tomcat类):
compileOnly group: 'org.apache.tomcat.embed', name: 'tomcat-embed-core', version: '10.1.5' compileOnly group: 'org.apache.tomcat', name: 'tomcat-catalina', version: '10.1.5'
- 若自动检测失效,强制Weld使用Tomcat容器:
在启动Tomcat前添加系统属性:
System.setProperty("org.jboss.weld.environment.container.class", "org.jboss.weld.environment.tomcat.TomcatContainer");
3. 调整Embedded Tomcat的类加载器和监听器配置
修改主类代码,确保Web应用类加载器能加载Weld的Tomcat集成类,同时使用正确的Weld监听器:
Tomcat tomcat = new Tomcat(); String webappDirLocation = "src/main/webapp/"; Context ctx = tomcat.addWebapp("/", new File(webappDirLocation).getAbsolutePath()); // 设置Web应用类加载器为当前线程类加载器,确保Weld能访问到Tomcat和自身的类 ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); ctx.setClassLoader(classLoader); File additionWebInfClasses = new File("build/classes/java/main/"); WebResourceRoot webResourceRoot = new StandardRoot(ctx); webResourceRoot.addPreResources( new DirResourceSet(webResourceRoot, "/WEB-INF/classes", additionWebInfClasses.getAbsolutePath(), "/")); // 替换为Weld Tomcat专属监听器 ctx.addApplicationListener("org.jboss.weld.environment.tomcat.WeldServletListener"); tomcat.enableNaming(); // 手动添加BeanManager的JNDI资源链接(Embedded Tomcat不会自动加载context.xml配置) ctx.getNamingResources().addResourceLink(new ResourceLink() {{ setName("BeanManager"); setGlobal("BeanManager"); setType("jakarta.enterprise.inject.spi.BeanManager"); }}); tomcat.getConnector(); tomcat.start(); tomcat.getServer().await();
4. 检查beans.xml的兼容性
确保WEB-INF下的beans.xml使用Jakarta EE 9+的命名空间(适配Tomcat10和Weld5):
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_4_0.xsd" version="4.0" bean-discovery-mode="all"> </beans>
验证
启动后查看日志,若出现org.jboss.weld.environment.tomcat.TomcatContainer initialize的条目,说明Weld已正确识别Tomcat环境,此时Bean注入和JNDI查找BeanManager应该能正常工作。
内容的提问来源于stack exchange,提问作者newuser
相关产品推荐
相关产品推荐

