Question

I am porting a REST layer to Wildfly/RESTEasy from Tomcat/Jersey. I have only begun to stub out the REST layer but it works. The only problem I am having so far is when I call an unhanded resource path that starts the root api path.

For example:

http://localhost:8080/tmoi-0.0.1/api2/account

matches my only resource and returns a valid json object.

http://localhost:8080/tmoi-0.0.1/notanapi

also behaves as expected since it does not match the path set out in the @ApplicationPath("/api2") and so returns a 404 with a body that says "Not Found" and nothing is logged on the server. But:

http://localhost:8080/tmoi-0.0.1/api2/account2

matches the ApplicationPath but no specific resource and ends up throwing this exception on the server:

[0m[33m16:27:19,852 WARN  [org.jboss.resteasy.core.ExceptionHandler] (default task-9) failed to execute: javax.ws.rs.NotFoundException: Could not find resource for full path: http://localhost:8080/tmoi-0.0.1/api2/account2
    at org.jboss.resteasy.core.registry.ClassNode.match(ClassNode.java:73) [resteasy-jaxrs-3.0.6.Final.jar:]
    at org.jboss.resteasy.core.registry.RootClassNode.match(RootClassNode.java:48) [resteasy-jaxrs-3.0.6.Final.jar:]
    at org.jboss.resteasy.core.ResourceMethodRegistry.getResourceInvoker(ResourceMethodRegistry.java:444) [resteasy-jaxrs-3.0.6.Final.jar:]
    at org.jboss.resteasy.core.SynchronousDispatcher.getInvoker(SynchronousDispatcher.java:234) [resteasy-jaxrs-3.0.6.Final.jar:]
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:171) [resteasy-jaxrs-3.0.6.Final.jar:]
    at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:220) [resteasy-jaxrs-3.0.6.Final.jar:]
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56) [resteasy-jaxrs-3.0.6.Final.jar:]

There is no web.xml configuration. My Application class looks like this.

@ApplicationPath("/api2")
public class TMOIApplication extends Application {
}

My one resource is this:

@Path("account")
@Produces(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class AccountService {
    @GET
    public NewAccount getAccount() {
        return new NewAccount("test");
    }

}

So why do I get the exception when I call the /api2/account2 instead of just returning a normal 404?

Update

I tested this on the Quickstart example Helloword-RS and it shows the same behavior. I ran across this post RESTEasy - @Path requiring a full path? that documents similar behavior. I guess my question now is:

Is there a NO-XML way to solve this or am I going to have to use the web.xml to pass parameters to RESTEasy?

This is a the more recent link to the docs referenced in the answer.

Update 2

Even though this has been answered, I would like to not that the web.xml answer makes no difference in resources that it can't locate under the root resource. Apparently, throwing an exception rather than just returning a 404 is the normal behavior as pointed out in the accepted answer.

Was it helpful?

Solution

The default behaviour for handling exceptions is to log the stack trace and respond with a HTML page containing status code and message. The user does get the right HTTP status code but in many cases the error page is unnecessary when creating an API.

If you want to provide your own behaviour for handling any exceptions, you can need to use an ExceptionMapper.

From the Resteasy Documentation:

You may override Resteasy built-in exceptions by writing an ExceptionMapper for the exception. For that matter, you can write an ExceptionMapper for any thrown exception including WebApplicationException

OTHER TIPS

Your AccountService class should be annotated with javax.enterprise.context.RequestScoped (or an EJB annotation such as javax.ejb.Stateless if you want to access an underlying JPA Entity Manager for example).

HTH.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top