javatomcatweldtomcat10embedded-tomcat

Basic Weld example with Embedded Tomcat not working


I am trying to use Weld with Embedded Tomcat (10.1.5) using a basic example and settings from official weld docs.

This weld injection with same code works fine with Tomcat on Eclipse.

However, on Embedded Tomcat, the injected bean is always null. If I try to lookup BeanManager using JNDI it throws this error:

//code
Context initContext = new InitialContext();
bm = (BeanManager) ((Context) initContext.lookup("java:comp/env")).lookup("BeanManager");
Exception: javax.naming.NamingException: WELD-001300: Unable to locate BeanManager

Added BeanManager entries to context.xml, web.xml, and empty beans.xml to WEB-INF.

gradle dependency:

implementation group: 'org.jboss.weld.servlet', name: 'weld-servlet-core', version: '5.1.0.Final'

main class:

Tomcat tomcat = new Tomcat();
String webappDirLocation = "src/main/webapp/";
Context ctx = tomcat.addWebapp("/", new File(webappDirLocation).getAbsolutePath());

// declare an alternate location for your "WEB-INF/classes" dir:
File additionWebInfClasses = new File("build/classes/java/main/");
WebResourceRoot webResourceRoot = new StandardRoot(ctx);
webResourceRoot.addPreResources(
        new DirResourceSet(webResourceRoot, "/WEB-INF/classes", additionWebInfClasses.getAbsolutePath(), "/"));

ctx.addApplicationListener(Listener.class.getName());

tomcat.enableNaming();
tomcat.getConnector();
tomcat.start();
tomcat.getServer().await();

What is the issue here? What extra setting is needed to use Weld with Embedded Tomcat ?

There is a curious difference in Weld startup logs too:

// Embedded Tomcat
Jan 26, 2023 11:50:56 PM org.jboss.weld.environment.servlet.WeldServletLifecycle initialize

// Tomcat with Eclipse
Jan 26, 2023 11:56:43 PM org.jboss.weld.environment.tomcat.TomcatContainer initialize


Solution

  • The Weld example was missing setResources() call which is needed to initialize this properly.

    ...
    WebResourceRoot webResourceRoot = new StandardRoot(ctx);
    webResourceRoot.addPreResources(
            new DirResourceSet(webResourceRoot, "/WEB-INF/classes", additionWebInfClasses.getAbsolutePath(), "/"));
    
    // this was missing 
    ctx.setResources(webResourceRoot);
    ...
    

    This is also easy to miss due to lack of documentation on embedded Tomcat.