Class GshTemplateClassLoaderRegistry
java.lang.Object
edu.internet2.middleware.grouper.app.gsh.template.GshTemplateClassLoaderRegistry
Per-JVM cache of compiled GSH Java template classes, keyed by template
name (config id). Each cache entry holds the source hash that produced
the class, the dedicated ByteArrayClassLoader that defines its bytecode,
and the loaded Class object itself.
On resolve():
- If the cache has an entry for the template name AND the cached source
hash matches the new source's hash, return the cached Class. Statics
on that Class survive across executions.
- Otherwise compile the source via GshTemplateJavaCompiler, define the
bytecode in a fresh ByteArrayClassLoader, atomically swap the cache
entry, and return the new Class. The old loader becomes unreferenced
and is eligible for GC once any in-flight executions holding
references drain.
The registry does not read the source from anywhere — the caller (the
dispatcher in Phase 4b) reads it from inline config (javaTemplateSource)
or from a container file (javaTemplateSourceContainerPath) and hands the
source string in. The registry only cares about (templateName, source).
Concurrency:
- Cache hits are lock-free (ConcurrentHashMap reads).
- Cache misses serialize per template name via per-name lock objects, so
two threads invoking the same template at the same time compile once,
not twice; concurrent resolves of different templates run in parallel.
GRP-7010
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classOne template version's cache entry — the source hash that produced it, the classloader holding its bytecode, and the loaded class.static classOutcome of a resolve() call — either a cached/freshly-compiled class on success, or a parse error / compile diagnostics on failure. -
Method Summary
Modifier and TypeMethodDescriptionstatic voidClear all cached template classes.Resolve a template by name.
-
Method Details
-
resolve
public static GshTemplateClassLoaderRegistry.GshTemplateResolveResult resolve(String templateName, String javaSource) Resolve a template by name. If the cached source hash matches the new source, returns the cached Class. Otherwise parses the FQN from source, compiles, defines in a fresh ByteArrayClassLoader, swaps the cache entry, returns the new Class. On parse or compile failure, returns a failure result; never throws for user-input problems.- Parameters:
templateName- logical template name (config id); must be non-emptyjavaSource- Java source body (caller has already read it from inline config or a container file); must be non-null- Returns:
- result with the resolved class on success, or with parse-error / compile diagnostics on failure
-
clearCache
public static void clearCache()Clear all cached template classes. Hooked into GrouperCacheUtils.clearAllCaches() and called by tests between cases. After clear, every subsequently-resolved template will be recompiled from source on first access. Per-template static state is reset. The per-template lock map is intentionally NOT cleared — locks are stable per template name and clearing them during concurrent use would allow two threads to acquire different lock objects for the same template name and both compile in parallel. Locks accumulate at most one entry per distinct template name ever seen on this JVM, which is negligible.
-