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

Reply via email to