You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by "James Meen (JIRA)" <ji...@apache.org> on 2019/02/22 01:21:00 UTC

[jira] [Commented] (TOMEE-2352) TomEE does not handle app using its own JAX-RS stack correctly

    [ 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)