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

Introduce extension API for customizing the ClassLoader in Jupiter #3028

Open
ledoyen opened this issue Sep 9, 2022 · 6 comments
Open

Introduce extension API for customizing the ClassLoader in Jupiter #3028

ledoyen opened this issue Sep 9, 2022 · 6 comments

Comments

@ledoyen
Copy link
Contributor

ledoyen commented Sep 9, 2022

Following #201 and #3014, this issue will focus on creating a new extension API in JUnit Jupiter that allows for ClassLoader customization.

This extension should be able to work in conjunction with others, such as @TestTemplate.

How I see it designed in JUnit Jupiter:

  • a new interface ClassLoaderModifier with a unique method ClassLoader modify(ClassLoader current)
    • the documentation should precise that the returned class loader should have the same parent as the given one

What needs to be checked :

  • Is this model sufficient for other class loading modifying tools (powermocks, robolectric, etc.) ?

🙏 Please do not troll, ask for due date or complain on this ticket, the original ticket is cluttered with these unhelpful comments and is really painful to read when it comes to what features should be implemented and how

@marcphilipp
Copy link
Member

While we might have to add some hooks to the platform to make this happen, I think we should focus this initial issue on providing a Jupiter extension like the one you have in fridujo/classpath-junit-extension.

@ledoyen Could you please change the issue description accordingly?

@ledoyen
Copy link
Contributor Author

ledoyen commented Sep 16, 2022

I updated the description as asked.

@marcphilipp Do not hesitate to modify it yourself, if you want to improve it or even change the objective / direction.

@sbrannen sbrannen changed the title Allow classloader customization Provide extension API for customizing the ClassLoader in Jupiter Sep 16, 2022
@sbrannen sbrannen changed the title Provide extension API for customizing the ClassLoader in Jupiter Introduce extension API for customizing the ClassLoader in Jupiter Sep 16, 2022
@marcphilipp marcphilipp modified the milestones: 5.10, 5.10 M1 Sep 29, 2022
@geoand
Copy link

geoand commented Oct 21, 2022

To expand a little on what is mentioned in #2579, Quarkus has to use a hack where the test methods are intercepted and "redirected" to a different test instance that is loaded and instantiated from a custom ClassLoader.
The reason this is necessary is because Quarkus performs various transformations on application classes which would otherwise be lost.
This mostly works, but does create problems, most importantly with method arguments which also need to be loaded from the same ClassLoader.

If we had an API where we could specify the ClassLoader to be used for loading the test, I am pretty sure all these problems would go away.

@atsiporu
Copy link

atsiporu commented Nov 9, 2022

Hello all,
I would like to refer to my comment in a related issue that presents my usecause.
#201 (comment)

Here is the body of the comment:

So with Junit4 I was able to run tests with my own runner via @RunWith annotation. This was super powerful and allowed me to use my own "special" class loader for each test. This "special" class loader job was to reload a subset of classes when those were accessed (actually it could implement different reloading policies but that's beside the point). What this effectively allowed me to achieve is running each test in a "sandbox".

I had multiple tests that were setting/requiring different values of static class variables running in parallel without stepping on each other toes.

My question is whether it's possible to achieve the same state of nirvana :) with a new Junit5?

Thank you very much for taking time to look and answer this.

My brute force attempt to use @ExtendWith along with custom implementation of TestInstanceFactory that was reloading class and returning instance of "reloaded" class failed miserably, because the framework validates that returned instance is of the same class as the passed in class.

@ledoyen
Copy link
Contributor Author

ledoyen commented Nov 10, 2022

@atsiporu what you are trying to achieve is doable today with a little bit of work. You can see here how such an extension works: https://github.com/fridujo/classpath-junit-extension/blob/master/src/main/java/com/github/fridujo/classpath/junit/extension/jupiter/AbstractClasspathExtension.java

However it presents some limitations regarding interoperability between classloaders.

That is what I wanted to analyze in the Quarkus extension so that we can supply an extension that suits all needs.

However for « sandboxing » as you put it, the example I supply should work nicely :)

@atsiporu
Copy link

@ledoyen thank you very much

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

5 participants