Skip to content

LDEV-6240 skip findLoadedClass in EnvClassLoader, clear callerCache on RPC flush#2775

Open
zspitzer wants to merge 1 commit into
lucee:7.0from
zspitzer:LDEV-6240-v7
Open

LDEV-6240 skip findLoadedClass in EnvClassLoader, clear callerCache on RPC flush#2775
zspitzer wants to merge 1 commit into
lucee:7.0from
zspitzer:LDEV-6240-v7

Conversation

@zspitzer

@zspitzer zspitzer commented Apr 8, 2026

Copy link
Copy Markdown
Member

Summary

  • Remove findLoadedClass() from EnvClassLoader.loadClass() — it returns classes from the JVM's internal cache which cannot be cleared after a PhysicalClassLoader flush
  • Add clearCallerCache() to EnvClassLoader and call it from PhysicalClassLoader.flush() for RPC classloaders
  • After flush, stale classes from the old classloader caused isAssignableFrom failures in ServiceLoader and other JDK code

https://luceeserver.atlassian.net/browse/LDEV-6240

Detail

When a library loaded via JavaSettings (RPC PhysicalClassLoader) uses ServiceLoader.load(), the thread context classloader (EnvClassLoader) loads the SPI implementation class by delegating to the RPC PCL on the call stack. The JVM caches this in findLoadedClass() permanently.

After PCL flush (idle eviction, reinit, or rename ratio), a new PCL is created. New code loads the SPI interface from the new PCL, but EnvClassLoader.findLoadedClass() still returns the old implementation class. ServiceLoader checks isAssignableFrom between the two → fails → "not a subtype".

Fix: skip findLoadedClass() entirely (rely on callerCache which we control and can clear), and clear callerCache on RPC flush.

Test plan

  • test/tickets/LDEV6240.cfc — 5 tests all passing
  • Test 4 auto-detects whether clearCallerCache() exists and verifies it works

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant