Monday, April 9, 2012

Axis2: Axis2 Web Services with Spring 3 on Tomcat

Overview:
This article looks at how you could easily integrate Spring with Apache Axis2 via a very simple example. You can find the sample source code here.

Also, you can refer to this comprehensive tutorial on integrating Apache Axis2 with Spring 3 and Hibernate 3.

Project Structure: Following diagram shows the maven project structure I have used for this post.


Step 2: Creating POJO Classes and Service Implementation
Employee.java
 package org.fazlan.employee.axis2spring.service.beans;
public class Employee {
 private Long id;
 private String firstName;
 private String lastName;
 public Long getId() {
   return id;
 }
 public void setId(Long id) {
   this.id = id;
 }
 public String getFirstName() {
   return firstName;
 }
 public void setFirstName(String firstName) {
   this.firstName = firstName;
 }
 public String getLastName() {
   return lastName;
 }
 public void setLastName(String lastName) {
   this.lastName = lastName;
 }
}

IService.java - The Service Interface.
 package org.fazlan.employee.axis2spring.service.services;
import java.util.List;
/**
* Created by IntelliJ IDEA.
* User: fazlan
* Date: 3/9/12
* Time: 4:36 PM
* To change this template use File | Settings | File Templates.
*/
public interface IService<T> {
 Long add(T t);
 boolean update(T t);
 boolean delete(Long id);
 T get(Long id);
 List<T> getAll();
}  

EmployeeService.java - Implementation of the Service
 package org.fazlan.employee.axis2spring.service.services;
import org.fazlan.employee.axis2spring.service.beans.Employee;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class EmployeeService implements IService<Employee> {
 private static Long ID = 0L;
 private Map<Long, Employee> employeeDao;
 public Long add(Employee employee) {
   employee.setId(++ID);
   update(employee);
   return ID;
 }
 public boolean update(Employee employee) {
   employeeDao.put(employee.getId(), employee);
   return true;
 }
 public boolean delete(Long id) {
   return employeeDao.remove(id) instanceof Employee;
 }
 public Employee get(Long id) {
   return employeeDao.get(id);
 }
 public List<Employee> getAll() {
   return new ArrayList<Employee>(employeeDao.values());
 }
 public void setEmployeeDao(Map<Long, Employee> employeeDao) {
   this.employeeDao = employeeDao;
 }
}

Step 4: Creating the Spring Lifecycle Management to Allow Axis2 to Aanage the Lifecycle of the Spring Services.
EmployeeSpringInit.java
 package org.fazlan.employee.axis2spring.service.services;
import org.apache.axiom.om.OMElement;
import org.apache.axis2.context.OperationContext;
import org.apache.axis2.context.ServiceContext;
import org.apache.axis2.engine.ServiceLifeCycle;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.description.AxisService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class EmployeeSpringInit implements ServiceLifeCycle {
 private static Log logger = LogFactory
   .getLog(EmployeeSpringInit.class);
  /**
  * this will be called during the deployement time of the service. irrespective
  * of the service scope this method will be called
  */
 public void startUp(ConfigurationContext ignore, AxisService service) {
   ClassLoader classLoader = service.getClassLoader();
   ClassPathXmlApplicationContext appCtx = new
     ClassPathXmlApplicationContext(new String[] {"classpath:spring/spring-app-context.xml"}, false);
   appCtx.setClassLoader(classLoader);
   appCtx.refresh();
   if (logger.isDebugEnabled()) {
     logger.debug("\n\nstartUp() set spring classloader via axisService.getClassLoader() ... ");
   }
 }
 /**
  * this will be called during the deployement time of the service. irrespective
  * of the service scope this method will be called
  */
 public void shutDown(ConfigurationContext ignore, AxisService service) {
 }
}

This loads the Spring bean configuration from classpath:spring/spring-app-context.xml.

Step 5: Configuring the Spring Beans and Wiring the Service Implementation (spring/spring-app-context.xml)
This is the Spring bean definition file in our application containing all the beans required to run the application.

The following is very important, this class and the spring bean needed to wire it could be used as an alternative to getting the ApplicationContext from the ServletContext.
 <bean id="applicationContext"
 class="org.apache.axis2.extensions.spring.receivers.ApplicationContextHolder" />

The complete Spring bean definition file,
 <beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:util="http://www.springframework.org/schema/util"
   xsi:schemaLocation= "http://www.springframework.org/schema/beans
              http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
              http://www.springframework.org/schema/util
              http://www.springframework.org/schema/util/spring-util-3.0.xsd">
 <bean id="applicationContext"
 class="org.apache.axis2.extensions.spring.receivers.ApplicationContextHolder" />
 <bean id="employeeSpringService" class="org.fazlan.employee.axis2spring.service.services.EmployeeService">
   <property name="employeeDao" ref="employeeDao"/>
 </bean>
 <util:map id="employeeDao"
      key-type="java.lang.Long"
      value-type="org.fazlan.employee.axis2spring.service.beans.Employee">
   <entry key="1" value-ref="emp1" />
   <entry key="2" value-ref="emp2" />
   <entry key="3" value-ref="emp3" />
 </util:map>
 <bean id="emp1" class="org.fazlan.employee.axis2spring.service.beans.Employee">
   <property name="id" value="1" />
   <property name="firstName" value="Apache" />
   <property name="lastName" value="Axis2" />
 </bean>
 <bean id="emp2" class="org.fazlan.employee.axis2spring.service.beans.Employee">
   <property name="id" value="2" />
   <property name="firstName" value="Apache" />
   <property name="lastName" value="Spring" />
 </bean>
 <bean id="emp3" class="org.fazlan.employee.axis2spring.service.beans.Employee">
   <property name="id" value="3" />
   <property name="firstName" value="Apache" />
   <property name="lastName" value="Tomcat" />
 </bean>
</beans>

Here, I am using an instance of java.util.Map to mock the database.

Step 6: Defining your Axis2 Service Configuration (META-INF/services.xml)
EmployeeSpringInit Service: Loading the Spring context
  <service name="EmployeeSpringInit" class="org.fazlan.employee.axis2spring.service.services.EmployeeSpringInit">
 <description>
  This web service initializes Spring.
 </description>
 <parameter name="ServiceClass" >org.fazlan.employee.axis2spring.service.services.EmployeeSpringInit</parameter>
 <parameter name="ServiceTCCL" >composite</parameter>
 <parameter name="load-on-startup" >true</parameter>
</service>

Here, we use this service to load the Spring context at the startup of the application.

EmployeeService - The actual service definition.
 <service name="EmployeeService">
 <description>
  Weather Spring POJO Axis2 AAR deployment
 </description>
 <parameter name="ServiceClass" >org.fazlan.employee.axis2spring.service.services.EmployeeService</parameter>
 <parameter name="ServiceObjectSupplier" >org.apache.axis2.extensions.spring.receivers.SpringAppContextAwareObjectSupplier</parameter>
 <excludeOperations>
     <operation>setEmployeeDao</operation>
 </excludeOperations>
 <parameter name="SpringBeanName" >employeeSpringService</parameter>
 <parameter name="SpringContextLocation">spring/spring-app-context.xml</parameter>
 <messageReceivers>
  <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
           class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
  <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
           class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
 </messageReceivers>
</service>

NOTE: I have excluded setEmployeeDao() as a web method.

By default, the Axis2 Engine will look for /applicationContext.xml to load the Spring bean configurations.

You can change this by either defining the following property.

 <parameter name="SpringContextLocation">spring/spring-app-context.xml</parameter>

This tells the Axis2 Engine where to locate the Spring application context file for this service. This is very useful when you have multiple Spring application services in the same Axis3 Engine.
Or,
You can place the Spring configuration file alongside the service.xml as in the following format. Axis2 Engine will implicitly detect this.

META-INF/<service-name>-application-context.xml

Putting all together,

 <serviceGroup>
 <service name="EmployeeSpringInit" class="org.fazlan.employee.axis2spring.service.services.EmployeeSpringInit">
 <description>
  This web service initializes Spring.
 </description>
 <parameter name="ServiceClass" >org.fazlan.employee.axis2spring.service.services.EmployeeSpringInit</parameter>
 <parameter name="ServiceTCCL" >composite</parameter>
 <parameter name="load-on-startup" >true</parameter>
</service>
<service name="EmployeeService">
 <description>
  Weather Spring POJO Axis2 AAR deployment
 </description>
 <parameter name="ServiceClass" >org.fazlan.employee.axis2spring.service.services.EmployeeService</parameter>
 <parameter name="ServiceObjectSupplier" >org.apache.axis2.extensions.spring.receivers.SpringAppContextAwareObjectSupplier</parameter>
 <excludeOperations>
     <operation>setEmployeeDao</operation>
 </excludeOperations>
 <parameter name="SpringBeanName" >employeeSpringService</parameter>
 <parameter name="SpringContextLocation">spring/spring-app-context.xml</parameter>
 <messageReceivers>
  <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
           class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
  <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
           class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
 </messageReceivers>
</service>
</serviceGroup>

Step 7: Building the Project
mvn clean install

Step 8: Deploying the Service
Now you can deploy this service on to any container. Here we'll deploy this on Tomcat server.

You need to copy the following *.jars to /axis2/WEB-INF/lib/ directory (e;i: /home/fazlan/apache-tomcat-6.0.32/webapps/axis2/WEB-INF/lib/)in your Axis2 WAR already deployed on Tomcat.

Spring 3.1.1.RELEASE jars
spring-aop-3.1.1.RELEASE.jar
spring-asm-3.1.1.RELEASE.jar
spring-beans-3.1.1.RELEASE.jar
spring-context-3.1.1.RELEASE.jar
spring-context-support-3.1.1.RELEASE.jar
spring-core-3.1.1.RELEASE.jar
spring-expression-3.1.1.RELEASE.jar
spring-jdbc-3.1.1.RELEASE.jar
spring-orm-3.1.1.RELEASE.jar
spring-tx-3.1.1.RELEASE.jar
spring-web-3.1.1.RELEASE.jar

Once, all the above *.jars are copied to /axis2/WEB-INF/lib/ on Tomcat. We are good to deploy the service and test.

Now you can deploy this service on to any container. Here we'll deploy this on Tomcat server.
If you have not already done, extract the axis2.war that comes with the Apache Axis2 distribution and deploy to Tomcat server.
You can verify the deployment http://localhost:8080/axis2/
Once verified the successful deployment of the Axis2 web archive on Tomcat, you can deploy the *.aar file.
- Either via http://localhost:8080/axis2/axis2-admin/ or,
- Manually copying the *.aar file to <$TOMCAT_HOME>/webapps/axis2/WEB-INF/services

You can also list down the existing Axis2 services via http://localhost:8080/axis2/services/listServices

After successfully deploying the service, you can access the service via http://localhost:8080/axis2/services/EmployeeService?wsdl

Step 9: Testing the Services via SOAP UI.

Option 1: Testing REFTful endpoint using CURL
Install CURL
sudo apt-get install curl

Now, after successfully installing CURL, we are ready to test the services.
Issue the following commands on the terminal.

POST a Resource: Adding a new employee resource.
- Adding the new employee record in the add.xml file.
 <ns:add xmlns:ns="http://services.service.axis2spring.employee.fazlan.org">
    <ns:employee xmlns:ax21="http://beans.service.axis2spring.employee.fazlan.org/xsd"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax21:Employee">
         <ax21:firstName>My FirstName</ax21:firstName>
         <ax21:id>1</ax21:id>
         <ax21:lastName>My LastName</ax21:lastName>
    </ns:employee>
</ns:add>

 curl -v -H "Accept: application/xml" -H "Content-type: application/xml" -X POST -d @add.xml http://localhost:8080/axis2/services/EmployeeService/add

GET Resource:
- Retrieving all the employee resources.
 curl -v http://localhost:8080/axis2/services/EmployeeService/getAll

- Retrieving a employee resource for a given id(id = 1).
 curl -v http://localhost:8080/axis2/services/EmployeeService/get?id=1

PUT a Resource: Updating an existing employee resource.
- Updating an existing employee record in the update.xml file.
 <ns:update xmlns:ns="http://services.service.axis2spring.employee.fazlan.org">
    <ns:employee xmlns:ax21="http://beans.service.axis2spring.employee.fazlan.org/xsd"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax21:Employee">
         <ax21:firstName>Update FirstName</ax21:firstName>
         <ax21:id>1</ax21:id>
         <ax21:lastName>Update LastName</ax21:lastName>
    </ns:employee>
</ns:update>

 curl -v -H "Accept: application/xml" -H "Content-type: application/xml" -X PUT -d @update.xml http://localhost:8080/axis2/services/EmployeeService/update

DELETE a Resource: Deleting an employee for a given id (id=1)
 curl -v http://localhost:8080/axis2/services/EmployeeService/delete?id=1


Option 2: Testing SOAP endpoints using SOAP UI.
Use the service URL(http://localhost:8080/axis2/services/EmployeeService?wsdl) and create a project on SOAP UI.


Summary:
Aixs2 is a fast Web Service Engine that enables us to deploy Web Services on any Web Container. Axis2 allows us to make use of these features by allowing us to integrate Spring.
You can find the sample source code here.

12 comments:

  1. Hello Fazlan, thanks for the article, is just what I needed.
    I have relied on the article to make use of Axis2 and Spring 3. In addition, I require a connection to a database, so I'm using DAO classes.
    However I am having trouble injecting the DAO classes. In Class SprigInit runs perfectly, the problem is in the class has the methods of the Web Service and also contains a DAO. When I run a DAO method throws a java.lang.NullPointerException, so it makes me think that the injection does not occur properly.
    These are my configuration files:

    - applicationContext.xml

    <beans
    xsi:schemaLocation="
    ...">

    <bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/dataBaseTEST?autoReconnect=true"/>
    <property name="username" value="root"/>
    <property name="password" value="r00t123"/>
    </bean>
    <bean id="springInit" class="test.spring.SpringInit"/>
    <bean id="services" class="test.Services">
    <property name="timbradorCuentasDao" ref="timbradorCuentasDao" />
    </bean>
    <bean id="timbradorCuentasDao" class="test.spring.dao.TimbradorCuentasDaoImpl">
    <property name="dataSource" ref="dataSource"/>
    </bean>
    </beans>

    - service.xml

    <serviceGroup>
    <service name="SpringInit" class="test.spring.SpringInit">
    <description>This web service initializes Spring.
    </description>
    <parameter name="ServiceClass">test.spring.SpringInit</parameter>
    <parameter name="ServiceTCCL">composite</parameter>
    <parameter name="load-on-startup">true</parameter>
    </service>

    <service name="Services" scope="application">
    <description></description>
    <messageReceivers>
    <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only" class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
    <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out" class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
    </messageReceivers>
    <parameter name="ServiceClass">test.Services</parameter>
    <parameter name="ServiceObjectSupplier">org.apache.axis2.extensions.spring.receivers.SpringAppContextAwareObjectSupplier</parameter>
    <parameter name="SpringBeanName">services</parameter>
    </service>
    </serviceGroup>

    - and the class

    public class Services {

    private TimbradorCuentasDao timbradorCuentasDao = null;

    public String hello(String name) throws DAOException {
    List<String> cuentas = timbradorCuentasDao.listaCuentas(); //This is the line that throws java.lang.NullPointerException
    System.out.println("Size: "+cuentas.size());
    return "Hello " + name;
    }

    public void setTimbradorCuentasDao(TimbradorCuentasDao timbradorCuentasDao) {
    this.timbradorCuentasDao = timbradorCuentasDao;
    }
    }

    Will you have any idea what part might be wrong?

    Thanks in advance

    ReplyDelete
    Replies
    1. Hi Victor,

      You're configuration looks good.
      Firstly, what I verified on your configuration was the 'timbradorCuentasDao' property in applicationContext.xml matches the setter in Services.java, which it does, and no issues there.

      Based on your comments, I also believe you see the 'SpringInit' service successfully and 'Services' as a faulty service in the axis2 service list.

      I reckon you're correct on DAO inject is not occurring correctly.

      Since you're using dbcp to establish a connection to the database, certain jars might be missing in the classpath while your container tries to initialize the datasource bean.

      e.g: MySQL driver in the classpath.

      Could you please check the log file in the container you deployed these services?
      e.g: /logs/catalina.out

      This should contain the exact reason for the failure.

      -Thanks,
      Fazlan

      Delete
    2. What I meant was,

      "Could you please check the log file in the container you deployed these services?
      e.g: <TOMCAT_HOME>/logs/catalina.out "

      Delete
    3. Hi Fazlan, thanks for your answer.
      Reviewing the log of Tomcat, there is no problem when deploying the aar.
      The log does not record any errors.
      Both services (SpringInit and Services) are published correctly. The problem occurs when you consume the hello method.
      The stack trace is as follows:

      INFO: Server startup in 3189 ms
      [ERROR] Exception occurred while trying to invoke service method hello
      java.lang.reflect.InvocationTargetException
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at org.apache.axis2.rpc.receivers.RPCUtil.invokeServiceClass(RPCUtil.java:212)
      at org.apache.axis2.rpc.receivers.RPCMessageReceiver.invokeBusinessLogic(RPCMessageReceiver.java:117)
      at org.apache.axis2.receivers.AbstractInOutMessageReceiver.invokeBusinessLogic(AbstractInOutMessageReceiver.java:40)
      at org.apache.axis2.receivers.AbstractMessageReceiver.receive(AbstractMessageReceiver.java:110)
      at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:181)
      at org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.java:172)
      at org.apache.axis2.transport.http.AxisServlet.doPost(AxisServlet.java:146)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
      at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
      at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
      at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999)
      at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565)
      at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307)
      at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
      at java.lang.Thread.run(Thread.java:680)
      Caused by: java.lang.NullPointerException
      at com.konesh.mx.ilion.IlionServices.hello(IlionServices.java:22)
      ... 29 more


      I made the following test in SpringInit:

      if(appCtx.getBeanFactory().getBean("timbradorCuentasDao") !=null)
      {
      System.out.println("timbradorCuentasDao is not NULL");
      }else{
      System.out.println("timbradorCuentasDao is NULL");
      }


      and always printed in the log "timbradorCuentasDao is not NULL"

      Even I can see both the WSDL correctly, the problem is to consume the hello method.

      Delete
    4. Hi Victor,

      Seems that this is a known issue due to a classloading problem.

      Refer to http://axis.apache.org/axis2/java/core/docs/spring.html#a23

      and perhaps this blog post might help you http://ravishbhupesh.wordpress.com/2009/02/26/axis2-hibernate-problem/

      However, if you're into Spring, then I suggest you go for Apache CXF. CXF treats as Spring as it's first class citizens. Personally, I think it's every easy to do configure Spring in CXF.

      -Fazlan

      Delete
  2. Victor,

    You can have a look at the following link on integrating Hibernate with Apache CXF. You can tryout the sample code attached in that article.

    http://fazlansabar.blogspot.com/2012/04/web-service-apache-cxf-integration-with_13.html

    Hope this helps!

    -Fazlan

    ReplyDelete
  3. Hello Fazlan,

    I've been doing some testing, if the service configuration "service" in the service.xml I remove the scope, throws me the following error:

    [ERROR] org / springframework / context / ApplicationContextAware
    java.lang.NoClassDefFoundError: org / springframework / context / ApplicationContextAware

    when consuming the method "hello".

    The libraries are inside the aar, are not within the folder axis2 libraries.

    ReplyDelete
    Replies
    1. You do not have the spring-context-*.jar in
      <axis2>/WEB-INF/lib.
      You need to copy the spring-*.jars into that

      Delete
  4. Hello Victor,

    After you inputs, I have updated this tutorial to make it a more practical one.

    Also, I did a tutorial(the link below) on how to integrate Spring/Hibernate with Axis2. You can check that as well. It's a simple but yet a comprehensive one.

    http://fazlansabar.blogspot.com/2012/04/apache-axis2-tutorial-integrating-with.html

    ReplyDelete
  5. Hello fazlan,
    I have get the following error
    java.lang.NullPointerException
    at org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver.invokeBusinessLogic(RPCInOnlyMessageReceiver.java:88)
    at org.apache.axis2.receivers.AbstractMessageReceiver.receive(AbstractMessageReceiver.java:110)
    at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:181)
    at org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.java:172)
    at org.apache.axis2.transport.http.AxisServlet.doPost(AxisServlet.java:146)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
    at java.lang.Thread.run(Unknown Source)

    ReplyDelete
    Replies
    1. Hey Prashant,

      As much as I'd love to help you on this, the provided details are not sufficient to make any real suggestions about this issue. All I can see is that it's a POST request. Did you look at the server logs?

      -Fazlan

      Delete
    2. Thanks for this beautiful article.
      But i am facing some problem in finding *.aar file.
      Please help me.

      Thanks in advance.

      Delete