Reputation: 1254
I am getting the following error when I try to return a custom object with Axis webservice:
aug 22, 2017 12:11:52 PM org.apache.axis.deployment.wsdd.WSDDService deployTypeMapping
SEVERE: Unable to deploy typemapping: {http://server}Case
java.lang.ClassNotFoundException: server._case
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1269)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1104)
at org.apache.axis.utils.ClassUtils$2.run(ClassUtils.java:187)
It seems like the webservice can't find my Case class but it is defined in the wsdl.
This is my code: Case:
package server;
import java.io.Serializable;
public class Case implements Serializable {
private static final long serialVersionUID = -1549174508068625157L;
private String id;
public Case() {
}
public Case(String id) {
this.id = id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
CaseServiceImpl:
package server;
public class CaseServiceImpl implements CaseService {
//This one works
@Override
public String hello(String message) {
return message;
}
//This one doesn't show up
@Override
public Case test() {
return new Case("TR-1");
}
}
CaseServiceImpl.wsdl (Auto-generated):
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://server" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://server" xmlns:intf="http://server" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!--WSDL created by Apache Axis version: 1.4
Built on Apr 22, 2006 (06:55:48 PDT)-->
<wsdl:types>
<schema elementFormDefault="qualified" targetNamespace="http://server" xmlns="http://www.w3.org/2001/XMLSchema">
<element name="test">
<complexType/>
</element>
<element name="testResponse">
<complexType>
<sequence>
<element name="testReturn" type="impl:Case"/>
</sequence>
</complexType>
</element>
<complexType name="Case">
<sequence>
<element name="id" nillable="true" type="xsd:string"/>
</sequence>
</complexType>
<element name="hello">
<complexType>
<sequence>
<element name="message" type="xsd:string"/>
</sequence>
</complexType>
</element>
<element name="helloResponse">
<complexType>
<sequence>
<element name="helloReturn" type="xsd:string"/>
</sequence>
</complexType>
</element>
</schema>
</wsdl:types>
<wsdl:message name="testResponse">
<wsdl:part element="impl:testResponse" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="helloResponse">
<wsdl:part element="impl:helloResponse" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="helloRequest">
<wsdl:part element="impl:hello" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="testRequest">
<wsdl:part element="impl:test" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="CaseServiceImpl">
<wsdl:operation name="test">
<wsdl:input message="impl:testRequest" name="testRequest">
</wsdl:input>
<wsdl:output message="impl:testResponse" name="testResponse">
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="hello">
<wsdl:input message="impl:helloRequest" name="helloRequest">
</wsdl:input>
<wsdl:output message="impl:helloResponse" name="helloResponse">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="CaseServiceImplSoapBinding" type="impl:CaseServiceImpl">
<wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="test">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="testRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="testResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="hello">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="helloRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="helloResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="CaseServiceImplService">
<wsdl:port binding="impl:CaseServiceImplSoapBinding" name="CaseServiceImpl">
<wsdlsoap:address location="http://localhost:8080/MORPOC_SOAP/services/CaseServiceImpl"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
I feel like I am missing something but I don't know what. Can somebody point me in the right direction?
Upvotes: 0
Views: 2102
Reputation: 1001
It seems that you have already found solution for your problem, but I will post detailed steps for potential readers. Hopefully it will also help to improve your solution, because I'm not sure that your issue is not in naming of the entity.
Preconditions:
Apache Tomcat/7.0.41
. For deploying the axis you just need to add previously downloaded axis folder into TOMCAT_HOME\webapps
folder.I have used the same bean and service implementation. So:
Case.java
package server;
import java.io.Serializable;
public class Case implements Serializable {
private static final long serialVersionUID = -1549174508068625157L;
private String id;
public Case() {
}
public Case(String id) {
this.id = id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
CaseService.java
package server;
interface CaseService {
String hello(String message);
Case test();
}
CaseServiceImpl.java
package server;
public class CaseServiceImpl implements CaseService {
//This one works
@Override
public String hello(String message) {
return message;
}
//This one doesn't show up
@Override
public Case test() {
return new Case("TR-1");
}
}
Once you have created this infrastructure you can generate wsdl based on your service interface. Go to the one level higher than the folder where compiled files are stored (Case.class
, CaseService.class
, CaseServiceImpl.class
). In our case this is:
And run following command:
%AXIS2_HOME%\bin\java2wsdl.bat -cp . -cn server.CaseService -of CaseService.wsdl
And new file CaseService.wsdl
will be created.
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:ns="http://server" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ax21="http://server/xsd" xmlns:ns1="http://org.apache.axis2/xsd" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" targetNamespace="http://server">
<wsdl:types>
<xs:schema xmlns:ax22="http://server/xsd" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://server">
<xs:import namespace="http://server/xsd"/>
<xs:element name="test">
<xs:complexType>
<xs:sequence/>
</xs:complexType>
</xs:element>
<xs:element name="testResponse">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="return" nillable="true" type="ax22:Case"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="hello">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="args0" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="helloResponse">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="return" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
<xs:schema attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://server/xsd">
<xs:complexType name="Case">
<xs:sequence>
<xs:element minOccurs="0" name="id" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<wsdl:message name="testRequest">
<wsdl:part name="parameters" element="ns:test"/>
</wsdl:message>
<wsdl:message name="testResponse">
<wsdl:part name="parameters" element="ns:testResponse"/>
</wsdl:message>
<wsdl:message name="helloRequest">
<wsdl:part name="parameters" element="ns:hello"/>
</wsdl:message>
<wsdl:message name="helloResponse">
<wsdl:part name="parameters" element="ns:helloResponse"/>
</wsdl:message>
<wsdl:portType name="CaseServicePortType">
<wsdl:operation name="test">
<wsdl:input message="ns:testRequest" wsaw:Action="urn:test"/>
<wsdl:output message="ns:testResponse" wsaw:Action="urn:testResponse"/>
</wsdl:operation>
<wsdl:operation name="hello">
<wsdl:input message="ns:helloRequest" wsaw:Action="urn:hello"/>
<wsdl:output message="ns:helloResponse" wsaw:Action="urn:helloResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="CaseServiceSoap11Binding" type="ns:CaseServicePortType">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<wsdl:operation name="test">
<soap:operation soapAction="urn:test" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="hello">
<soap:operation soapAction="urn:hello" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="CaseServiceSoap12Binding" type="ns:CaseServicePortType">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<wsdl:operation name="test">
<soap12:operation soapAction="urn:test" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="hello">
<soap12:operation soapAction="urn:hello" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="CaseServiceHttpBinding" type="ns:CaseServicePortType">
<http:binding verb="POST"/>
<wsdl:operation name="test">
<http:operation location="test"/>
<wsdl:input>
<mime:content type="application/xml" part="parameters"/>
</wsdl:input>
<wsdl:output>
<mime:content type="application/xml" part="parameters"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="hello">
<http:operation location="hello"/>
<wsdl:input>
<mime:content type="application/xml" part="parameters"/>
</wsdl:input>
<wsdl:output>
<mime:content type="application/xml" part="parameters"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="CaseService">
<wsdl:port name="CaseServiceHttpSoap11Endpoint" binding="ns:CaseServiceSoap11Binding">
<soap:address location="http://localhost:8080/axis2/services/CaseService"/>
</wsdl:port>
<wsdl:port name="CaseServiceHttpSoap12Endpoint" binding="ns:CaseServiceSoap12Binding">
<soap12:address location="http://localhost:8080/axis2/services/CaseService"/>
</wsdl:port>
<wsdl:port name="CaseServiceHttpEndpoint" binding="ns:CaseServiceHttpBinding">
<http:address location="http://localhost:8080/axis2/services/CaseService"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Now we are ready for generating WS components. From the folder where CaseService.wsdl
was generated execute following command:
%AXIS2_HOME%\bin\WSDL2Java -uri CaseService.wsdl -d adb -s -ss -sd -ssi -o service
And new folder service
will be generated. This command generates also a skeleton for your WS methods of which should be implemented. So open CaseServiceSkeleton.java
and implement hello
and test
methods. Result should be something like that:
package server;
public class CaseServiceSkeleton implements CaseServiceSkeletonInterface {
public HelloResponse hello(Hello hello0) {
CaseService caseService = new CaseServiceImpl();
String hello = caseService.hello(hello0.getArgs0());
HelloResponse helloResponse = new HelloResponse();
helloResponse.set_return(hello);
return helloResponse;
}
public TestResponse test(Test test2) {
CaseService caseService = new CaseServiceImpl();
Case test = caseService.test();
server.xsd.Case aCase = new server.xsd.Case();
aCase.setId(test.getId());
TestResponse testResponse = new TestResponse();
testResponse.set_return(aCase);
return testResponse;
}
}
Because you have a dependency on CaseService
, CaseServiceImpl
and Case
(which were generated during step #1) copy these file into the same folder where CaseServiceSkeleton.java
was generated.
Now you are ready for generating of *.aar
file. It will be used for the WS deployment. Navigate to the newly generated service
folder and execute ant command:
ant -buildfile build.xml
And in build\lib\
folder will be created CaseService.aar
.
For some reason Test.class
was not automatically included into the *.aar
file, so it is needed to be added manually - just copy Test.class
from build/classes
folder into newly generated CaseService.aar
to the server
folder. After all these steps CaseService.aar\server
folder should look like that:
Now you can deploy it to the axis - just copy it to WEB-INF\services\
in axis web application. One you start application server new service should appear. Go to the http://your_host:your_port/axis_application_name/services/listServices
. If deployment went successfully following page should appear:
Service Invocation
There are a lot of ways how to invoce the provided services. In our case we will used generated client stubs. For generating the client please use following command from the folder with wsdl file:
%AXIS2_HOME%\bin\WSDL2Java -uri CaseService.wsdl -d adb –o client
This command will generate src folder with two files: CaseServiceStub.java
and CaseServiceCallbackHandler.java
. These files will be used by client application.
Now we are ready for creation of the client application itself:
Client.java
package client;
import org.apache.axis2.AxisFault;
public class Client {
public static void main(String... args) {
try {
CaseServiceStub stub = new CaseServiceStub("http://localhost:8080/axis/services/CaseService");
invokeHelloMethod(stub);
invokeTestMethod(stub);
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
}
}
public static void invokeHelloMethod(CaseServiceStub stub) {
try {
CaseServiceStub.Hello request = new CaseServiceStub.Hello();
request.setArgs0("Hello World");
CaseServiceStub.HelloResponse response = stub.hello(request);
System.out.println("Hello method says: " + response.get_return());
} catch (java.rmi.RemoteException e) {
e.printStackTrace();
}
}
public static void invokeTestMethod(CaseServiceStub stub) {
try {
CaseServiceStub.Test request = new CaseServiceStub.Test();
CaseServiceStub.TestResponse response = stub.test(request);
System.out.println("Test method says: " + response.get_return().getId());
} catch (java.rmi.RemoteException e) {
e.printStackTrace();
}
}
}
Do not forget to change WS url during creation of CaseServiceStub
object. In result after execution of this class you have to get following output:
Hello method says: Hello World
Test method says: TR-1
Hope this will helps people execute your example :)
Upvotes: 1
Reputation: 1254
Apparently I can't use the name Case for my class since case
is reserved and it get's decapitalized at some point. After renaming the class it works.
Upvotes: 0