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.

10 comments:

  1. Hello Shivendra,

    I have upgraded the Axis2 client to 1.6 but still I am facing the prolem with tmp files not getting deleted. Can you please let me know how to how to invoke TempFileManager to manage these temp file?

    Regards,
    Amber Gupta

    ReplyDelete
    Replies
    1. You don't need to invoke TempFileManager explicitly. Could you post your relevant code and state the problem you are facing.

      Delete
    2. Hi..I have the same problem Amber..Could you tell me if you found the solution for it.. Thanks

      Delete
  2. HI Shivendra,

    I am using axis 1.6, problem with my code is that java is not recognizing ListenerManager.defaultConfigurationContext
    there is no such field as defaultConfigurationContext in Listenermanager. Can you tell me in which jar will I find the correct Listenermanager

    ReplyDelete
  3. Yes, excellent analysis of the Axis2 memory leak issue. My only concern is that a JVM shutdown implies a server shutdown and that is not an option you want to always revisit on a production server.

    ReplyDelete
    Replies
    1. Thank, You are correct JVM shutdown is not an option in production. You could avoid new temp file creation on every call by reusing configurationContext. Which could be done by calling default construct new ServiceClient() while invoking remote service.

      Delete
    2. As per your comment, problem can be solved by "Which could be done by calling default construct new ServiceClient() while invoking remote service.".


      Can you provide a sample code to resolve it programatically at the client side itself with 1.6.1 axis2 version.

      Delete
  4. This comment has been removed by the author.

    ReplyDelete
  5. Can we do like this, create a ConfigurationContext only once in a static block and use it in all the subsequent calls.

    ReplyDelete