Saturday, October 16, 2010

Dealing with low disk space problem caused by AXIS2 temp files

Recently I came across interesting scenario where axis2 modules jars file were getting created on every execution of axis2 client code. This was resulting in low disk space since temp directory was flooded with temp jars created by axis2. We can't avoid creation of these jars in temp dir since these are modules jars used by axis2 class loader to load modules class needed to engage axis2 modules. What we can difinitely do is reusing the generated jar files created on first use and deleted these temp file on JVM shut down.

Lets first see how to reuse the temp file generated.

As we know ConfigurationContext object created every time client tries to invoke the service or every time we create ServiceClient instance. To avoid this situation we need to cache ConfigurationContext class once created. We need to modify AXIS2 1.4 ServiceClient code as follows(Highlighted):

ServiceClient#configureServiceClient

if (configContext == null) {
if (ListenerManager.defaultConfigurationContext == null) {
configContext = ConfigurationContextFactory.
createConfigurationContextFromFileSystem(null, null);
ListenerManager.defaultConfigurationContext = configContext;
createConfigCtx = true;
} else {
configContext = ListenerManager.defaultConfigurationContext;
}
}

Now lets try to delete the single set of temp file on JVM shutdown.
AXIS2 engine does the write thing while creating these temp file. it also calls java.io.File#deleteOnExit which tells the JVM to delete these file on exit.
But unfortunately AXIS2 class loader will be referring these files so these could not be deleted by JVM(which is un resolved bug in JVM). To deal with it once you are done with using serviceclient. you have to call ServiceClient#cleanup. Cleanup method looks into temp folder start with _axis2 and deletes all files which are not referred by axis2 which may be present from previous JVM session.
The temp file created in one JVM session will be deleted not on JVM exit but in the nest session of JVM. When you invoke ServiceClient#cleanUp().

AXIS2 1.5 onward the startegy for dealing with temp file is improved. Here responsibility to manage temp files are delegated to class named TempFileManager instead of using java.io.File#createTempFile directly.

This uses TempFileManager#createTempFile which along with temp folder to contain the jars creates another file named tempFolderName suffixed by .lck. On both of these java.io.File#deleteOnExit is called. JVM will not be able to delete the temp folder containing the temp jars but it will be able to delete the .lck file on shout down. Since these is no reference to .lck file. Now on next start up when TempFileManager class is loaded it has static block which will look for all axis2 temp folder for which corresponding .lck file is not present.

The advantage is if you are using AXIS2 1.5 you don't need to call ServiceClient#cleanup to clean these temp file. It will be cleaned up on TempFileManager class loading.

Friday, October 15, 2010

Engaging modules in AXIS2 on client side

Engaging modules at client side gets quite frustrating when you have written stand alone client on eclipse. There are no. of ways you can do that. The easiest one is to change module extensions form .mar to .jar so that you can add them to eclipse class path. You don't have to make any other changes and you can engage module at client side programatically.

suppose you want to engage addressing module, then following code will be sufficient provided you have addressing.jar file in your class path.

ServiceClient sc = new ServiceClient();
sc.engageModule("addressing");

Now lets remove addressing jar from class path and try running the same code. You will get infamous "Unable to engage module : addressing"!

So what if I don't want to change the extension of modules. We need to pass location of module file while creating configuration context as follows.

ConfigurationContext configContext =
ConfigurationContextFactory.createConfigurationContextFromFileSystem("E:/LAB/apache/axis2-1.3-bin/axis2-1.3/repository","E:/LAB/apache/axis2_repo/axis2.xml");
ServiceClient sc = new ServiceClient(configContext,null);
sc.engageModule("addressing");

Engaging modules can be set globally when you pass axis2.xml while creating configuartion context. You need to uncomment <module ref="addressing"/> in axis2.xml. Now sc.engageModule("addressing"); is not needed to engage addressing module. Moreover if you don't want addressing feature for every client request comment <module ref="addressing"/> in axis2.xml and engage module by calling ServiceClient#engageModule when needed.

There is another way to provide modules information at runtime by setting :Constants.AXIS2_REPO and Constants.AXIS2_CONF config properties.

System.setProperty(Constants.AXIS2_REPO, "C:/MyFolder/MySoftwareLab/tools/axis2-1.5.1-bin/axis2-1.5.1/repository");
System.setProperty(Constants.AXIS2_CONF, "your local axis2 path");

Above works because of following code of AXIS2 engine.

if (repoLocation == null) {
//checking wether user has set the system property
repoLocation = System.getProperty(Constants.AXIS2_REPO);
}

if (axis2xml == null) {
// If not, check for a system property setting
axis2xml = System.getProperty(Constants.AXIS2_CONF);

Friday, October 1, 2010

Test your WSDL skills

I have compiled a list of WSDL question which can be used to test one's WSDL understanding. These questions may not cover each area in depth, but can be used to enhance basic understanding of WSDL.

1. What are the extensibilty element required to be added as WSDL extension in case of SOAP binding?

SOAP:Binding > messaging style and transport,
SOAP:Operation> SOAP action and SOAP message style(RPC/Document),
SOAP:body/SOAP:Header/SOAP:Fault > talks about message encoding style(encoded/literal), namespace of elements in body in case of SOAP encoded style,
SOAP:address > tells about web service end point

2. Which elements of WSDL take targetnamespace of WSDL definition?
message, portType, binding

3. Which elements of WSDL doesn't support extension?
message, portType

4. Can I define a schema in types element without targetNamespace?
No, TargetNamespace has to be not null.

5. Can I define targetNamespace of schema in types element different from targetNamespace of WSDL?
Yes, its perfectly legal as long as targetNamespace of schema is specified in definition or in definition of one of the imported WSDL.

6. What the WSDL imports used for?
WSDL import are meant only to import other WSDL and not for importing XML schema.

7. Can I have targetnamespace of imported WSDL different from namespace attribute of import element?

No, It must be same and namespace and location field of import element is mandatory.

8. What should be the sequence for WSDL types and WSDL import element?

Import element is present it should precedes types element.

9. Can I use xml schema import definition to import XML schema form types element of some other WSDL?

No, its not possible.

10. What are the message exchange pattern that an endpoint can support?

Request: endpoint receives a message
Request-Response: Endpoint receives message and send a correlated message.
Solicit-Response: Endpoint send a message and receives a correlated message.
Notification: Endpoint send a message.

11. Can request (one way) MEP send back fault?

No

12. Part definition refers to which part of fault message?

Details

13. Webservice server could not process soap message due to incorrect header, should it send back fault message with fault:detail populated?

No, Fault detail should be populated only if SOAP:Body element of incoming message has invalid data.

14. Can we have more than one binding for given portType?

Yes

15. Can binding element provide address information?

No

16. What are the different type of bindings supported in WSDL?

SOAP, HTTP, MIME. Though BP prohibits use of HTTP and MIME.

17. SOAP:body element has defined namespace attribute, can I tell which style of service it represents?

RPC

18. What is default style, in case style attribute is not mentioned in WSDL?

document

19. Can fault message can have multiple parts?

Fault message must have single part. Message style of soap fault is always assumed to be "Document" since fault don't contain parameters.