Null Pointer Exception in RestEasy Asynchronous Request

I worked in Resteasy, where I have to make an asynchronous request to the server. The real goal: I will submit a form that will be converted to a .xlsx file, which will take no more than 10 seconds. Thus, an asynchronous request is the best way. I followed the procedures at the following link.

https://docs.jboss.org/resteasy/docs/3.0.9.Final/userguide/html_single/#Asynchronous_HTTP_Request_Processing

I am making an ajax request as follows.

$.ajax({ url : 'rest/parentPath/childPath', type : 'GET', success : function(data, status, xhr) { console.log(xhr.getResponseHeader('Location')); }, failure : function(data) { console.log(data); }, error : function(error,status) { } }); 

ParentClass.java

 import javax.ws.rs.container.AsyncResponse; import javax.ws.rs.container.Suspended; @Component @Path("/parentPath") public class ParentClass { @GET @Path("childPath") @Produces("text/plain") public void asyncFunction(@Suspended final AsyncResponse response){ Thread t = new Thread() { @Override public void run() { try { Response jaxrs = Response.ok("basic").type(MediaType.TEXT_PLAIN).build(); System.out.println("entered======================= ================================================="); response.resume(jaxrs); } catch (Exception e){ e.printStackTrace(); } } }; t.start(); } } 

If I just make an ajax request, it gives me a 503 Service unavailable error , but I do my asynchronous task, I can confirm by seeing that my sysout is in the wildfly log. But this is not how to do asynchronous operations. I should see the answer of my asynchronous task in the second request. I followed the procedures in this link.

https://docs.jboss.org/resteasy/docs/3.0.9.Final/userguide/html_single/#async_job

If I put ?asynch=true in the request url, we immediately get a 202 Accepted response with the position of the asynchronous job in the response. But he did not even go into the try statement. The error is called in the wildfly terminal as follows.

 19:11:41,733 WARN [org.jboss.resteasy.core.ExceptionHandler] (pool-4-thread-1) Failed executing GET /parentPath/childPath: org.jboss.resteasy.spi.BadRequestExcept ion: Failed processing arguments of org.jboss.resteasy.spi.metadata.ResourceMethod@44d4407c at org.jboss.resteasy.core.MethodInjectorImpl.injectArguments(MethodInjectorImpl.java:104) [resteasy-jaxrs-3.0.10.Final.jar:] at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:112) [resteasy-jaxrs-3.0.10.Final.jar:] at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:296) [resteasy-jaxrs-3.0.10.Final.jar:] at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:250) [resteasy-jaxrs-3.0.10.Final.jar:] at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:237) [resteasy-jaxrs-3.0.10.Final.jar:] at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:356) [resteasy-jaxrs-3.0.10.Final.jar:] at org.jboss.resteasy.core.AsynchronousDispatcher.invokeSuper(AsynchronousDispatcher.java:237) [resteasy-jaxrs-3.0.10.Final.jar:] at org.jboss.resteasy.core.AsynchronousDispatcher$1.call(AsynchronousDispatcher.java:278) [resteasy-jaxrs-3.0.10.Final.jar:] at org.jboss.resteasy.core.AsynchronousDispatcher$1.call(AsynchronousDispatcher.java:269) [resteasy-jaxrs-3.0.10.Final.jar:] at java.util.concurrent.FutureTask.run(FutureTask.java:266) [rt.jar:1.8.0_25] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [rt.jar:1.8.0_25] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [rt.jar:1.8.0_25] at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_25] Caused by: java.lang.NullPointerException at org.jboss.resteasy.core.ResourceMethodInvoker.initializeAsync(ResourceMethodInvoker.java:374) [resteasy-jaxrs-3.0.10.Final.jar:] at org.jboss.resteasy.core.AsynchronousResponseInjector.inject(AsynchronousResponseInjector.java:43) [resteasy-jaxrs-3.0.10.Final.jar:] at org.jboss.resteasy.core.MethodInjectorImpl.injectArguments(MethodInjectorImpl.java:89) [resteasy-jaxrs-3.0.10.Final.jar:] ... 12 more 

If I made the same request again with asynch=true , it shows the same error, but with (pool-4-thread-2) instead of (pool-4-thread-1)

This means that the exception does not occur on the server side, but at the runtime level. Coz any exception that occurred in my code will be present in the log file, but not in the wildfly terminal. I will publish the web.xml files, WebConfig.java, build.gradle. I just copy the same thing as in jboss docs, but I cannot understand why this exception occurs at the wildfly level.

web.xml

 <?xml version="1.0" encoding="UTF-8"?> <web-app 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" version="3.0"> <display-name>Web Application</display-name> <distributable /> <listener> <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class> </listener> <listener> <listener-class>org.jboss.resteasy.plugins.spring.SpringContextLoaderListener</listener-class> </listener> <!-- Context Configuration locations for Spring XML files --> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:/applicationContext-resources.xml classpath:/applicationContext-dao.xml classpath:/applicationContext-service.xml classpath*:/applicationContext.xml /WEB-INF/applicationContext*.xml </param-value> </context-param> <context-param> <param-name>resteasy.servlet.mapping.prefix</param-name> <param-value>/rest</param-value> </context-param> <context-param> <param-name>resteasy.async.job.service.enabled</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>resteasy.async.job.service.max.job.results</param-name> <param-value>100</param-value> </context-param> <!-- Maximum wait time on a job when a client is querying for it --> <context-param> <param-name>resteasy.async.job.service.max.wait</param-name> <param-value>300000</param-value> </context-param> <!-- Thread pool size of background threads that run the job --> <context-param> <param-name>resteasy.async.job.service.thread.pool.size</param-name> <param-value>100</param-value> </context-param> <!-- Set the base path for the Job uris --> <context-param> <param-name>resteasy.async.job.service.base.path</param-name> <param-value>/asynch/jobs</param-value> </context-param> <servlet> <servlet-name>resteasy-servlet</servlet-name> <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class> <init-param> <param-name>javax.ws.rs.Application</param-name> <param-value>com.mypackage.service.WebConfig</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>resteasy-servlet</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>login.html</welcome-file> </welcome-file-list> </web-app> 

Webconfig.java

 import java.util.HashSet; import java.util.Set; import javax.ws.rs.core.Application; public class WebConfig extends Application { private Set<Object> singletons = new HashSet<Object>(); private Set<Class<?>> empty = new HashSet<Class<?>>(); public WebConfig() { // ADD YOUR RESTFUL RESOURCES HERE this.singletons.add(new SignupService()); this.singletons.add(new UserService()); this.singletons.add(new ParentClass()); } public Set<Class<?>> getClasses() { return this.empty; } public Set<Object> getSingletons() { return this.singletons; } } 

build.gradle

 apply plugin: 'java' apply plugin: 'war' apply plugin: 'eclipse-wtp' apply plugin: 'eclipse' // Uses JDK 8 sourceCompatibility = 1.8 targetCompatibility = 1.8 // 1. Get dependencies from Maven local repository // 2. Get dependencies from Maven central repository repositories { mavenLocal() mavenCentral() maven { url "http://repo1.maven.org/maven2" } } configurations { provided } sourceSets { main { compileClasspath += configurations.provided } } //Project dependencies dependencies { //Spring framework core compile 'org.springframework:spring-web:4.1.4.RELEASE' compile 'org.springframework:spring-core:4.1.4.RELEASE' compile 'org.springframework:spring-context:4.1.4.RELEASE' compile 'org.springframework:spring-context-support:4.1.4.RELEASE' compile 'org.springframework:spring-orm:4.1.4.RELEASE' compile 'org.springframework.security:spring-security-core:4.0.0.RELEASE' //MySQL database driver //compile 'mysql:mysql-connector-java:5.1.34' compile 'com.oracle:ojdbc6:11.2.0.1.0' //Hibernate framework compile 'org.hibernate:hibernate-core:4.3.8.Final' compile 'commons-dbcp:commons-dbcp:1.2.2' //Servlet API compile 'javax.servlet:servlet-api:2.5' //Base-64 Apache commons compile 'commons-codec:commons-codec:1.10' //log4j compile 'log4j:log4j:1.2.17' compile 'org.slf4j:slf4j-simple:1.7.10' //XmlBeans Equity Valuation compile 'org.apache.xmlbeans:xmlbeans:2.6.0' //Poi Equity Valuation compile 'org.apache.poi:poi:3.10.1' //Poi ooxml Equity Valuation compile 'org.apache.poi:poi-ooxml:3.10.1' //Poi ooxml Schemas Equity Valuation compile 'org.apache.poi:poi-ooxml-schemas:3.10.1' //Jacob Equity Valuation compile 'jacob:jacob:1.18-M2' //Google gson compile 'com.google.code.gson:gson:2.3.1' provided 'org.jboss.resteasy:resteasy-jaxrs:3.0.11.Final' provided 'org.jboss.resteasy:resteasy-spring:3.0.11.Final' } 
+2
java asynchronous jax-rs wildfly-8 resteasy
source share
1 answer

Tried to add a comment, but a word limit.
Now I can do asynchronous work. I found that using AsynchResponse and suspension annotations throws this exception. this is not required for asynchronous job processing. The reason for your null pointer is that there is a combination for these two components.

There are two asynchronous things, and the documentation really mixes them 1. Asynchronous response . Using Suspended and AsynchResponse will free the server thread that received the request, and the work will be done using the newly created thread. But the client will wait for an answer. Until your new thread completes and sends it back. For this, no changes are required in web.xml.


2. Asynchronous job processing . Here you set resteasy.async.job.service.enabled to true in the web.xml file and any other optional parameters (if necessary). No other changes are required for APi. My method was @POST @Path("/helloworld") public Response getHelloWorld() { log.info("API invoked"); longLiftingJob(); log.info("API invoke done"); return Response.status(200).entity("Hello World").build(); } @POST @Path("/helloworld") public Response getHelloWorld() { log.info("API invoked"); longLiftingJob(); log.info("API invoke done"); return Response.status(200).entity("Hello World").build(); }

With the true parameter in web.xml, the framework will call the call in a new thread (just put it) and return with the job ID for it in response 202. as a location header, like
Location β†’ http://127.0.0.1:8080/myrest/asynch/jobs/1432015827488-1

The client performs a GET / POST at the above URL and will receive the response returned by the API after the API completes. But the actual client never expects such asynchronous operation.

+1
source share

All Articles