Question

I want to create a REST server.

I added maven dependencies, my pom.xml looks like this:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>abptc_server</groupId>
    <artifactId>abptc_server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <build>
        <sourceDirectory>src</sourceDirectory>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.0</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>

            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-server</artifactId>
            <version>9.1.3.v20140225</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-servlet</artifactId>
            <version>9.1.3.v20140225</version>
        </dependency>

        <dependency>
            <groupId>javax.ws.rs</groupId>
            <artifactId>jsr311-api</artifactId>
            <version>1.1.1</version>
        </dependency>

        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-core</artifactId>
            <version>1.18.1</version>
        </dependency>

        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-server</artifactId>
            <version>1.18.1</version>
        </dependency>

        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-client</artifactId>
            <version>1.18.1</version>
        </dependency>

        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-servlet</artifactId>
            <version>1.18.1</version>
        </dependency>

        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-json</artifactId>
            <version>1.18.1</version>
        </dependency>

    </dependencies>
</project>

I added the maven-assembly-plugin because I want a single jar, which I can execute:

java -cp target/abptc_server-0.0.1-SNAPSHOT-jar-with-dependencies.jar server.MinimalServerRest

When I run the server in eclipse, it works well, but when I execute the jar, the server fails after one REST request: GET http://localhost:9999/employee/getEmployee

The error:

2014-03-20 11:40:46.996:INFO::main: Logging initialized @576ms
2014-03-20 11:40:47.133:INFO:oejs.Server:main: jetty-9.1.z-SNAPSHOT
2014-03-20 11:40:47.176:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@7dbe444b{/,null,AVAILABLE}
2014-03-20 11:40:47.194:INFO:oejs.ServerConnector:main: Started ServerConnector@6bb9db06{HTTP/1.1}{0.0.0.0:9999}
2014-03-20 11:40:47.194:INFO:oejs.Server:main: Started @777ms
márc. 20, 2014 11:40:53 DE com.sun.jersey.api.core.PackagesResourceConfig init
INFO: Scanning for root resource and provider classes in the packages:
  rest
márc. 20, 2014 11:40:53 DE com.sun.jersey.api.core.ScanningResourceConfig logClasses
INFO: Root resource classes found:
  class rest.EmployeeSvc
  class rest.StudentSvc
márc. 20, 2014 11:40:53 DE com.sun.jersey.api.core.ScanningResourceConfig init
INFO: No provider classes found.
márc. 20, 2014 11:40:54 DE com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version 'Jersey: 1.18.1 02/19/2014 03:28 AM'
márc. 20, 2014 11:40:54 DE com.sun.jersey.spi.container.ContainerResponse write
SEVERE: A message body writer for Java class dto.Employee, and Java type class dto.Employee, and MIME media type application/json was not found.
The registered message body writers compatible with the MIME media type are:
*/* ->
  com.sun.jersey.core.impl.provider.entity.FormProvider
  com.sun.jersey.core.impl.provider.entity.StringProvider
  com.sun.jersey.core.impl.provider.entity.ByteArrayProvider
  com.sun.jersey.core.impl.provider.entity.FileProvider
  com.sun.jersey.core.impl.provider.entity.InputStreamProvider
  com.sun.jersey.core.impl.provider.entity.DataSourceProvider
  com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General
  com.sun.jersey.core.impl.provider.entity.ReaderProvider
  com.sun.jersey.core.impl.provider.entity.DocumentProvider
  com.sun.jersey.core.impl.provider.entity.StreamingOutputProvider
  com.sun.jersey.core.impl.provider.entity.SourceProvider$SourceWriter
  com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General
  com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General

márc. 20, 2014 11:40:54 DE com.sun.jersey.spi.container.ContainerResponse logException
SEVERE: Mapped exception to response: 500 (Internal Server Error)
javax.ws.rs.WebApplicationException: com.sun.jersey.api.MessageException: A message body writer for Java class dto.Employee, and Java type class dto.Employee, and MIME media type application/json was not found.

    at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:284)
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1510)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1419)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1409)
    at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:409)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:540)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:715)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:711)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:552)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:219)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1112)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:479)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:183)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1046)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
    at org.eclipse.jetty.server.Server.handle(Server.java:462)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:281)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:232)
    at org.eclipse.jetty.io.AbstractConnection$1.run(AbstractConnection.java:505)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:607)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:536)
    at java.lang.Thread.run(Thread.java:744)
Caused by: com.sun.jersey.api.MessageException: A message body writer for Java class dto.Employee, and Java type class dto.Employee, and MIME media type application/json was not found.

    ... 24 more

I searched SO for answers:

https://stackoverflow.com/a/12427046/598280 and https://stackoverflow.com/a/6027161/598280 I already added jersey-json depencency.

https://stackoverflow.com/a/11936282/598280 I dont have web.xml and the server runs well, when I execute in eclipse, so the problem is with maven.

https://stackoverflow.com/a/13108540/598280 Same.

According to Mark Needham blog, my server class looks fine:

ServletHolder sh = new ServletHolder(ServletContainer.class);
sh.setInitParameter("com.sun.jersey.config.property.resourceConfigClass", "com.sun.jersey.api.core.PackagesResourceConfig");

// Set the package where the services reside
sh.setInitParameter("com.sun.jersey.config.property.packages", "rest");
sh.setInitParameter("com.sun.jersey.api.json.POJOMappingFeature", "true");

Server server = new Server(9999);
ServletContextHandler context = new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS);
context.addServlet(sh, "/*");
server.start();
server.join();

How can I solve this problem?

UPDATE:

My packed jar looks like this:jar

I didnt checked all depencency (it has 23 individual depencency) but it looks fine from here. Should I check all?

Here is maven clean install output: http://pastebin.com/Whk2qr2i

Was it helpful?

Solution

Hmm, the problem with this approach is that if multiple JARS have the same files they get overwritten. E.g. All those jars probably have META-INF/MANIFEST.MF files but only one will actually be present. This could apply to other files. This can cause odd behaviour

I would try building them as separate JARS with maven and then try running and see if that works. You can use the assembly plugin to build a ZIP containing your application JAR and all the JAR files in a lib folder, and a script to run it. E.g. The contents of the zip would look like:

abptcserver/
    lib/
        dependency1.jar
        dependency2.jar
        dependency3.jar
    abptcserver.jar
    run.sh
    run.bat

Youc an then configure the shell and batch scripts to run your server with all JARS in the lib directory on the class path. I imagine you'll get less unexpected behaviour this way, its also more robust and more user friendly to run

OTHER TIPS

Use maven's shade plugin instead of assembly plugin.

It doesn't overwrite classes, even if there there are present with same name in different jars, and will resolve this issue.

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