-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Comments
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. |
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. |
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. |
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. |
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 contextClassLoader
(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-suppliedClassLoader
and falls back to the "default ClassLoader" only if the suppliedClassLoader
isnull
. For loading services, Spring does not use Java'sServiceLoader
mechanism but rather its ownSpringFactoriesLoader
which performs the same task as Java'sServiceLoader
but with explicit control over whichClassLoader
is used. Note thatSpringFactoriesLoader
delegates toorg.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 customClassLoader
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 ofClassLoaderUtils.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 inServiceLoaderTestEngineRegistry
TestExecutionListener
loading inServiceLoaderTestExecutionListenerRegistry
Extension
loading inExtensionRegistry#registerAutoDetectedExtensions
ConsoleTestExecutor#createCustomClassLoader
ClasspathScanner
configuration/instantiation inReflectionUtils
ReflectionUtils#loadClass(String)
Deliverables
ClassLoader
.ClassLoader
for the current framework class (e.g., viagetClass().getClassLoader()
) instead ofClassLoaderUtils.getDefaultClassLoader()
where appropriate.ClassLoader
(TCCL) where necessary.The text was updated successfully, but these errors were encountered: