CLOVER🍀

That was when it all began.

Javaのクラスファイルを検索できる、Jandexを試す

これは、なにをしたくて書いたもの?

Javaのクラスファイルを検索できる、Jandexというライブラリーがあります。このブログ内でも間接的に何度か扱ってきているのですが、
いつの間にかorganizationが移っていたりドキュメントができたりしていたので、この機会に1度ちゃんと見てみようかなと思いまして。

Jandex

Jandexは、Javaのクラスファイルを検索したり、リフレクションに関する機能を持つライブラリーです。

Jandex :: Jandex documentation

以下のような機能があります。

  • クラスに対してメモリ効率の高いインデックスを作成する
    • Indexing a set of classes into a memory efficient representation
  • アノテーションの参照と検索ができる
    • Browsing and searching for annotations, including Java 8 type annotations
  • ジェネリクスの型情報を含む、宣言および参照と検索ができる
    • Browsing and searching for declarations and types, including generic type information
  • クラスやインターフェースの検証階層の参照や検索ができる
    • Browsing and searching through the class and interface inheritance hierarchy
  • インデックスをストレージに保存し、ロードできる
    • Persisting an index in a custom storage efficient format and fast loading of that format
  • 以前のAPIと保存したインデックスファイルに対する互換性がある
    • Compatibility with previous API and storage format versions, as described in the Compatibility Promise
  • API、CLI、Apache AntやApache Mavenプラグインによる実行ができる
    • Execution via API, command line tool, Ant, and Maven plugin

個人的には、Hibernateあたりでよく名前を見ていました。

なお、インデックスをファイルに保存した場合の互換性ですが、以前のバージョンのファイルを読むことはできるようですが、
新しいバージョンのファイルは読めないとされています。

Jandexですが、以前はJBoss ASのorganizationにありました。

GitHub - jbossas/jandex: Moved to WildFly

Mavenプラグインは、WildFlyの方に跡があります。本体の方も、1度WildFlyのorganizationに移動していたようです。

GitHub - wildfly/jandex-maven-plugin: Jandex Plugin for Apache Maven

今はSmallRyeのorganizationにあります。

GitHub - smallrye/jandex: Java Annotation Indexer

SmallRyeに移動したのは、3.0からのようです。

Move to SmallRye · Issue #124 · smallrye/jandex · GitHub

Javadocはこちら。

org.jboss.jandex package summary - jandex 3.1.2 javadoc

それでは、試していってみましょう。

環境

今回の環境は、こちら。

$ java --version
openjdk 17.0.7 2023-04-18
OpenJDK Runtime Environment (build 17.0.7+7-Ubuntu-0ubuntu122.04.2)
OpenJDK 64-Bit Server VM (build 17.0.7+7-Ubuntu-0ubuntu122.04.2, mixed mode, sharing)


$ mvn --version
Apache Maven 3.9.2 (c9616018c7a021c1c39be70fb2843d6f5f9b8a1c)
Maven home: $HOME/.sdkman/candidates/maven/current
Java version: 17.0.7, vendor: Private Build, runtime: /usr/lib/jvm/java-17-openjdk-amd64
Default locale: ja_JP, platform encoding: UTF-8
OS name: "linux", version: "5.15.0-73-generic", arch: "amd64", family: "unix"

Jandexを使う

では、まずはJandexを普通に使っていってみましょう。参考にするのは、このあたりですね。

Getting Jandex :: Jandex documentation

Browsing Declarations and Types :: Jandex documentation

Indexing Classes :: Jandex documentation

Maven依存関係等。

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>io.smallrye</groupId>
            <artifactId>jandex</artifactId>
            <version>3.1.2</version>
        </dependency>

        <dependency>
            <groupId>jakarta.platform</groupId>
            <artifactId>jakarta.jakartaee-web-api</artifactId>
            <version>10.0.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.9.3</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.assertj</groupId>
            <artifactId>assertj-core</artifactId>
            <version>3.24.2</version>
        </dependency>
    </dependencies>

Jandexはこちらですね。

        <dependency>
            <groupId>io.smallrye</groupId>
            <artifactId>jandex</artifactId>
            <version>3.1.2</version>
        </dependency>

あとはサンプルとしてのJakarta EE APIや、テスト用のライブラリを含めています。

検索対象のソースコード

Jandexではクラスを検索できるということなので、検索対象のソースコードを用意してみます。

お題はJAX-RSとCDIにしましょう。

src/main/java/org/littlewings/jandex/JaxrsActivator.java

package org.littlewings.jandex;

import jakarta.ws.rs.ApplicationPath;
import jakarta.ws.rs.core.Application;

@ApplicationPath("")
public class JaxrsActivator extends Application {
}

エンティティ的なクラス。

src/main/java/org/littlewings/jandex/entity/Book.java

package org.littlewings.jandex.entity;

public class Book {
    String isbn;
    String title;
    Integer price;

    // getter/setterは省略
}

インターフェース。

src/main/java/org/littlewings/jandex/service/BookService.java

package org.littlewings.jandex.service;

import org.littlewings.jandex.entity.Book;

import java.util.List;

public interface BookService {
    Book findByIsbn(String isbn);

    List<Book> findAll();
}

抽象クラス。

src/main/java/org/littlewings/jandex/service/PrintService.java

package org.littlewings.jandex.service;

public abstract class PrintService<T> {
    void print(T entity) {
        System.out.println(entity);
    }
}

インターフェースを実装し、抽象クラスを継承したCDI管理Bean。

src/main/java/org/littlewings/jandex/service/BookServiceImpl.java

package org.littlewings.jandex.service;

import jakarta.enterprise.context.ApplicationScoped;
import org.littlewings.jandex.entity.Book;

import java.util.Collections;
import java.util.List;

@ApplicationScoped
public class BookServiceImpl extends PrintService<Book> implements BookService {
    @Override
    public Book findByIsbn(String isbn) {
        return new Book();
    }

    @Override
    public List<Book> findAll() {
        return Collections.emptyList();
    }
}

抽象クラスを継承した、CDI管理Bean。

src/main/java/org/littlewings/jandex/service/MessagePrintService.java

package org.littlewings.jandex.service;

import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class MessagePrintService extends PrintService<String> {
}

JAX-RSリソースクラス、かつCDI管理Bean。

src/main/java/org/littlewings/jandex/resource/BookResource.java

package org.littlewings.jandex.resource;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import org.littlewings.jandex.entity.Book;
import org.littlewings.jandex.service.BookService;

import java.util.List;

@Path("books")
@ApplicationScoped
public class BookResource {
    @Inject
    BookService bookService;

    @GET
    @Path("{isbn}")
    @Produces(MediaType.APPLICATION_JSON)
    public Book findByIsbn(@PathParam("isbn") String isbn) {
        return bookService.findByIsbn(isbn);
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public List<Book> findAll() {
        return bookService.findAll();
    }
}

これらをJandexで検索する対象とします。

Jandexを使ってクラスを検索する

では、Jandexを使っていきましょう。確認は、テストコードで行います。

まずは雛形から。

src/test/java/org/littlewings/jandex/JandexTest.java

package org.littlewings.jandex;

import org.jboss.jandex.*;
import org.junit.jupiter.api.Test;
import org.littlewings.jandex.entity.Book;
import org.littlewings.jandex.resource.BookResource;
import org.littlewings.jandex.service.BookService;
import org.littlewings.jandex.service.BookServiceImpl;
import org.littlewings.jandex.service.MessagePrintService;
import org.littlewings.jandex.service.PrintService;

import java.io.IOException;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Set;

import static org.assertj.core.api.Assertions.assertThat;

class JandexTest {

    // ここに、テストを書く!
}

このあたりを見ながら使っていってみます。

Browsing Declarations and Types :: Jandex documentation

特定のクラスを検索。

    @Test
    void findClass() throws IOException {
        Index index = Index.of(
                JaxrsActivator.class,
                BookResource.class,
                BookService.class,
                PrintService.class,
                BookServiceImpl.class,
                MessagePrintService.class,
                Book.class
        );

        ClassInfo classInfo = index.getClassByName(DotName.createSimple("org.littlewings.jandex.entity.Book"));
        assertThat(classInfo.name().toString()).isEqualTo("org.littlewings.jandex.entity.Book");
    }

IndexにClassクラスを登録して

        Index index = Index.of(
                JaxrsActivator.class,
                BookResource.class,
                BookService.class,
                PrintService.class,
                BookServiceImpl.class,
                MessagePrintService.class,
                Book.class
        );

DotNameを使って対象を作成します。文字列またはClassクラスから作成できますが、今回はすべて文字列で指定することにします。

DotName - jandex 3.1.2 javadoc

Indexに対して、特定のクラスを検索。

        ClassInfo classInfo = index.getClassByName(DotName.createSimple("org.littlewings.jandex.entity.Book"));
        assertThat(classInfo.name().toString()).isEqualTo("org.littlewings.jandex.entity.Book");

メソッドの戻り値は、検索対象に応じてClassInfoやAnnotationInstanceだったりします。詳しくは、Indexが実装している
インターフェースであるIndexViewを見てみましょう。

IndexView - jandex 3.1.2 javadoc

Indexは、Indexerというクラスに対して検索対象のクラスを登録して作成することもできます。

    @Test
    void findClassUsingIndexer() throws IOException {
        Indexer indexer = new Indexer();
        indexer.indexClass(JaxrsActivator.class);
        indexer.indexClass(BookResource.class);
        indexer.indexClass(BookService.class);
        indexer.indexClass(PrintService.class);
        indexer.indexClass(BookServiceImpl.class);
        indexer.indexClass(MessagePrintService.class);
        indexer.indexClass(Book.class);

        Index index = indexer.complete();

        ClassInfo classInfo = index.getClassByName(DotName.createSimple("org.littlewings.jandex.entity.Book"));
        assertThat(classInfo.name().toString()).isEqualTo("org.littlewings.jandex.entity.Book");
    }

ここから先は、簡単な例を載せていきましょう。

あるパッケージ内に含まれるクラスを検索。

    @Test
    void findClassesInPackage() throws IOException {
        Index index = Index.of(
                JaxrsActivator.class,
                BookResource.class,
                BookService.class,
                PrintService.class,
                BookServiceImpl.class,
                MessagePrintService.class,
                Book.class
        );

        Collection<ClassInfo> classesInPackage =
                index.getClassesInPackage(DotName.createSimple("org.littlewings.jandex.service"));
        List<ClassInfo> classesInPackageAsList =
                classesInPackage
                        .stream()
                        .sorted(Comparator.comparing(c -> c.name().toString()))
                        .toList();

        assertThat(classesInPackageAsList).hasSize(4);
        assertThat(classesInPackageAsList.get(0).name().toString())
                .isEqualTo("org.littlewings.jandex.service.BookService");
        assertThat(classesInPackageAsList.get(1).name().toString())
                .isEqualTo("org.littlewings.jandex.service.BookServiceImpl");
        assertThat(classesInPackageAsList.get(2).name().toString())
                .isEqualTo("org.littlewings.jandex.service.MessagePrintService");
        assertThat(classesInPackageAsList.get(3).name().toString())
                .isEqualTo("org.littlewings.jandex.service.PrintService");
    }

インターフェースを実装したクラスを検索。

    @Test
    void findInterfaceImplementations() throws IOException {
        Index index = Index.of(
                JaxrsActivator.class,
                BookResource.class,
                BookService.class,
                PrintService.class,
                BookServiceImpl.class,
                MessagePrintService.class,
                Book.class
        );

        Set<ClassInfo> classesInfo =
                index.getAllKnownImplementors(DotName.createSimple("org.littlewings.jandex.service.BookService"));
        assertThat(classesInfo).hasSize(1);

        assertThat(classesInfo.stream().toList().get(0).name().toString())
                .isEqualTo("org.littlewings.jandex.service.BookServiceImpl");
    }

サブクラスを検索。

    @Test
    void findSubClasses() throws IOException {
        Index index = Index.of(
                JaxrsActivator.class,
                BookResource.class,
                BookService.class,
                PrintService.class,
                BookServiceImpl.class,
                MessagePrintService.class,
                Book.class
        );

        Collection<ClassInfo> classesInfo =
                index.getAllKnownSubclasses(DotName.createSimple("org.littlewings.jandex.service.PrintService"));
        assertThat(classesInfo).hasSize(2);

        List<ClassInfo> classesInfoAsList =
                classesInfo
                        .stream()
                        .sorted(Comparator.comparing(c -> c.name().toString()))
                        .toList();

        assertThat(classesInfoAsList.get(0).name().toString())
                .isEqualTo("org.littlewings.jandex.service.BookServiceImpl");
        assertThat(classesInfoAsList.get(1).name().toString())
                .isEqualTo("org.littlewings.jandex.service.MessagePrintService");
    }

アノテーションを付与した対象を検索。

    @Test
    void findClassesByAnnotation() throws IOException {
        Index index = Index.of(
                JaxrsActivator.class,
                BookResource.class,
                BookService.class,
                PrintService.class,
                BookServiceImpl.class,
                MessagePrintService.class,
                Book.class
        );

        List<AnnotationInstance> annotationInstances =
                index.getAnnotations(DotName.createSimple("jakarta.enterprise.context.ApplicationScoped"));
        assertThat(annotationInstances).hasSize(3);

        AnnotationInstance annotationInstance = annotationInstances.get(0);
        AnnotationTarget annotationTarget = annotationInstance.target();
        assertThat(annotationTarget.kind()).isEqualTo(AnnotationTarget.Kind.CLASS);
        assertThat(annotationTarget.asClass().name().toString())
                .isEqualTo("org.littlewings.jandex.resource.BookResource");

        assertThat(annotationInstances.get(1).target().asClass().name().toString())
                .isEqualTo("org.littlewings.jandex.service.BookServiceImpl");
        assertThat(annotationInstances.get(2).target().asClass().name().toString())
                .isEqualTo("org.littlewings.jandex.service.MessagePrintService");
    }

メソッドに付与されたアノテーションも対象にできます。

    @Test
    void findClassAndMethodByAnnotation() throws IOException {
        Index index = Index.of(
                JaxrsActivator.class,
                BookResource.class,
                BookService.class,
                PrintService.class,
                BookServiceImpl.class,
                MessagePrintService.class,
                Book.class
        );

        List<AnnotationInstance> annotationInstances =
                index.getAnnotations(DotName.createSimple("jakarta.ws.rs.Path"));
        assertThat(annotationInstances).hasSize(2);

        AnnotationInstance annotationInstance1 = annotationInstances.get(0);
        AnnotationTarget annotationTarget1 = annotationInstance1.target();
        assertThat(annotationTarget1.kind()).isEqualTo(AnnotationTarget.Kind.METHOD);
        assertThat(annotationTarget1.asMethod().name().toString()).isEqualTo("findByIsbn");
        assertThat(annotationTarget1.asMethod().declaringClass().name().toString())
                .isEqualTo("org.littlewings.jandex.resource.BookResource");

        AnnotationInstance annotationInstance2 = annotationInstances.get(1);
        AnnotationTarget annotationTarget2 = annotationInstance2.target();
        assertThat(annotationTarget2.kind()).isEqualTo(AnnotationTarget.Kind.CLASS);
        assertThat(annotationTarget2.asClass().name().toString())
                .isEqualTo("org.littlewings.jandex.resource.BookResource");
    }

ジェネリクスの情報を扱った例。

    @Test
    void generics() throws IOException {
        Index index = Index.of(
                JaxrsActivator.class,
                BookResource.class,
                BookService.class,
                PrintService.class,
                BookServiceImpl.class,
                MessagePrintService.class,
                Book.class
        );

        ClassInfo classInfo =
                index.getClassByName(DotName.createSimple("org.littlewings.jandex.service.BookServiceImpl"));

        MethodInfo methodInfo = classInfo.method("findAll");
        Type type = methodInfo.returnType();
        assertThat(type.name().toString()).isEqualTo("java.util.List");
        List<Type> types = type.asParameterizedType().arguments();
        assertThat(types).hasSize(1);
        assertThat(types.get(0).name().toString()).isEqualTo("org.littlewings.jandex.entity.Book");
    }
Jandexのインデックスをファイルに保存する

Jandexのインデックス(Index)は、ファイルに保存したりロードしたりもできます。

Indexing Classes :: Jandex documentation

簡単な例を書いてみましょう。

src/test/java/org/littlewings/jandex/JandexIndexFileTest.java

package org.littlewings.jandex;

import org.jboss.jandex.*;
import org.junit.jupiter.api.Test;
import org.littlewings.jandex.entity.Book;
import org.littlewings.jandex.resource.BookResource;
import org.littlewings.jandex.service.BookService;
import org.littlewings.jandex.service.BookServiceImpl;
import org.littlewings.jandex.service.MessagePrintService;
import org.littlewings.jandex.service.PrintService;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

class JandexIndexFileTest {
    @Test
    void storeAndLoadIndex() throws IOException {
        Index createIndex = Index.of(
                JaxrsActivator.class,
                BookResource.class,
                BookService.class,
                PrintService.class,
                BookServiceImpl.class,
                MessagePrintService.class,
                Book.class
        );

        try (BufferedOutputStream bos = new BufferedOutputStream(Files.newOutputStream(Paths.get("target/index.idx")))) {
            IndexWriter writer = new IndexWriter(bos);
            writer.write(createIndex);
        }

        Index loadedIndex;

        try (BufferedInputStream bis = new BufferedInputStream(Files.newInputStream(Paths.get("target/index.idx")))) {
            IndexReader reader = new IndexReader(bis);
            loadedIndex = reader.read();
        }

        Collection<ClassInfo> classesInPackage =
                loadedIndex.getClassesInPackage(DotName.createSimple("org.littlewings.jandex.service"));
        List<ClassInfo> classesInPackageAsList =
                classesInPackage
                        .stream()
                        .sorted(Comparator.comparing(c -> c.name().toString()))
                        .toList();

        assertThat(classesInPackageAsList).hasSize(4);
        assertThat(classesInPackageAsList.get(0).name().toString())
                .isEqualTo("org.littlewings.jandex.service.BookService");
        assertThat(classesInPackageAsList.get(1).name().toString())
                .isEqualTo("org.littlewings.jandex.service.BookServiceImpl");
        assertThat(classesInPackageAsList.get(2).name().toString())
                .isEqualTo("org.littlewings.jandex.service.MessagePrintService");
        assertThat(classesInPackageAsList.get(3).name().toString())
                .isEqualTo("org.littlewings.jandex.service.PrintService");
    }
}

Indexの保存にはIndexWriterを

        Index createIndex = Index.of(
                JaxrsActivator.class,
                BookResource.class,
                BookService.class,
                PrintService.class,
                BookServiceImpl.class,
                MessagePrintService.class,
                Book.class
        );

        try (BufferedOutputStream bos = new BufferedOutputStream(Files.newOutputStream(Paths.get("target/index.idx")))) {
            IndexWriter writer = new IndexWriter(bos);
            writer.write(createIndex);
        }

IndexのロードにはIndexReaderを使います。

        Index loadedIndex;

        try (BufferedInputStream bis = new BufferedInputStream(Files.newInputStream(Paths.get("target/index.idx")))) {
            IndexReader reader = new IndexReader(bis);
            loadedIndex = reader.read();
        }

他にも、CLI(java -jar)やApache Antのタスク、Apache Mavenのプラグインを使ったインデックスファイル作成の方法もあるようです。

Jandex Maven Pluginを使って、ビルド時にJandexのIndexを作成する

最後に、Jandex Maven Pluginを使ってビルド時にJandexのインデックスをファイルとして作成してみます。

Basic Maven Plugin Usage :: Jandex documentation

先程のプロジェクトに、Mavenプラグインを追加します。

    <build>
        <plugins>
            <plugin>
                <groupId>io.smallrye</groupId>
                <artifactId>jandex-maven-plugin</artifactId>
                <version>3.1.2</version>
                <executions>
                    <execution>
                        <id>make-index</id>
                        <goals>
                            <goal>jandex</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

つまり、こうなりました。

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>io.smallrye</groupId>
            <artifactId>jandex</artifactId>
            <version>3.1.2</version>
        </dependency>

        <dependency>
            <groupId>jakarta.platform</groupId>
            <artifactId>jakarta.jakartaee-web-api</artifactId>
            <version>10.0.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.9.3</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.assertj</groupId>
            <artifactId>assertj-core</artifactId>
            <version>3.24.2</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>io.smallrye</groupId>
                <artifactId>jandex-maven-plugin</artifactId>
                <version>3.1.2</version>
                <executions>
                    <execution>
                        <id>make-index</id>
                        <goals>
                            <goal>jandex</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

Jandexによる検索対象のソースコードは、先ほどと同じとします。

Jandex Maven Pluginは、デフォルトではprocess-classesフェーズにバインドされています。

The jandex goal is bound to the process-classes phase by default.

なのでmvn compileでは動作せず、mvn process-classesでJandexのインデックスファイルが作成されます。

$ mvn process-classes

## または
$ mvn compile jandex:jandex

動作時のログ。

[INFO] --- jandex:3.1.2:jandex (make-index) @ jandex-maven-plugin-example ---
[INFO] Saving Jandex index: /path/to/target/classes/META-INF/jandex.idx

デフォルトの保存先は、META-INF/jandex.idx(target/classes/META-INF/jandex.idx)です。

Jandex Maven Pluginによって作成されたインデックスファイルを使ったテスト。

src/test/java/org/littlewings/jandex/JandexMavenPluginCreatedIndexFileTest.java

package org.littlewings.jandex;

import org.jboss.jandex.*;
import org.junit.jupiter.api.Test;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

class JandexMavenPluginCreatedIndexFileTest {
    @Test
    void loadIndex() throws IOException {
        Index index;

        try (BufferedInputStream bis = new BufferedInputStream(getClass().getClassLoader().getResourceAsStream("META-INF/jandex.idx"))) {
            IndexReader reader = new IndexReader(bis);
            index = reader.read();
        }

        Collection<ClassInfo> classesInPackage =
                index.getClassesInPackage(DotName.createSimple("org.littlewings.jandex.service"));
        List<ClassInfo> classesInPackageAsList =
                classesInPackage
                        .stream()
                        .sorted(Comparator.comparing(c -> c.name().toString()))
                        .toList();

        assertThat(classesInPackageAsList).hasSize(4);
        assertThat(classesInPackageAsList.get(0).name().toString())
                .isEqualTo("org.littlewings.jandex.service.BookService");
        assertThat(classesInPackageAsList.get(1).name().toString())
                .isEqualTo("org.littlewings.jandex.service.BookServiceImpl");
        assertThat(classesInPackageAsList.get(2).name().toString())
                .isEqualTo("org.littlewings.jandex.service.MessagePrintService");
        assertThat(classesInPackageAsList.get(3).name().toString())
                .isEqualTo("org.littlewings.jandex.service.PrintService");
    }
}

Indexはテスト内で作成せず、Jandex Maven Pluginでビルド時に作成したものを使用しています。

        Index index;

        try (BufferedInputStream bis = new BufferedInputStream(getClass().getClassLoader().getResourceAsStream("META-INF/jandex.idx"))) {
            IndexReader reader = new IndexReader(bis);
            index = reader.read();
        }

その他の設定については、こちらのページを参照。

Advanced Maven Plugin Usage :: Jandex documentation

また、Maven Shade Pluginと組み合わせた時の話はこちらに記載があります。

Using Jandex Maven Plugin with Shading :: Jandex documentation

今回は、こんなところにしておきましょう。

まとめ

Jandexを試してみました。

前々から存在は知っていたものの、SmallRyeのorganizationに移っていたのとドキュメントができているのに気づいたのを契機に、
ちゃんと見てみようかなと思って今回試してみました。

クラスの検索には便利だと思うので、覚えておきましょう。