-
-
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
Load classes using the test's own ClassLoader
#3280
Conversation
@chrisr3 Are there any docs stating that? |
I would expect so, although I was actually thinking of my own experience profiling an application which did a lot of classloading. We noticed that protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
synchronized(this.getClassLoadingLock(name)) {
Class<?> c = this.findLoadedClass(name);
if (c == null) {
try {
if (this.parent != null) {
c = this.parent.loadClass(name, false);
} else {
c = this.findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException var10) {
}
if (c == null) {
c = findClass(name);
}
}
...
} And all of this contention disappeared when we switched to The JavaDoc for
|
ClassLoader
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR!
I've requested a few minor changes.
...-jupiter-params/src/main/java/org/junit/jupiter/params/provider/MethodArgumentsProvider.java
Outdated
Show resolved
Hide resolved
junit-platform-commons/src/main/java/org/junit/platform/commons/util/ReflectionUtils.java
Outdated
Show resolved
Hide resolved
junit-platform-commons/src/main/java/org/junit/platform/commons/util/ReflectionUtils.java
Outdated
Show resolved
Hide resolved
junit-jupiter-api/src/main/java/org/junit/jupiter/api/condition/MethodBasedCondition.java
Outdated
Show resolved
Hide resolved
junit-jupiter-api/src/main/java/org/junit/jupiter/api/condition/MethodBasedCondition.java
Outdated
Show resolved
Hide resolved
Hi @chrisr3, Do you have time to make the requested changes? We'd like to release 5.10 M1 soon. So if you don't have time, I can take over the PR and make the changes after merging. |
I'll try to find time today 👍 |
@chrisr3 Could you please also add some tests that use a custom class loader for this (see |
Sigh, I am not going to have time to look at this today after all. |
You may also find the |
No worries, @chrisr3. It seems that we will not be releasing 5.10 M1 over the weekend but rather (hopefully) before the end of next week. So if you can get to it in the first few days of next week, that would be fine. |
Actually, please use the If the |
899d03c
to
6a17013
Compare
Hmmm... I've written a lot of fiddly class-loading Java code over the years, and that experience has taught me that the JVM maintains an internal cache of classes that it has already loaded. The JVM only invokes However, no classes returned by X.class.getClassLoader() instanceof TestClassloader which means the JVM can bypass I need to think about how to test this 🤔. |
When I add this: System.err.println(customType.getClassLoader() instanceof TestClassLoader); to
So I don't understand what you are claiming. In any case, In summary, |
I updated one of our tests using From that you can see that So maybe that's what you were hinting at. In any case, I still think As for how to "test this", statements like the following from that test are sufficient in my opinion. assertThat(parameterType).isNotEqualTo(CustomType.NestedType.class); |
Oh my, I see what you've done... Try executing this: var customType1 = customTypeClassLoader.loadClass(customTypeName);
var customType2 = customTypeClassLoader.loadClass(customTypeName); |
Indeed... it's not production-ready.
But I'm not worried about that. None of our tests attempt to load the same class twice. So I can live with that.
|
6a17013
to
34acc96
Compare
FWIW, I pushed a fix for that |
@chrisr3, if you run into any challenges with testing the changes, feel free to finish up the PR without the tests, and someone in the team will add tests afterwards. Depending on the use case, you might need to use the Cheers, Sam |
i would actually have suggested using |
Hi @chrisr3, I see you've made all of the requested changes. 👍 So, all that's missing is:
Since you mentioned that you didn't have time to address #3290 (#3290 (comment)), do you think you'll have time to finish this PR this week? If not, that's absolutely not a problem. Someone in the team can take over the PR and finish it. Please just let us know about your availability for completing this issue. Thanks! |
34acc96
to
c261e19
Compare
I think this test has an error: diff --git a/platform-tests/src/test/java/org/junit/platform/commons/util/ReflectionUtilsTests.java b/platform-tests/src/test/java/org/junit/platform/commons/util/ReflectionUtilsTests.java
index e8bc60ff01..877139f3cd 100644
--- a/platform-tests/src/test/java/org/junit/platform/commons/util/ReflectionUtilsTests.java
+++ b/platform-tests/src/test/java/org/junit/platform/commons/util/ReflectionUtilsTests.java
@@ -1049,10 +1049,9 @@ class ReflectionUtilsTests {
var parameterTypes = method.getParameterTypes();
assertThat(parameterTypes).extracting(Class::getName).containsExactly(nestedTypeName);
- Class<?> parameterType = parameterTypes[0].getClass();
+ Class<?> parameterType = parameterTypes[0];
assertThat(parameterType).isNotEqualTo(CustomType.NestedType.class);
- // The ClassLoader is null because of the behavior of our TestClassLoader.
- assertThat(parameterType.getClassLoader()).isNull();
+ assertThat(parameterType.getClassLoader()).isEqualTo(customTypeClassLoader);
});
}
} |
Oops... that's embarrassing. 😮 Good catch! I'll fix it right away. |
It's no good - I've run out of time to look at this PR further 😞. |
Don't worry about it, @chrisr3. We'll try to take it from here. Thanks for bringing the issue to our attention, creating the PR, assisting with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for making the requested changes.
I'm approving this PR and will take it from here.
Prior to this commit, the extensions supporting @MethodSource, @EnabledIf, and @DisabledIf failed to load an external class if the external class was not visible to JUnit's default ClassLoader. This commit addresses those issues by loading external classes using the ClassLoader obtained from the test class or falling back to JUnit's default ClassLoader if the test's ClassLoader cannot be obtained. This allows JUnit to find the classes while running in a custom ClassLoader arrangement -- for example, inside an OSGi framework. Closes junit-team#3292 Closes junit-team#3279 Closes junit-team#3280
Load classes using a
ClassLoader
obtained from the test class or fall back to the default class loader.This allows JUnit to find the classes while running inside an OSGi framework.
I hereby agree to the terms of the JUnit Contributor License Agreement.