Affects Version/s: 1.0 RC1, 1.0 RC2, 1.0 final, 1.0.1, 1.0.2, 1.1 RC1, 1.1 RC2, 1.1 final, 1.1.1, 1.1.2, 1.1.3, 1.1.4, 1.1.5, 1.2 RC1, 1.2 RC2, 1.2 final, 1.2.1, 1.2.2, 1.2.3, 1.2.4, 1.2.5, 1.2.6, 1.2.7, 1.2.8, 2.0 M1, 2.0 M2, 2.0 M3, 2.0 M4, 2.0 M5, 2.0 RC1, 2.0 RC2, 2.0 RC3, 2.0 RC4, 2.0 final, 2.0.1, 2.0.2, 1.2.9, 2.0.3, 2.0.4, 2.0.5, 2.0.6, 2.0.7, 2.0.8, 2.1 M1, 2.1 M2, 2.1 M3, 2.1 M4, 2.5 RC1, 2.5 RC2, 2.5 final, 2.5.1, 2.5.2, 2.5.3, 2.5.4
Fix Version/s: 3.0 M3
Last commented by a User:false
Current approach in CachedIntrospectionResults is to cache "weakly" classes that are supposed to be "not cache-safe".
This unfortunately causes that "weakly" cached introspection results can expire on gc.
Rebuilding cached introspection results is costly in environments where there are lots of classes on a classpath.
What is more rebuilding cause multi-threaded applications to synchronize on rebuilding. That cause significant drops in performance for periods of rebuilding which is not acceptable.
This had been observed with JMeter running against some portal installation and diagnosed with YJP 7.5 profiler.
Maybe it is not common approach to put spring jars on a server classpath, but it will become more and more common with environments (OSGi for instance) where spring is a part of a platform.
So putting spring jar on a server classpath cause all application classes not to be cache-safe.
Workaround that forces applications to register it classloaders as cache-safe explicitly does seem a wrong solution for a problem to me.
I propose a different approach where unloading of cached introspection results is triggered by unloading a classloader.
It has two of benefits compared to existing solution.
1. Application do not need to register and unregister their classloaders.
2. Introspection results are persisted as long as application is loaded and do not expire on GC.
3. Cached introspection results expire when application is unloaded.
Modified CachedIntrospectionResults class from 2.0 version renamed to CachedIntrospectionResults2 follows as proposed solution.
Note that I've decided to use 2.0 version because I see improvements done in later version as a step in a wrong direction.
As you can see implementation is straight-forward and does not require any registration/unregistration of classloaders, and isCacheSafe method had been removed entirely (all classes are regarded as cache safe).
Also I've proven (at least locally on my laptop) that solution works with test below.
To run test below you need to change some private members of CachedIntrospectionResults to public access.
Also you will need to give some jar with some class to test against it (here mysql jdbc driver had been used).
Tested on jdk1.5.0_10 SUN Linux (Centos 5.0)
I plan to test this solution further on a staging environment for my current project and I will post results.