tomee-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "James Meen (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (TOMEE-2352) TomEE does not handle app using its own JAX-RS stack correctly
Date Fri, 22 Feb 2019 01:21:00 GMT

    [ https://issues.apache.org/jira/browse/TOMEE-2352?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16774647#comment-16774647
] 

James Meen commented on TOMEE-2352:
-----------------------------------

Added the missing check for...
openejb.jaxrs.on
to the afterApplicationCreated overload.  It solved the problem and Jersey apps load without
CXF detecting them.

Added to PR 406 which needs to be merged into master to be included in the next release.

> TomEE does not handle app using its own JAX-RS stack correctly
> --------------------------------------------------------------
>
>                 Key: TOMEE-2352
>                 URL: https://issues.apache.org/jira/browse/TOMEE-2352
>             Project: TomEE
>          Issue Type: Bug
>          Components: TomEE Core Server
>    Affects Versions: 7.0.5, 7.1.0, 8.0.0-M1
>            Reporter: Peter Varga
>            Priority: Major
>
> war files that rely on Jersey instead of Apache CXF package their own JAX-RS related
jars in the .war and can declare the following in their web.xml:
> {code:xml}
> <servlet>
>   <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
>   <init-param>
>     <param-name>javax.ws.rs.Application</param-name>
>     <param-value>com.myapp.JaxRSApp</param-value>
>   </init-param>
> </servlet>
> {code}
> TomEE has some logic to deal with apps that deploy their own JAX-RS as shown by the following
code in in the DiscoverAnnotatedBeans class in AnnotationDeployer.java:
> {code:java}
> boolean restHandledByTheWebApp;
> try {
>   restHandledByTheWebApp = webModule.getClassLoader().loadClass(Application.class.getName())
!= Application.class;
> } catch (final Throwable e) { // ClassNotFoundException or NoClassDefFoundError
>   restHandledByTheWebApp = false;
> }
> {code}
> However, to trigger that, one must set the following in system.properties:
> {{openejb.classloader.forced-load = javax.ws.rs}}
> So assume that's been set.
> Deploying such an app then results in the following exception in catalina.log on startup
of the webapp:
> {noformat}
> 09-Dec-2018 10:19:29.372 SEVERE [localhost-startStop-1] org.apache.openejb.observer.ObserverManager$MethodInvocation.invoke
error invoking org.apache.tomee.webservices.TomeeJaxRsService@4f4c4b1a
>  org.apache.openejb.server.rest.OpenEJBRestRuntimeException: can't create class com.myapp.JaxRSApp
> 	at org.apache.openejb.server.rest.RESTService.afterApplicationCreated(RESTService.java:165)
> 	at org.apache.tomee.webservices.TomeeJaxRsService.afterApplicationCreated(TomeeJaxRsService.java:53)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> 	at java.lang.reflect.Method.invoke(Method.java:498)
> 	at org.apache.openejb.observer.ObserverManager$MethodInvocation.invoke(ObserverManager.java:406)
> 	at org.apache.openejb.observer.ObserverManager$InvocationList.invoke(ObserverManager.java:521)
> 	at org.apache.openejb.observer.ObserverManager.doFire(ObserverManager.java:111)
> 	at org.apache.openejb.observer.ObserverManager.fireEvent(ObserverManager.java:100)
> 	at org.apache.openejb.loader.SystemInstance.fireEvent(SystemInstance.java:134)
> 	at org.apache.tomee.catalina.TomcatWebAppBuilder.afterStart(TomcatWebAppBuilder.java:1773)
> 	at org.apache.tomee.catalina.GlobalListenerSupport.lifecycleEvent(GlobalListenerSupport.java:116)
> 	at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:94)
> 	at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:395)
> 	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:160)
> 	at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:754)
> 	at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:730)
> 	at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)
> 	at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:629)
> 	at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1839)
> 	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
> 	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
> 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
> 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
> 	at java.lang.Thread.run(Thread.java:748)
> Caused by: java.lang.ClassCastException: Cannot cast com.myapp.JaxRSApp to javax.ws.rs.core.Application
> 	at java.lang.Class.cast(Class.java:3369)
> 	at org.apache.openejb.server.rest.RESTService.afterApplicationCreated(RESTService.java:156)
> 	... 25 more
> {noformat}
> With some limited debugging, this appears to be because {{ProcessAnnotatedBeans}} class'
{{public WebModule deploy(final WebModule webModule)}} method processes servlets and handles
javax.ws.rs.core.Application declarations - but doesn't do the 'restHandledByTheWebApp' check
as DiscoverAnnotatedBeans does.
> {code:java}
> // if the servlet is a rest init servlet don't deploy rest classes automatically
> for (final ParamValue param : servlet.getInitParam()) {
>   if (param.getParamName().equals(Application.class.getName()) || param.getParamName().equals("javax.ws.rs.Application"))
{
>     webModule.getRestApplications().clear();
>     webModule.getRestApplications().add(param.getParamValue());
>     break;
>   }
> }
> {code}
> Related to this - there is also the following in RESTService.java to let apps opt-out
of container's JAX-RS:
> {code:java}
> final AppInfo appInfo = event.getApp();
> if ("false".equalsIgnoreCase(appInfo.properties.getProperty("openejb.jaxrs.on", "true")))
{
> return;
> }
> {code}
> However, this is only checked in 
> {code:java}
> public void afterApplicationCreated(@Observes final AssemblerAfterApplicationCreated
event)
> {code}
> but the other overload of this method does not check it:
> {code:java}
> public void afterApplicationCreated(final AppInfo appInfo, final WebAppInfo webApp)
> {code}
> If it did, the exception would also be avoided.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Mime
View raw message