Jersey 2 on Jboss 7
Asked Answered
H

5

10

Has anyone had success deploying Jersey 2.x with JBoss 7.x? I've tried deploying Jersey 2.5 with JBoss 7.1.1 but encountered errors like:

"java.lang.NoSuchMethodError: javax.ws.rs.core.Application.getProperties()Ljava/util/Map;"

I believe this issue is because JBoss comes bundled with RestEasy which is a JAX-RS 1.0 implementation while Jersey is a JAX-RS 2.0 implementation. So I took the following steps to disable RestEasy:

1) Added the following to my web.xml:

<context-param>
    <param-name>resteasy.scan</param-name>
    <param-value>false</param-value>
</context-param>
<context-param>
    <param-name>resteasy.scan.providers</param-name>
    <param-value>false</param-value>
</context-param>
<context-param>
    <param-name>resteasy.scan.resources</param-name>
    <param-value>false</param-value>
</context-param>

2) Followed the discussion here, I modified my JBoss' standalone.xml, module.xml, and domain.xml to remove all references to JAXRS1.1 / RestEasy.

3) This led to another error: "java.lang.NoClassDefFoundError: org/objectweb/asm/ClassVisitor" which I resolved by adding the following to my pom.xml:

<dependency>
    <groupId>asm</groupId>
    <artifactId>asm</artifactId>
    <version>3.3.1</version>
</dependency>

So finally my app deploys without errors but now I cannot seem to access any of my Jersey resources. Jetty 8 works fine, however. I also was able to run Jersey 1.x without having to take steps #2 and #3 but I would prefer to use Jersey 2.x if possible.

Additionally I've also tried creating a jboss-deployment-structure.xml file, but then I still encounter the previous errors like "java.lang.NoSuchMethodError: javax.ws.rs.core.Application.getProperties()Ljava/util/Map;"

<?xml version="1.0" encoding="UTF-8"?>  
<jboss-deployment-structure>
  <deployment>
    <exclusions>
            <module name="org.jboss.resteasy.resteasy-atom-provider"/>  
            <module name="org.jboss.resteasy.resteasy-cdi"/>  
            <module name="org.jboss.resteasy.resteasy-jackson-provider"/>  
            <module name="org.jboss.resteasy.resteasy-jaxb-provider"/>  
            <module name="org.jboss.resteasy.resteasy-jaxrs"/>  
            <module name="org.jboss.resteasy.resteasy-jettison-provider"/>  
            <module name="org.jboss.resteasy.resteasy-jsapi"/>  
            <module name="org.jboss.resteasy.resteasy-multipart-provider"/>  
            <module name="org.jboss.resteasy.resteasy-yaml-provider"/>  
            <module name="org.apache.log4j"/>  
            <module name="org.apache.commons.pool"/>  
            <module name="javax.ws.rs.api"/>
    </exclusions>
  </deployment>
</jboss-deployment-structure>

Has anyone had any luck with Jboss and Jersey 2.x? Any help would be appreciated.

Hurtle answered 16/1, 2014 at 21:36 Comment(5)
This should be related with J2EE libraries that are conflicting. be sure on that which version of java is using by jersey 2, and which version of j2ee libraries provided by your Jboss version. check themBramwell
Since javax.ws.rs.core.Application is in module javax.ws.rs.api, excluding this in jboss-deployment-structure.xml should remove the class. Do you use EAR or WAR, where did you put the jboss-deployment-structure.xml? You can turn on Logging with category "jboss.modules" on TRACE or look at the MBean jboss.modules:type=ModuleLoader to get more informationArvillaarvin
@Erhard: I'm using a WAR and tried adding jboss-deployment-structure.xml to WEB-INF and META-INF and get the same results. Setting the logging level to trace reveals that the jboss-deployment-structure.xml is indeed not excluding the JAXRS 1.x javax.ws.rs.core.application, so I'm looking into why. Erhan, I also tried to compile my WAR through Maven using the Java7 compiler (JBoss uses Java7 but I compile the WAR with Java6) but nothing changed.Hurtle
I'm afraid, I don't really know why it doesn't work in your case. Exchanging hibernate 4 with 3 or JSF 2 with 1.2 worked for me quite well. But then I always exchanged one module with another (other slot) Maybe javaee.api pulls in the javax.ws.rs.api event if its excluded. I would try to temporarily remove the dependency on javax.ws.rs.api in module javaee.api and/or create a module javax.ws.rs.api with another slot and your Jersey implementation and include it in WEB-INF/jboss-deployment-structure.xml. But then I can't guarantee that ist helps.Arvillaarvin
Seems that javaee.api pulls javax.ws.rs.api module transitively. See here : community.jboss.org/thread/231153Rubberneck
G
14

You can use Jersey 2 on JBoss 7 if you configure your jboss-deployment-structure.xml similar to this:

<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
<deployment>

<exclude-subsystems>
  <subsystem name="resteasy" />
</exclude-subsystems>

<exclusions>
  <module name="javaee.api" />
  <module name="javax.ws.rs.api"/>
  <module name="org.jboss.resteasy.resteasy-jaxrs" />
</exclusions>

<local-last value="true" />

</deployment>
</jboss-deployment-structure>

Because JBoss 7 includes dependencies of modules, it is not sufficient to exclude the resteasy module itself but you need to exclude the whole javaee.api module. Also make sure to not exclude too many modules. This may also break your application - the example above is sufficient to disable resteasy.

As you already discovered, you still need to include the following lines in your web.xml

  <context-param>
   <param-name>resteasy.scan</param-name>
   <param-value>false</param-value>
  </context-param>
  <context-param> 
   <param-name>resteasy.scan.providers</param-name>
   <param-value>false</param-value>
  </context-param>
  <context-param>
   <param-name>resteasy.scan.resources</param-name>
   <param-value>false</param-value>
  </context-param>
Gressorial answered 22/4, 2014 at 14:4 Comment(4)
Thanks! This works better than modifying the JBoss configuration files. However, are you able to access any of your Jersey REST resources? I'm getting 404s on all of them. I actually tried switching out Jersey 2 with Resteasy 3 (both are JAX 2.0 so minimal code changes) and can access my resources. I also had to do something similar to the jboss-deployment-structure mentioned above in order for my Resteasy 3.0 to not conflict with the JBoss' Resteasy 2Hurtle
Also, all of my Jersey resources work fine in Jetty, so I think it possibly has something to do with the JBoss exclusions?Hurtle
Actually, I was able to get Jersey to read my resources and work around the 404 issue. For some reason, package scanning wasn't working in JBoss but I was able to just use individual class resource registration. Thanks again for your helpHurtle
this answer was very helpful!Baynebridge
W
3

This is similar to this question

So bit of copy/paste with just different subsystem at play.

You should exclude jaxrs subsystem from being activated for your deployment add this into META-INF/jboss-deployment-structure.xml

    <jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
      <deployment>
         <!-- exclude-subsystem prevents a subsystems deployment unit processors running on a deployment -->
         <!-- which gives basically the same effect as removing the subsystem, but it only affects single deployment -->
         <exclude-subsystems>
            <subsystem name="jaxrs" />
        </exclude-subsystems>

         <!-- This is needed in any case even if you don't use exclude-subsystem above-->        
         <exclusions>  
          <module name="javax.ws.rs.api" />  
        </exclusions>  
      <deployment>
     </jboss-deployment-structure>

or you can go to standalone.xml and remove subsystem there. To do so, you need to remove

<subsystem xmlns="urn:jboss:domain:jaxrs:1.x">
...
...
<subsystem>

part of configuration, extension part of on top can stay it wont hurt either way. or you can connect to server with CLI and run

/subsystem=jaxrs:remove()

In any case I would recommend to read bit about class loading in AS7 https://docs.jboss.org/author/display/AS72/Class+Loading+in+AS7

Just a note, exclude-subsystems functionality and deployment-strucure:1.2 was added in 7.1.2 and as such will not work on on 7.1.1.

You can still remove jaxrs subsystem but that affects whole server.

Wrier answered 10/4, 2014 at 22:38 Comment(1)
Thanks for your help and resources! Unfortunately I have to support JBoss 7.1.1, so I wasn't able to test your solution (also apologies for my slow reply, I was off this problem for a while). However, I wonder if the other answer might work better since it can be used across multiple JBoss versions?Hurtle
S
2

I had almost the very same issue (https://mcmap.net/q/1162489/-jersey-2-1-jboss-7-1-nosuchmethoderror-getproperties):

"Need to run Jersey 2.23.1 web app, already running on Tomcat7 in JBoss 7.1.1."

Unfortunately, nothing here worked for me, but some pieces were handy taking me towards a final solution:

  1. Turn off Resteasy package scanning in your web.xml:

    <context-param>
      <param-name>resteasy.scan</param-name>
      <param-value>false</param-value>
    </context-param>
    <context-param> 
      <param-name>resteasy.scan.providers</param-name>
      <param-value>false</param-value>
    </context-param>
    <context-param>
      <param-name>resteasy.scan.resources</param-name>
      <param-value>false</param-value>
    </context-param>
    
  2. Remove all tags with "jaxrs" from standalone.xml. Otherwise you will still face LinkageError because JBoss keeps 1.1 spec "on".

  3. Create yourApp.war!WEB-INF\jboss-deployment-structure.xml just like is pointed out here: https://docs.jboss.org/author/display/AS7/Class+Loading+in+AS7#ClassLoadinginAS7-JBossDeploymentStructureFile

This way, not only:

java.lang.NoSuchMethodError: javax.ws.rs.core.Application.getProperties()Ljava/util/Map;

Disapears, but also, JAXB works fine (No ClassNotFoundException for javax.xml.bind.JAXBException once module javax.xml.bind.api is also activated).

Obs1: The original question is mixing jersey 1.x with jersey 2.x. There is no PojoMappingFeature in jersey 2.x and base package is org.glassfish.jersey. Take a look at https://jersey.java.net/documentation/latest/migration.html#mig-1-x-json

Obs2: I have also tried other approaches like extending ResourceConfig and scanning packages from there or registering classes directly. Nothing worked like the proper documentation in item 3. So kept my servlet untouched:

    <servlet>
      <servlet-name>WebNize REST Service</servlet-name>
      <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
      <init-param>
        <param-name>jersey.config.server.provider.packages</param-name>
        <param-value>br.com.webnize.rest.service</param-value>
      </init-param>
      <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
      <servlet-name>WebNize REST Service</servlet-name>
      <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>

I hope it helps!

Shears answered 8/7, 2016 at 19:14 Comment(1)
Why this was voted down? (it is currently the working solution in my app)Shears
S
0

Here's the combination that worked for me (much of it came from the other answers in this post - thanks everyone!).

  1. Jersey 2.22.1 + JBoss EAP 6.4 (based on JBoss AS 7.5)
  2. Exclude the jaxrs and resteasy subsystems via jboss-deployment-structure.xml
  3. Did not make changes in any JBoss modules as doing so caused other things not to work in my environment
  4. Disabled the resteasy scans via the context params in web.xml as others have pointed out
  5. Took out the Jersey init-param for the provider classes and instead implemented a javax.ws.rs.core.Application to self-register my Jersey resource classes

At this point the web app deployed successfully without error, but I was getting 404 trying to access my REST service.

  1. Last thing I did was in web.xml where I changed Jersey from a servlet to a filter and it started working
Shadchan answered 17/2, 2016 at 21:43 Comment(0)
S
0

Following on from Clemens82's answer, After excluding the javaee.api module, I encountered this problem:

java.lang.NoClassDefFoundError: javax/xml/ws/Endpoint
    at java.lang.Class.getDeclaredMethods0(Native Method) [rt.jar:1.7.0_72]
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2615) [rt.jar:1.7.0_72]
    at java.lang.Class.getDeclaredMethods(Class.java:1860) [rt.jar:1.7.0_72]
    at org.springframework.core.type.StandardAnnotationMetadata.getAnnotatedMethods(StandardAnnotationMetadata.java:152) [spring-core-4.2.5.RELEASE.jar:4.2.5.RELEASE]

To fix it, I had to add the javax.xml.ws.api dependency into jboss-deployment-structure.xml. Additionally, I added the javax.servlet.api as this should be provided by container if using servlets.

<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
    <deployment>
        <dependencies>
            <module name="javax.xml.ws.api" /> <!-- Required due to exclusion of javaee.api below -->
            <module name="javax.servlet.api" /> <!-- Required due to exclusion of javaee.api below -->
        </dependencies>
        <exclude-subsystems>
            <subsystem name="resteasy" />
        </exclude-subsystems>
        <exclusions>
            <module name="javaee.api" />
            <module name="javax.ws.rs.api"/>
            <module name="org.jboss.resteasy.resteasy-jaxrs" />
        </exclusions>
        <local-last value="true" />
    </deployment>
</jboss-deployment-structure>
Site answered 31/3, 2016 at 9:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.