Groovy class loaders and script engine tweaks to reduce leaks#856
Conversation
WalkthroughChangesThe PR adds an optional script-factory destruction lifecycle, closes Groovy classloaders during configuration replacement and teardown, and integrates script cleanup into site context destruction and creation failure handling. Context rebuilds now log destruction failures without aborting the rebuild. Script and site lifecycle cleanup
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant SiteContextManager
participant SiteContext
participant GroovyScriptFactory
participant GroovyClassLoader
SiteContextManager->>SiteContext: destroy previous context
SiteContext->>GroovyScriptFactory: destroy()
GroovyScriptFactory->>GroovyClassLoader: close active loader
SiteContext->>SiteContext: close parent classLoader
SiteContextManager->>SiteContextManager: log destruction failure and continue rebuild
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/main/java/org/craftercms/engine/service/context/SiteContextFactory.java (1)
351-364: 🩺 Stability & Availability | 🔴 Critical | ⚡ Quick winAssign resources to
siteContextimmediately to ensure cleanup on failure.If an exception is thrown by methods like
getApplicationContextorgetUrlRewriter, the newly createdclassLoader,scriptFactory, andappContextwill leak. Because they are currently assigned tositeContextat the end of the block,siteContext.destroy()in thecatchblock will see these fields asnulland skip their cleanup.Assign them immediately after creation so the error-handling block can successfully release them.
🐛 Proposed fix
URLClassLoader classLoader = getClassLoader(siteContext); + siteContext.setClassLoader(classLoader); ScriptFactory scriptFactory = getScriptFactory(siteContext, classLoader); + siteContext.setScriptFactory(scriptFactory); ConfigurableApplicationContext appContext = getApplicationContext(siteContext, classLoader, config, resolvedAppContextPaths, resourceLoader); + siteContext.setApplicationContext(appContext); UrlRewriter urlRewriter = getUrlRewriter(siteContext, resolvedUrlRewriteConfPaths, resourceLoader); HierarchicalConfiguration proxyConfig = getProxyConfig(siteContext, resolvedProxyConfPaths, resourceLoader); HierarchicalConfiguration translationConfig = getTranslationConfig(siteContext, resolvedTranslationConfPaths, resourceLoader); - siteContext.setScriptFactory(scriptFactory); siteContext.setConfig(config); siteContext.setGlobalApplicationContext(globalApplicationContext); - siteContext.setApplicationContext(appContext); - siteContext.setClassLoader(classLoader); siteContext.setUrlRewriter(urlRewriter);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/java/org/craftercms/engine/service/context/SiteContextFactory.java` around lines 351 - 364, Update the site-context initialization flow around getClassLoader, getScriptFactory, and getApplicationContext to assign each newly created resource to siteContext immediately after creation. Ensure the catch-path siteContext.destroy() can clean up resources if a later call such as getUrlRewriter or getProxyConfig fails, and remove or avoid relying on the deferred assignments at the end of the block.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@src/main/java/org/craftercms/engine/service/context/SiteContextFactory.java`:
- Around line 351-364: Update the site-context initialization flow around
getClassLoader, getScriptFactory, and getApplicationContext to assign each newly
created resource to siteContext immediately after creation. Ensure the
catch-path siteContext.destroy() can clean up resources if a later call such as
getUrlRewriter or getProxyConfig fails, and remove or avoid relying on the
deferred assignments at the end of the block.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 37aea899-b0d6-4abc-8efc-68479ff2e817
📒 Files selected for processing (6)
src/main/java/org/craftercms/engine/scripting/ScriptFactory.javasrc/main/java/org/craftercms/engine/scripting/impl/GroovyScriptFactory.javasrc/main/java/org/craftercms/engine/service/context/SiteContext.javasrc/main/java/org/craftercms/engine/service/context/SiteContextFactory.javasrc/main/java/org/craftercms/engine/service/context/SiteContextManager.javasrc/test/java/org/craftercms/engine/scripting/impl/GroovyScriptFactoryTest.java
…erly release on failure
|
@coderabbitai review |
✅ Action performedReview finished.
|
Groovy class loaders and script engine tweaks to reduce leaks
https://github.com/craftersoftware/craftercms/issues/1266