1 Reply Latest reply on Apr 12, 2015 1:37 AM by jaikiran

    Null Pointer Exception in RestEasy Asynchronous Request

    krnaveen14

      I was working in Resteasy where I've to make a asynchronous request to server. The real purpose is, I'll be submitting a form which will be converted into a .xlsx file which will take atleast 10 seconds to complete. So Asynchronous request is the best way here. I followed the procedures from the following link.

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

      I'm making the ajax request like this.

      $.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 simply make a ajax request, it gives me 503 Service unavailable error but I do get my Asynchronous task executed, I can confirm by seeing my sysout present in wildfly log. But this is not a way how a asynchronous should be done. I've to be able to see the response 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, immediately i get a response of 202 Accepted with a location of asynchronous job in response. But it didn't even entered into the try statement. An error is thrown in the wildfly terminal like this.

      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 exception is not occured at the server side but at the runtime layer. Coz any exception occured inside my code will be present in log file but not in wildfly terminal. I'll post the web.xml, WebConfig.java, build.gradle files. I'm just replicating the same thing which is done in jboss docs, but I cant figure out why is this exception occuring at the wildfly layer.

      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'

      }