Jersey 2 on Jboss 7

11,827

Solution 1

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>

Solution 2

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.

Solution 3

I had almost the very same issue (https://stackoverflow.com/a/38273524/4534078):

"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!

Share:
11,827
Minh Nguyen
Author by

Minh Nguyen

Hey there, I'm a Java, JavaScript, and mobile developer with 8+ years experience. Feel free to contact me, I'm on the web at www.minh.io

Updated on July 18, 2022

Comments

  • Minh Nguyen
    Minh Nguyen almost 2 years

    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.

  • Minh Nguyen
    Minh Nguyen over 9 years
    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 2
  • Minh Nguyen
    Minh Nguyen over 9 years
    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?
  • Minh Nguyen
    Minh Nguyen over 9 years
    Also, all of my Jersey resources work fine in Jetty, so I think it possibly has something to do with the JBoss exclusions?
  • Minh Nguyen
    Minh Nguyen over 9 years
    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 help
  • Rohit
    Rohit over 8 years
    this answer was very helpful!
  • Reginaldo Santos
    Reginaldo Santos over 7 years
    Why this was voted down? (it is currently the working solution in my app)