Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revise ClassLoader lookups across the platform #806

Open
3 tasks
sbrannen opened this issue Apr 25, 2017 · 4 comments
Open
3 tasks

Revise ClassLoader lookups across the platform #806

sbrannen opened this issue Apr 25, 2017 · 4 comments

Comments

@sbrannen
Copy link
Member

sbrannen commented Apr 25, 2017

Overview

Although current use of ClassLoaderUtils.getDefaultClassLoader() works for the most common class loading scenarios, it is not always appropriate to default to using the thread context ClassLoader (TCCL) when loading user types via reflection.

This issue is inspired by the issues discussed in #805 and serves as an umbrella issue for potential class loading issues across the platform.

Related Issues

Comparison to class loading in Spring

If we take inspiration from the Spring Framework, we can see that org.springframework.util.ClassUtils.forName(String, ClassLoader) accepts a user-supplied ClassLoader and falls back to the "default ClassLoader" only if the supplied ClassLoader is null. For loading services, Spring does not use Java's ServiceLoader mechanism but rather its own SpringFactoriesLoader which performs the same task as Java's ServiceLoader but with explicit control over which ClassLoader is used. Note that SpringFactoriesLoader delegates to org.springframework.util.ClassUtils.forName(String, ClassLoader) to actually load the service class.

Initial Analysis

JUnit does not necessarily need the flexibility of SpringFactoriesLoader, but for certain scenarios we will likely have to supply a custom ClassLoader instead of relying on the "default ClassLoader" which currently is typically the thread context ClassLoader (TCCL).

Supplying getClass().getClassLoader() is likely a viable option. However, we should not change the implementation of ClassLoaderUtils.getDefaultClassLoader(). Rather, we should simply use it less often and then only as a fallback.

FWIW, we actually did have the foresight to create org.junit.platform.commons.util.ReflectionUtils.loadClass(String, ClassLoader), but... we never supply it anything other than the default ClassLoader. 😉

Use Cases to Investigate

The following use cases should be investigated to determine how best to look up the ClassLoader to use.

  • TestEngine loading in ServiceLoaderTestEngineRegistry
  • TestExecutionListener loading in ServiceLoaderTestExecutionListenerRegistry
  • Jupiter Extension loading in ExtensionRegistry#registerAutoDetectedExtensions
  • Additional classpath entries in ConsoleTestExecutor#createCustomClassLoader
  • ClasspathScanner configuration/instantiation in ReflectionUtils
  • ReflectionUtils#loadClass(String)

Deliverables

  • For each of the aforementioned Use Cases to Investigate, determine how best to look up the ClassLoader.
  • Use the ClassLoader for the current framework class (e.g., via getClass().getClassLoader()) instead of ClassLoaderUtils.getDefaultClassLoader() where appropriate.
  • Ensure that tools have the ability to set the thread context ClassLoader (TCCL) where necessary.
@stale
Copy link

stale bot commented May 13, 2021

This issue has been automatically marked as stale because it has not had recent activity. Given the limited bandwidth of the team, it will be automatically closed if no further activity occurs. Thank you for your contribution.

@stale stale bot added the status: stale label May 13, 2021
@stale
Copy link

stale bot commented Jun 3, 2021

This issue has been automatically closed due to inactivity. If you have a good use case for this feature, please feel free to reopen the issue.

@stale stale bot closed this as completed Jun 3, 2021
@kriegfrj
Copy link
Contributor

kriegfrj commented Jun 3, 2021

As an OSGi user, my vote is that this issue should not be allowed to disappear. I have provided a few patches for some selected issues, but at the moment I have a lot of code in JUnit client code that is dedicated to working around these classloader issues.

@stale
Copy link

stale bot commented Jun 21, 2022

This issue has been automatically marked as stale because it has not had recent activity. Given the limited bandwidth of the team, it will be automatically closed if no further activity occurs. Thank you for your contribution.

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

No branches or pull requests

4 participants