Skip to content

ensure consistent use of context class loader#12579

Open
graemerocher wants to merge 4 commits into
5.0.xfrom
property-expression-resolver-fix
Open

ensure consistent use of context class loader#12579
graemerocher wants to merge 4 commits into
5.0.xfrom
property-expression-resolver-fix

Conversation

@graemerocher
Copy link
Copy Markdown
Contributor

@graemerocher graemerocher commented Mar 27, 2026

If an application is loaded with the alternative context loader there are cases where this context loader is not used. This addresses those cases.

Copilot AI review requested due to automatic review settings March 27, 2026 14:21
@graemerocher graemerocher added the type: improvement A minor improvement to an existing feature label Mar 27, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates service discovery to prefer the thread context class loader (with fallback), improving behavior in environments where services/resources are visible via TCCL rather than the defining class’ loader.

Changes:

  • Use TCCL as a fallback when loading PropertyExpressionResolver implementations.
  • Use TCCL (with null fallback) when loading access log LogElementBuilder implementations.
  • Initialize DefaultBeanIntrospector with TCCL (with fallback) to improve introspection reference discovery.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
inject/src/main/java/io/micronaut/context/env/DefaultPropertyPlaceholderResolver.java Prefer TCCL fallback for loading PropertyExpressionResolver services when environment isn’t an Environment.
http-server-netty/src/main/java/io/micronaut/http/server/netty/handler/accesslog/element/AccessLogFormatParser.java Load LogElementBuilder services using TCCL with fallback to the builder class loader.
core/src/main/java/io/micronaut/core/beans/DefaultBeanIntrospector.java Initialize default introspector’s classloader from TCCL with fallback.

Comment thread core/src/main/java/io/micronaut/core/beans/DefaultBeanIntrospector.java Outdated
@graemerocher
Copy link
Copy Markdown
Contributor Author

@copilot apply changes based on the comments in this thread

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 27, 2026

@copilot apply changes based on the comments in this thread

Applied in e5236a6 — renamed cl to classLoader in both DefaultBeanIntrospector.java and AccessLogFormatParser.java.

…ut-projects/micronaut-core into property-expression-resolver-fix
Copilot AI review requested due to automatic review settings March 27, 2026 15:22
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Comment on lines 81 to 83
exResolvers = new ArrayList<>(DEFAULT_EXPRESSION_RESOLVERS);
ClassLoader classLoader = (environment instanceof Environment e) ? e.getClassLoader() : environment.getClass().getClassLoader();
ClassLoader classLoader = (environment instanceof Environment e) ? e.getClassLoader() : fallbackClassLoader();
SoftServiceLoader.load(PropertyExpressionResolver.class, classLoader).collectAll(exResolvers);
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The class loader selection for PropertyExpressionResolver discovery changed to prefer the thread context class loader when environment is not an Environment. Please add a regression test that sets a custom TCCL with a test PropertyExpressionResolver service entry and verifies it is discovered/used, to prevent future regressions in this class-loader-sensitive behavior.

Copilot uses AI. Check for mistakes.
Comment on lines +98 to 103
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (classLoader == null) {
classLoader = LogElementBuilder.class.getClassLoader();
}
SoftServiceLoader<LogElementBuilder> builders = SoftServiceLoader.load(LogElementBuilder.class, classLoader)
.disableFork();
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Service loading of LogElementBuilder now prefers the thread context class loader in the static initializer. Please add a regression test that sets a custom TCCL with an additional LogElementBuilder via META-INF/services and asserts it is picked up (and also that the fallback works when TCCL is null), since this behavior is class-loader dependent and easy to break inadvertently.

Copilot uses AI. Check for mistakes.
@sonarqubecloud
Copy link
Copy Markdown

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

Labels

type: improvement A minor improvement to an existing feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants