asm issueshttps://gitlab.ow2.org/asm/asm/-/issues2023-12-20T13:59:35Zhttps://gitlab.ow2.org/asm/asm/-/issues/318010reset() methods for the Tree API2023-12-20T13:59:35ZAura Leereset() methods for the Tree APICurrently, when 'xyz.accept(cn)' is called twice for a ClassNode, everything will be duplicated inside that ClassNode.
A 'reset()' method in each Node of the Tree API would be a neat feature to have, in order to overwrite all current i...Currently, when 'xyz.accept(cn)' is called twice for a ClassNode, everything will be duplicated inside that ClassNode.
A 'reset()' method in each Node of the Tree API would be a neat feature to have, in order to overwrite all current information of a Node with new information (using accept), without the need of recreating the node and replacing all existing Node references.
For ClassNode it would look like something like this:
```java
public void reset() {
this.methods.clear();
this.fields.clear();
this.version = 0;
this.access = 0;
this.name = null;
this.signature = null;
this.superName = null;
this.interfaces = new ArrayList<>();
this.sourceFile = null;
this.sourceDebug = null;
this.module = null;
this.outerClass = null;
this.outerMethod = null;
this.outerMethodDesc = null;
this.visibleAnnotations = null;
this.invisibleAnnotations = null;
this.visibleTypeAnnotations = null;
this.invisibleTypeAnnotations = null;
this.attrs = null;
this.innerClasses = new ArrayList<>();
this.nestHostClass = null;
this.nestMembers = null;
this.permittedSubclasses = null;
this.recordComponents = null;
}
```
Currently, I have my own implementation of ClassNode with the specified reset() method, but when ASM is updated, I would have to add new fields to this method.https://gitlab.ow2.org/asm/asm/-/issues/318005Is there an opportunity to improve the JDK major release upgrade experience?2023-10-21T13:41:59ZDanny ThomasIs there an opportunity to improve the JDK major release upgrade experience?Hello! Danny from the Netflix JVM Ecosystem team here. I just finished our readiness work for JDK 21 and our friends `ClassReader` and `ClassVisitor` were responsible for the majority of issues we've seen across many libraries, except fo...Hello! Danny from the Netflix JVM Ecosystem team here. I just finished our readiness work for JDK 21 and our friends `ClassReader` and `ClassVisitor` were responsible for the majority of issues we've seen across many libraries, except for one compatibility issue in Lombok due to changes in javac. It's a problem exacerbated by the common practice of shading ASM, which means though the project is quite proactive about adding support for the next release, we can't just force an upgrade to ASM-latest, we're coupled to releases of the libraries themselves. Just off the top of my head there's shaded ASM in:
- Byte Buddy (own experimental property)
- Guice
- Groovy
- Gradle Test Retry Plugin
- JaCoCo
- Javassist
- Jersey
- Spring Framework (forked, but still has version checks but set to latest version, experimental check in ClassVisitor patched out)
With JDK releases accelerated to the extent they are now this is something everyone is dealing with far more regularly than years past. It's doubly a problem for our team, not only getting ready for a GA releases, but because we're often testing on ea, nightly or custom builds, and we need to build and canary against real applications. To unblock us, I had to build an `asm-all` dependency that takes `spring-core` ASM and copies it it to every known shaded asm package and inject it first on the classpath. While updating that library today to test [a PR that's particularly important to us](https://github.com/openjdk/jdk/pull/15718) and ASM breaking the build, tests, runtime and Jenkins code coverage plugins, but after hacking in the upgrade everything working great, I wondered to myself if these strict version checks are really necessary, and perhaps the same safety could be guaranteed while throwing an error only when a class file is truly unreadable/incompatible.
That approach would have seen us through JDK 16 to 22, and perhaps beyond without an error. So, I thought I'd come and ask what your current thinking about this is. Are the strict version/experimental checks really necessary, or is it safe to throw an incompatible version exception when encountering unknown constant tags, opcodes, etc.? I understand the format itself imposes those restrictions, because the sizes of each block needs to be known ahead of time. I guess there must have been changes that don't involve new block types, but still aren't backwards compatible, generic type annotations maybe?
With the `ClassFile` API is still a long time away from being available, not to mention adopted broadly, I think any improvement to the JDK upgrade experience w/ ASM would be a real boon to the ecosystem.
We use Gradle, so I was considering doing what we did for the JakartaEE migration: we use Gradle transforms in our [gradle-jakartaee-migration-plugin](https://github.com/nebula-plugins/gradle-jakartaee-migration-plugin), we would just upgrade ASM on the fly during artifact resolution. That's saved us a _huge_ amount of trouble, as we have a lot of legacy code with `javax` references, and made roman riding two legacy frameworks, plus Spring Boot 2 and Spring Boot 3 at the same time a cinch. It'd be very little effort to build (in fact the Tomcat JakartaEE migration tool is a fine streaming and recursive shading implementation, I'd just use as an implementation detail). It'd would work for dependencies of both the build and the project, but would only benefit Gradle users, so thought I'd ask here first before I solve this problem for us, when there might an opportunity to help out here instead.
If you think there is an opportunity here, some advice on what kind of confidence/quality bar we'd need to meet to allow the removal of these specific version and experimental version checks would be all I'd need to get started.
Appreciate your time. Cheers!Eric BrunetonEric Bruneton