PDA

View Full Version : WebServices using Axis, What am I missing ?


frodeh
Oct 12th, 2004, 02:46 AM
I have tried to expand the 4-step tutorial by making the increase-price into a web-service. I have used the JPetStore as basis for figuring out what to do.

I have created a inteface :

package server;

import bus.Product;


public interface ProductManagerService {
public void increasePrice(int pct) ;

public Product getProduct(int id);


}


and a remote one :

package server;

import bus.Product;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface RemoteProductManager extends Remote {


public void increasePrice(int pct) throws RemoteException;

}



I have implemented the first interface into Product manager :
public class ProductManager implements Serializable,ProductManagerService {


Created the class reffered to in axis :
package server;

import org.springframework.remoting.jaxrpc.ServletEndpoin tSupport;
import bus.ProductManager;


public class JaxRpcProductManager extends ServletEndpointSupport
implements RemoteProductManager, ProductManagerService {
private ProductManagerService prodman;

protected void onInit() {
System.out.println("Initiating ProductManager for RPC");
this.prodman = (ProductManagerService) getWebApplicationContext().getBean("prodMan");
}
public void increasePrice(int pct) {
System.out.println("Increasing price");
prodman.increasePrice(pct);
}



}

I also added the axisi-servlet to the web.xml (same way as in JPetStore).
I created the server-config.wsdd and added this :

<service name="ProductManager" provider="java:RPC">
<parameter name="allowedMethods" value="*"/>
<parameter name="className" value="server.JaxRpcProductManager"/>
<beanMapping qname="springtut:Product" xmlns:springtut="urn:springtut" languageSpecificType="java:bus.Product"/>
</service>

The bean-mapping for product was added as an next-step expansion to a method : getProduct
and for verifying that the autogenerated wsdl-file looks good.

All of this makes the axis work fine, The servlet generates the correct responeses for all web-requests I make :
/springapp/axis
/springapp/axis/ProductManager
/springapp/axis/ProductManager?wsdl

Nothing wrong so far...

Until I try to access the service....

I test it using the DynamicInvoker-sample from the latest axis-distro (this is a nice utility for testing WebServices..)

I get a response like this :

C:\development\axis-1_2RC1>java samples.client.DynamicInvoker http://localhost:8080/springapp/axis/ProductManager?wsdl increasePrice 10
Reading WSDL document from 'http://localhost:8080/springapp/axis/ProductManager?wsdl'
Preparing Axis dynamic invocation
Executing operation increasePrice with parameters:
pct=10
Exception in thread "main" AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}stackTrace:java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?
at org.apache.axis.message.SOAPFaultBuilder.createFau lt(SOAPFaultBuilder.java:221)
at org.apache.axis.message.SOAPFaultBuilder.endElemen t(SOAPFaultBuilder.java:128)
at org.apache.axis.encoding.DeserializationContext.en dElement(DeserializationContext.java:1077)
at org.apache.xerces.parsers.SAXParser.endElement(SAX Parser.java:1403)
at org.apache.xerces.validators.common.XMLValidator.c allEndElement(XMLValidator.java:1550)
at org.apache.xerces.framework.XMLDocumentScanner$Con tentDispatcher.dispatch(XMLDocumentScanner.java:11 49)
at org.apache.xerces.framework.XMLDocumentScanner.par seSome(XMLDocumentScanner.java:381)
at org.apache.xerces.framework.XMLParser.parse(XMLPar ser.java:1098)
at javax.xml.parsers.SAXParser.parse(Unknown Source)
at org.apache.axis.encoding.DeserializationContext.pa rse(DeserializationContext.java:225)
at org.apache.axis.SOAPPart.getAsSOAPEnvelope(SOAPPar t.java:645)
at org.apache.axis.Message.getSOAPEnvelope(Message.ja va:424)
at org.apache.axis.handlers.soap.MustUnderstandChecke r.invoke(MustUnderstandChecker.java:62)
at org.apache.axis.client.AxisClient.invoke(AxisClien t.java:173)
at org.apache.axis.client.Call.invokeEngine(Call.java :2737)
at org.apache.axis.client.Call.invoke(Call.java:2720)
at org.apache.axis.client.Call.invoke(Call.java:2396)
at org.apache.axis.client.Call.invoke(Call.java:2319)
at org.apache.axis.client.Call.invoke(Call.java:1776)
at samples.client.DynamicInvoker.invokeMethod(Dynamic Invoker.java:237)
at samples.client.DynamicInvoker.main(DynamicInvoker. java:114)

{http://xml.apache.org/axis/}hostname:fh_lt

java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?
at org.apache.axis.message.SOAPFaultBuilder.createFau lt(SOAPFaultBuilder.java:221)
at org.apache.axis.message.SOAPFaultBuilder.endElemen t(SOAPFaultBuilder.java:128)
at org.apache.axis.encoding.DeserializationContext.en dElement(DeserializationContext.java:1077)
at org.apache.xerces.parsers.SAXParser.endElement(SAX Parser.java:1403)
at org.apache.xerces.validators.common.XMLValidator.c allEndElement(XMLValidator.java:1550)
at org.apache.xerces.framework.XMLDocumentScanner$Con tentDispatcher.dispatch(XMLDocumentScanner.java:11 49)
at org.apache.xerces.framework.XMLDocumentScanner.par seSome(XMLDocumentScanner.java:381)
at org.apache.xerces.framework.XMLParser.parse(XMLPar ser.java:1098)
at javax.xml.parsers.SAXParser.parse(Unknown Source)
at org.apache.axis.encoding.DeserializationContext.pa rse(DeserializationContext.java:225)
at org.apache.axis.SOAPPart.getAsSOAPEnvelope(SOAPPar t.java:645)
at org.apache.axis.Message.getSOAPEnvelope(Message.ja va:424)
at org.apache.axis.handlers.soap.MustUnderstandChecke r.invoke(MustUnderstandChecker.java:62)
at org.apache.axis.client.AxisClient.invoke(AxisClien t.java:173)
at org.apache.axis.client.Call.invokeEngine(Call.java :2737)
at org.apache.axis.client.Call.invoke(Call.java:2720)
at org.apache.axis.client.Call.invoke(Call.java:2396)
at org.apache.axis.client.Call.invoke(Call.java:2319)
at org.apache.axis.client.Call.invoke(Call.java:1776)
at samples.client.DynamicInvoker.invokeMethod(Dynamic Invoker.java:237)
at samples.client.DynamicInvoker.main(DynamicInvoker. java:114)


I get the same message in the server-logs.

Also make note that the line "Initiating ProductManager.." never shows up in any log, as it does when I add the same line in JPetStore.

So now my question is : What am I missing ??

frodeh
Oct 13th, 2004, 04:24 AM
:idea:
It seems that I also have to create the servlet-definition (in web.xml) :

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/dataAccessContext-local.xml /WEB-INF/applicationContext.xml
</param-value>
</context-param>

<servlet>
<servlet-name>context</servlet-name>
<servlet-class>org.springframework.web.context.ContextLoaderServl et</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>


In my last attempt I also moved some definitions out of the springapp-servlet.xml into those two new configuration-files as well as moving the jdbc-parameters into a seperate properties-file.

Now my response is :


C:\development\axis-1_2RC1>java samples.client.DynamicInvoker http://localhost:8080/springapp/axis/ProductManager?wsdl increasePrice 10
Reading WSDL document from 'http://localhost:8080/springapp/axis/ProductManager?wsdl'
Preparing Axis dynamic invocation
Executing operation increasePrice with parameters:
pct=10

Done!
And the prices is updatet. :D

The key element here was probably the context-servlet I added in web.xml

Since the docs on this subject still is missing, my next step is to start removing elements I suspect has been coded for the other three remoting-scenarioes.

To make the springapp into a web-service would be a great addon to the existing tutorial. Best seperated into two paths: one for using jaxrpc and one for the other three remoting-methods (Hessian, Burlaup and HTTP-invoker) since those uses the same code... [/quote]

Juergen Hoeller
Oct 19th, 2004, 08:33 AM
Indeed, your Spring root application context has to be loaded before your Axis servlet.

On Servlet 2.4 and most Servlet 2.3 containers, ContextLoaderListener will be fine to achieve this. On older servers, you might need ContextLoaderServlet, for example for WebLogic 8.1 (at least its early versions) and WebSphere 5.

Effectively, ContextLoaderServlet will work on all web containers (that's why all our sample apps use it); it is just less elegant. As of Servlet 2.4, ContextLoaderListener is the recommended strategy.

Juergen

frodeh
Oct 19th, 2004, 10:06 AM
Thanks.
An example of the listener would be nice...

And, as I now am relatively well into my project, I have another 'problem' regarding the integration Spring-Axis.

My application has a web-interface which uses some validation-classes (implements validator), and this class is invoked by the spring-servlet (i suspect).

How can I reuse this validator on an instance created from a Axis-request ?

Regards
Frode Halvorsen

frodeh
Oct 22nd, 2004, 02:31 AM
The validator was relatively easy to use, I found the code for this in another discussion : http://forum.springframework.org/showthread.php?t=10964

But how do I 'bind' the data from the source-object (instanciated and populated by axis) to my spring-managed bean ? Like the spring-servlet does with request-command?

I would hope there is an easier way than manually copying every property between those objects.

Regards
Frode

yrgo
Nov 22nd, 2004, 12:20 PM
I have also problems with cofnfiguring AXIS.

Although I should be doing everything the same way as described here I'm not able to get the automatic wsdl generating to work (requests to /services/myservice?wsdl return status code 404) . But requests to /axis or /axis/myservice return correct result.

What could possible cause this kind of behaviour?

My web.xml:

<listener> <listener-class>org.springframework.web.context.ContextLoaderListe ner</listener-class>
</listener>
<servlet>
<servlet-name>springapp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>axis</servlet-name>
<servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>
<load-on-startup>5</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>axis</servlet-name>
<url-pattern>/axis/*</url-pattern>
</servlet-mapping>

server-config.wsdd file:

<service name="PrivacyProfileService" provider="java:RPC">
<parameter name="allowedMethods" value="*"/>
<parameter name="className" value="com.mgine.privacyprofile.service.server.JaxRpcPriv acyProfileService"/>
</service>
<service name="Version" provider="java:RPC">
<parameter name="allowedMethods" value="getVersion"/>
<parameter name="className" value="org.apache.axis.Version"/>
</service>

Thanks!

Gideon
Nov 22nd, 2004, 12:38 PM
Hi,


<servlet-mapping>
<servlet-name>axis</servlet-name>
<url-pattern>/axis/*</url-pattern>
</servlet-mapping>




this should be correct because you tell the Axis Sevlet to listen on: /axis/*
and not on /services/*

mfg Gideon

yrgo
Nov 24th, 2004, 07:51 AM
Thanks!

It seems that the service list page generated by AXIS has invalid links to WSDL files. For some reason it tries to find them from /services/* whereas they are under axis/.

I also had one jar file missing on my classpath on client side which caused the exception being thrown.

roarjo
Dec 9th, 2004, 02:44 AM
Axis servlet do not load.
Have deployed the jpetstore application and observed it exposes the axis services perfectly.
So it should be straight forward to compile a similar web.xml to load the axis servlet for another Spring application myapp:
<servlet>
<servlet-name>context</servlet-name>
<servlet-class>org.springframework.web.context.ContextLoaderServl et</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>myapp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet>
<servlet-name>axis</servlet-name>
<servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>myapp</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>axis</servlet-name>
<url-pattern>/axis/*</url-pattern>
</servlet-mapping>

Whatever I try in the browser for url = .../myapp/axis/*
tomcat responds: HTTP Status 404 - Servlet axis is not available

What am I missing?

Thanks

roarjo
Dec 9th, 2004, 04:01 AM
My problem was due to a missing .jar, don't know exactly which.
With all .jars from jpetstore Axis now responds correctly.

lkjairath@yahoo.com
Jan 27th, 2005, 02:26 PM
could you please list all the steps for turning the step by step tutorial to a web service endpoint and client application. (including the diretories where you put the files and commands to use all the way.

Thx. in advance.

lkj

markm
Oct 18th, 2005, 10:23 AM
I've been trying to work through this example and am stuck at figuring out what is supposted to go inside the applicationContext.xml (and dataAccessContets-local.xml).

I can get the wsdl from the url http://localhost:8080/springapp/axis/ProductManager?WSDL
successfully.

I've added

<listener> <listener-class>org.springframework.web.context.ContextLoaderListe ner</listener-class>
</listener>

to the web.xml

When i call the service from DynamicInvoker i get

Exception in thread "main" AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: org.springframework.beans.factory.NoSuchBeanDefini tionException: No bean named 'prodMan' is defined: org.springframework.beans.factory.support.DefaultL istableBeanFactory defining beans []; root of BeanFactory hierarchy
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}hostname:MarkM

org.springframework.beans.factory.NoSuchBeanDefini tionException: No bean named 'prodMan' is defined: org.springframework.beans.factory.support.DefaultL istableBeanFactory defining beans []; root of BeanFactory hierarchy

Can anybody tell me what's supposed to go inside the applicationContext.xml file?

Thanks,

Mark

incubator
Oct 21st, 2005, 07:56 AM
also can someone tell how you configure a webapp client for the webservice?
jpetstore only uses a regular application, not a web app.

I tried deploying one on jboss but got an eexception from axis that there was no engine configuration file found (when deployong the client web app).
A regular client application seems to work fine to call the service