xzer / run-jetty-run

Official successor of https://code.google.com/p/run-jetty-run/
86 stars 26 forks source link

The calling class org.jboss.resteasy.cdi.CdiInjectorFactory is placed in multiple bean archives #213

Open flamant opened 5 years ago

flamant commented 5 years ago

Hello, I use runjettyrun and have an issue. I try to deploy and run a Java-angular-maven-multi module application INSIDE ECLIPSE on Jetty 9.4.8 .

Here is my web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">

    <display-name>Tourism Applicationwith Angular</display-name>
    <description>
        This is a simple web application with a source code organization
        based on the recommendations of the Application Developer's Guide.
    </description>
    <display-name>Archetype Created Web Application</display-name>

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

   <listener>
    <listener-class>
            org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
        </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>    

    <servlet>
        <servlet-name>Resteasy</servlet-name>
        <servlet-class>
            org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
        </servlet-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>webservice.TourismWebService</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>Resteasy</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

</web-app>

I expose the CDI bean manager through JNDI by creating jetty-env.xml under WEB-INF (http://www.agorava.org/news/2012/07/10/Starting-a-CDI-webapp-from-Maven-with-Weld-servlet-and-jetty-plugin/)

<!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>

To allow Jetty to load the server Classes, I create the file jetty-web.xml under WEB-INF (http://wiki.eclipse.org/Jetty/Reference/Jetty_Classloading)

<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
    <Configure class="org.eclipse.jetty.webapp.WebAppContext">
       <Call name="prependServerClass">
          <Arg>-org.eclipse.jetty.servlet.listener.IntrospectorCleaner</Arg>
       </Call>   
       <Call name="prependServerClass">
          <Arg>-org.eclipse.jetty.servlet.listener.ELContextCleaner</Arg>
       </Call>    
       <Call name="prependServerClass">
          <Arg>-org.eclipse.jetty.util.Decorator</Arg>
       </Call>
       <Call name="prependServerClass">
          <Arg>-org.eclipse.jetty.util.DecoratedObjectFactory</Arg>
       </Call>
       <Call name="prependServerClass">
          <Arg>-org.eclipse.jetty.server.handler.ContextHandler.</Arg>
       </Call>
       <Call name="prependServerClass">
          <Arg>-org.eclipse.jetty.server.handler.ContextHandler</Arg>
       </Call>
       <Call name="prependServerClass">
          <Arg>-org.eclipse.jetty.servlet.ServletContextHandler</Arg>
       </Call>
    </Configure>

And when I run jetty to deploy my war, I have the following error. I searched deeply on the web, but found no solution

2018-11-21 20:41:16.229:INFO:oejs.session:main: No SessionScavenger set, using defaults
    2018-11-21 20:41:16.234:INFO:oejs.session:main: Scavenging every 660000ms
    20:41:16.328 [main] INFO org.jboss.weld.environment.servletWeldServlet - WELD-ENV-001006: org.jboss.weld.environment.servlet.EnhancedListener used to initialize Weld
    20:41:16.410 [main] DEBUG org.jboss.resteasy.cdi.i18n - RESTEASY010540: Doing a lookup for BeanManager in java:comp/BeanManager
    20:41:16.417 [main] DEBUG org.jboss.resteasy.cdi.i18n - RESTEASY010610: Unable to obtain BeanManager from java:comp/BeanManager
    20:41:16.417 [main] DEBUG org.jboss.resteasy.cdi.i18n - RESTEASY010540: Doing a lookup for BeanManager in java:app/BeanManager
    20:41:16.417 [main] DEBUG org.jboss.resteasy.cdi.i18n - RESTEASY010610: Unable to obtain BeanManager from java:app/BeanManager
    20:41:16.421 [main] DEBUG org.jboss.resteasy.cdi.i18n - RESTEASY010550: Error occurred trying to look up via CDI util.
    org.jboss.weld.exceptions.IllegalStateException: WELD-001327: Unable to identify the correct BeanManager. The calling class org.jboss.resteasy.cdi.CdiInjectorFactory is placed in multiple bean archives
        at org.jboss.weld.SimpleCDI.ambiguousBeanManager(SimpleCDI.java:95)
        at org.jboss.weld.SimpleCDI$ClassNameToBeanManager.findBeanManager(SimpleCDI.java:68)
        at org.jboss.weld.SimpleCDI$ClassNameToBeanManager.apply(SimpleCDI.java:46)
        at org.jboss.weld.SimpleCDI$ClassNameToBeanManager.apply(SimpleCDI.java:39)
        at org.jboss.weld.util.cache.ReentrantMapBackedComputingCache$1.apply(ReentrantMapBackedComputingCache.java:55)
        at org.jboss.weld.util.cache.ReentrantMapBackedComputingCache$1.apply(ReentrantMapBackedComputingCache.java:51)
        at org.jboss.weld.util.cache.ReentrantMapBackedComputingCache.getValue(ReentrantMapBackedComputingCache.java:64)
        at org.jboss.weld.SimpleCDI.getBeanManager(SimpleCDI.java:104)
        at org.jboss.weld.SimpleCDI.getBeanManager(SimpleCDI.java:37)
        at org.jboss.resteasy.cdi.CdiInjectorFactory.lookupBeanManagerCDIUtil(CdiInjectorFactory.java:232)
        at org.jboss.resteasy.cdi.CdiInjectorFactory.lookupBeanManager(CdiInjectorFactory.java:152)
        at org.jboss.resteasy.cdi.CdiInjectorFactory.<init>(CdiInjectorFactory.java:44)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at java.lang.Class.newInstance(Class.java:442)
        at org.jboss.resteasy.spi.ResteasyDeployment.start(ResteasyDeployment.java:148)
        at org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap.contextInitialized(ResteasyBootstrap.java:28)
        at org.eclipse.jetty.server.handler.ContextHandler.callContextInitialized(ContextHandler.java:890)
        at org.eclipse.jetty.servlet.ServletContextHandler.callContextInitialized(ServletContextHandler.java:532)
        at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:853)
        at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:344)
        at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1515)
        at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1477)
        at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:785)
        at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:261)
        at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:545)
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
        at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:133)
        at org.eclipse.jetty.server.Server.start(Server.java:418)
        at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:107)
        at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:113)
        at org.eclipse.jetty.server.Server.doStart(Server.java:385)
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
        at runjettyrun.Bootstrap.main(Bootstrap.java:89)
    20:41:16.423 [main] DEBUG org.jboss.resteasy.cdi.i18n - RESTEASY010565: Found BeanManager in ServletContext
    20:41:16.423 [main] DEBUG org.jboss.resteasy.cdi.i18n - RESTEASY010565: Found BeanManager in ServletContext

I posted this question on stackoverflow and had this answer :

This is likely a configuration issue only.

This is the code that's triggering your error ...

https://github.com/weld/core/blob/6c2b09fac4e694a20877f017424acd6c4b3e3439/impl/src/main/java/org/jboss/weld/SimpleCDI.java#L50-L71

When CDI initializes it sees multiple Bean Managers.

Put a breakpoint in the for loop in that code so you can debug and see where it's pulling those Bean Managers from. So I debugged it putting a breakpoint image5 image5

and here are three debug windows print screen image6

image6

image7

image8

Do you understand the signification of the code and if so could you explain me where is the error ?

It seems that the deployment takes into account twice the dependencies and there is a conflict between ones included in WEB-INF/lib and the dependencies coming from local maven repository (../.m2/repository/...)

Here is the configuration of Jetty on Eclipse image9

image9

chang-chao commented 5 years ago

Hi @flamant , Can you provide a simplified project that can reproduce this issue?