Giter Site home page Giter Site logo

jandex's Introduction

jandex's People

Contributors

alesj avatar brmeyer avatar ctomc avatar dependabot[bot] avatar famod avatar franz1981 avatar fromage avatar gastaldi avatar geoand avatar gnodet avatar gsmet avatar gunnarmorling avatar hboutemy avatar heiko-braun avatar jdcasey avatar jorsol avatar kurobako avatar ladicek avatar maozturk avatar marschall avatar mikeedgar avatar mkouba avatar n1hility avatar ppalaga avatar sanne avatar shadogray avatar smallrye-ci avatar stuartwdouglas avatar vlsi avatar yrodiere avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jandex's Issues

Reproducible index lookups

Calling the same sequence of Jandex methods for the same set of JARs should yeld the same results (incl. the ordering of entries).

A PR follows.

Incorrect type variable resolution for signatures

When indexing multiple classes, during class signature parsing/resolution, the wrong bounds can be resolved for a type variable, because the indexer reuses the signature parser and the signature parser reuses resolved type variables between consecutive calls to the index method.

Reproduce with:

package com.example;
public interface WithMethodSignature {
    public <E extends Runnable> E myMethod(E arg);
}
package com.example;
import java.util.Iterator;
public interface WithClassSignature<E extends Exception> extends Iterator<E /*what's the bound?*/ > {
}
package com.example;
import java.io.InputStream;
import org.assertj.core.api.Assertions;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
import org.jboss.jandex.Index;
import org.jboss.jandex.Indexer;
import org.junit.jupiter.api.Test;
public class JandexTest {
    @Test //passes
    public void classSignatureOnly()
            throws Exception {
        verifyIndex(createIndex(WithClassSignature.class), WithClassSignature.class);
    }
    @Test //passes
    public void classSignatureBeforeMethodSignature()
            throws Exception {
        verifyIndex(createIndex(WithClassSignature.class, WithMethodSignature.class), WithClassSignature.class);
    }
    @Test //fails
    public void classSignatureAfterMethodSignature()
            throws Exception {
        verifyIndex(createIndex(WithMethodSignature.class, WithClassSignature.class), WithClassSignature.class);
    }
    private Index createIndex(Class<?>... types)
            throws Exception {
        Indexer indexer = new Indexer();
        for (Class<?> type : types) { //order matters
            String classNameAsResource = type.getName().replace('.', '/') + ".class";
            try (InputStream fis = type.getClassLoader().getResourceAsStream(classNameAsResource);) {
                indexer.index(fis);
            }
        }
        Index index = indexer.complete();
        return index;
    }
    private void verifyIndex(Index index, Class<?> generic) {
        DotName bound = DotName.createSimple(((Class<?>) generic.getTypeParameters()[0].getBounds()[0]).getName());
        ClassInfo indexedGeneric = index.getClassByName(DotName.createSimple(generic.getName()));
        DotName indexedInterfaceBound = indexedGeneric.interfaceTypes().get(0).asParameterizedType().arguments().get(0).asTypeVariable()
                .bounds().get(0).asClassType().name();
        Assertions.assertThat(indexedInterfaceBound).isEqualTo(bound);
    }
}

Could not index class ...

Hi,
I found this error while trying jruby + wildfly-swarm
https://github.com/helio-frota/wildfly-swarm-jruby-sinatra

2015-12-08 00:08:48,378 WARN  [org.jboss.as.server.deployment] (MSC service thread 1-4) WFLYSRV0003: Could not index class jnr/x86asm/SEGMENT.class at /wildfly-swarm-jruby-sinatra.war/WEB-INF/lib/jnr-x86asm-1.0.2.jar: java.lang.NullPointerException
    at org.jboss.jandex.DotName.equals(DotName.java:293)
    at org.jboss.jandex.DotName.equals(DotName.java:293)
    at org.jboss.jandex.DotName.equals(DotName.java:293)
    at org.jboss.jandex.Type.equals(Type.java:358)
    at org.jboss.jandex.StrongInternPool.eq(StrongInternPool.java:139)
    at org.jboss.jandex.StrongInternPool.intern(StrongInternPool.java:247)
    at org.jboss.jandex.NameTable.intern(NameTable.java:84)
    at org.jboss.jandex.Indexer.parseType(Indexer.java:1317)
    at org.jboss.jandex.Indexer.parseType(Indexer.java:1296)
    at org.jboss.jandex.Indexer.processFieldInfo(Indexer.java:287)
    at org.jboss.jandex.Indexer.index(Indexer.java:1445)
    at org.jboss.as.server.deployment.annotation.ResourceRootIndexer.indexResourceRoot(ResourceRootIndexer.java:99)
    at org.jboss.as.server.deployment.annotation.AnnotationIndexProcessor.deploy(AnnotationIndexProcessor.java:51)
    at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:147)
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948)
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

2015-12-08 00:08:48,380 WARN  [org.jboss.as.server.deployment] (MSC service thread 1-4) WFLYSRV0003: Could not index class jnr/x86asm/Mem.class at /wildfly-swarm-jruby-sinatra.war/WEB-INF/lib/jnr-x86asm-1.0.2.jar: java.lang.NullPointerException
    at org.jboss.jandex.DotName.equals(DotName.java:293)
    at org.jboss.jandex.DotName.equals(DotName.java:293)
    at org.jboss.jandex.DotName.equals(DotName.java:293)
    at org.jboss.jandex.Type.equals(Type.java:358)
    at java.util.Arrays.equals(Arrays.java:2829)
    at org.jboss.jandex.StrongInternPool.eq(StrongInternPool.java:132)
    at org.jboss.jandex.StrongInternPool.intern(StrongInternPool.java:247)
    at org.jboss.jandex.NameTable.intern(NameTable.java:88)
    at org.jboss.jandex.Indexer.intern(Indexer.java:1038)
    at org.jboss.jandex.Indexer.processMethodInfo(Indexer.java:263)
    at org.jboss.jandex.Indexer.index(Indexer.java:1446)
    at org.jboss.as.server.deployment.annotation.ResourceRootIndexer.indexResourceRoot(ResourceRootIndexer.java:99)
    at org.jboss.as.server.deployment.annotation.AnnotationIndexProcessor.deploy(AnnotationIndexProcessor.java:51)
    at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:147)
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948)
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

2015-12-08 00:08:48,382 WARN  [org.jboss.as.server.deployment] (MSC service thread 1-4) WFLYSRV0003: Could not index class jnr/x86asm/CpuInfo$Vendor.class at /wildfly-swarm-jruby-sinatra.war/WEB-INF/lib/jnr-x86asm-1.0.2.jar: java.lang.NullPointerException
    at org.jboss.jandex.DotName.equals(DotName.java:293)
    at org.jboss.jandex.DotName.equals(DotName.java:293)
    at org.jboss.jandex.DotName.equals(DotName.java:293)
    at org.jboss.jandex.DotName.equals(DotName.java:293)
    at org.jboss.jandex.Type.equals(Type.java:358)
    at java.util.Arrays.equals(Arrays.java:2829)
    at org.jboss.jandex.StrongInternPool.eq(StrongInternPool.java:132)
    at org.jboss.jandex.StrongInternPool.intern(StrongInternPool.java:247)
    at org.jboss.jandex.NameTable.intern(NameTable.java:88)
    at org.jboss.jandex.GenericSignatureParser.parseTypeList(GenericSignatureParser.java:365)
    at org.jboss.jandex.GenericSignatureParser.parseTypeArguments(GenericSignatureParser.java:340)
    at org.jboss.jandex.GenericSignatureParser.parseClassTypeSignature(GenericSignatureParser.java:311)
    at org.jboss.jandex.GenericSignatureParser.parseClassSignature(GenericSignatureParser.java:249)
    at org.jboss.jandex.Indexer.parseClassSignature(Indexer.java:944)
    at org.jboss.jandex.Indexer.applySignatures(Indexer.java:960)
    at org.jboss.jandex.Indexer.index(Indexer.java:1449)
    at org.jboss.as.server.deployment.annotation.ResourceRootIndexer.indexResourceRoot(ResourceRootIndexer.java:99)
    at org.jboss.as.server.deployment.annotation.AnnotationIndexProcessor.deploy(AnnotationIndexProcessor.java:51)
    at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:147)
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948)
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

2015-12-08 00:08:48,384 WARN  [org.jboss.as.server.deployment] (MSC service thread 1-4) WFLYSRV0003: Could not index class jnr/x86asm/SerializerIntrinsics.class at /wildfly-swarm-jruby-sinatra.war/WEB-INF/lib/jnr-x86asm-1.0.2.jar: java.lang.NullPointerException
    at org.jboss.jandex.DotName.equals(DotName.java:293)
    at org.jboss.jandex.DotName.equals(DotName.java:293)
    at org.jboss.jandex.DotName.equals(DotName.java:293)
    at org.jboss.jandex.Type.equals(Type.java:358)
    at java.util.Arrays.equals(Arrays.java:2829)
    at org.jboss.jandex.StrongInternPool.eq(StrongInternPool.java:132)
    at org.jboss.jandex.StrongInternPool.intern(StrongInternPool.java:247)
    at org.jboss.jandex.NameTable.intern(NameTable.java:88)
    at org.jboss.jandex.Indexer.intern(Indexer.java:1038)
    at org.jboss.jandex.Indexer.processMethodInfo(Indexer.java:263)
    at org.jboss.jandex.Indexer.index(Indexer.java:1446)
    at org.jboss.as.server.deployment.annotation.ResourceRootIndexer.indexResourceRoot(ResourceRootIndexer.java:99)
    at org.jboss.as.server.deployment.annotation.AnnotationIndexProcessor.deploy(AnnotationIndexProcessor.java:51)
    at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:147)
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948)
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

Support JEP 309: Dynamic Class-File Constants (introduced in JDK 11)

Current code throws:

java.lang.IllegalStateException: Unknown tag! pos=156 poolCount = 174
	at org.jboss.jandex.Indexer.processConstantPool(Indexer.java:1563)
	at org.jboss.jandex.Indexer.index(Indexer.java:1597)

This is the output of javap -v <classfile>

  #157 = Dynamic            #1:#156       // #1:$jacocoData:Ljava/lang/Object;

The fileset classes not present in resulting index

I have the following maven project: pom.xml is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.github.mvysny.vaadin-jandex</groupId>
    <artifactId>vaadin-jandex</artifactId>
    <version>14.4.6-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <vaadin.version>14.4.6</vaadin.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin-bom</artifactId>
                <version>${vaadin.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin</artifactId>
            <optional>true</optional>
            <exclusions>
                <!-- Webjars are only needed when running in Vaadin 13 compatibility mode -->
                <exclusion>
                    <groupId>com.vaadin.webjar</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.webjars.bowergithub.insites</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.webjars.bowergithub.polymer</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.webjars.bowergithub.polymerelements</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.webjars.bowergithub.vaadin</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.webjars.bowergithub.webcomponents</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <!-- in order to build Jandex index for Vaadin jars, we need to unpack them first -->
            <plugin>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>3.1.2</version>
                <executions>
                    <execution>
                        <id>unpack-dependencies</id>
                        <phase>process-sources</phase>
                        <goals>
                            <goal>unpack-dependencies</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <includeGroupIds>com.vaadin</includeGroupIds>
<!--                    <outputDirectory>${project.build.directory}/classes</outputDirectory>-->
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.jboss.jandex</groupId>
                <artifactId>jandex-maven-plugin</artifactId>
                <version>1.0.8</version>
                <executions>
                    <execution>
                        <id>make-index</id>
                        <goals>
                            <goal>jandex</goal>
                        </goals>
                        <!-- phase is 'process-classes by default' -->
                    </execution>
                </executions>
                <configuration>
                    <fileSets>
                        <fileSet>
                            <directory>${project.build.directory}/dependency</directory>
                        </fileSet>
                    </fileSets>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Running mvn clean package on this project will result in an empty Jandex index being produced (the jandex.idx only has 18 bytes).

Running with mvn clean package -X shows that Jandex plugin actually walks over the Vaadin classes, it simply won't include those in the resulting index:

...
[INFO] Indexed com.vaadin.flow.internal.BrowserLiveReload$Backend (0 annotations)
[INFO] Indexed com.vaadin.flow.internal.UsageStatistics$1 (0 annotations)
[INFO] Indexed com.vaadin.flow.internal.StateNode$1 (0 annotations)
[INFO] Indexed com.vaadin.flow.internal.UsageStatistics (0 annotations)
[INFO] Indexed com.vaadin.flow.internal.UsageStatistics$UsageEntry (0 annotations)
[INFO] Indexed com.vaadin.flow.internal.StateNode$FeatureSetKey (0 annotations)
[INFO] Indexed com.vaadin.flow.internal.ResponseWriter (1 annotations)
...

Index classes used in the constant pool

Issue #50 was flawed because we didn't want to index all methods calls, so I thought that clients could specify which calls we wanted to flag during indexing, but this doesn't work with packaged indexes.

Now, in Quarkus we have a double step to run transformers conditionally:

  • We have an APT plugin in some modules that add a marker file to META-INF
  • If the marker is here, we register transformers for all class files of that jar, but only if their constant pool references class constants from a list Foo,Bar,Gee

This allows us to only transform classes that use a certain special feature.

Now, in quarkusio/quarkus#814 I want to add a transformer based on the usage of a Router class, and could take the same road, but it would still require scanning the constant pool of every class. I would either create a new extension just for this, or add it to the existing resteasy extension, but every user would pay the ConstPool scanning.

And in quarkusio/quarkus#10929 I definitely don't want to create an extension for a single class, which should be provided by Quarkus Core. And I don't want to add it to Quarkus Core if it means scanning every application class ConstPool even if nobody uses this class. I can't use the marker file in this case.

Therefore, I think we can solve all issues if Jandex indexes CONSTANT_Class (7) entries. Ultimately all method calls reference Fieldref/Methodref/InterfaceMethodref (https://docs.oracle.com/javase/specs/jvms/se14/html/jvms-4.html#jvms-4.4.2) which reference CONSTANT_Class_info (https://docs.oracle.com/javase/specs/jvms/se14/html/jvms-4.html#jvms-4.4.1).

I don't think this would add a huge size to the index, and would allow us to scan efficiently for classes which make calls to special classes, which would work for ORM with Panache, as well as the Reverse-Router and Logging with Panache use-cases without having to use marker files or even creating extensions for single classes just to have the marker.

I can work on this if you think this is the right idea.

WDYT @n1hility @stuartwdouglas @mkouba ?

Move to SmallRye

For the 3.0 release, we want to move Jandex to SmallRye (and use the automated release process SmallRye has). Ideally, all Jandex repos (this one, the typeannotation-test, and the Maven plugin) would be brought into one (covered by #122).

The groupId would change from org.jboss[.jandex] to io.smallrye (or io.smallrye.jandex, but I'd probably prefer the first one :-) ). The artifactIds or packages wouldn't change (so packages would still be org.jboss.jandex), as that would be too big of a break.

EDIT: as part of this, also rename the master branch to main.

Get all classes from a package

I know Jandex is mostly about annotations but I was wondering if we could extend it a bit to keep an index of packages, subpackages and classes in these packages.

When building native applications with external libraries, it can happen that all the content of a package needs to be registered for reflection and that it is the only way to really be sure we do not forget anything and future-proof enough.

Listing classes manually is very cumbersome and brittle for large APIs.

Given the index is a closed world, it sounds feasible, right?

Thoughts?

Runtime Invisible Annotations

We had an issue a few weeks back smallrye/smallrye-open-api#716 requesting information to be utilized from a @Retention(RetentionPolicy.CLASS) annotation. I'm curious if there is any interest in having runtime invisible annotations present in an index. I suppose the original reason for leaving them out was to more closely match reflection APIs, correct? Is this something that could be a candidate for version 3?

Not a parameterized type! exception during indexing a class

I have found this error in the Wildfly server logs while deploying my application. Finally, I was able to create a simple test that reproduces this issue. Note that I use Lombok in my project, so it is likely that this is not an issue of Jandex per se, but it might be a problem of Lombok code generation, or some other problem.

To demonstrate, let's assume we have the following class:

@AllArgsConstructor(access = AccessLevel.PACKAGE)
public class SampleEntity {
	private Set<@TypeAnnotation String> userRoles;

	public Set<String> getUserRoles() {
		return userRoles;
	}
}

where the @TypeAnnotation is just an empty annotation. The test project is avaliable here: jandex-sample-project.zip. A simple test I have created just tries to index this class by Jandex.

When running mvn clean verify, the following exception occurs:

java.lang.IllegalArgumentException: Not a parameterized type!
        at org.jboss.jandex.Type.asParameterizedType(Type.java:228)
        at org.jboss.jandex.Indexer.resolveTypePath(Indexer.java:767)
        at org.jboss.jandex.Indexer.resolveTypeAnnotation(Indexer.java:727)
        at org.jboss.jandex.Indexer.resolveTypeAnnotations(Indexer.java:612)
        at org.jboss.jandex.Indexer.index(Indexer.java:1604)
        at sk.tosix.sample.IndexerTest.test(IndexerTest.java:17)

I have played a bit with this, and it seems that the following causes the error to disappear:

  • I have let Lombok to delombok the source of this Lombok-annotated class; Jandexing the generated class goes without issues.
  • Removing the @TypeAnnotation from the userRoles declaration makes the error disappear.
  • Removing the @AllArgsConstructor annotation and creating the constructor by hand (basically the same as delomboking the class) makes the error disappear.
  • opening this project in Eclipse and compiling it there (not by javac, but by ecj) makes the error disappear.

It is possible that it is Lombok to blame here, but as I am no expert in bytecode interpretation and as it is Jandex that throws the error, I am asking you guys for help :)

Unsupported Java 8 syntax

The following code fails with IllegalArgumentException:

public class Main { 

    public static <T> T[] producer(T... ts){
        return ts;
    }

    public static <T> void consumer(Supplier<? extends T> objs){
    }

    public static void main(String[] args) throws IOException {
        consumer(Main::producer);
        new Indexer().index(Main.class.getClassLoader().getResourceAsStream("com/test/Main.class"));
    }
}

The full stack trace is:

Exception in thread "main" java.lang.IllegalArgumentException: Expected character '^' at position 2
at org.jboss.jandex.GenericSignatureParser.expect(GenericSignatureParser.java:262)
at org.jboss.jandex.GenericSignatureParser.parseMethodSignature(GenericSignatureParser.java:298)
at org.jboss.jandex.Indexer.parseMethodSignature(Indexer.java:971)
at org.jboss.jandex.Indexer.applySignatures(Indexer.java:958)
at org.jboss.jandex.Indexer.index(Indexer.java:1449)
at com.test.Main.main(Main.java:29)

Here is a simple test project, hope this helps.

Exception when writing big indices

Caused by: java.io.UTFDataFormatException: encoded string too long: 68271 bytes
        at java.io.DataOutputStream.writeUTF(DataOutputStream.java:364)
        at java.io.DataOutputStream.writeUTF(DataOutputStream.java:323)
        at org.jboss.jandex.IndexWriterV2.writeStringTable(IndexWriterV2.java:216)
        at org.jboss.jandex.IndexWriterV2.write(IndexWriterV2.java:193)
        at org.jboss.jandex.IndexWriter.write(IndexWriter.java:107)
        at org.jboss.jandex.IndexWriter.write(IndexWriter.java:74)

What's the license?

Neither the pom.xml not the README state what the license of this software is.

jandex related no such method exception

My wildlfy 10.0.0.0 server (which I can not change since an application called i2b2 needs to work with) is sending me the next error:

[javax.enterprise.resource.webcontainer.jsf.application] (ServerService Thread Pool -- 73) java.lang.NoSuchMethodException: org.jboss.as.jsf.injection.JandexAnnotationProvider.(javax.servlet.ServletContext, com.sun.faces.spi.AnnotationProvider): java.lang.NoSuchMethodException: org.jboss.as.jsf.injection.JandexAnnotationProvider.(javax.servlet.ServletContext, com.sun.faces.spi.AnnotationProvider)

at java.lang.Class.getConstructor0(Class.java:3082) [rt.jar:1.8.0_192]

at java.lang.Class.getDeclaredConstructor(Class.java:2178) [rt.jar:1.8.0_192]

at com.sun.faces.spi.ServiceFactoryUtils.getProviderFromEntry(ServiceFactory.java:83) [jsf-impl-2.2.12-jbossorg-2.jar:2.2.12-jbossorg-2]

at com.sun.faces.spi.AnnotationProviderFactory.createAnnotationProvider(AnnotationProviderFactory.java:70) [jsf-impl-2.2.12-jbossorg-2.jar:2.2.12-jbossorg-2]

at com.sun.faces.config.ConfigManager$AnnotationScanTask.<init>(ConfigManager.java:931) [jsf-impl-2.2.12-jbossorg-2.jar:2.2.12-jbossorg-2]

at com.sun.faces.config.ConfigManager.initialize(ConfigManager.java:385) [jsf-impl-2.2.12-jbossorg-2.jar:2.2.12-jbossorg-2]

at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:227) [jsf-impl-2.2.12-jbossorg-2.jar:2.2.12-jbossorg-2]

at io.undertow.servlet.core.ApplicationListeners.contextInitialized(ApplicationListeners.java:187) [undertow-servlet-1.3.23.Final.jar:1.3.23.Final]

at io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:198) [undertow-servlet-1.3.23.Final.jar:1.3.23.Final]

at org.wildfly.extension.undertow.deployment.UndertowDeploymentService.startContext(UndertowDeploymentService.java:100)

at org.wildfly.extension.undertow.deployment.UndertowDeploymentService$1.run(UndertowDeploymentService.java:82)

at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [rt.jar:1.8.0_192]

at java.util.concurrent.FutureTask.run(FutureTask.java:266) [rt.jar:1.8.0_192]

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [rt.jar:1.8.0_192]

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [rt.jar:1.8.0_192]

at java.lang.Thread.run(Thread.java:748) [rt.jar:1.8.0_192]

at org.jboss.threads.JBossThread.run(JBossThread.java:320)

Can you please tell me what version of jandex I need to upload into my wildfly server to avoid this error? My server has jandex so I will truly need to upgrade it. If you can provide some instructions also this could be great (I am kind of new to wildfly and jandex)
thanks a lot

Experiment with Multi-Module Multi-JVM setup

Jandex needs to be built and distributed on an older JVM than the bytecode it can read and needs to be tested with. Explore some form of setup where the test data classes (potentially including the tests if required) are in a separate module with a more recent JVM, the main jandex jar itself.

ArrayIndexOutOfBoundsException

Ran into a case where scanning some libraries found an ArrayIndexOutOfBoundsException. This was based on 2.1.3.Final.

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
	at org.jboss.jandex.Indexer.updateTypeTarget(Indexer.java:841)
	at org.jboss.jandex.Indexer.updateTypeTargets(Indexer.java:624)
	at org.jboss.jandex.Indexer.index(Indexer.java:1603)
	at test.Main.main(Main.java:14)

This occurred using a simple test program:

package test;

import java.io.IOException;
import java.io.InputStream;

import org.jboss.jandex.Index;
import org.jboss.jandex.Indexer;

public class Main {

  public static void main(String[] args) throws IOException {
    Indexer indexer = new Indexer();
    InputStream stream = Main.class.getClassLoader().getResourceAsStream("test/Broken.class");
    indexer.index(stream);
    Index index = indexer.complete();
  }
}

and failed on this class:

package test;

import java.util.List;

import org.checkerframework.checker.nullness.qual.NonNull;

public class Broken {

  public static <U extends @NonNull List<String>> U listOf() {
    return null;
  }

}

This was, obviously, from a much more complicated example, but I tried to reduce it down to the simplest case that still generated the exception.

As far as I could tell, the problem lies here:

            case TYPE_PARAMETER_BOUND: {
                TypeParameterBoundTypeTarget boundTarget = target.asTypeParameterBound();
                type = getTypeParameters(enclosingTarget)[boundTarget.position()]
                           .asTypeVariable().boundArray()[boundTarget.boundPosition()];
                break;
            }

where the boundTarget.position is 1, and boundPosition is 1, but while the getTypeParameters returns a 2-element array, the second array (for boundPosition) is only a 1-element array, and thus, fails.
Unfortunately, I couldn't follow the code logic enough to track the underlying problem, so just reporting with all the data I did get.

Cheers.

Indexer vs DotName.equals() for a nested class with simple name that ends with $

If there is a nested class with simple name Test$, e.g. org.jboss.jandex.test.IndexerTestCase$Test$ (note that although it's not recommended it's legal to use $ in a class name) then Indexer decodes the DotName as:

componentized	true	
innerClass	true	
local	"" (id=108)	
prefix	DotName  (id=111)	
   componentized	true	
   innerClass	true	
   local	"Test" (id=117)
   prefix	DotName  (id=86)	
      componentized	true	
      innerClass	false	
      local	"test" (id=130)	
      prefix	DotName  (id=131)	
         ...

The toString() of the DotName is org.jboss.jandex.test.IndexerTestCase$Test$ however the equals() method does not match the following:

DotName org = DotName.createComponentized(null, "org");
DotName jboss = DotName.createComponentized(org, "jboss");
DotName jandex = DotName.createComponentized(jboss, "jandex");
DotName test = DotName.createComponentized(jandex, "test");
DotName indexerTestCase = DotName.createComponentized(test, "IndexerTestCase");
DotName testName = DotName.createComponentized(indexerTestCase, Test$.class.getSimpleName(), true);

whose toString() is also org.jboss.jandex.test.IndexerTestCase$Test$.

Maybe I'm missing something obvious.

annotation value with enum parameter

Hello,
I try to use jandex to add annotation like:
@XmlAccessorType(XmlAccessType.FIELD)

So I use the following code:
classCreator.addAnnotation(AnnotationInstance.create(
DotName.createSimple(XmlAccessorType.class.getName()), null,
new AnnotationValue[]{
AnnotationValue.createEnumValue("value",
DotName.createSimple(XmlAccessType.class.getName()),
String.valueOf(XmlAccessType.FIELD))}));

but I try a lot of different value for string value: "FIELD", String.valueOf(XmlAccessType.FIELD), XmlAccessType.FIELD.toString(), XmlAccessType.FIELD.toString(), XmlAccessType.FIELD.name() but it never work.
AnnotationValue.createStringValue work but impossible to have a string value for a regular enum.
generated class has the annotation but without value:
@XmlAccessorType
public class Reply {
instead of
@XmlAccessorType(XmlAccessType.FIELD)
public class Reply {

So I think there is a bug with value of type string for enum. Why not used an object type for value instead of String?

Support a reliable way to get a parameter type

Currently, to get the parameter type, we need to do something like:

methodParameterInfo.method().parameters().get(methodParameterInfo.position())

The issue with this is that parameters() includes the synthetic parameters (confirmed by @FroMage ) whereas they are not counted in the result of position(), leading to incorrect results if we have synthetic parameters.

@FroMage implemented a nice user friendly API to get the parameter name. We should do the same for the parameter type.

Support scanning of selected packages, classes in other dependencies

Inspired by the movement on #138...

The plug-in supports scanning .class files.

Has there ever been thought to including .class entries in other dependency JARs?

In this Helidon issue helidon-io/helidon#2729 referenced from #138, the use case is this: The application currently being built by maven (and for which the Jandex plug-in is executed) contains endpoints with MicroProfile OpenAPI annotations. Those endpoints happen to refer to POJO business classes defined in other dependencies which might or might not also bear OpenAPI annotations.

It would be great to have a way to create a single Jandex index (from one execution of the plug-in) that included not only information about the current project's classes but also selected classes from other dependencies, JARs which do not have their own Jandex indices.

Of course, one would want a way to identify which dependencies, which classes or packages within them, etc. to include in the scan.

A workaround, also mentioned in the Helidon issue, would be to extract the contents of selected other dependencies into temp directories and point fileset configuration to the extracted contents. For the developer, though, it'd be simpler to be able to tell just the Jandex plug-in about those other dependencies and the relevant selection of packages/classes, rather than involve other plug-ins to extract their contents to disk first.

IndexView - add method/s to handle repeatable annotations

org.jboss.jandex.IndexView.getAnnotations(DotName) currently does not return the instances of repeatable annotations and that's ok (repeatable annotations are compiled into the container annotations anyway). However, we should probably add some convenient method to handle repeatable annotations as well, ie. something similar to java.lang.reflect.AnnotatedElement.getAnnotationsByType(Class<T>). Of course, we can't modify the behavior of IndexView.getAnnotations() due to backwards compatibility.

Example:

@Repeatable(Routes.class)
public @interface Route {

    @interface Routes {
        Route[] value();
    }
}

// the boolean param can be used to specify whether to return repeatable annotations or not  
Collection<AnnotationInstance> annotations = index.getAnnotations(DotName.createSimple(Route.class.getName()), true); 

Incorrect handling of the optional class bound in the class type variables

package org.jboss.jandex.test;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.math.BigInteger;

public class ClassBounds<V1 extends @ClassBounds.NonNull BigInteger,
        V2 extends @ClassBounds.Nullable Runnable> {
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE_USE)
    public @interface NonNull {
    }

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE_USE)
    public @interface Nullable {
    }
}

Test class:

package org.jboss.jandex.test;

import org.jboss.jandex.Index;
import org.jboss.jandex.Indexer;
import org.junit.Test;

import java.io.IOException;

public class TestClassBounds {
    @Test
    public void classBounds() throws IOException {
        Indexer indexer = new Indexer();
        indexer.index(ClassBounds.class.getResourceAsStream("ClassBounds.class"));
        Index index = indexer.complete();
        System.out.println("subclasses");
        index.printSubclasses();
        System.out.println("annotations");
        index.printAnnotations();
    }
}

Actual error:

java.lang.ArrayIndexOutOfBoundsException: 1
	at org.jboss.jandex.Indexer.updateTypeTarget(Indexer.java:847)
	at org.jboss.jandex.Indexer.updateTypeTargets(Indexer.java:630)
	at org.jboss.jandex.Indexer.index(Indexer.java:1618)
	at org.jboss.jandex.test.TestClassBounds.classBounds(TestClassBounds.java:13)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)

It looks like jandex misses something like openjdk/jdk@9d7f8bc

Configurable persistent index format version in the Maven plugin

The Maven plugin could expose a configuration property for setting which index version to write. It would then call IndexWriter.write(Index, int) instead of just IndexWriter.write(Index). Default would be unconfigured, which would lead to calling IndexWriter.write(Index) and hence using the latest index version.

The purpose would be to decouple Jandex version bump from Jandex persistent index format version bump. Libraries that produce and distribute a Jandex index could decide to bump Jandex without bumping the persistent index format, so that the index remains readable by older Jandex versions.

On the other hand, there's clear desire to make libraries ship latest indices, so that new Jandex features can be used, so maybe we would only allow configuring a subset of possible index versions? Say, current and current - 1, something like that.

Determine if a method/field is synthetic

I didn't find an easy way to determine if a field/method is synthetic.

The answer could have been "use Modifier.isSynthetic()" but unfortunately this method is package private.

I wonder if we should provide something in Jandex similar to what we have on reflection Field/Method?

Decommission the JANDEX project in Red Hat JIRA

Jandex historically used the JBoss.org JIRA (now Red Hat JIRA), but it has obviously moved to GitHub Issues. The JIRA project needs to be decommissioned to avoid confusion. There's just 6 open issues at the moment, and at least 1 has been fixed in 2.4.0.Final (JANDEX-41, module-info.class support), so it shouldn't be a big deal.

Manually creating index objects

Hey Jason, etal. I started playing around again with using Jandex in Hibernate.

The thing I am still unsure of is how to manually build ClassInfo, MethodInfo, etc objects. For background, this is related to applying orm.xml mapping overrides. I realize this is a unique use-case, but wondered if you know of anything else using Jandex in a similar fashion or thoughts on how to best accomplish this.

The main thing I run into is that I need to re-create all of the AnnotationTarget references, which seems to get messy

Add option to index methods that call specified methods

We're going to need to be able to ask Jandex for methods that call specified methods. It would be nice if we could tell Jandex to index all calls to Foo.bar() (which could be a list of methods) so that later we can query this and do bytecode modification or compile-time validation only for the methods where those call are located.

While indexing, Jandex could look at the bytecode and record methods that call the set of specified methods we're after. Then we can query Jandex for all methods calling those methods.

Uniform API for accessing annotations from AnnotationTarget

Two PRs (#64, #75) already attempt to make the annotation access API more regular. I think this should be addressed holistically. In my opinion, all the annotation access methods should be present on AnnotationTarget, so that all annotation targets expose uniform API. It would look roughly like this:

interface AnnotationTarget {
    ...

    boolean hasAnnotation(DotName name);
    AnnotationInstance annotation(DotName name);
    Collection<AnnotationInstance> annotationWithRepeatable(DotName name, IndexView index);
    Collection<AnnotationInstance> annotations();
    Map<DotName, List<AnnotationInstance>> annotationsMap();

    boolean hasDirectAnnotation(DotName name);
    AnnotationInstance directAnnotation(DotName name);
    Collection<AnnotationInstance> directAnnotationWithRepeatable(DotName name, IndexView index);
    Collection<AnnotationInstance> directAnnotations();
    Map<DotName, List<AnnotationInstance>> directAnnotationsMap();
}

The direct* methods would return annotations that are present directly on the annotation target, while the generic methods would -- just like now -- return annotations present on the annotation target as well as nested annotation targets.

This would unfortunately be a breaking change, because ClassInfo currently exposes a very different API than other annotation targets and there's a name collision.

2.0.3...2.2.2: IllegalArgumentException: Not an array type for method like void method(@Nullable Object[])

Sample:

public interface EqualityComparer<T> {
  boolean equal(T v1, T v2);

  int hashCode(T t);
}
  private static class ArrayEqualityComparer
      implements EqualityComparer<@Nullable Object[]> {
    @Override public boolean equal(@Nullable Object[] v1, @Nullable Object[] v2) {
      return Arrays.deepEquals(v1, v2);
    }

    @Override public int hashCode(@Nullable Object[] t) {
      return Arrays.deepHashCode(t);
    }
  }

Error (in jandex 2.0.3.Final and 2.2.2.Final):

Caused by: java.lang.IllegalArgumentException: Not an array type!
  at org.jboss.jandex.Type.asArrayType(Type.java:254)
  at org.jboss.jandex.Indexer.resolveTypePath(Indexer.java:621)
  at org.jboss.jandex.Indexer.resolveTypeAnnotation(Indexer.java:593)
  at org.jboss.jandex.Indexer.resolveTypeAnnotations(Indexer.java:478)
  at org.jboss.jandex.Indexer.index(Indexer.java:1458)
  at com.github.vlsi.jandex.JandexWork.execute(JandexWork.kt:52)

See https://issues.apache.org/jira/browse/CALCITE-4459

Indexer option to control ClassInfo sorting

SmallRye's OpenAPI implementation uses Jandex. Not only for annotation processing but also to get general reflective class info. Unfortunately object fields are sorted by Jandex: https://github.com/wildfly/jandex/blob/61d1115e0a0f15dcfb2b0bbd082100f847963529/src/main/java/org/jboss/jandex/ClassInfo.java#L557
This ultimately alters the field order of all objects appearing in the openapi file, though in most cases declaration order is desired.

It would therefore be great to have an Indexer option to configure ClassInfo's field sorting behavior. Maybe for completeness also for methods.

Thanks!

Add test input java classes to jandex repository

Currently, it is hard to write tests since jandex repository defaults to source=target=1.6, and the test code that uses type annotations just does not compile.

It would be nice if there was a way to add test classes right into jandex repository (e.g. via Maven toolchains or Gradle toolchains)

modify: renameTo() return unchecked, jar file lost

On my linux box: java -jar jandex.jar -m modules/org/slf4j/main/slf4j-api-1.5.10.jar

  if (modify) {
        jarFile.delete();
        tmpCopy.renameTo(jarFile);
  }

can lead to:
rename("/tmp/slf4j-api-1.5.10003664802446273229194jmp", "modules/org/slf4j/main/slf4j-api-1.5.10.jar") = -1 EXDEV (Invalid cross-device link)

a somewhat unusual file system layout makes such simple code break - file lost!!

Generics - recursive bound results in UnresolvedTypeVariable

If a class declares a recursive bound (which should be legal and often used e.g. in builders) such as interface Score<S extends Score<S>> {} the type hierarchy contains an UnresolvedTypeVariable. And according to the javadoc "This type will only occur as a result of a bug, or a non-compliant Java class file".

A test can be found here:
mkouba@2141db3

In fact, I'm not quite sure whether it's a bug or how to handle this correctly.

Add classname to "Required class information is missing" error

See https://github.com/wildfly/jandex/blob/7f2c075ba9246e4b6cc8fe7f3e3678dc2b64891c/src/main/java/org/jboss/jandex/Indexer.java#L926

The error message is hard to understand, and the root cause is not clear.

What do you think if the error includes the class name or something else for making the exception actionable?

The current exception:

Caused by: java.lang.IllegalStateException: Required class information is missing
         at org.jboss.jandex.Indexer.rebuildNestedType(Indexer.java:926)
         at org.jboss.jandex.Indexer.resolveTypePath(Indexer.java:786)
         at org.jboss.jandex.Indexer.resolveTypeAnnotation(Indexer.java:705)
         at org.jboss.jandex.Indexer.resolveTypeAnnotations(Indexer.java:613)
         at org.jboss.jandex.Indexer.index(Indexer.java:1602)
         at org.hibernate.boot.archive.scan.spi.ClassFileArchiveEntryHandler.toClassDescriptor(ClassFileArchiveEntryHandler.java:64)
         at org.hibernate.boot.archive.scan.spi.ClassFileArchiveEntryHandler.handleEntry(ClassFileArchiveEntryHandler.java:52)

Context: https://www.postgresql.org/message-id/AM0PR04MB652919E6F344C84DC3073D0D96140%40AM0PR04MB6529.eurprd04.prod.outlook.com

Index getAllKnownSubInterface

My need is to get all interface wich extends another interface.
The issue is that index is class oriented. So I can get subclass or class which implement an interface. But I found not solution to get interface which inherit from another.

example

interface A{
}
interface B extends A{
}
interface C extends B{
}

goal is to be abble to get C and B.
I try to use getAllKnownImplementors but it skip interface (I have check source)
I try to do my own method with a recurssive method:

    void produceRecursiveProxies(IndexView index,
            DotName interfaceDN,
            BuildProducer<NativeImageProxyDefinitionBuildItem> proxies) {
        index.getKnownDirectImplementors(interfaceDN).stream()
                .filter(classinfo -> Modifier.isInterface(classinfo.flags()))
                .map(ClassInfo::name)
                .forEach((className) -> {
                    proxies.produce(new NativeImageProxyDefinitionBuildItem(className.toString()));
                    produceRecursiveProxies(index, className, proxies);
                });

    }

but getKnownDirectImplementors seems to not return the interface but only class... not sure ?
Best is to have a new function in indexer for that.
getKnownSubInterface

Add isEnumConstant to FieldInfo

java.lang.reflect.Field has the method isEnumConstant that uses the package private value Modifier.ENUM. The value of the constant 0x4000 is defined in the class file format to indicate that a field is "declared as an element of an enum" (https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.5-200-A.1).

It would be a nice convenience to implement a similar method on FieldInfo checking for 0x4000 in the field's flags.

package org.jboss.jandex;
...
public final class FieldInfo implements AnnotationTarget {
    ...
    static final int ENUM = 0x00004000;
    ....
    public boolean isEnumConstant() {
        return (flags() & ENUM) != 0;
    }
    ....
}

This is closely related (it seems) to #54 and #60.

Indexer.index() shouldn't return ClassInfo

The Indexer.index() method returns ClassInfo representing the just-indexed class. This precludes doing two-phase class processing, which is required to correctly resolve some recursive types. As a first step, Indexer.index() should be changed to return void -- indexed classes should only be accessible from a complete index.

Add method to find extending interfaces of target interface

I would like to be able to (efficiently) look up all the interfaces that extends a target interface.
Say for example that I have

public interface SomeInterface {

}

and there is an interface that extends is:

public interface SomeExtendingInterface extends SomeInterface {

}

Neither index.getAllKnownSubclasses() nor index.getAllKnownImplementors() covers the aforementioned usecase so I am forced do the following (inefficient) lookup:

    List<ClassInfo> getAllInterfacesExtending(DotName target, IndexView index) {
        List<ClassInfo> result = new ArrayList<>();
        Collection<ClassInfo> knownClasses = index.getKnownClasses();
        for (ClassInfo clazz : knownClasses) {
            if (!Modifier.isInterface(clazz.flags())) {
                continue;
            }
            List<DotName> interfaceNames = clazz.interfaceNames();
            boolean found = false;
            for (DotName interfaceName : interfaceNames) {
                if (interfaceName.equals(target)) {
                    found = true;
                    break;
                }
            }
            if (found) {
                result.add(clazz);
            }
        }
        return result;
    }

Document strategy for shading dependencies and merging indices

AFAIK the current "standard" is to include index as META-INF/index.idx.
However, that would result in collisions when dependencies are shaded, so it looks like jandex is not ready for adding indices to Java libraries yet :(

I think it would be helpful if there was a documented procedure to merge indices (and remap classnames) for shading dependencies (e.g. Resource Transformers for maven-shade-plugin, Content Merging in com.github.johnrengelman.shadow Gradle plugin, and so on).

Look into supporting type aliases

In the evolution of Jakarta EE 8 to 9 there is a package name change complicates support for the now legacy type, even though there are no semantic differences. In a prototype of arc I was looking at trying to make the minimal changes to have arc support the jakarta.* package while also handling existing code to work. This resulted in duplicate DotName instances and checks like the following:

    public static final DotName PRIORITY = create(jakarta.annotation.Priority.class);
    public static final DotName PRIORITY_JAVAX = create("javax.annotation.Priority");

...
                    } else if (DotNames.PRIORITY.equals(annotation.name())
                            || DotNames.PRIORITY_JAVAX.equals(annotation.name())) {
                        alternativePriority = annotation.value().asInt();
                    } else {

This issue is about whether an alias notion can effectively be added to jandex. It has been pointed out that:

  • DotNames can be created by extensions, and so not all instances will be updated to know about the alias
  • DotNames are not associated with an index, so introducing the alias there will also not handle existing usage without a change to DotName to be index aware.

It seems like what is needed is an alias registry in DotName that is populated by a new factory method, and that all instance would check for an alias.

Add more documentation

The existing Jandex documentation consists of a README, which is even somewhat outdated, and a Javadoc. This needs to be improved quite a bit. I'd personally downplay the published Javadoc (it's enough you have access to it in an IDE) and instead focus on a user guide kind of thing. We could use the SmallRye documentation site (https://smallrye.io/docs/), as we plan to move to SmallRye anyway (#124).

RFE: Add method ClassInfo.toClass() for Quarkus (API gap)

As discussed here with Stuart and Guillaume:
https://quarkusio.zulipchat.com/#narrow/stream/187038-dev/topic/Convert.20Jandex.20ClassInfo.20to.20Class
quarkus extensions often have to convert a Jandex ClassInfo into a Class, which Jandex doesn't support (it's an API gap).

Now, converting it into a Class, does mean the Class gets instantiated, which means the user must be well aware of the cost of that side effect, but that seems obvious to me - otherwise ClassInfo would not exist.

The code itself:

public <T> Class<T> toClass() {
        String className = name().toString();
       ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        try {
            return (Class<T>) classLoader.loadClass(className);
        } catch (ClassNotFoundException e) {
            throw new IllegalStateException("The class (" + className
                    + ") cannot be created.", e);
        }
}

Exception when indexing guava-30.0-jre

jandex is not capable of parsing the current guava release, guava-30.0-jre. It fails when indexing ClosingFuture.class.
Please see the stacktrace:

java -jar ~/.m2/repository/org/jboss/jandex/2.2.1.Final/jandex-2.2.1.Final.jar ~/.m2/repository/com/google/guava/guava/30.0-jre/guava-30.0-jre.jar
ERROR: Could not index com/google/common/util/concurrent/ClosingFuture.class: Class extends type annotation appeared on a non class target
java.lang.IllegalStateException
	at org.jboss.jandex.IndexWriterV2$ReferenceTable.getReferenceEntry(IndexWriterV2.java:125)
	at org.jboss.jandex.IndexWriterV2$ReferenceTable.positionOf(IndexWriterV2.java:132)
	at org.jboss.jandex.IndexWriterV2.positionOf(IndexWriterV2.java:448)
	at org.jboss.jandex.IndexWriterV2.writeTypeTargetFields(IndexWriterV2.java:381)
	at org.jboss.jandex.IndexWriterV2.writeTypeTarget(IndexWriterV2.java:366)
	at org.jboss.jandex.IndexWriterV2.writeAnnotationTarget(IndexWriterV2.java:335)
	at org.jboss.jandex.IndexWriterV2.writeAnnotation(IndexWriterV2.java:319)
	at org.jboss.jandex.IndexWriterV2.writeReferenceOrFull(IndexWriterV2.java:614)
	at org.jboss.jandex.IndexWriterV2.writeClassEntry(IndexWriterV2.java:537)
	at org.jboss.jandex.IndexWriterV2.writeClasses(IndexWriterV2.java:472)
	at org.jboss.jandex.IndexWriterV2.write(IndexWriterV2.java:207)
	at org.jboss.jandex.IndexWriter.write(IndexWriter.java:107)
	at org.jboss.jandex.IndexWriter.write(IndexWriter.java:74)
	at org.jboss.jandex.JarIndexer.createJarIndex(JarIndexer.java:193)
	at org.jboss.jandex.JarIndexer.createJarIndex(JarIndexer.java:86)
	at org.jboss.jandex.Main.getIndex(Main.java:87)
	at org.jboss.jandex.Main.execute(Main.java:68)
	at org.jboss.jandex.Main.main(Main.java:53)

I became aware of this problem because a deployment of mine is using this version of guava, and when I deploy the EAR in to JBoss EAP 7.3.2, a warning with a similar stacktrace is thrown. The version of jandex in the JBoss is jandex-2.1.2.Final-redhat-00001, however this problem still exists with the 2.2.1 release.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.