Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jersey returning 404, after invoking the correct @Path

This thing is puzzling me already for quite some time.. I am trying to embed a Jersey container within Jetty. Following the examples I am able to embed Jersey, and I see my exposed REST method is being exposed. however, for some weird reason my Jersey does return a 404. It looks like Jersey is not capable to resolve the correct endpoint. Unfortunately it doesn't tell me why, but just throws a NotFoundException :-(.

I am 100% certain my method is invoked. The System.out.println within that method is shown in the console, and my Eclipse debugger clearly passes the set breakpoint. It doesn't matter whether I use Jersey 2.0, 2.3, 2.4,1, 2.4. All have the same result.. Here the code snippets of my configuration:

StartJetty.java :

        final int mainport = 9123;

        Server jettyServer = new Server(mainport);
        HandlerCollection handlerCollection = new ContextHandlerCollection();
        jettyServer.setHandler(handlerCollection);

        ServletHolder jerseyServlet = context.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, "/");
        jerseyServlet.setInitOrder(1);
        jerseyServlet.setInitParameter("jersey.config.server.provider.packages", "com.test.rest");

        handlerCollection.addHandler(context);
    jettyServer.start();
        jettyServer.join();

Snippet from the REST resource: com.test.rest.PersonsRSImpl.class:

@Path("/persons")
@Produces( MediaType.APPLICATION_JSON)
public class PersonsRSImpl {

    private PersonManager personMgr = PersonManager.getInstance();


    @Path("/list")
    public Collection<Person> list() {
        System.out.println("In Person::list" );
        return personMgr.getPersons();
    }


}

My Person object is a simple POJO, with some JAXB annotations. Adding/removing them makes no difference at all.

Last but not least: pom.xml http://maven.apache.org/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.test</groupId>
    <artifactId>integrationexample</artifactId>
    <packaging>jar</packaging>
    <version>1.0.0-SNAPSHOT</version>
    <name>Test project</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.build.outputEncoding>UTF-8</project.build.outputEncoding>
        <jetty.version>7.5.4.v20111024</jetty.version>
        <jersey.version>2.4.1</jersey.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-server</artifactId>
            <version>${jetty.version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-servlet</artifactId>
            <version>${jetty.version}</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-http-spi</artifactId>
            <version>${jetty.version}</version>
        </dependency>

        <!-- Jersey JAX-RS -->
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet</artifactId>
            <version>${jersey.version}</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-simple-http</artifactId>
            <version>${jersey.version}</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-moxy</artifactId>
            <version>${jersey.version}</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
    </dependencies>


    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>com.test.StartJetty</mainClass>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

I enabled a trace of Jersey (thank you Michal). The result trace is:

Jersey trace

HTTP/1.1 404 Not Found
X-Jersey-Tracing-000: START       [ ---- /  ---- ms |  ---- %] baseUri=[http://localhost:9123/rest/] requestUri=[http://localhost:9123/rest/persons/list] method=[GET] authScheme=[n/a] accept=[text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8] accept-encoding=[gzip, deflate] accept-charset=n/a accept-language=[en-US,en;q=0.5] content-type=n/a content-length=n/a
X-Jersey-Tracing-001: PRE-MATCH   [ 0,01 /  1,03 ms |  0,10 %] PreMatchRequest summary: 0 filters
X-Jersey-Tracing-002: MATCH       [ ---- /  1,21 ms |  ---- %] Matching path [/persons/list]
X-Jersey-Tracing-003: MATCH       [ ---- /  1,27 ms |  ---- %] Pattern [/persons(/.*)?] IS selected
X-Jersey-Tracing-004: MATCH       [ ---- /  1,41 ms |  ---- %] Matched resource: template=[/persons] regexp=[/persons(/.*)?] matches=[/persons] from=[/persons/list]
X-Jersey-Tracing-005: MATCH       [ ---- /  1,54 ms |  ---- %] Matching path [/list]
X-Jersey-Tracing-006: MATCH       [ ---- /  1,58 ms |  ---- %] Pattern [/list(/.*)?] IS selected
X-Jersey-Tracing-007: MATCH       [ ---- /  1,76 ms |  ---- %] Matched resource: template=[/list] regexp=[/list(/.*)?] matches=[/list] from=[/list]
X-Jersey-Tracing-008: MATCH       [ ---- /  1,90 ms |  ---- %] Matched locator : public java.util.Collection com.test.rest.PersonsRSImpl.list()
X-Jersey-Tracing-009: MATCH       [ ---- /  2,08 ms |  ---- %] Resource instance: [com.test.rest.PersonsRSImpl @3cceafcb]
X-Jersey-Tracing-010: MATCH       [ ---- /  2,21 ms |  ---- %] Resource instance: [java.util.HashMap$Values @25591d82]
X-Jersey-Tracing-011: MATCH       [ 4,23 /  5,30 ms | 75,92 %] RequestMatching summary
X-Jersey-Tracing-012: RESP-FILTER [ 0,00 /  5,52 ms |  0,05 %] Response summary: 0 filters
X-Jersey-Tracing-013: FINISHED    [ ---- /  5,58 ms |  ---- %] Response status: 404/CLIENT_ERROR|Not Found
Cache-Control: must-revalidate,no-cache,no-store
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 1284
Server: Jetty(7.5.4.v20111024)

Hope some of you have a clue on what's going on!

like image 751
user2978801 Avatar asked Nov 11 '13 10:11

user2978801


1 Answers

You need to annotate your resource method list() with an annotation that would indicate to which HTTP method should the resource method respond to (in this case it would be @GET):

@GET
@Path("/list")
public Collection<Person> list() {
    System.out.println("In Person::list" );
    return personMgr.getPersons();
}

Otherwise the resource method would be invoked but it will be treated as sub-resource locator. For more information about sub-resources and sub-resource locators refer to the JAX-RS 2.0 spec or Jersey User Guide dedicated to Sub-resources.

like image 76
Michal Gajdos Avatar answered Oct 26 '22 20:10

Michal Gajdos