Tuesday, September 15, 2009

Avoid Jar Indexing

If your classpath includes jars that are indexed then performance of service factory lookup can be severely impacted. You should avoid using indexed jars. During a quick scan of built-in JRE jars I saw no sign of jar indexing so it appears not particularly important to use. If the JRE doesn’t find it useful then perhaps we shouldn’t either.

The problem relates to caching of information in the classloader infrastructure. The service factory lookup algorithm performs a global search through the classpath for a particular resource (javax.xml.parsers.SAXParserFactory for example). Observation of system behavior and a brief examination of the JRE code suggest that this lookup is cached for jars. This means after the first lookup subsequent lookups perform no further file system activity. This caching helps reduce the cost of subsequent service factory lookups. In the case of indexed jars, however, I noticed that this caching breaks down. Information from dependant jars that are referenced through a jar index doesn’t seem to get cached correctly. This means that for every single service factory lookup the jars referenced through the index are physically scanned again for the resource. This can cause a lot of additional file system activity.

I noticed the problem when working with Jersey and JAXB. It turns out that certain usage patterns of Jersey and JAXB can result in a very high number of service factory lookups (for SAXParserFactory) and those lookups are extra slow if you happen to have an indexed jar in your classpath. In this case there were two issues compounding each other to become an obvious performance problem when each on their own might go unnoticed. Without excessive factory lookups or without indexed jars then the problem is not nearly so noticeable. With both, however, you end up with lots of extra file system activity that definitely impacts performance.

It is interesting to note how I ended up in this situation. Previous to this I wasn’t even aware of jar indexing. I was using maven to build my project and decided that I wanted to add some manifest information to my jar. I searched the internet and found an example of creating a jar manifest with maven. I proceeded to cut and paste the sample into my own project. Unfortunately it just so happened that the sample also requested jar indexing. Oops, now my performance was worse. I fear anyone else that finds this same sample could encounter the same problem and not even know.

No comments:

Post a Comment