users@jersey.java.net

[Jersey] separation of interfaces and implementation class: works in Jersey, not in GlassFish

From: Koper, Dies <diesk_at_fast.au.fujitsu.com>
Date: Fri, 13 Sep 2013 16:42:45 +1000

I'm developing a REST API using JAX-RS 1.1 (it has to run on GF
3.1.2.2).

I want to separate the interfaces and implementation because there are
different teams doing the real implementation and (for testing) a dummy
implementation:

I don't want the implementers to have any control over the interfaces.

 

Currently I have the following, which runs fine in Jersey 2.1, but gives
a "Conflicting URI templates." error on GF:

 

[#|2013-09-13T15:02:46.353+0900|SEVERE|glassfish3.1.2|com.sun.jersey.spi
.inject.Errors|_ThreadID=95;_ThreadName=Thread-2;|The following errors
and warnings have been detected with resource and/or provider classes:

  SEVERE: Conflicting URI templates. The URI template / for root
resource class my.api.impl.AccountService and the URI template /
transform to the same regular expression (/.*)?

 

Source code:

 

package my.api;

 

public interface AccountResource {

 

    @GET

    @Path("/account")

    @Produces(MediaType.APPLICATION_JSON)

    Account getAccount();

}

 

and

 

package my.api.impl;

 

@Path("")

public class AccountService implements AccountResource {

 

    @Override

    public Account getAccount() {

        return foo;

    }

}

 

The suggestion of @Path("") on the concrete class came from on old post
on this list.

(maybe relevant, but I have multiple interfaces and implementations like
this, e.g. RoleResource under "/roles" with a RoleService with @Path("")
as above.)

 

The deployment methods to Jersey and GF are different, I don't know if
that's relevant too.

For Jersey, I host the endpoint using Jersey specific classes:

 

        final ResourceConfig rc = new ResourceConfig()

                .packages("my.api");

        return
GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI),

                rc);

 

With GlassFish, I added a web.xml and application implementation class:

 

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

          http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"

       version="3.0">

       <servlet>

             <servlet-name>my.api.RestApplication</servlet-name>

       </servlet>

 

       <servlet-mapping>

             <servlet-name>my.api.RestApplication</servlet-name>

             <url-pattern>/api/*</url-pattern>

       </servlet-mapping>

</web-app>

 

With:

 

@ApplicationPath("api/*")

public class RestApplication extends Application {

 

    @Override

    public Set<Class<?>> getClasses() {

        Set<Class<?>> set = new HashSet<Class<?>>(1);

        set.add(AccountResource.class);

        set.add(RoleResource.class);

        set.add(AccountService.class);

        set.add(RoleService.class);

        return set;

    }

}

 

What am I doing wrong?

 

Cheers,

Dies Koper