Cannot reach EJB exposed as REST service

2.3k views Asked by At

I'm trying to expose some EJBs as REST web service using JAX-RS annotations. When I deploy war file containing EJB Jar in WEB-INF/lib to Wildfly 8, I can see in web admin panel EJB Jar as deployed, But I cannot reach REST endpoints and get 404.

This is content of web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <servlet-mapping>
        <servlet-name>javax.ws.rs.core.Application</servlet-name>
        <url-pattern>/separated/*</url-pattern>
    </servlet-mapping>
</web-app>

This is a sample session bean I'm trying to serve as web service and put in jar file:

@Stateless(name = "TestSessionEJB")
@LocalBean
public class TestSessionBean {

    @PersistenceContext(unitName = "TestPU")
    private EntityManager em;

    public AuthenticationSessionBean() {
    }

    @GET
    @Path("ep")
    public String testEP() {
        return "Hello from testEP()";
    }
}

I cannot reach testEP through /<war_file_name>/separated/ep. Added ejb-jar.xml descriptor to WEB-INF/, still no success. I made another service with classes compiled and deployed directly in war file's WEB-INF/classes:

@ApplicationPath("/integrated")
public class TestRestApp extends Application {
}

@Path("/ep")
public class TestRestEp {

    @GET
    public String doGet() {
        return "success";
    }
}

Here I can reach doGet() through /<war_file_name>/integrated/ep.

Am I missing something? Can I deploy EJBs as separated jar files and expose them as REST web services with no wrapper?

UPDATE: I annotated TestSessionBean with ApplicationPath("separated") and made it extending from javax.ws.rs.Application. Still getting 404 but this time It's different; 404 without "Not Found" body. If I make an endpoint path same as an endpoint in TestRestApp, e.g @Path("ep") It maps to endpoint in TestRestApp and I get "success" instead of "Hello from testEP()" by navigating to /<war_file_name>/separated/ep. If I annotate a method in TestSessionBean with a path not defined in TestRestApp result is 404. I cleared my web.xml out of servlet definitions and still same result.

1

There are 1 answers

6
Paul Samsotha On BEST ANSWER

First

Simply annotating an EJB class's method with JAX-RS annotations will not make the method a JAX-RS resource method. You need to make TestSessionBean a root resource class by annotating it with @Path, like you did with TestRestEp. Or you can make this class a Sub-Resource and have a Root resource pass the request to this class. I'd just stick to the former, if you have no idea what the latter means.

Second

Keeping in mind Wildfly (JBoss) modular architceture

Stated in the Resteasy (Wildfly's JAX-RS implementation) Reference Guide:

Resteasy and JAX-RS are automically loaded into your deployment's classpath, if and only if you are deploying a JAX-RS Application.

That being said, your web.xml doesn't create a JAX-RS application. You are basically depending on the (default JAX-RS specified) javax.ws.rs.Application servlet, which is only loaded if the JAX-RS module is loaded into the Server.

When you have an Application subclass, with the @ApplicationPath annotation, this creates a JAX-RS application and the JAX-RS module is loaded into the Server and the classpath will be scanned for resource classes.

Also stated in the JAX-RS spec:

The resources and providers that make up a JAX-RS application are configured via an application-supplied subclass of Application. An implementation MAY provide alternate mechanisms for locating resource classes and providers (e.g. runtime class scanning) but use of Application is the only portable means of configuration.

So I would stick to the Application subclass. No web.xml needed