JAX-RS with Jersey not working in JBoss AS

2020-08-02 19:41发布

问题:

I'm trying to upload simple REST service onto JBoss AS 7.1 (or TomEE JAX-RS).

My web.xml:

<servlet>
    <servlet-name>jersey-serlvet</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>com.sun.jersey.config.property.packages</param-name>
        <param-value>com.javacodegeeks.jersey.main</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>jersey-serlvet</servlet-name>
    <url-pattern>/rs/*</url-pattern>
</servlet-mapping>

Dependencies on pom.xml:

<dependency>
    <groupId>javax.ws.rs</groupId>
    <artifactId>javax.ws.rs-api</artifactId>
    <version>2.0.1</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-server</artifactId>
    <version>1.9</version>
</dependency>

Server endpoint:

@Path("account")
public class AccountDetailsService {

    @GET
    @Path("/details/{param}")
    @Produces(MediaType.TEXT_PLAIN)
    public Response getAccountDetails(@PathParam("param") String accountName) {
        String output = "Account Name : " + accountName;
        return Response.status(200).entity(output).build();
    }
}

But I get this error:

17:37:00,450 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-2) MSC00001: Fai led to start service
jboss.deployment.unit."jersey-example.war".POST_MODULE: org.jboss.msc.service.StartException in service
jboss.deployment.unit."jersey-example.war".POST_MODULE: Failed to process phase POST_MODULE of deployment "jersey-example.war"
        at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:119) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final]
        at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
        at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_80-ea]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_80-ea]
        at java.lang.Thread.run(Thread.java:745) [rt.jar:1.7.0_80-ea] Caused by:org.jboss.as.server.deployment.DeploymentUnitProcessingException:
JBAS01123 2: Only one JAX-RS Application Class allowed. 
com.sun.jersey.api.core.ClasspathResour ceConfig
com.sun.jersey.api.core.ResourceConfig
com.sun.jersey.api.core.PackagesResour ceConfig
com.sun.jersey.api.core.DefaultResourceConfig
com.sun.jersey.api.core.WebAppR esourceConfig
com.sun.jersey.server.impl.application.DeferredResourceConfig
com.sun.je rsey.api.core.ClassNamesResourceConfig
com.sun.jersey.api.core.ScanningResourceConfig
com.sun.jersey.api.core.ApplicationAdapter
        at org.jboss.as.jaxrs.deployment.JaxrsScanningProcessor.scan(JaxrsScanningProcessor.java:209)
        at org.jboss.as.jaxrs.deployment.JaxrsScanningProcessor.deploy(JaxrsScanningProcessor.java:105)
        at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:113)[jboss-as-server-7.1.1.Final.jar:7.1.1.Final]
        ... 5 more

Why does it happen if the same works fine on Tomcat 7 container?


update:

20:15:03,078 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-3) MSC00001: Failed to start service jboss.web.dep
loyment.default-host./ROOT: org.jboss.msc.service.StartException in service jboss.web.deployment.default-host./ROOT: Fai
led to start service
        at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1767) [jboss-msc-1.0.2.G
A.jar:1.0.2.GA]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_51]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_51]
        at java.lang.Thread.run(Thread.java:744) [rt.jar:1.7.0_51]
Caused by: java.lang.IllegalStateException: JBAS018038: Root contexts can not be deployed when the virtual host configur
ation has the welcome root enabled, disable it and redeploy
        at org.jboss.as.web.deployment.WebContextInjector.inject(WebContextInjector.java:57)
        at org.jboss.as.web.deployment.WebContextInjector.inject(WebContextInjector.java:38)
        at org.jboss.msc.inject.CastingInjector.inject(CastingInjector.java:55) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
        at org.jboss.msc.service.ServiceControllerImpl.doInject(ServiceControllerImpl.java:1549) [jboss-msc-1.0.2.GA.jar
:1.0.2.GA]
        at org.jboss.msc.service.ServiceControllerImpl.access$1900(ServiceControllerImpl.java:49) [jboss-msc-1.0.2.GA.ja
r:1.0.2.GA]
        at org.jboss.msc.service.ServiceControllerImpl$StartTask.performInjections(ServiceControllerImpl.java:1780) [jbo
ss-msc-1.0.2.GA.jar:1.0.2.GA]
        at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1741) [jboss-msc-1.0.2.G
A.jar:1.0.2.GA]
        ... 3 more

回答1:

The error

JBAS011232: Only one JAX-RS Application Class allowed

gives you a hint about the problem. JBoss 7 uses RESTEasy as JAX-RS implementation. Your application is using Jersey. And it looks like Jersey and RESTEasy are not getting on very well in JBoss 7.

To use Jersey as JAX-RS implementation in JBoss 7, you need to disable RESTEasy, which is bundled by default in JBoss 7.

Try adding the following lines to 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>

If it doesn't work, create a file called jboss-deployment-structure.xml under your WEB-INF folder with the following content to exclude RESTEasy modules:

<?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-jaxrs" />
            <module name="org.jboss.resteasy.resteasy-jaxb-provider" />
            <module name="org.jboss.resteasy.resteasy-jackson-provider" />
            <module name="org.jboss.resteasy.resteasy-jsapi" />
            <module name="org.jboss.resteasy.resteasy-multipart-provider" />
            <module name="org.jboss.resteasy.async-http-servlet-30" />
        </exclusions>
    </deployment>
</jboss-deployment-structure>

The error

JBAS018038: Root contexts can not be deployed when the virtual host configuration has the welcome root enabled, disable it and redeploy

happens when you're trying to deploy an app to root context (either using the name ROOT.war or / context in jboss-web.xml) but the AS welcome page is already occupying that.

To solve it, shut down the server and edit the standalone.xml:

<subsystem xmlns="urn:jboss:domain:web:1.2" default-virtual-server="default-host" 
    native="false">  
    <virtual-server name="default-host" enable-welcome-root="false">  
    ...  
</subsystem>

For more details, have a look here.



回答2:

The solution was quite non-obvious...

1) The following lines was added to 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) Next lines from web-xml was commented out:

<!--<init-param>
    <param-name>com.sun.jersey.config.property.packages</param-name>
    <param-value>com.javacodegeeks.jersey.main</param-value>
</init-param>-->

3) No need to create a jboss-deployment-structure.xml or edit standalone.xml.