users@jersey.java.net

Re: [Jersey] Jersey provider-detection fails under Tomcat?

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Wed, 07 Jan 2009 12:06:18 +0100

On Jan 6, 2009, at 7:01 PM, Gili wrote:

>
> Paul,
>
> Can you clarify what would happen if all classes (including
> infrastructure
> ones) were to be marked using @Provider.

It would mean that infrastructure provides may get registered by the
user configuration when scanning e.g. file-based scanning as you
found. They are not intended to be registered by the end-user.


> You've said in the past this would
> break something but I don't understand what.
>

I recall saying that i would have to do some workarounds so that such
providers are not registered by the user configuration when scanning.
What i want to avoid is having to hard code package names to ignore or
doing some other workaround. I could annotate with another annotation
which states that it is to be ignored on scanning. But this all seems
unnecessary when there is a simpler solution of not annotating.

In what i proposed in my previous email was that infrastructure
providers should not cause the application to fail if the
infrastructure provider class cannot be initialized. For user-
registered providers i am proposing the opposite. For example, perhaps
in your application you are not using JAXB (i dunno if you are or not,
but lets assume so for the sake of argument you are not and are using
Java 5) if the JAXB providers were annotated with @Provider your
application would fail because the JAXB providers cannot not be
instantiated and you would have to add JAXB jars to your class path
even though you do not require JAXB.

Paul.


> Thanks,
> Gili
>
>
> Paul Sandoz wrote:
>>
>>
>> On Jan 6, 2009, at 6:03 PM, Gili wrote:
>>
>>>
>>> I used a debugger to walk through the code and as far as I can
>>> tell if
>>> @Provider is missing then the Guice getComponentProvider() is never
>>> invoked
>>> in the first place (this is in Jersey revision 1816).
>>
>> Thanks for doing that, it now confirms what i expected.
>>
>>
>>> Sounds like a second
>>> bug in Jersey no?
>>>
>>
>> Yes. I think the manner of a fix depends on where we choose to fail
>> on
>> class initialization. My preference would be that we fix the
>> annotation class scanner to fail on class loading causing an error
>> for
>> the config initialization resulting in application failure i.e. that
>> is the earliest point it can fail for such initialization cases. (In
>> general initialization of classes should fail on class loading for
>> all
>> cases.)
>>
>> I am still pondering what to do about the infrastructure providers.
>> Having looked at it more, i really want to avoid annotating them with
>> @Provider so they *do not* get picked up by user-defined
>> configuration, and we still need to support the "keep on trucking"
>> approach to the infrastructure providers. So i now think we need to
>> treat @Provider providers registered by the user different to those
>> registered by META-INF/service and supplied by Jersey. So i would
>> like
>> to revert back the multipart readers/writers to not be annotated with
>> @Provider.
>>
>> In summary:
>>
>> 1) the user-registered configuration class loading will perform
>> class initialization and if initialization fails the application will
>> fail early
>> before instantiation is attempted;
>>
>> 2) we can improve the reporting of infrastructure providers that
>> fail to load (a concise warning that also alleviates concerns for
>> those
>> who do not have an issue and linking to the dependencies
>> document seems appropriate); and
>>
>> 3) The ResourceConfig implementations should ignore any classes not
>> annotated with @Provider or @Path. I still need to think
>> how to do this without breaking compatibility. I am not sure
>> it is possible.
>>
>> Paul.
>>
>>
>>> Gili
>>>
>>>
>>> Paul Sandoz wrote:
>>>>
>>>> After some further investigation I realized that my evaluation is
>>>> wrong. Only when instantiating does a NoClassDefFoundError
>>>> regardless
>>>> of the difference in class loading (which is in the process of
>>>> being
>>>> fixed).
>>>>
>>>> I notice that your GuiceComponentProviderFactory is instantiating
>>>> the
>>>> provider class. The registered IoC component provider factory
>>>> will be
>>>> asked to instantiate components registered in both cases (@Provider
>>>> and META-INF/services) and if the provider factory returns null
>>>> Jersey
>>>> instantiates. For some reasons your provider factory is
>>>> instantiating
>>>> for the case of a class annotated with @Provider but not otherwise,
>>>> does your code have some logic to check annotations on the
>>>> classes it
>>>> instantiates?
>>>>
>>>> Paul.
>>>>
>>>> On Dec 24, 2008, at 3:10 AM, Gili wrote:
>>>>
>>>>>
>>>>> Here is what I found out:
>>>>>
>>>>> - The MultiPart provider fails to initialize because Javamail is
>>>>> missing.
>>>>> Glassfish bundles this dependency, whereas Tomcat does not.
>>>>> - If the MessageBodyReader omits @Provider then no error message
>>>>> shows up.
>>>>> The binding fails silently, causing Jersey to issue a confusing
>>>>> error
>>>>> message about the MessageBodyReader being missing when in fact
>>>>> it is
>>>>> not.
>>>>> - If the MessageBodyReader is annotated using @Provider the
>>>>> following
>>>>> exception shows up when the webapp is initialized:
>>>>>
>>>>> SEVERE: Exception starting filter warpServletFilter
>>>>> java.lang.NoClassDefFoundError: javax/mail/MessagingException
>>>>> at java.lang.Class.getDeclaredConstructors0(Native Method)
>>>>> at java.lang.Class.privateGetDeclaredConstructors(Class.java:
>>>>> 2389)
>>>>> at java.lang.Class.getDeclaredConstructors(Class.java:1836)
>>>>> at
>>>>> com
>>>>> .google
>>>>> .inject.spi.InjectionPoint.forConstructorOf(InjectionPoint.java:
>>>>> 192)
>>>>> at
>>>>> com
>>>>> .google
>>>>> .inject.ConstructorInjector.<init>(ConstructorInjector.java:
>>>>> 45)
>>>>> at com.google.inject.InjectorImpl$5.create(InjectorImpl.java:
>>>>> 728)
>>>>> at com.google.inject.InjectorImpl$5.create(InjectorImpl.java:
>>>>> 724)
>>>>> at
>>>>> com.google.inject.internal.FailableCache
>>>>> $1.create(FailableCache.java:
>>>>> 32)
>>>>> at
>>>>> com
>>>>> .google.inject.internal.ReferenceCache.create(ReferenceCache.java:
>>>>> 54)
>>>>> at
>>>>> com
>>>>> .google
>>>>> .inject
>>>>> .internal
>>>>> .AbstractReferenceCache
>>>>> .internalCreate(AbstractReferenceCache.java:
>>>>> 59)
>>>>> at
>>>>> com
>>>>> .google
>>>>> .inject
>>>>> .internal.AbstractReferenceCache.get(AbstractReferenceCache.java:
>>>>> 116)
>>>>> at
>>>>> com.google.inject.internal.ReferenceCache.get(ReferenceCache.java:
>>>>> 28)
>>>>> at
>>>>> com.google.inject.internal.FailableCache.get(FailableCache.java:
>>>>> 43)
>>>>> at
>>>>> com.google.inject.InjectorImpl
>>>>> $LateBoundConstructor.bind(InjectorImpl.java:431)
>>>>> at
>>>>> com
>>>>> .google.inject.ClassBindingImpl.initialize(ClassBindingImpl.java:
>>>>> 46)
>>>>> at
>>>>> com
>>>>> .google.inject.InjectorImpl.initializeBinding(InjectorImpl.java:
>>>>> 320)
>>>>> at
>>>>> com
>>>>> .google
>>>>> .inject.InjectorImpl.createJustInTimeBinding(InjectorImpl.java:
>>>>> 615)
>>>>> at
>>>>> com
>>>>> .google
>>>>> .inject
>>>>> .InjectorImpl.createJustInTimeBindingRecursive(InjectorImpl.java:
>>>>> 558)
>>>>> at
>>>>> com
>>>>> .google
>>>>> .inject.InjectorImpl.getJustInTimeBinding(InjectorImpl.java:
>>>>> 168)
>>>>> at
>>>>> com
>>>>> .google.inject.InjectorImpl.getBindingOrThrow(InjectorImpl.java:
>>>>> 128)
>>>>> at
>>>>> com.google.inject.InjectorImpl.getBinding(InjectorImpl.java:105)
>>>>> at
>>>>> com.google.inject.InjectorImpl.getBinding(InjectorImpl.java:60)
>>>>> at
>>>>> com
>>>>> .sun
>>>>> .jersey
>>>>> .spi
>>>>> .guice
>>>>> .container
>>>>> .GuiceComponentProviderFactory
>>>>> .getComponentProvider(GuiceComponentProviderFactory.java:98)
>>>>> at
>>>>> com
>>>>> .sun
>>>>> .jersey
>>>>> .spi
>>>>> .guice
>>>>> .container
>>>>> .GuiceComponentProviderFactory
>>>>> .getComponentProvider(GuiceComponentProviderFactory.java:87)
>>>>> at
>>>>> com
>>>>> .sun
>>>>> .jersey
>>>>> .core
>>>>> .spi
>>>>> .component
>>>>> .ioc
>>>>> .IoCProviderFactory._getComponentProvider(IoCProviderFactory.java:
>>>>> 68)
>>>>> at
>>>>> com
>>>>> .sun
>>>>> .jersey
>>>>> .core
>>>>> .spi
>>>>> .component
>>>>> .ProviderFactory.getComponentProvider(ProviderFactory.java:
>>>>> 126)
>>>>> at
>>>>> com
>>>>> .sun
>>>>> .jersey
>>>>> .core
>>>>> .spi
>>>>> .component.ProviderServices.getComponent(ProviderServices.java:
>>>>> 163)
>>>>> at
>>>>> com
>>>>> .sun
>>>>> .jersey
>>>>> .core
>>>>> .spi
>>>>> .component
>>>>> .ProviderServices.getProvidersAndServices(ProviderServices.java:
>>>>> 119)
>>>>> at
>>>>> com
>>>>> .sun
>>>>> .jersey
>>>>> .core
>>>>> .spi
>>>>> .factory
>>>>> .MessageBodyFactory.getProviderMap(MessageBodyFactory.java:
>>>>> 136)
>>>>> at
>>>>> com
>>>>> .sun
>>>>> .jersey
>>>>> .core
>>>>> .spi
>>>>> .factory.MessageBodyFactory.initReaders(MessageBodyFactory.java:
>>>>> 110)
>>>>> at
>>>>> com
>>>>> .sun
>>>>> .jersey
>>>>> .core.spi.factory.MessageBodyFactory.init(MessageBodyFactory.java:
>>>>> 105)
>>>>> at
>>>>> com
>>>>> .sun
>>>>> .jersey
>>>>> .server
>>>>> .impl
>>>>> .application.WebApplicationImpl.initiate(WebApplicationImpl.java:
>>>>> 462)
>>>>> at
>>>>> com
>>>>> .sun
>>>>> .jersey
>>>>> .spi
>>>>> .guice.container.servlet.GuiceServlet.initiate(GuiceServlet.java:
>>>>> 47)
>>>>> at
>>>>> com
>>>>> .sun
>>>>> .jersey
>>>>> .spi
>>>>> .container.servlet.ServletContainer.load(ServletContainer.java:
>>>>> 540)
>>>>> at
>>>>> com
>>>>> .sun
>>>>> .jersey
>>>>> .spi
>>>>> .container.servlet.ServletContainer.init(ServletContainer.java:
>>>>> 207)
>>>>> at
>>>>> com
>>>>> .wideplay
>>>>> .warp.servlet.ServletDefinition.init(ServletDefinition.java:
>>>>> 50)
>>>>> at
>>>>> com
>>>>> .wideplay
>>>>> .warp
>>>>> .servlet.ManagedServletPipeline.init(ManagedServletPipeline.java:
>>>>> 31)
>>>>> at
>>>>> com
>>>>> .wideplay
>>>>> .warp
>>>>> .servlet
>>>>> .ManagedFilterPipeline.initPipeline(ManagedFilterPipeline.java:38)
>>>>> at com.wideplay.warp.servlet.WebFilter.init(WebFilter.java:
>>>>> 70)
>>>>> at
>>>>> org
>>>>> .apache
>>>>> .catalina
>>>>> .core
>>>>> .ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:
>>>>> 275)
>>>>> at
>>>>> org
>>>>> .apache
>>>>> .catalina
>>>>> .core
>>>>> .ApplicationFilterConfig
>>>>> .setFilterDef(ApplicationFilterConfig.java:
>>>>> 397)
>>>>> at
>>>>> org
>>>>> .apache
>>>>> .catalina
>>>>> .core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:
>>>>> 108)
>>>>> at
>>>>> org
>>>>> .apache
>>>>> .catalina.core.StandardContext.filterStart(StandardContext.java:
>>>>> 3709)
>>>>> at
>>>>> org
>>>>> .apache.catalina.core.StandardContext.start(StandardContext.java:
>>>>> 4363)
>>>>> at
>>>>> org
>>>>> .apache
>>>>> .catalina.core.ContainerBase.addChildInternal(ContainerBase.java:
>>>>> 791)
>>>>> at
>>>>> org
>>>>> .apache.catalina.core.ContainerBase.addChild(ContainerBase.java:
>>>>> 771)
>>>>> at
>>>>> org.apache.catalina.core.StandardHost.addChild(StandardHost.java:
>>>>> 525)
>>>>> at
>>>>> org
>>>>> .apache
>>>>> .catalina.startup.HostConfig.deployDescriptor(HostConfig.java:
>>>>> 627)
>>>>> at
>>>>> org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:
>>>>> 511)
>>>>> at
>>>>> org.apache.catalina.startup.HostConfig.check(HostConfig.java:1231)
>>>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native
>>>>> Method)
>>>>> at
>>>>> sun
>>>>> .reflect
>>>>> .NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>>>> at
>>>>> sun
>>>>> .reflect
>>>>> .DelegatingMethodAccessorImpl
>>>>> .invoke(DelegatingMethodAccessorImpl.java:25)
>>>>> at java.lang.reflect.Method.invoke(Method.java:597)
>>>>> at
>>>>> org
>>>>> .apache
>>>>> .tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:
>>>>> 297)
>>>>> at
>>>>> com
>>>>> .sun
>>>>> .jmx
>>>>> .interceptor
>>>>> .DefaultMBeanServerInterceptor
>>>>> .invoke(DefaultMBeanServerInterceptor.java:836)
>>>>> at
>>>>> com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:
>>>>> 761)
>>>>> at
>>>>> org
>>>>> .apache.catalina.manager.ManagerServlet.check(ManagerServlet.java:
>>>>> 1471)
>>>>> at
>>>>> org
>>>>> .apache
>>>>> .catalina.manager.ManagerServlet.deploy(ManagerServlet.java:
>>>>> 824)
>>>>> at
>>>>> org
>>>>> .apache.catalina.manager.ManagerServlet.doGet(ManagerServlet.java:
>>>>> 350)
>>>>> at javax.servlet.http.HttpServlet.service(HttpServlet.java:
>>>>> 617)
>>>>> at javax.servlet.http.HttpServlet.service(HttpServlet.java:
>>>>> 717)
>>>>> at
>>>>> org
>>>>> .apache
>>>>> .catalina
>>>>> .core
>>>>> .ApplicationFilterChain
>>>>> .internalDoFilter(ApplicationFilterChain.java:
>>>>> 290)
>>>>> at
>>>>> org
>>>>> .apache
>>>>> .catalina
>>>>> .core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:
>>>>> 206)
>>>>> at
>>>>> org
>>>>> .apache
>>>>> .catalina
>>>>> .core.StandardWrapperValve.invoke(StandardWrapperValve.java:
>>>>> 233)
>>>>> at
>>>>> org
>>>>> .apache
>>>>> .catalina
>>>>> .core.StandardContextValve.invoke(StandardContextValve.java:
>>>>> 191)
>>>>> at
>>>>> org
>>>>> .apache
>>>>> .catalina
>>>>> .authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:
>>>>> 525)
>>>>> at
>>>>> org
>>>>> .apache
>>>>> .catalina.core.StandardHostValve.invoke(StandardHostValve.java:
>>>>> 128)
>>>>> at
>>>>> org
>>>>> .apache
>>>>> .catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:
>>>>> 102)
>>>>> at
>>>>> org
>>>>> .apache
>>>>> .catalina
>>>>> .core.StandardEngineValve.invoke(StandardEngineValve.java:
>>>>> 109)
>>>>> at
>>>>> org
>>>>> .apache
>>>>> .catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:
>>>>> 286)
>>>>> at
>>>>> org
>>>>> .apache
>>>>> .coyote.http11.Http11Processor.process(Http11Processor.java:
>>>>> 845)
>>>>> at
>>>>> org.apache.coyote.http11.Http11Protocol
>>>>> $Http11ConnectionHandler.process(Http11Protocol.java:583)
>>>>> at
>>>>> org.apache.tomcat.util.net.JIoEndpoint
>>>>> $Worker.run(JIoEndpoint.java:
>>>>> 447)
>>>>> at java.lang.Thread.run(Thread.java:619)
>>>>> Caused by: java.lang.ClassNotFoundException:
>>>>> javax.mail.MessagingException
>>>>> at
>>>>> org
>>>>> .apache
>>>>> .catalina
>>>>> .loader.WebappClassLoader.loadClass(WebappClassLoader.java:
>>>>> 1387)
>>>>> at
>>>>> org
>>>>> .apache
>>>>> .catalina
>>>>> .loader.WebappClassLoader.loadClass(WebappClassLoader.java:
>>>>> 1233)
>>>>> at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:
>>>>> 320)
>>>>> ... 75 more
>>>>>
>>>>> I filed two bug reports:
>>>>> https://jersey.dev.java.net/issues/show_bug.cgi?id=171
>>>>> https://jersey.dev.java.net/issues/show_bug.cgi?id=172
>>>>>
>>>>> Gili
>>>>>
>>>>>
>>>>> Gili wrote:
>>>>>>
>>>>>> It's taking me forever to debug this, but in the process of
>>>>>> troubleshooting I noticed that MultiPartReader isn't annotated
>>>>>> with
>>>>>> @Provider as required according to MessageBodyReader's
>>>>>> specification. The
>>>>>> Javadoc reads "To add a MessageBodyReader implementation,
>>>>>> annotate
>>>>>> the
>>>>>> implementation class with @Provider". Could this be it? It still
>>>>>> doesn't
>>>>>> explain why this works under Glassfish without the annotation.
>>>>>>
>>>>>> Gili
>>>>>>
>>>>>>
>>>>>> Gili wrote:
>>>>>>>
>>>>>>> I took my existing webapp, moved from Glassfish v2 to Tomcat and
>>>>>>> all of a
>>>>>>> sudden I get:
>>>>>>>
>>>>>>> SEVERE: A message body reader for Java type, class
>>>>>>> com.sun.jersey.multipart.MultiPart, and MIME media type,
>>>>>>> multipart/
>>>>>>> mixed,
>>>>>>> was not found
>>>>>>>
>>>>>>> I'm guessing that Jersey provider scanning is failing under
>>>>>>> Tomcat
>>>>>>> for
>>>>>>> some reason...? Paul, Craig can you guys confirm this?
>>>>>>>
>>>>>>> Thanks,
>>>>>>> Gili
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>> --
>>>>> View this message in context:
>>>>> http://n2.nabble.com/Jersey-provider-detection-fails-under-Tomcat--tp1688690p1696750.html
>>>>> Sent from the Jersey mailing list archive at Nabble.com.
>>>>>
>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>>>
>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>>
>>>>
>>>>
>>>
>>> --
>>> View this message in context:
>>> http://n2.nabble.com/Jersey-provider-detection-fails-under-Tomcat--tp1688690p2118383.html
>>> Sent from the Jersey mailing list archive at Nabble.com.
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>>
>>
>
> --
> View this message in context: http://n2.nabble.com/Jersey-provider-detection-fails-under-Tomcat--tp1688690p2118627.html
> Sent from the Jersey mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>