Asynchronous Process not Working in javax.ws.rs.*(REST Client) - java

I demonstrate asynchronous process in REST API using javax(2.26 version). When I tried I got"A filter or servlet of the current chain does not support asynchronous operations." I don't know what to do with that. I tried many ways but doesn't work out.
The below is the resource file
Resource.java
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.container.Suspended;
import javax.ws.rs.core.MediaType;
import com.jersey.rest.User;
#Path("/async")
public class AsynDemo {
#POST
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public void asyncMethod(#Suspended final AsyncResponse response, User user) {
new Thread() {
public void run() {
response.resume(true);
}
}.start();
}
}
Pom.xml
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jersey</groupId>
<artifactId>rest</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>rest</name>
<build>
<finalName>rest</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<inherited>true</inherited>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<!-- use the following artifactId if you don't need servlet 2.x compatibility -->
<!-- artifactId>jersey-container-servlet</artifactId -->
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>2.26</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<!-- uncomment this to get JSON support-->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.security</groupId>
<artifactId>oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.10.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.11.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.0</version>
</dependency>
</dependencies>
<properties>
<jersey.version>2.26-b03</jersey.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
Client checking java file
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import com.jersey.rest.User;
public class MainTesting {
public static void main(String[] args) {
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:9090/rest/jwt/async");
AsyncInvoker invoker = target.request().async();
Future<Boolean> response = invoker.post(Entity.entity(new User(), MediaType.APPLICATION_JSON), Boolean.class);
try {
System.out.println(response.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
APPLICATION ERROR
SEVERE: Servlet.service() for servlet [Jersey jwt Application] in context with path [/rest] threw exception [java.lang.UnsupportedOperationException: Asynchronous processing not supported on Servlet 2.x container.] with root cause
java.lang.UnsupportedOperationException: Asynchronous processing not supported on Servlet 2.x container.
at org.glassfish.jersey.servlet.WebComponent$3.suspend(WebComponent.java:137)
at org.glassfish.jersey.servlet.internal.ResponseWriter.suspend(ResponseWriter.java:125)
at org.glassfish.jersey.server.ServerRuntime$AsyncResponder.suspend(ServerRuntime.java:921)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:326)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:337)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at..................```
Tomcat exception
```WARNING: Unable to start async because the following classes in the processing chain do not support async [org.glassfish.jersey.servlet.ServletContainer]
java.lang.IllegalStateException: A filter or servlet of the current chain does not support asynchronous operations.
at org.apache.catalina.connector.Request.startAsync(Request.java:1692)
at org.apache.catalina.connector.RequestFacade.startAsync(RequestFacade.java:1050)
at org.glassfish.jersey.servlet.async.AsyncContextDelegateProviderImpl$ExtensionImpl.getAsyncContext(AsyncContextDelegateProviderImpl.java:112)
at org.glassfish.jersey.servlet.async.AsyncContextDelegateProviderImpl$ExtensionImpl.suspend(AsyncContextDelegateProviderImpl.java:96)
at org.glassfish.jersey.servlet.internal.ResponseWriter.suspend(ResponseWriter.java:125)
at org.glassfish.jersey.server.ServerRuntime$AsyncResponder.suspend(ServerRuntime.java:921)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:326)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:337)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Err....
Aug 21, 2020 5:07:24 PM org.glassfish.jersey.servlet.internal.ResponseWriter suspend
WARNING: Attempt to put servlet request into asynchronous mode has failed. Please check your servlet configuration - all Servlet instances and Servlet filters involved in the request processing must explicitly declare support for asynchronous request processing.
java.lang.IllegalStateException: A filter or servlet of the current chain does not support asynchronous operations.
at org.apache.catalina.connector.Request.startAsync(Request.java:1692)
at org.apache.catalina.connector.RequestFacade.startAsync(RequestFacade.java:1050)
at org.glassfish.jersey.servlet.async.AsyncContextDelegateProviderImpl$ExtensionImpl.getAsyncContext(AsyncContextDelegateProviderImpl.java:112)
at org.glassfish.jersey.servlet.async.AsyncContextDelegateProviderImpl$ExtensionImpl.suspend(AsyncContextDelegateProviderImpl.java:96)
at org.glassfish.jersey.servlet.internal.ResponseWriter.suspend(ResponseWriter.java:125)
at org.glassfish.jersey.server.ServerRuntime$AsyncResponder.suspend(ServerRuntime.java:921)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:326)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
at org.glassfish.jersey.server.Serv.....
Aug 21, 2020 5:07:24 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [Jersey jwt Application] in context with path [/rest] threw exception [javax.ws.rs.ProcessingException: Attempt to suspend a connection of an asynchronous request failed in the underlying container.] with root cause
javax.ws.rs.ProcessingException: Attempt to suspend a connection of an asynchronous request failed in the underlying container.
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:327)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:337)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
....```
Could you help me to solve this? :)

Add <async-supported>true</async-supported> in web.xml servlet definition.
<servlet>
<servlet-name>Jersey jwt 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>com.jersey.jwt</param-value>
</init-param>
<async-supported>true</async-supported>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey jwt Application</servlet-name>
<url-pattern>/jwt/*</url-pattern>
</servlet-mapping>
it solved the issue.

Related

ContainerException: The ResourceConfig instance does not contain any root resource classes while deploying my app on Wildfly Server

i'm trying to make a simple rest service and deploy the app on wildfly server and when i try to deploy my app on server i have the following exception:
Cannot upload deployment: {"WFLYCTL0080: Failed services" =>
{"jboss.undertow.deployment.default-server.default-host./resttestapp" =>
"org.jboss.msc.service.StartException in service
jboss.undertow.deployment.default-server.default-host./resttestapp:
com.sun.jersey.api.container.ContainerException: The ResourceConfig
instance does not contain any root resource classes. Caused by:
com.sun.jersey.api.container.ContainerException: The ResourceConfig
instance does not contain any root resource classes."}}
I've tried a lot of thing from stackoverflow but nothing works for me.
I'm using Wildfly 9.0.2 (standalone, deploying via admin console), Intellij idea.
This is part of my pom.xml:
<groupId>cz.prg.rob</groupId>
<artifactId>resttestapp</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>resttestapp Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<jersey.version>1.19.4</jersey.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.sun.jersey/jersey-core -->
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>${jersey.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.sun.jersey/jersey-server -->
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>${jersey.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.sun.jersey/jersey-bundle -->
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-bundle</artifactId>
<version>${jersey.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20180813</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.6</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.codehaus.jackson/jackson-mapper-asl -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
</dependencies>
This is my web.xml:
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>JerseyServlet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>cz.prg.rob</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>JerseyServlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
This is my service class:
package cz.prg.rob;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import java.util.Date;
#Path("/name")
public class UserService {
#GET
#Produces("text/plain")
public String getName() {
return "Qwerty";
}
#GET
#Path("/user")
#Produces("application/json")
public User getUser(#QueryParam("name") String name, #QueryParam("surname") String surname, #QueryParam("birthDate") Date birthDate) {
return new User(name, surname, birthDate);
}
}
and this is a part of my User (model) class:
#NoArgsConstructor
#AllArgsConstructor
#Data
public class User {
private String name;
private String surname;
private Date birthDate;
}
This is my project structure:
I can't understand what i'm doing wrong. Please help me.
The solution that helped me:
I've added this as init param of JerseyServlet
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>cz.prg.rob.UserServiceApplication</param-value>
</init-param>
And this is the class where i've defined my resource class
public class UserServiceApplication extends Application {
public Set<Class<?>> getClasses() {
Set<Class<?>> s = new HashSet<Class<?>>();
s.add(UserService.class);
return s;
}
}
So looks like i have to say to jersey which classes are resource classes explicitly. If you want to add new resource classes just add them in HashSet into getClasses() method.

How to get Glassfish 4.1.1 and Jersey to work with JSON?

For days I am trying to get Glassfish 4.1.1 and Jersey working together. The tricky part is when there is communication via JSON.
I tried many solutions to get JSON data transfer working. Alas, still not working.
Glassfish and Jersey are 'standards', so I guess there is a standard way to combine these two? What is the correct way of configuring JSON?
Whenever I am starting to work with JSON, I get all kinds of errors.
The last errors I get:
2016-11-25T15:59:52.070+0100|Warning: StandardWrapperValve[Jersey Web Application]: Servlet.service() for servlet Jersey Web Application threw exception
java.lang.ClassNotFoundException: javax.xml.parsers.ParserConfigurationException not found by org.eclipse.persistence.moxy [228]
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1532)
at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:75)
etc, etc.
The maven dependencies are:
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>nl.xyz</groupId>
<artifactId>GlassfishJerseyJson</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>GlassfishJerseyJson</name>
<build>
<finalName>GlassfishJerseyJson</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<!-- <webXml>src\main\webapp\WEB-INF\web.xml</webXml> -->
</configuration>
</plugin>
<plugin>
<groupId>org.glassfish.maven.plugin</groupId>
<artifactId>maven-glassfish-plugin</artifactId>
<version>2.1</version>
<configuration>
<glassfishDirectory>${local.glassfish.home}</glassfishDirectory>
<user>admin</user>
<passwordFile>${local.glassfish.passfile}</passwordFile>
<domain>
<name>domain1</name>
<httpPort>8080</httpPort>
<adminPort>4848</adminPort>
</domain>
<components>
<component>
<name>${project.artifactId}</name>
<artifact>target/${project.build.finalName}.war</artifact>
</component>
</components>
<debug>true</debug>
<terse>false</terse>
<echo>true</echo>
</configuration>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.6.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.6.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.5.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
<properties>
<jersey.version>2.24.1</jersey.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
The JQuery call is:
function findResource() {
$.ajax({
type: 'GET',
accepts: { json: "application/json, text/javascript" },
dataType: "json",
url: resourceURL,
success: function(data){
alert( "Back from resource: name=" + data.name);
},
error: function(jqXHR, textStatus, errorThrown){
alert('Back from resource error: ' + textStatus + ' - Error: ' + errorThrown + " - Response: " + jqXHR.responseText);
}
});
}
Resource java file:
#Path("myresource")
public class MyResource {
#GET
#Produces( MediaType.APPLICATION_JSON)
public Wine2 getIt() {
Wine2 w = new Wine2();
w.setId( 100);
w.setCountry( "france");
return w;
}
}
Configuration: option 1: web.xml (left the default first line out):
<web-app version="2.5" 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_2_5.xsd">
<servlet>
<servlet-name>Jersey Web 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>org.coenraets.cellar</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/webapi/*</url-pattern>
</servlet-mapping>
</web-app>
Configuration: option 2: MyApplication.java
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
public class MyApplication extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> s = new HashSet<Class<?>>();
s.add( MyResource.class);
s.add( WineResource.class);
return s;
}
}
Yesssss!!!! I found the complete answer.
The solution is by using the original (see above) maven libs ANd to change the following files in the GLASSFISH/modules folder to verion 2.5.0 (or similar):
org.eclipse.persistence.moxy.jar
org.eclipse.persistence.core.jar
The solution came via [this webpage][1] and similar sites.
In this post and others the org.eclipse.persistence.moxy.jar file in the $Glassfish/modules is replaced with the 2.5.0 version.
Just use the following instead of your moxy dependency:
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.6.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.6.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.5.1</version>
<scope>provided</scope>
</dependency>
The libs are included in the standard Glassfish 4 installation, therefore the provided scope is sufficient.
And you should remove these dependencies:
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>javax.json</groupId>
<artifactId>javax.json-api</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
and
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<!-- <version>2.4.1</version>
<scope>provided</scope> -->
</dependency>
You don't need them and most of the Jersey dependencies can be set to provided.
If you don't get it to work: I created a gist with an example project, it has only 4 files: pom.xml, web.xml, MyResource.class and Cow.class. This includes everything you need for a basic setup and it works on Glassfish 4 without any additional libs.
Try to add in Library: Java EE7 API Library, JAX-RS, Jersey.
The solution for you can be to provide a custom JSON Provider your Jersey Application. It's definition will look like this:
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
#Produces(MediaType.APPLICATION_JSON)
public class CustomJsonProvider extends JacksonJaxbJsonProvider {
private static final ObjectMapper MAPPER = new ObjectMapper();
static {
MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
MAPPER.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
MAPPER.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.DEFAULT);
MAPPER.enable(SerializationFeature.INDENT_OUTPUT);
}
public CustomJsonProvider() {
super();
setMapper(MAPPER);
}
}
Then a feature that will register your custom JSON Provider to the Jersey Application context:
import javax.ws.rs.core.Feature;
import javax.ws.rs.core.FeatureContext;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
public class MarshallingFeature implements Feature {
#Override
public boolean configure(FeatureContext context) {
context.register(CustomJsonProvider.class, MessageBodyReader.class, MessageBodyWriter.class);
return true;
}
}
Finally, register that feature in the Jersey Application class constructor:
import javax.ws.rs.ApplicationPath;
import org.glassfish.jersey.server.ResourceConfig;
#ApplicationPath("ws")
public class ApplicationConfig extends ResourceConfig {
public ApplicationConfig() {
register(MarshallingFeature.class);
// register ressource classes
}
}
And these are the dependencies you need to add to your Maven pom.xml:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.5.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.8.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.2</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.8.6</version>
<type>jar</type>
</dependency>
Hope it helps.

Another Guice + Jersey error NoSuchMethodError

Well, GeneralUtilities does not even have the method getSystemProperty so not so weird it fails.
What is the best way to handle this?
Deploying on Liberty Profile.
Error:
[1/12/16 15:01:58:482 CET] 00000027 com.ibm.ws.webcontainer.servlet E SRVE0271E: Uncaught init() exception created by servlet [Jersey Web Application] in application [Agent-1.0.0-SNAPSHOT]: java.lang.NoSuchMethodError: org/glassfish/hk2/utilities/general/GeneralUtilities.getSystemProperty(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
at org.jvnet.hk2.internal.ServiceLocatorImpl.<clinit>(ServiceLocatorImpl.java:122)
at org.jvnet.hk2.external.generator.ServiceLocatorGeneratorImpl.initialize(ServiceLocatorGeneratorImpl.java:66)
at org.jvnet.hk2.external.generator.ServiceLocatorGeneratorImpl.create(ServiceLocatorGeneratorImpl.java:98)
at org.glassfish.hk2.internal.ServiceLocatorFactoryImpl.internalCreate(ServiceLocatorFactoryImpl.java:312)
at org.glassfish.hk2.internal.ServiceLocatorFactoryImpl.create(ServiceLocatorFactoryImpl.java:268)
at org.glassfish.jersey.internal.inject.Injections._createLocator(Injections.java:138)
at org.glassfish.jersey.internal.inject.Injections.createLocator(Injections.java:123)
at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:308)
at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:338)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:171)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:363)
at javax.servlet.GenericServlet.init(GenericServlet.java:244)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.init(ServletWrapper.java:332)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.loadOnStartupCheck(ServletWrapper.java:1423)
at com.ibm.ws.webcontainer.webapp.WebApp.doLoadOnStartupActions(WebApp.java:1180)
at com.ibm.ws.webcontainer.webapp.WebApp.commonInitializationFinally(WebApp.java:1148)
at com.ibm.ws.webcontainer.webapp.WebApp.initialize(WebApp.java:1054)
at com.ibm.ws.webcontainer.webapp.WebApp.initialize(WebApp.java:6448)
at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost.startWebApp(DynamicVirtualHost.java:446)
at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost.startWebApplication(DynamicVirtualHost.java:441)
at com.ibm.ws.webcontainer.osgi.WebContainer.startWebApplication(WebContainer.java:980)
at com.ibm.ws.webcontainer.osgi.WebContainer.startModule(WebContainer.java:804)
at com.ibm.ws.app.manager.web.internal.WebModuleHandlerImpl.deployModule(WebModuleHandlerImpl.java:102)
at com.ibm.ws.app.manager.module.internal.DeployedAppInfoBase.deployModule(DeployedAppInfoBase.java:874)
at com.ibm.ws.app.manager.module.internal.DeployedAppInfoBase.deployModules(DeployedAppInfoBase.java:834)
at com.ibm.ws.app.manager.module.internal.DeployedAppInfoBase.deployApp(DeployedAppInfoBase.java:821)
at com.ibm.ws.app.manager.war.internal.WARApplicationHandlerImpl.install(WARApplicationHandlerImpl.java:80)
at com.ibm.ws.app.manager.internal.statemachine.StartAction.execute(StartAction.java:139)
at com.ibm.ws.app.manager.internal.statemachine.ApplicationStateMachineImpl.enterState(ApplicationStateMachineImpl.java:1168)
at com.ibm.ws.app.manager.internal.statemachine.ApplicationStateMachineImpl.run(ApplicationStateMachineImpl.java:781)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1143)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:618)
at java.lang.Thread.run(Thread.java:785)
JerseyConfig
import com.google.inject.Guice;
import com.google.inject.Injector;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.jersey.server.ResourceConfig;
import org.jvnet.hk2.guice.bridge.api.GuiceBridge;
import org.jvnet.hk2.guice.bridge.api.GuiceIntoHK2Bridge;
import javax.inject.Inject;
public class JerseyConfig extends ResourceConfig {
#Inject
public JerseyConfig(ServiceLocator locator) {
packages("no.services.agent");
GuiceBridge.getGuiceBridge().initializeGuiceBridge(locator);
// add your Guice modules.
Injector injector = Guice.createInjector(new GuiceModule());
GuiceIntoHK2Bridge guiceBridge = locator.getService(GuiceIntoHK2Bridge.class);
guiceBridge.bridgeGuiceInjector(injector);
}
}
SelftestResource
#Path("/")
#Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML, MediaType.TEXT_HTML})
#Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML, MediaType.TEXT_HTML})
public class SelftestResource {
#GET
public Response selftest(){
return Response.ok().build();
}
}
web.xml
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.services.agent.guice.JerseyConfig</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
pom.xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-servlet</artifactId>
<version>3.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.hk2</groupId>
<artifactId>guice-bridge</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-multibindings</artifactId>
<version>3.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
Based on what you said I believe the fix is to use the 2.4.0-b31 version of the guice-bridge

Tomcat 7 does not scan annotations when using Jersey 2

I have a Jersey 2 Maven project.
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!-- This web.xml file is not required when using Servlet 3.0 container,
see implementation details http://jersey.java.net/nonav/documentation/latest/jax-rs.html -->
<web-app version="2.5" 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_2_5.xsd">
<servlet>
<servlet-name>com.api.rest.ApplicationResource</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>com.api.rest.ApplicationResource</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
</web-app>
pom.xml:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.api</groupId>
<artifactId>GLI_API</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>GLI_API</name>
<build>
<finalName>GLI_API</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<inherited>true</inherited>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<!-- use the following artifactId if you don't need servlet 2.x compatibility -->
<!-- artifactId>jersey-container-servlet</artifactId -->
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>2.21</version>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP-java6</artifactId>
<version>2.2.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.36</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.9</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.mindrot</groupId>
<artifactId>jbcrypt</artifactId>
<version>0.3m</version>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>com.cloudinary</groupId>
<artifactId>cloudinary-http44</artifactId>
<version>1.2.1</version>
</dependency>
</dependencies>
<properties>
<jersey.version>2.19</jersey.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
My project works fine when working locally. But it doesn't work anymore when i deploy it on my remote server.
So what happens is basically, that the WAR gets deployed correctly but there is really no error or warning in catalina.out. I get a 404 on every of my defined endpoints.
catalina.out:
Sep 14, 2015 2:03:00 PM org.apache.catalina.startup.HostConfig deployWAR
INFO: Deploying web application archive /var/lib/tomcat7/webapps/GLI_API.war
Sep 14, 2015 2:04:17 PM org.apache.catalina.startup.HostConfig deployWAR
INFO: Deploying web application archive /var/lib/tomcat7/webapps/ICDS_API.war
Sep 14, 2015 2:04:23 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory /var/lib/tomcat7/webapps/ROOT
Sep 14, 2015 2:04:23 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8080"]
Sep 14, 2015 2:04:23 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 84867 ms
ApplicationResource:
package com.api.rest;
import java.util.logging.Logger;
import org.glassfish.jersey.filter.LoggingFilter;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.ServerProperties;
import com.api.provider.ResponseCorsFilter;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
public class ApplicationResource extends ResourceConfig {
private static final Logger LOGGER = null;
public ApplicationResource() {
// Register resources and providers using package-scanning.
packages("com.api");
System.out.println("started");
register(MultiPartFeature.class);
// Register my custom provider - not needed if it's in my.package.
register(ResponseCorsFilter.class);
// Register an instance of LoggingFilter.
register(new LoggingFilter(LOGGER, true));
// Enable Tracing support.
property(ServerProperties.TRACING, "ALL");
}
}
What could be the problem? I developed on tomcat8 (but don't remember using something specifically) and deployed on tomcat7. Could this be a problem?
This endpoint should be reachable: http://54.228.220.152:8080/GLI_API/api/item
The other API works fine - so the server in general is working.
Also - if you don't have the final answer i would really appreciate it if you can point me to files/directories to look at since i don't get any error.
You may try to enable annotation scanning by setting this init parameter to your servlet:
<servlet>
...
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.yourproject.packageWhereYourResourcesAre</param-value>
</init-param>
...
</servlet>
Update
It seems you have compiled against Java 8, while Tomcat runs with Java 7? Try this:
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
You may also want to update your web.xml to 3.0:
<web-app version="3.0" 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">

How can I send a JSON object with Jersey in a Rest Service

I'm trying to make a restful service with jersey, for that I'm using the jersey example for a maven project. So this is what I got:
my pom.xml:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>simple-service-webapp</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>simple-service-webapp</name>
<build>
<finalName>simple-service-webapp</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<inherited>true</inherited>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<!-- use the following artifactId if you don't need servlet 2.x compatibility -->
<!-- artifactId>jersey-container-servlet</artifactId -->
</dependency>
<!-- uncomment this to get JSON support <dependency> <groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId> </dependency> -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.6.0</version>
</dependency>
</dependencies>
<properties>
<jersey.version>2.19</jersey.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
my web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!-- This web.xml file is not required when using Servlet 3.0 container,
see implementation details http://jersey.java.net/nonav/documentation/latest/jax-rs.html -->
<web-app version="2.5" 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_2_5.xsd">
<servlet>
<servlet-name>Jersey Web 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>com.example</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/webapi/*</url-pattern>
</servlet-mapping>
</web-app>
the resource
package com.example;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
/**
* Root resource (exposed at "myresource" path)
*/
#Path("/myresource")
public class MyResource {
/**
* Method handling HTTP GET requests. The returned object will be sent
* to the client as "text/plain" media type.
*
* #return String that will be returned as a text/plain response.
*/
#GET
#Produces(MediaType.TEXT_PLAIN)
public String getIt() {
return "Got it!";
}
#Path( "complexObject/{name}" )
#GET
#Produces( { MediaType.APPLICATION_JSON } )
public ComplexObject complexObject( #PathParam( "name" ) String name ) {
return new ComplexObject(name);
}
}
The ComplexObject class is just a class with a string.
when I hit the url: http://localhost:8080/simple-service-webapp/webapi/myresource/
This work, I get "Got it!"
but when I hit on: http://localhost:8080/simple-service-webapp/webapi/myresource/complexObject/capo
I get this error on the console:
SEVERE: MessageBodyWriter not found for media type=application/json,
type=class com.example.ComplexObject, genericType=class
com.example.ComplexObject.
How can I fix this?
With this dependency
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.6.0</version>
</dependency>
You will still need to register the provider. You could register it individually
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>
com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider
</param-value>
</init-param>
Or since the dependency also comes with Jackson ExceptionMappers, you might want to just have the whole package scanned (just add it to the list of packages)
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>
com.example,
com.fasterxml.jackson.jaxrs.json
</param-value>
</init-param>
Another option, besides using the above dependency, is to use Jersey's "wrapper" dependency (which handle the registration of the of the providers, among a couple other things such as Jackson Entity Filtering. Just used
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
</dependency>
With this dependency, do registration is required. It is automatically registered through Jersey's auto-discoverable feature

Categories

Resources