-
Notifications
You must be signed in to change notification settings - Fork 330
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
Replace ClassGraph classpath scanning with ServiceLoader or something else #3899
Comments
Thanks for integrating OpenRewrite at apache/jmeter as well; neat to see how you're applying the tool. I've gone ahead and enabled ingesting apache/jmeter to the Moderne Platform as well, such that you can also use that to run recipes. It might take a bit of time to show up there, as I suspect it suffers from the same OOM issue, but when it does you'll find it in the Apache organization in https://app.moderne.io I also like your suggestion to swap out ClassGraph, as indeed those OOM have come up before. Colleagues might be the better judge of that than I am at this point on the relative merits; perhaps @knutwannheden as a first judge on the viability? |
@vlsi I have been thinking the same thing for a while now. Here some comments:
While I have used Jandex extensively while working on Quarkus projects, I am at this point unsure how it actually operates and is different from ClassGraph. But I don't think it is out of the question to replace ClassGraph with Jandex, if that solves our issues. In the long term I would however also favor a |
The key difference is that one can build "annotation index" at the build time, and then it is much faster to load and process than scanning the files repeatedly. In other words, as you build However, auto-service might help creating |
The same should work for SaaS and CLI. Of course, it would require adding I've made the similar change in JMeter a year ago: apache/jmeter#5885 |
I think I would like the META-INF/services files to be transparent to the recipe author by having the files generated at build-time by our build plugin. What do you think about that? |
That is one of the options, however, how would you implement that? How would you add I think it should be good enough to divert users to autoservice and/or manual META-INF/services creation samples.
In my experience, it is much more useful to have a validator, however, it is a different topic. |
The ultimate solution would be an openrewrite recipe that adds |
I was thinking that the build plugin would use ClassGraph (or similar) the way it currently does to scan the Java class files and YAML files in the build output folder and generate some kind of manifest into the META-INF folder which then gets added to the jar. So it would not necessarily have to be a Java service. |
It almost seems like producing and adding a Jandex index to the recipe jar would be the simplest solution as a first step. That would slightly increase the build time and recipe jar size, but would allow getting rid of the expensive scanning at runtime. |
Java service is something that has zero-arg constructor which you require for the recipe anyway. Everything else (jandex indices or whatever) would require custom processing which might make it harder for the users, especially when it comes to shaded jars. |
Adding a small note here that some of the wider community of OpenRewrite recipe producers don't use the same Gradle build plugins, or even use Maven. So might be good to keep those in mind as well with any changes we produce here, that we ideally don't enforce any changes there. |
I have not double-checked that, however, I think the root cause of In other words, a low-hanging fruit here may be to list the jars that OpenRewrite needs to scan.
For instance, |
Note: there is already
|
What problem are you trying to solve?
org.openrewrite.config.Environment.Builder#scanClassLoader
causesOutOfMemoryError
It is hard to display in heap dump analysis, however, scanning Apache JMeter classpath triggers OOM with
-Xmx2500m
heap.Describe the solution you'd like
OpenRewrite
should either load recipes on demand or it should useServiceLoader
to locate services.It would avoid spending time on classpath scan.
Have you considered any alternatives or workarounds?
Can OpenRewrite search the recipe when user requests the exact recipe name?
For instance:
Why throwing
Recipes not found
exception? Can it just requestClass.forName("org.openrewrite.java.testing.junit5.JUnit5BestPractices")
and orclassLoader.getResources("META-INF/openrewrite/recipes.yml")
? Then it won't need to scan all the classpath jars for every execution.An alternative option could be adding https://github.com/smallrye/jandex annotation index, however, it would be an overkill.
Additional context
I am integrating OpenRewrite to Apache JMeter, and having OR trigger OOM is painful: apache/jmeter#6217
The text was updated successfully, but these errors were encountered: