Uploaded image for project: 'OpenWebBeans'
  1. OpenWebBeans
  2. OWB-1290

java.lang.ClassNotFoundException: org.apache.webbeans.proxy.OwbNormalScopeProxy if request scope bean has a classloader missing the proxy marker

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Closed
    • Major
    • Resolution: Fixed
    • None
    • None
    • Injection and Lookup
    • None

    Description

      In some servlet containers (I'm looking at you jetty) the `HttpServletRequest` class is loaded from a classloader that is a common parent of both the webapp and the server.

      If you are integrating OWB by including the OWB JAR files in the webapp's .war file (as distinct from a server-side integration) then, naturally enough, the classloader of `HttpServletRequest` will not have the `OwbNormalScopeProxy` class... because it shouldn't

      When you then try to inject a `HttpServletRequest`, we get to https://github.com/apache/openwebbeans/blob/12873ed083df9986e82d2f84a423ea50053672c8/webbeans-impl/src/main/java/org/apache/webbeans/portable/ProviderBasedProducer.java#L56-L61

      ClassLoader loader = returnType.getClassLoader();
      if (loader == null)
      {
          loader = WebBeansUtil.getCurrentClassLoader();
      }
      Class<T> proxyClass = proxyFactory.createProxyClass(loader, returnType);
      

      Which will result in a stack trace similar to this:

      java.lang.ClassNotFoundException: org.apache.webbeans.proxy.OwbNormalScopeProxy
      at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
      at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
      at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
      at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
      at java.lang.ClassLoader.defineClass1(Native Method)
      at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
      at java.lang.ClassLoader.defineClass(ClassLoader.java:642)
      at sun.reflect.GeneratedMethodAccessor37.invoke(Unknown Source)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:498)
      at org.apache.webbeans.proxy.Unsafe.defineAndLoadClass(Unsafe.java:121)
      at org.apache.webbeans.proxy.AbstractProxyFactory.createProxyClass(AbstractProxyFactory.java:249)
      at org.apache.webbeans.proxy.AbstractProxyFactory.createProxyClass(AbstractProxyFactory.java:223)
      at org.apache.webbeans.proxy.NormalScopeProxyFactory.createProxyClass(NormalScopeProxyFactory.java:271)
      at org.apache.webbeans.portable.ProviderBasedProducer.produce(ProviderBasedProducer.java:61)
      at org.apache.webbeans.portable.AbstractProducer.produce(AbstractProducer.java:134)
      at org.apache.webbeans.component.AbstractOwbBean.create(AbstractOwbBean.java:122)
      at org.apache.webbeans.context.DependentContext.getInstance(DependentContext.java:68)
      at org.apache.webbeans.context.AbstractContext.get(AbstractContext.java:125)
      at org.apache.webbeans.container.BeanManagerImpl.getReference(BeanManagerImpl.java:813)
      at org.apache.webbeans.container.BeanManagerImpl.getInjectableReference(BeanManagerImpl.java:673)
      at org.apache.webbeans.inject.AbstractInjectable.inject(AbstractInjectable.java:100)
      at org.apache.webbeans.inject.InjectableField.doInjection(InjectableField.java:65)
      at org.apache.webbeans.portable.InjectionTargetImpl.injectFields(InjectionTargetImpl.java:227)
      at org.apache.webbeans.portable.InjectionTargetImpl.inject(InjectionTargetImpl.java:213)
      at org.apache.webbeans.portable.InjectionTargetImpl.inject(InjectionTargetImpl.java:203)
      at org.apache.webbeans.component.AbstractOwbBean.create(AbstractOwbBean.java:126)
      at org.apache.webbeans.component.ManagedBean.create(ManagedBean.java:66)
      at org.apache.webbeans.context.creational.BeanInstanceBag.create(BeanInstanceBag.java:76)
      at org.apache.webbeans.context.AbstractContext.getInstance(AbstractContext.java:159)
      at org.apache.webbeans.context.AbstractContext.get(AbstractContext.java:125)
      at org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.getContextualInstance(NormalScopedBeanInterceptorHandler.java:101)
      at org.apache.webbeans.intercept.RequestScopedBeanInterceptorHandler.getContextualInstance(RequestScopedBeanInterceptorHandler.java:76)
      at org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.get(NormalScopedBeanInterceptorHandler.java:71)
      

      It seems like there should be some validation that the marker interface is available from the loader class and then fall back to `WebBeansUtil.getCurrentClassLoader()`... (or maybe just always use that!)

       

       

      Attachments

        1. Screenshot 2019-06-19 at 17.26.33.png
          863 kB
          Stephen Connolly

        Activity

          People

            Unassigned Unassigned
            stephenc Stephen Connolly
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: