Re: Opcodes.ASM5 and visitModule

Remi Forax <[email protected]> Wed, 5 Jul 2017 18:42:42 +0200 (CEST)
Newsgroups gmane.comp.java.objectweb.asm
Message-ID <[email protected]>
> De: "Cédric Champeau" <[email protected]>
> À: [email protected]
> Envoyé: Mercredi 5 Juillet 2017 17:46:46
> Objet: [asm] Opcodes.ASM5 and visitModule

> Hi folks,

Hi Cedric, 

> I have a question regarding the API of ASM 6, and how to use it properly. For
> Gradle, we do what we call "compile classpath snapshotting", which is basically
> computing an ABI signature for all classes (if a dependency changes, and that
> its ABI didn't change, we don't need to recompile). For that, of course, we use
> ASM 5. So far, we used a patched `ClassReader` which blindly accepted the Java
> 9 format version, and visited the classes with Opcodes.ASM5.

> Then, I faced some mocking issues [1], which turned out to be solved if I
> upgraded to ASM 6 alpha. So far so good, I tried it, but then lots of tests
> started to fail with:

> Malformed jar [asm-all-6.0_ALPHA.jar] found on classpath. Gradle 5.0 will no
> longer allow malformed jars on a classpath.

> which is an error message coming from our compile classpath snapshotting.
> Ironically, the ASM 6 jar wouldn't be analyzable with ASM 6! I switched to the
> debug version of ASM which gave me a little more insight: it failed on
> `visitModule`, which, I suspected, was related to our snapshotter visiting the
> module-info file in asm6 jar.

ASM 6 jars are indeed java 9 compatible so they have a module-info.class. 
ASM since the release 4 is able to downgrade itself if necessary, i.e. you can use ASM 6 but ask for visit like ASM 5 by setting the field api of the visitors to ASM 5. 
In your code, you ask for the visitors compatible with the ASM5 API, so while ASM 6 is able to read module-info it can only calls a ASM6 visitor API, 

so here you have two choices, one is to keep asking for the ASM5 visitor API and filter out the module-info.class or you ask for the ASM6 visitor API. 

> And indeed, here's the sources:

> public ModuleVisitor visitModule() {
> if (api < Opcodes.ASM6) {
> throw new RuntimeException();
> }
> if (cv != null) {
> return cv.visitModule();
> }
> return null;
> }

> Then my question is, given that I started visiting with ASM5, which didn't know
> about modules, shouldn't it just *ignore* visitModule and return null, instead
> of failing? If not, then it would be a good idea to provide a better error
> message.

yes, we should provide a better error message. 
Silently ignoring a non supported use case is a bad habit, ASM has been there, and we had users asking why the method visitFoo was not called, so it's better to blow, people will be forced to RTFM or ask a question on the mailing list :) 

> As a side note, I need to figure out what parts of a module descriptor we should
> consider relevant to the ABI signature.

Before starting, the module-info.class has more info that the module-info.java, it also list all the packages (exported or not), the version and the main class, 
the two later values are just metadata. 

The module info can carry annotations, so if a referenced annotation change, you may want to recompile the module-info. 
Otherwise, if the module-info change, 
- you obviously have to recompile itself. 
- if the export information change, from exported to non-exported, you have to recompile all classes that use a class inside the package newly not exported. 
- if you have a new package, you have to check all connected modules, because it can introduce a split packages, with the caveat that javac tends to allow split package at compile time because it doesn't know if two modules will be present at the same time at runtime, so split packages may be fine at compile time but not at runtime. 
- all other info, open, open-packages, uses and provides are data that are checks only at runtime (or at boot time). 

> [1] https://github.com/cglib/cglib/issues/106

> Thanks,
> Cédric

Rémi 

> --
> You receive this message as a subscriber of the [email protected] mailing list.
> To unsubscribe: mailto:[email protected]
> For general help: mailto:[email protected]?subject=help
> OW2 mailing lists service home page: http://www.ow2.org/wws


-- 
You receive this message as a subscriber of the [email protected] mailing list.
To unsubscribe: mailto:[email protected]
For general help: mailto:[email protected]?subject=help
OW2 mailing lists service home page: http://www.ow2.org/wws