Avoiding Mistakes Made Using Axis2, Page 2
4 — Writing Correct services.xml For Service Group And Single Service
A service archive file can contain one or more services, but one service archive file can only have one services.xml file or rather one services configuration file. The simplest scenario is having one service inside an archive file. In that case services.xml can be written as one of the following format;
<service> <parameter name="serviceClass"> org.apache.axis2.MyService <parameter> <service>
I should note here that in the above, the case name of the service will always be the name of the archive file.
<serviceGroup> <service name="MyService"> <parameter name="serviceClass"> org.apache.axis2.MyService <parameter> <service> <serviceGroup>
In option 2 the name attribute of the service element is a mandatory attribute, and value of the name attribute become the name of the service and name of the service group will be the name of the archive file.
In the case of multiple services in one service archive (service group) case, the services.xml file should look like option 2 and should contain <service name=""> </service> for each of the services in the archive file. Each of the services will be named using the value of the name attribute corresponding to its service element. As an example, if the service archive file contains two services then services.xml should look like below:
<serviceGroup> <service name="ABC"> <parameter name="serviceClass"> org.apache.axis2.ABCService <parameter> <service> <service name="XYZ"> <parameter name="serviceClass"> org.apache.axis2.XYZService <parameter> <service> <serviceGroup>
5 — Relating wslds And Services in a Service Archive File
As discussed in the previous section the problem of getting a completely different wsdl files at the runtime can be solved by putting the original wsdl file in to an archive file. So if you are interested in seeing the same wsdl at the run time, then you have to put the wsdl file into META-INF directory in the service archive file in which case, you can name the wsdl file the way you want. There are, however, some rules that need to be followed if you try to put the original wsdl into a service archive.
Rule 1: In the case of single service archive case (service archive contain only one service), then as discussed above name of the service always be the name of the archive file. Then name of the service archive file should be the name of the service element in the wsdl (local name), as an example if the wsdl look like follows,
<wsdl:definitions xmlns:wsdl=http://schemas.xmlsoap.org/wsdl/ ..> <wsdl:types> <xs:schema targetNamespace="http://org.apache.axis2/xsd" > </xs:schema> </wsdl:types> <wsdl:portType name="MyPort"> </wsdl:portType> <wsdl:binding name="MyBiding" type="tns: MyPort"> </wsdl:binding> <wsdl:service name="MyService"> <wsdl:port name=" MyPort " binding="tns: MyBiding "> <soap:address location="http://127.0.0.1:3502/axis2/services/MyService " /> </wsdl:port> </wsdl:service>
In this case the name of the service archive should be MyService.aar , then only the correct mapping will taken place and user can get the same wsdl that he used to generate the service.
Rule 2: In the case of a service group, you can put more than one (depending on the requirement) wsdl file and you can relate them using the same logic discussed in Rule 1. As an example if you have two wsdl files, and its service elements are named foo" and bar" respectively then the services.xml file should look like as follows
<serviceGroup> <service name="foo"> . </service> <service name="bar"> . </service> </ serviceGroup>
6 — Parameters and Properties
Axis2 has two hierarchies called description hierarchy (static data) and context hierarchy (dynamic data). Static data are the data that are coming from different descriptors like axis2.xml, services.xml and module.xml, while dynamic data are populated and used at the run time. Parameters are designed to be used as static data, and they can be defined in anywhere in the above description files. Most of the time parameters are to configure the system. You can use parameters at the run time as well. For example if a service wants to write data to a file, then the name of the file can be taken from parameters, and some other use case can be database parameters for a module like WS-transaction. The way of defining a parameter in any of the descriptors is as follows:
<parameter name="myPara" locked="flase">Any XML junk, String, int , etc</parameter>
You should note that parameters are designed to store primitive data types such as String or int double and OM elements, NOT any type of objects. However, it is not invalid to store any types of object inside a parameter but that is not the right way to follow.
Properties are designed to share data across run time environment, and value of the property can be any type. So main difference between parameters and properties is, parameters are stayed in description hierarchy and properties are stayed in context hierarchy. The simplest usage of a property could be to share data between two handlers in the execution chain, one handler can set some property in the message context and some other handler can perform some validation depending on that property.
Most of the time users are trying to misuse properties and parameters, and they trying to access them in the wrong way. For example, they define parameters in a description file and trying to access them as properties at runtime. In this case, they won't get the required result. Rather, most of the time a null point exception results. At runtime what you have is message context, so message context has to access them separately.
Object obj = msgCtx.getProperty(String key); Parameter parameter = msgCtx.getParameter(String key);
7 — Service and Module Isolation
In Axis2 both the services and modules are said to be isolated, meaning each of them has their own classloaders. Service isolation (module isolation as well) is a very important feature in real time environment where if two different services want to use two different version of some third party library. How can they achieve their goals unless they have separate class loading mechanisms? What happens if the two versions are put into the same location? Since the full qualified name (including package name) of the two classes are the same in the both the versions, which will be picked by the Thread Context Class Loader (TCCL)?
You can't initialize two versions of the same class in one JVM, therefore Axis2 introduced service isolation to tackle this problem. If you want to use two versions of the same third party library then put them into service archive file so that the two services will be able to load without having any problems.
It should not that if you put some resources in a side service archive file (say foo), then you cannot directly access those resources from some other location. You have get foos classloader and the load the resources using that.
There are a few ways to access resources in a service archive:
Option 1: If you are trying to access the resources outside of the service implementation class (for example, if you trying to initialize a service implementation class at the message receiver level) then the correct way follows:
First get the corresponding AxisService , since class loader reference is there in the AxisService.
AxisService service = msgCtx.getAxisService();
Next get its class loader,
ClassLoader loader = service.getClassLoader ();
If you want to load or initialize some class in the archive file
Class servicClass =Class.forName(MyServiceClass" , loader,true);
If you want to read a resource file in it, then
Option 2: Inside service implementation class or any classes loaded by the service class loader, then the correct way of accessing the class loader is:
ClassLoader loader = getClass().getClassLoader();
Using this loader you can load resources, load classes, and more.
You should note that when a service deploys in the system and when it get initialize in axis2, all the classes in the archive file are loaded using the class loader created for that particular service, and it parent class loader may either be TCCL or a system class loader (Class loader common to both services and modules) in addition to that class loading taken place in child first technique.
It should be noted that any classes or resources in either module or service cannot be access using TCCL, since service resources are not visible through TCCL.