Axis FAQ

These questions seem to be frequently asked:


What is Axis? What is its relationship to Apache SOAP?
Axis is essentially Apache SOAP 3.0. It is a from-scratch rewrite, designed around a streaming model (using SAX internally rather than DOM). The intention is to create a more modular, more flexible, and higher-performing SOAP implementation (relative to Apache SOAP 2.0).
Why call it "Axis"?
The name "Axis" was chosen because, when the project started, the XML Protocol working group had not chosen a name for its protocol. The intent was for Axis to support SOAP 1+, XML-RPC, and XMLP (whatever it wound up being called), so calling it "Apache SOAP 3.0" would have missed the mark. Recently, the XML Protocol working group decided to retain the SOAP name, so perhaps it would have been better to keep Axis as part of the Apache SOAP project. C'est la vie.

(According to the README, Axis stands for "Apache eXtensible Interaction System", which could mean almost anything.)

Is Axis close to a release of some kind?
The first beta was released on March 15, 2002, the second on April 29, 2002, and the third on July 9, 2002. We are hoping for a 1.0 release in the Summer of 2002.
What is Axis's status overall?
To keep track of Axis's progress:
Why do some classes fail to load under Tomcat?
Tomcat will not load classes with package names starting "java." or "javax." from the WEB-INF directory. jars containing such classes need to be installed in $TOMCAT_HOME/common/lib rather than in WEB-INF/lib. Currently (April 25, 2002) jaxrpc.jar is such a jar.
What if I can't find the answer to my question here?
Try the mailing lists.
How do I report bugs?
See bugs.
How does Axis create my backend service objects?  Can I control this?
Axis supports a "scope" parameter on services, which can be set to "request" (make a new object to service each request - this is the default), "session" (associate a new object with each session), and "application" (all users share a singleton object).  WARNING: If you set the scope to "session" or "application", it is possible that multiple threads of control may attempt to access your object's methods at the same time. It is your responsibility to ensure that your objects are thread-safe in these cases.
So does Axis support sessions?
Yes.  We have a session abstraction which allows an extensible set of underlying implementations - take a look at the class org.apache.axis.session.Session for details.  In particular, we currently support sessions based on HTTP cookies and also transport-independent sessions based on SOAP headers.  It is up to some handler on the request chain to set up an appropriate Session implementation and attach it to the MessageContext with MessageContext.setSession() so that anyone who wants to use session semantics can get at it.
Cool, SOAP header-based sessions?  How do I make that work?
There is a Handler class called "org.apache.axis.handlers.  SimpleSessionHandler" which implements this functionality. You need to include this handler in the request and response flows of both your client and your server.  Take a look at our session test (test.session.TestSimpleSession) for an example.
What else can I do with sessions?
Any time after the session context has been established, calling getSession() on the current messageContext will obtain you a reference to a Session object.  You may use this object like a Hashtable to store arbitrary data associated with this Session.  For instance, on one request you might extract the caller's name and address from a database (an expensive operation), and then cache them in the Session object for fast access on subsequent invocations from the same caller.  This functionality can be used either by custom Handlers or by your backend service object itself.
How do I get access to the MessageContext in my service object?
Use the static MessageContext.getCurrentContext() method at any time during a method call on your object.
Where do I put my <typeMapping>/<beanMapping> information?
There are two places in the WSDD where type mappings are appropriate.  At the top level, just under <deployment>, they become global type mappings, and all services deployed in the Axis engine will be able to use them.  Alternately, you can place them inside your <service> tag, and then the mappings will only be accessible by that particular service.
What is the relationship between JAXM and Axis?
JAXM is a specification (NB. not an implementation) of two sets of interfaces: javax.xml.soap and javax.xml.messaging. Recently, the former set has been moved to its own specification, "SOAP with Attachments API for Java" (SAAJ), by Sun. Axis implements the SAAJ (javax.xml.soap) interfaces.
How does Axis figure out which deployed service to call?
Axis has a very flexible dispatch mechanism, with three built-in options, and the ability to customize your own.  Dispatch to a service in Axis really means setting the service field in the MessageContext as it flows through the various Handlers in your configuration.  Once the service is set, the engine will be able to call it at the appropriate time.  So who does the setting?  Any Handler who wants to.

The default dispatch mechanism for Axis is by URL, so that if you access http://myhost/axis/services/WeatherReport, you will get the "WeatherReport" service.  This mechanism works because the HTTP transport in Axis has the URLMapper (org.apache.axis.handlers.http.URLMapper) Handler deployed on the request chain.  The URLMapper takes the incoming URL, extracts the last part of it as the service name, and attempts to look up a service by that name in the current EngineConfiguration.

Similarly you could deploy the HTTPActionHandler to dispatch via the SOAPAction HTTP header.  You can also feel free to set the service in your own custom way - for instance, if you have a transport which funnels all messages through a single service, you can just set the service in the MessageContext before your transport calls the AxisEngine.  Or if you dispatch based on the contents of a SOAP header, or the time of day, you could write a Handler which did that.

If no Handler has set the service by the time someone needs to deserialize the SOAP message, we will attempt to look it up using the namespace of the first body element.  So for instance:

<SOAP:Body>
  <ns:MyMethod xmlns:ns="./axis/Weather"/>
</SOAP:Body>

This message would look up "./axis/Weather" in the namespace mapping list to see if there was an associated service.

How do I associate a namespace mapping with my service?
The WSDD for your service should look something like this:

<service name="MyService" provider="java:RPC">
  <namespace>http://my.com/MyServiceNamespace</namespace>
  ...
</service>
  

How do I set a timeout when using WSDL2Java stubs?

There is a setTimeout method on the org.apache.axis.client.Stub class, which is the class all emitted stubs extend.

Here is how to set the timeout given a service named Foo:

 FooServiceLocator loc = new FooServiceLocator();
 FooService binding = loc.getFooService();
 org.apache.axis.client.Stub s = (Stub) binding;
 s.setTimeout(1000);  // 1 second, in miliseconds
 

The default timeout in Axis 1.1 and later is 60 seconds. Axis 1.0 did not have a default timeout (i.e. it defaulted to 0). This timeout value is set on the HTTP socket and is not a connection timeout, which requires implementation we do not have as of Axis 1.1.

How do I set a header when using WSDL2Java stubs?

There are two styles of headers, explicit and implicit. Explicit headers are defined in the WSDL of the service. The WSDL2Java generation tool will recognize these headers in most cases and emit stub class methods that include the headers as arguments to the methods.

In other cases, you may want to set headers that are not explicitly called out in the WSDL. For instance, you want to do some custom processing in a handler or add security. In this case you can add headers to request before you invoke the stub method.

There are are two setHeader APIs on the org.apache.axis.client.Stub class. The first takes the namespace, name and value of the header.

setHeader(String namespace, String partName, Object headerValue)
The second takes a SoapHeaderElement:
setHeader(SOAPHeaderElement header)

Here is an example of using the first API

 FooServiceLocator loc = new FooServiceLocator();
 FooService binding = loc.getFooService();
 org.apache.axis.client.Stub s = (Stub) binding;
 s.setHeader("http://my.name.space/headers", "mysecurityheader", "This guy is OK");
 result = binding.myOperation(...);