1

I'm trying to write a simple Jersey server application. My code works fine only when I use XML. But when I request a result in JSON I get this error:

org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo MessageBodyWriter not found for media type={application/json, q=1000}, type=class il.zukermandl.jersey.demo.model.User, genericType=class il.zukermandl.jersey.demo.model.User.

Here is my simple Java code.

@Path("/users")
public class UserService {
    @GET
    @Produces({APPLICATION_JSON, APPLICATION_XML})
    public Response getUser() {        
        return ok(new User()).build();
    }
}

I use JAXB annotations for my entity.

@XmlRootElement(name = "user")
@XmlType(propOrder = {"id", "name", "age"})
public class User {
    private Long id;
    private String name;
    private Integer age;
    // getters,setters and ctrs were omitted
}

My config class.

public class AppConfig extends Application {
    @Override
    public Set<Class<?>> getClasses() {
        final Set<Class<?>> resources = new HashSet<Class<?>>();
        resources.add(il.zukermandl.jersey.demo.service.UserService.class);
        return resources;
    }
}

And web.xml descriptor.

    <servlet>
        <servlet-name>Application</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>il.zukermandl.jersey.demo</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Application</servlet-name>
        <url-pattern>/rest_v1/*</url-pattern>
    </servlet-mapping>

I think the main issue is in my pom.xml file. So here it is

    <dependencies>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet</artifactId>
            <version>2.17</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-jackson</artifactId>
            <version>2.17</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.3.2</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.3.2</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.3.2</version>
        </dependency>            
    </dependencies>

I use Tomcat 8.0.9 to run my code. Any ideas how to add JSON support to this app?

UPD

Here is the structure of my project.

WEB-INF
    ├── classes
    │   ├── il
    │   │   └── zukermandl
    │   │       └── jersey
    │   │           └── demo
    │   │               ├── AppConfig.class
    │   │               ├── model
    │   │               │   └── User.class
    │   │               └── service
    │   │                   └── UserService.class
    │   └── misc.txt
    ├── lib
    │   ├── aopalliance-repackaged-2.4.0-b10.jar
    │   ├── hk2-api-2.4.0-b10.jar
    │   ├── hk2-locator-2.4.0-b10.jar
    │   ├── hk2-utils-2.4.0-b10.jar
    │   ├── javassist-3.18.1-GA.jar
    │   ├── javax.annotation-api-1.2.jar
    │   ├── javax.inject-2.4.0-b10.jar
    │   ├── javax.ws.rs-api-2.0.1.jar
    │   ├── jersey-client-2.17.jar
    │   ├── jersey-common-2.17.jar
    │   ├── jersey-container-servlet-2.17.jar
    │   ├── jersey-container-servlet-core-2.17.jar
    │   ├── jersey-guava-2.17.jar
    │   ├── jersey-media-jaxb-2.17.jar
    │   ├── jersey-server-2.17.jar
    │   ├── osgi-resource-locator-1.0.1.jar
    │   └── validation-api-1.1.0.Final.jar
    └── web.xml
barbara
  • 3,111
  • 6
  • 30
  • 58
  • Yeah I can't reproduce the problem. With exactly what you've provided, it works fine for me. But one thing to mention is that the `AppConfig` class it not used. Which isn't a problem, as you are already package scanning. Also the Jackson provider should be auto discovered, so need to configure anything. I don't see why it wouldn't, but I would check if the `jersey-media-json-jackson` jar is in the lib of the webapp when you deploy it to Tomcat. That's the only way I could see it not working – Paul Samsotha Mar 30 '15 at 18:05
  • And your concern about the `pom.xml` is a non issue. Only thing I would fix is to get rid of all the Jackson dependencies, except for `jersey-media-json-jackson`. The jersey-media dependency already pulls them in. Again a non-issue, just being thorough :-) – Paul Samsotha Mar 30 '15 at 18:09
  • You can try to explicitly register the JacksonFeature and see what happens. Add an init param to the jersey serlvet `jersey.config.server.provider.classnames` - value `org.glassfish.jersey.jackson.JacksonFeature` – Paul Samsotha Mar 30 '15 at 18:21
  • When I added classnames to `web.xml` I got the error: `30-Mar-2015 21:24:53.827 SEVERE [http-nio-7777-exec-7] null.null MessageBodyWriter not found for media type={application/json, q=1000}, type=class il.zukermandl.jersey.demo.model.User, genericType=class il.zukermandl.jersey.demo.model.User.` – barbara Mar 30 '15 at 18:25
  • That's the same error. Like I said I can't reproduce the problem. Is that all you have in your current project? What you have above. Because just with everything up there, it works fine. – Paul Samsotha Mar 30 '15 at 18:29
  • Maybe I should write a custom `MessageBodyWriter`? – barbara Mar 30 '15 at 18:31
  • Nooo... You don't need it. That's what the `jersey-media-json-jackson` is for. – Paul Samsotha Mar 30 '15 at 18:33
  • Try to create a new project, using [this archetype](https://jersey.java.net/documentation/latest/getting-started.html#new-webapp). Add your classes to it (minus the `AppConfig`). Change the dependency from `jersey-container-servlet-core` to `jersey-container-servlet` and add the `jersey-media-json-jackson`. This is exactly what I did, except I didn't use the command line. My IDE alread has that archetype – Paul Samsotha Mar 30 '15 at 18:35
  • Yeah, as I suspected, the `jersey-media-json-jackson` jar along with with its Jackson dependencies aren't getting transfered into the lib. That, I don't know the reason, since all the Jersey jars are getting transferred. That's odd. This is what you need to figure out – Paul Samsotha Mar 30 '15 at 18:44
  • The `jersey-media-json-jackson` jar along with its dependencies [shown here](http://stackoverflow.com/a/29316666/2587435), should have all been transferred to the lib when you build/deployed the app – Paul Samsotha Mar 30 '15 at 18:49
  • Wow! Thanks. I added two jars to classpath (jackson-jaxrs-json-provider-2.3.2.jar + jersey-media-json-jackson-2.17.jar) and just restart the server and it works fine for me now. – barbara Mar 30 '15 at 19:13
  • Why do I get the feeling you're not actually using Maven, and just have a pom.xml for decoration ;-) – Paul Samsotha Mar 31 '15 at 00:28
  • Actually I use maven. And it add some jars to classpath. – barbara Mar 31 '15 at 13:00

1 Answers1

0

Just in case someone else runs into same problem, I solved it by adding

shadowJar {
    mergeServiceFiles()
}

to build.gradle. Looks like plugin id "com.github.johnrengelman.shadow" version "4.0.3" does shadowing wrong way without it.

metamaker
  • 2,307
  • 2
  • 19
  • 18