reflections: [0.10.2] Reflections does not detect any classes, if base class (or package prefix) is passed as argument, and application is running as a jar

Given the application built using Java 11 and Spring Boot framework, interface DeviceCode, residing inside the some.package package, and enum classes some.package.a.A, some.package.b.B, some.package.c.C, each implementing the DeviceCode: and code:

public interface DeviceCode {

  static List<DeviceCode> getDeviceCodes() {
    Reflections reflections = new Reflections(DeviceCode.class);
    Set<Class<? extends DeviceCode>> classes = reflections.getSubTypesOf(DeviceCode.class);
    // ...
  }
}

// SomeService.java that runs the code above on start
@Service
class SomeService {

  private final List<DeviceCode> devices = DeviceCode.getDeviceCodes();
  // ...
} 

Expected behaviour:

After migrating from 0.9.12, reflections should detect all the classes implementing DeviceCode interface, in this case A, B, C, as usual, no matter the environment that the application runs on.

Actual behaviour:

Although the code runs as expected, when ran using the IDE (e.g. IntelliJ IDEA), or build tools (during tests) like Maven, no class is detected when the application is launched using java -jar command. Same issue appears, if we initiate reflections using interface’s package as an argument:

    Reflections reflections = new Reflections("some.package"); // or new Reflections (DeviceCode.class.getPackageName());

Current workaround:

Reflections object must be initiated using ConfigurationBuilder instance, in order to restore the previous functionality, when application is running as a jar.

    Reflections reflections =
        new Reflections(new ConfigurationBuilder().forPackages(DeviceCode.class.getPackageName()));
    Set<Class<? extends DeviceCode>> classes = reflections.getSubTypesOf(DeviceCode.class);

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 34
  • Comments: 16

Commits related to this issue

Most upvoted comments

same problem, and we use java -jar command online…

i found another workaround:

var reflections = new Reflections(new ConfigurationBuilder()
                .setUrls(ClasspathHelper.forPackage(DeviceCode.class.getPackageName())));
var classes = reflections.getTypesAnnotatedWith(DeviceCode.class);

The workaround mentioned above does not work for JAR files created with Spring Boot. JAR URL is then

jar:file:/home/me/myproject/target/myproject.jar!/BOOT-INF/classes!/

and it internally throws an exception that /BOOT-INF/classes!/ cannot be opened.

Can confirm, had the exact same issue. Worked when started “outside” of a JAR, failed when inside when using new Reflections("my.pkg.name.here").

The provided workaround worked like a charm, thanks a lot!