4 Replies Latest reply on Jan 11, 2016 9:00 AM by tremes

    WELD with embedded Jetty

    erg144

      I've been trying to figure out how to run weld with an embedded version of jetty and not having much luck (in fact, i can not seem to get it to run under jetty at all).  I seem to get a host of strange errors that I can not seem to resolve.

       

      When running under jetty I will get this following error:

       

      java.lang.RuntimeException: WELD-ENV-001024: Could not bind BeanManager reference to JNDI: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial|If the naming context is read-only, you may need to use a configuration to bind the BeanManager instead, such as Tomcats context.xml or Jettys jetty-web.xml.

       

      this would seem I don't have a web.xml and/or a jetty-env.xml - both which exist and seem proper.

       

      <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

          xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee

               http://xmlns.jcp.org/xml/ns/javaee/web-app_3_0.xsd"

          version="3.0">

          <listener>

              <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>

          </listener>

       

          <resource-env-ref>

              <description>Object factory for the CDI Bean Manager</description>

              <resource-env-ref-name>BeanManager</resource-env-ref-name>

              <resource-env-ref-type>javax.enterprise.inject.spi.BeanManager</resource-env-ref-type>

          </resource-env-ref>

      </web-app>

      <!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN"

         "http://www.eclipse.org/jetty/configure.dtd">

      <Configure id="webAppCtx" class="org.eclipse.jetty.webapp.WebAppContext">

          <New id="BeanManager" class="org.eclipse.jetty.plus.jndi.Resource">

              <Arg>

                  <Ref id="webAppCtx" />

              </Arg>

              <Arg>BeanManager</Arg>

              <Arg>

                  <New class="javax.naming.Reference">

                      <Arg>javax.enterprise.inject.spi.BeanManager</Arg>

                      <Arg>org.jboss.weld.resources.ManagerObjectFactory</Arg>

                      <Arg />

                  </New>

              </Arg>

          </New>

      </Configure>

       

       

      When I try and run embedded I get the following:

       

      INFO: WELD-ENV-001007: Initialize Weld using ServletContextListener

      Jan 07, 2016 7:20:01 AM org.jboss.weld.bootstrap.WeldStartup <clinit>

      INFO: WELD-000900: 2.3.1 (Final)

      Jan 07, 2016 7:20:01 AM org.jboss.weld.bootstrap.WeldStartup startContainer

      INFO: WELD-000101: Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.

      Jan 07, 2016 7:20:01 AM org.jboss.weld.interceptor.util.InterceptionTypeRegistry <clinit>

      WARN: WELD-001700: Interceptor annotation class javax.ejb.PostActivate not found, interception based on it is not enabled

      Jan 07, 2016 7:20:01 AM org.jboss.weld.interceptor.util.InterceptionTypeRegistry <clinit>

      WARN: WELD-001700: Interceptor annotation class javax.ejb.PrePassivate not found, interception based on it is not enabled

      Jan 07, 2016 7:20:01 AM org.jboss.weld.environment.jetty.JettyContainer initialize

      INFO: WELD-ENV-001201: Jetty 7.2+ detected, CDI injection will be available in Servlets and Filters. Injection into Listeners is not supported.

      2016-01-07 07:20:03.520:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@3ebff828{/,file:///E:/ccidev_data/workspace/Voyager/jetty-try2/src/main/webapp/,AVAILABLE}

      2016-01-07 07:20:03.568:INFO:oejs.ServerConnector:main: Started ServerConnector@6f80fafe{HTTP/1.1,[http/1.1]}{0.0.0.0:8085}

      2016-01-07 07:20:03.568:INFO:oejs.Server:main: Started @3915ms

       

      So far - so good.  However when I have an injectable component I get

       

      WARNING: The following warnings have been detected: WARNING: Unknown HK2 failure detected:

      MultiException stack 1 of 3

      org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=Injectable,parent=Service1,qualifiers={},position=-1,optional=false,self=false,unqualified=null,340210621)

          at org.jvnet.hk2.internal.ThreeThirtyResolver.resolve(ThreeThirtyResolver.java:75)

          at org.jvnet.hk2.internal.ClazzCreator.resolve(ClazzCreator.java:211)

          at org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:234)

          at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:357)

          at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)

          at org.glassfish.jersey.process.internal.RequestScope.findOrCreate(RequestScope.java:162)

          at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2072)

          at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:767)

       

      here is my code:

       

      public static void main(final String[] args) throws Exception {

       

              String webOrverrideXMFile = null;

              final Path start = Paths.get("");

              final int maxDepth = 5;

              try (final Stream<Path> stream = Files.find(start, maxDepth, (path, attr) -> path.getFileName().toString()

                      .contains("web.xml"))) {

                  webOrverrideXMFile = stream.findFirst().get().getParent().getParent().toString();

              }

              catch (final Exception e) {

                  System.out.println("could not find web override file");

                  e.printStackTrace();

              }

       

              final WebAppContext webapp = new WebAppContext();

       

              webapp.setContextPath("/");

              webapp.setResourceBase(webOrverrideXMFile);

       

              final Server jettyServer = new Server(8085);

              jettyServer.setHandler(webapp);

       

              final ServletHolder jerseyServlet = webapp

                      .addServlet(org.glassfish.jersey.servlet.ServletContainer.class, "/*");

              jerseyServlet.setInitOrder(0);

       

              // Tells the Jersey Servlet which REST service/class to load.

              jerseyServlet.setInitParameter("jersey.config.server.provider.classnames", Service1.class.getCanonicalName());

       

              try {

                  jettyServer.start();

                  jettyServer.join();

              }

              catch (final RuntimeException e) {

                  e.printStackTrace();

              }

              finally {

                  // jettyServer.destroy();

              }

          }

        • 1. Re: WELD with embedded Jetty
          tremes

          Hi Ed,

          Well it is really not clear to me. Which version of Jetty do you use? The stacktrace you provided looks more like some Jersey integration problem but I might be wrong. Can you point me to SystemInjecteeImpl code? Do you have any reproducer? I am not Jersey expert but this looks quite similar http://stackoverflow.com/questions/30230070/org-glassfish-hk2-api-unsatisfieddependencyexception-there-was-no-object-ava… 

          • 2. Re: WELD with embedded Jetty
            erg144

            Thanks for the quick response.

             

            This is a very simple example. When I take out weld and create the injectable manually – works fine.  When I try and use CDI, it cannot find it.

             

            FYI – I currently use weld with deltaspike in several other projects that run under Tomcat.  I am trying to create a standalone jar that I can run with the java –jar and have an embeddable container.

             

             

            Injectable class -

            package com.cc;

             

            import java.util.Random;

             

            public class Injectable {

             

                public String getRangom() {

                    final Random rand = new Random();

                    final int i = rand.nextInt();

                    final String str = new Integer(i).toString();

                    return str;

             

                }

            }

             

            Service Class

            package com.cc;

             

            import javax.inject.Inject;

            import javax.ws.rs.GET;

            import javax.ws.rs.Path;

            import javax.ws.rs.Produces;

            import javax.ws.rs.core.MediaType;

             

            @Path("/entry-point")

            public class Service1 {

                @Inject

                Injectable inj;

             

                @GET

                @Path("test")

                @Produces(MediaType.TEXT_PLAIN)

                public String test() {

                    String results = "none";

                    if (this.inj != null) {

            results = this.inj.getRangom();

                    }

                    return results;

                }

            }

             

             

             

            Here is my pom

            <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

                xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

                <modelVersion>4.0.0</modelVersion>

                <parent>

                    <groupId>com.cc</groupId>

                    <artifactId>voyager-top</artifactId>

                    <version>0.0.1-SNAPSHOT</version>

                </parent>

                <groupId>com.cc</groupId>

                <artifactId>jetty-try2</artifactId>

                <version>0.0.1-SNAPSHOT</version>

                <packaging>war</packaging>

                <properties>

                    <!-- Adapt this to a version found on http://central.maven.org/maven2/org/eclipse/jetty/jetty-maven-plugin/ -->

                    <jettyVersion>9.3.6.v20151106</jettyVersion>

                    <jersey-version>2.22.1</jersey-version>

                    <junit-version>4.12</junit-version>

            <weld.version>2.3.2.Final</weld.version>

            </properties>

                <dependencies>

             

                    <dependency>

            <groupId>org.glassfish.web</groupId>

            <artifactId>el-impl</artifactId>

            <version>2.2</version>

                    </dependency>

                    <dependency>

            <groupId>org.eclipse.jetty</groupId>

            <artifactId>jetty-server</artifactId>

            <version>${jettyVersion}</version>

                    </dependency>

                    <dependency>

            <groupId>org.eclipse.jetty</groupId>

            <artifactId>jetty-servlet</artifactId>

            <version>${jettyVersion}</version>

                    </dependency>

             

                    <dependency>

            <groupId>org.eclipse.jetty</groupId>

            <artifactId>jetty-webapp</artifactId>

            <version>${jettyVersion}</version>

                    </dependency>

             

                    <dependency>

            <groupId>org.eclipse.jetty</groupId>

            <artifactId>jetty-util</artifactId>

            <version>${jettyVersion}</version>

                    </dependency>

             

             

                    <dependency>

            <groupId>org.glassfish.jersey.core</groupId>

            <artifactId>jersey-server</artifactId>

            <version>${jersey-version}</version>

                    </dependency>

                    <dependency>

            <groupId>org.glassfish.jersey.containers</groupId>

            <artifactId>jersey-container-servlet-core</artifactId>

            <version>${jersey-version}</version>

                    </dependency>

                    <dependency>

            <groupId>org.glassfish.jersey.containers</groupId>

            <artifactId>jersey-container-jetty-http</artifactId>

            <version>${jersey-version}</version>

                    </dependency>

                    <dependency>

            <groupId>org.glassfish.jersey.media</groupId>

            <artifactId>jersey-media-moxy</artifactId>

            <version>${jersey-version}</version>

                    </dependency>

                    <dependency>

            <groupId>org.jboss.weld.servlet</groupId>

            <artifactId>weld-servlet</artifactId>

                    </dependency>

                </dependencies>

                <build>

                    <plugins>

            <plugin>

            <artifactId>maven-war-plugin</artifactId>

            <configuration>

            <version>3.0</version>

            </configuration>

            </plugin>

            <plugin>

            <groupId>org.eclipse.jetty</groupId>

            <artifactId>jetty-maven-plugin</artifactId>

            <version>9.3.1-SNAPSHOT</version>

            </plugin>

            <plugin>

            <artifactId>maven-compiler-plugin</artifactId>

            <configuration>

            <source>1.8</source>

            <target>1.8</target>

            </configuration>

            </plugin>

                    </plugins>

                </build>

            </project>

            • 3. Re: WELD with embedded Jetty
              tremes

              Ok. So I reproduced the problem. My interpretation is following: org.glassfish.jersey.servlet.ServletContainer (note that jersey-container-servlet-core is for Servlet 2.x) uses HK2 as javax.inject implementation and HK2 doesn't likely know anything about CDI beans. The problem is discussed at http://stackoverflow.com/questions/18963627/how-to-integrate-jax-rs-with-cdi-in-a-servlet-3-0-container but it doesn't include Jetty. You can try to include dependency to jersey-gf-cdi-ban-custom-hk2-binding but it didn't help to me.  I wonder whether you need to use Jetty? Wouldn't be Jersey Grizzly HTTP container sufficient? This should work jersey/examples/cdi-webapp at master · jersey/jersey · GitHub

              • 4. Re: WELD with embedded Jetty
                tremes

                I finally managed to get it working. Check attachment.