14

I want make RESTful services using embedded jetty with JAX-RS (either resteasy or jersey). I am trying to create with maven/eclipse setup. if I try to follow http://wikis.sun.com/pages/viewpage.action?pageId=21725365 link I am not able to resolve error from ServletHolder sh = new ServletHolder(ServletContainer.class);

public class Main {

    @Path("/")
    public static class TestResource {

        @GET
        public String get() {
            return "GET";
        }
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws Exception {
        ServletHolder sh = new ServletHolder(ServletContainer.class);

        /*
         * For 0.8 and later the "com.sun.ws.rest" namespace has been renamed to
         * "com.sun.jersey". For 0.7 or early use the commented out code instead
         */
        // sh.setInitParameter("com.sun.ws.rest.config.property.resourceConfigClass",
        // "com.sun.ws.rest.api.core.PackagesResourceConfig");
        // sh.setInitParameter("com.sun.ws.rest.config.property.packages",
        // "jetty");
        sh.setInitParameter("com.sun.jersey.config.property.resourceConfigClass",
            "com.sun.jersey.api.core.PackagesResourceConfig");
        sh.setInitParameter("com.sun.jersey.config.property.packages",
            "edu.mit.senseable.livesingapore.platform.restws");
        // sh.setInitParameter("com.sun.jersey.config.property.packages",
        // "jetty");
        Server server = new Server(9999);

        ServletContextHandler context = new ServletContextHandler(server, "/",
            ServletContextHandler.SESSIONS);
        context.addServlet(sh, "/*");
        server.start();
        server.join();
        // Client c = Client.create();
        // WebResource r = c.resource("http://localhost:9999/");
        // System.out.println(r.get(String.class));
        //
        // server.stop();
    }
}

even this is not working. can anyone suggest me something/tutorial/example ?

Shaggy Frog
  • 27,575
  • 16
  • 91
  • 128
rinku
  • 415
  • 2
  • 19
  • 29

4 Answers4

19

huh, linked page is ancient - last update 3 years ago.

Do you really need jetty? Jersey has excellent thoroughly tested integration with Grizzly (see http://grizzly.java.net) which is also acting as Glassfish transport layer and it is possible to use it as in your example.

See helloworld sample from Jersey workspace, com.sun.jersey.samples.helloworld.Main class starts Grizzly and "deploys" helloworld app: http://repo1.maven.org/maven2/com/sun/jersey/samples/helloworld/1.9.1/helloworld-1.9.1-project.zip .

If you really need jetty based sample, I guess I should be able to provide it (feel free to contact me).

EDIT:

ok, if you really want jetty, you can have it :) and looks like its fairly simple. I followed instructions from http://docs.codehaus.org/display/JETTY/Embedding+Jetty and was able to start helloworld sample:

public static void main(String[] args) throws Exception {
    Server server = new Server(8080);
    Context root = new Context(server,"/",Context.SESSIONS);
    root.addServlet(new ServletHolder(new ServletContainer(new PackagesResourceConfig("com.sun.jersey.samples.helloworld"))), "/");
    server.start();
}

http://localhost:8080/helloworld is accessible. I used Jetty 6.1.16. Hope it helps!

You can find more information about configuring Jersey in servlet environment in user guide, see http://jersey.java.net/nonav/documentation/latest/

EDIT:

dependencies.. but this is kind of hard to specify, it changed recently in jersey.. so..

pre 1.10:

<dependency>
    <groupId>org.mortbay.jetty</groupId>
    <artifactId>jetty</artifactId>
    <version>6.1.16</version>
</dependency>
<dependency>
     <groupId>com.sun.jersey</groupId>
     <artifactId>jersey-server</artifactId>
     <version>${jersey.version}</version>
</dependency>

post 1.10:

<dependency>
    <groupId>org.mortbay.jetty</groupId>
    <artifactId>jetty</artifactId>
    <version>6.1.16</version>
</dependency>
<dependency>
     <groupId>com.sun.jersey</groupId>
     <artifactId>jersey-servlet</artifactId>
     <version>${jersey.version}</version>
</dependency>

and you need this maven repo for jetty:

<repositories>
    <repository>
        <id>codehaus-release-repo</id>
        <name>Codehaus Release Repo</name>
        <url>http://repository.codehaus.org</url>
    </repository>
</repositories>
Pavel Bucek
  • 5,304
  • 27
  • 44
  • yes actually I was looking for embedded jetty based example can you guide me about that? – rinku Sep 15 '11 at 08:02
  • ok, answer updated, I can provide complete (maven project) sample if required. – Pavel Bucek Sep 15 '11 at 14:22
  • Hi, this is awesome this is what exactly I wanted :) but I am not able to resolve all maven dependencies .. can you post the all required dependencies ? Thanks for the help :) – rinku Sep 17 '11 at 07:53
  • done. You'll need additional dependencies for jersey-client etc, but you should be able to easily figure it out. – Pavel Bucek Sep 17 '11 at 09:23
  • Hi I am getting the following error: `HTTP ERROR 503 Problem accessing /helloworld/. Reason: com.sun.jersey.api.container.ContainerException: The ResourceConfig instance does not contain any root resource classes. Caused by: javax.servlet.UnavailableException: com.sun.jersey.api.container.ContainerException: The ResourceConfig instance does not contain any root resource classes.` – rinku Sep 17 '11 at 09:54
  • I tried the following code: ` import org.mortbay.jetty.Server; import org.mortbay.jetty.servlet.Context; import org.mortbay.jetty.servlet.ServletHolder; import com.sun.jersey.api.core.PackagesResourceConfig; import com.sun.jersey.spi.container.servlet.ServletContainer; public class OneServletContext { public static void main(String[] args) throws Exception { Server server = new Server(8080); Context root = new Context(server, "/", Context.SESSIONS); root.addServlet(new ServletHolder(new ServletContainer( -- server.start(); } }` – rinku Sep 17 '11 at 09:57
  • Hi I tried the same thing but getting HTTP 503 error. sorry I am a newbie in this will it be possible for you to share the complete sample maven project? – rinku Sep 17 '11 at 10:08
  • you need to change package name in PackagesResourceConfig constuructor to match your resources package name (it does perform recursive scan) – Pavel Bucek Sep 17 '11 at 10:15
  • Thanks it worked finally :) .. can I use any java resource class in place of helloworld? any special restrictions for the syntax in that? – rinku Sep 17 '11 at 10:48
  • Do you know how I can inject any object reference and then refer it in resource class later.. I have posted a new question http://stackoverflow.com/questions/7510874/access-external-objects-in-jersey-resource-class can you suggest something? – rinku Sep 22 '11 at 08:26
  • Hi , the suggestion mentioned in http://stackoverflow.com/questions/7510874/access-external-objects-in-jersey-resource-class/7512273#7512273 is not seem to be working.. any comments? – rinku Sep 28 '11 at 08:12
  • we can take it offline. The best way how to solve would be sharing some common sample, I can create clean maven project or I can fix your app, choice is yours. – Pavel Bucek Sep 29 '11 at 20:15
  • I'm coming to this problem late, but I'd also say be aware of the difference between the licenses - grizzly is cddl, and jetty is apache – bityz May 02 '13 at 18:37
10

Here's a github repo with a Maven based HelloWorld sample configured for Grizzly on master branch and for Jetty on "jetty" branch:

https://github.com/jesperfj/jax-rs-heroku

Despite the repo name it's not Heroku specific. Start the server by running the command specified in Procfile, e.g.

$ java -cp "target/dependency/*":target/classes Main
Jesper J.
  • 993
  • 8
  • 17
4

Embedded jetty with reaseasy without web.xml

java code:

    final QueuedThreadPool threadPool = new QueuedThreadPool();
    threadPool.setMinThreads(2); // 10
    threadPool.setMaxThreads(8); // 200
    threadPool.setDetailedDump(false);
    threadPool.setName(SERVER_THREAD_POOL);
    threadPool.setDaemon(true);

    final SelectChannelConnector connector = new SelectChannelConnector();
    connector.setHost(HOST);
    connector.setAcceptors(2);
    connector.setPort(PROXY_SEVLET_PORT);
    connector.setMaxIdleTime(MAX_IDLE_TIME);
    connector.setStatsOn(false);
    connector.setLowResourcesConnections(LOW_RESOURCES_CONNECTIONS);
    connector.setLowResourcesMaxIdleTime(LOW_RESOURCES_MAX_IDLE_TIME);
    connector.setName(HTTP_CONNECTOR_NAME);            

    /* Setup ServletContextHandler */
    final ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
    contextHandler.setContextPath("/");
    contextHandler.addEventListener(new ProxyContextListener());

    contextHandler.setInitParameter("resteasy.servlet.mapping.prefix","/services");

    final ServletHolder restEasyServletHolder = new ServletHolder(new HttpServletDispatcher());
    restEasyServletHolder.setInitOrder(1);

/* Scan package for web services*/
restEasyServletHolder.setInitParameter("javax.ws.rs.Application","com.viacom.pl.cprox.MessageApplication");

    contextHandler.addServlet(restEasyServletHolder, "/services/*");

    final HandlerList handlers = new HandlerList();
    handlers.setHandlers(new Handler[] { contextHandler });

    final Server server = new Server();
    server.setThreadPool(threadPool);
    server.setConnectors(new Connector[] { connector });
    server.setHandler(handlers);
    server.setStopAtShutdown(true);
    server.setSendServerVersion(true);
    server.setSendDateHeader(true);
    server.setGracefulShutdown(1000);
    server.setDumpAfterStart(false);
    server.setDumpBeforeStop(false);

    server.start();
    server.join();

Web services detector:

package com.viacom.pl.cprox;

import java.util.HashSet;
import java.util.Set;

import javax.ws.rs.core.Application;

import org.reflections.Reflections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.viacom.pl.cprox.services.impl.AbstractWebServiceMethod;

public class MessageApplication extends Application {

    private static final Logger LOGGER = LoggerFactory.getLogger(MessageApplication.class);

    private Set<Object> singletons = new HashSet<Object>();

    @SuppressWarnings("rawtypes")
    public MessageApplication() {

        /* Setup RestEasy */
        Reflections reflections = new Reflections("com.viacom.pl.cprox.services.impl");

        /*All my web services methods wrapper class extends AbstractWebServiceMethod, so it is easy to get sub set of expected result.*/
        Set<Class<? extends AbstractWebServiceMethod>> set = reflections
                .getSubTypesOf(AbstractWebServiceMethod.class);
        for (Class<? extends AbstractWebServiceMethod> clazz : set) {
            try {
                singletons.add(clazz.newInstance());
            } catch (InstantiationException e) {
                LOGGER.error(e.getMessage(), e);
            } catch (IllegalAccessException e) {
                LOGGER.error(e.getMessage(), e);
            }
        }
    }

    @Override
    public Set<Object> getSingletons() {
        return singletons;
    }
}

pom.xml

<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-jaxb-provider</artifactId>
    <version>2.2.0.GA</version>
</dependency>
<dependency>
    <groupId>org.reflections</groupId>
    <artifactId>reflections</artifactId>
    <version>0.9.9-RC1</version>
</dependency>

<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-jaxrs</artifactId>
    <version>3.0.3.Final</version>
</dependency>
Karol Król
  • 3,320
  • 1
  • 34
  • 37
2

I was able to get this maven archetype up and running in half an hour.

See https://github.com/cb372/jersey-jetty-guice-archetype

Steps:

git clone https://github.com/cb372/jersey-jetty-guice-archetype.git
mvn install
mvn archetype:generate -DarchetypeGroupId=org.birchall \
    -DarchetypeArtifactId=jersey-jetty-guice-archetype -DarchetypeVersion=1.0
mvn compile exec:java -Dexec.mainClass=com.yourpackage.Main

Huge thanks to cb372 for creating this archetype. It makes it so easy.

Community
  • 1
  • 1
Jess
  • 23,901
  • 21
  • 124
  • 145