All right, I dug more into this.
(UN)Marshallers will get their class loader from invocation context, if present. At least that's what's happening in my case.
What I'm struggling with - is that I want to *always* use the thread's context classloader for any class look-up operations. And I just can't seem to find a way to do it.
When an invocation context is being associated with the class loader, the rule is this:
a) If configuration has a !null class loader, use it
b) if global configuration has a !null class loader, use it
c) use thread.contextClassLoader
I tried creating a classloader that will delegate resolveClass() to Thread.contextClassLoader (and assigning it to individual configuration objects for caches), but that doesn't work because of how Class.forName0() is implemented (classes actually attach to my classloader, instead of the one I delegate to)
I tried setting 'null' class loader to 'global' configuration, but that causes a NPE when component registry initializes (that's probably a bug as well)
I thought of providing my own instances of GlobalConfiguration/Configuration objects that will return Thread.currentClassLoader from classLoader() method, but these classes can not be extended.
It doesn't seem possible without meddling with Infinispan source, which I'd rather avoided...
1 of 1 people found this helpful
you can configure the class loader in use directly through the API, by using cache.getAdvancedCache().with(ClassLoader cl)
Thank you mircea.markus wish I knew this earlier
Still facing a couple of issues:
One, is that entrySet() leaves the objects hanging (so a wrong class loader can get them), but I probably can re-compact the cache when I know class loader is about to change.
Two, I use Enum keys. It seems when the cache entries are looked up using those keys, and the keys come from Enum values from 2 different class loaders, the keys don't match. That's likely because Enum.equals() returns simply this==other. So I need to provide a custom Equality implementation to compare enums in a more portable way.
Doing both these things helped. Calling cache.compact() after an entry set makes sure no object references are dangling around.
Using custom configuration object, set my own Equivalence implementation (cb.dataContainer().keyEquivalence(myEquivalence)), so now data moves fine between class loaders, when needed.