smallrye / jandex

Java Annotation Indexer

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Regression: Index containing class names that start with $ no longer have a consistent DotName.

pferraro opened this issue · comments

CC @MikeEdgar
This appears to be a regression with the parsing of DotNames caused by 3779e75

Consider the following test condition for the org.jboss.cdi.tck.tests.definition.name.$Dollar class:

Class<?> targetClass = $Dollar.class;
Indexer indexer = new Indexer();
try (InputStream stream = targetClass.getClassLoader().getResourceAsStream(targetClass.getName().replace('.', '/') + ".class")) {
    indexer.index(stream);
    Index index = indexer.complete();
    DotName name = DotName.createSimple(targetClass.getName());
    Assert.assertNotNull(index.getClassByName(name));
}

This assertion passes in 2.3.1, but fails in 2.4.0.
If I revert the above commit, the above assertion succeeds.

This is somewhat critical, as it causes a regression in the Jakarta TCK for CDI running against WildFly + Jandex 2.4.0 for the following test:
https://github.com/eclipse-ee4j/cdi-tck/blob/3.0/impl/src/main/java/org/jboss/cdi/tck/tests/definition/name/NameDefinitionTest.java#L109

[ERROR] org.jboss.cdi.tck.tests.definition.name.NameDefinitionTest.testNameStartingWithDollarCharacter  Time elapsed: 0.049 s  <<< FAILURE!
jakarta.enterprise.inject.UnsatisfiedResolutionException: Unable to resolve any beans of class org.jboss.cdi.tck.tests.definition.name.$Dollar
	at deployment.9d9c1e656827b7ae88a4f45c576e6894daaaf63.war//org.jboss.cdi.tck.tests.definition.name.NameDefinitionTest.testNameStartingWithDollarCharacter(NameDefinitionTest.java:110)

... and thus prevents WildFly from upgrading any of the smallrye components that require Jandex 2.4.0 (e.g. smallrye-open-api).

While I think there is a way to fix this particular scenario (since it is not an inner class), I think ultimately the only way to solve this properly is with something like the solution @Ladicek mentioned in #97. I can put together a PR for this case -or- would it be better to revert #130 and reopen #97 until it can be solved properly?

PR #149 handles this particular scenario. Looking at this one also made me realize that $ in package (and maybe module) names should also be handled differently. As mentioned in #97, handling $ elsewhere within a nested class name may require looking at the InnerClasses attribute.

As mentioned in #97, handling $ elsewhere within a nested class name may require looking at the InnerClasses attribute.

So the purpose of DotName is to represent the same data of a String, but in a way that can support reuse of component parts in a radix tree fashion. It’s not a mini Class. The attributes for isInnerClass etc were supposed to be hints that say “this is the last part of the name to split on that looks like an inner class”, and not an introspection mechanism that would say it truly is . In hindsight these probably should not have been exposed. The big problem with using InnerClass data is that the same identical name string is no longer unique so it makes the concept much harder to reason about.

@n1hility, thanks for pointing this out. If I understand correctly, the better way to think about DotName (from a client perspective) is as a memory efficient CharSequence. I think both #130 and #149 preserve the original intent, only going so far as to avoid interpreting $ as a nested class delimiter where it is certain to be part of the class name.

The big problem with using InnerClass data is that the same identical name string is no longer unique so it makes the concept much harder to reason about.

I don't quite follow this. Do you mean that a DotName constructed using the information available in InnerClasses may fail the equals test with one constructed via createSimple?

Yea I think that's a good point. If we were to look at whether given class is truly nested or not, we'd be able to construct more "correct" DotNames in the componentized form, but the createSimple method can't infer the same information from anything. Using $ in class names is such a pain! :-)

I'll release 2.4.1.Final shortly.

Actually I wanted to take a look at #147 first :-) If I'm able to figure that one quickly, I'll include it in 2.4.1.Final. If not, I'll release 2.4.1.Final without a fix for that, tomorrow at latest.

I have a fix for #147, I just need to get permissions to https://github.com/wildfly/typeannotation-test/ and I'll be fine. 2.4.1.Final happening today now depends on someone (@n1hility most likely :-) ) granting me those permissions :-)

Jandex 2.4.1.Final is released:

Sorry it took me so long, I had to wait for typeannotation-test to percolate to Central. Now, we have to wait for this release to hit Central :-)