1

I would like to list all the files of a given package inside a module in java 9.

I'm using this code to accomplish the task (I've also tried with different ways to get the class loader):

String packageName= io.packageToBeScanned.AnyClass.class.getPackageName();
String packageNameToUri= packageToUri(packageName);

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
//ClassLoader classLoader = ClassLoader.getPlatformClassLoader();
//ClassLoader classLoader = ClassLoader.getSystemClassLoader();
//ClassLoader classLoader = getClass().getClassLoader();
//ClassLoader classLoader = getClass().getModule().getClassLoader();
Enumeration<URL> resources = classLoader.getResources(packageNameToUri);
while(resources.hasMoreElements()){
    URL resource = resources.nextElement();
    File f = new File(resource.getFile());
    ...
}

All fine all good, but when I add the module-info file, nothing works.

When I run a junit test (in src/test/jata) it correctly scans the package under src/main/java/io/packageToBeScanned only if the module-info is not present.

I've tried to open the module, but without success. I've also tried to open the package: no success. Or to open the package to moduleName: no success.

module moduleName {
    exports io.packageToBeScanned;
}

I know that modules were thought as a way to hide packages from the outside, but it's the library itself that I want to scan itself! I'm out of ideas...

Thank you.

-- UPDATE --

I saw that if I run a junit,

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.6.2</version>
</dependency>

then the error occurs. If instead I run the code in a public static void main(String[] args) then no error occurs...

Printing resource.getFile() without module-info results in

/target/test-classes/io/packageToBeScanned
/target/classes/io/packageToBeScanned

With module-info, instead,

/target/test-classes/io/packageToBeScanned/
/target/test-classes/io/packageToBeScanned

It doesn't care if the scanned package contains private, package-private, or public classes.

MauroT
  • 320
  • 2
  • 12
  • 2
    Turning to modules requires more than just adding a module-info. It also requires using a module-path instead of a class-path. As a side note, to process the package of `io.packageToBeScanned.AnyClass.class`, you should also use `io.packageToBeScanned.AnyClass.class.getClassLoader()` instead of `Thread.currentThread().getContextClassLoader()`. The latter may evaluate to an entirely unrelated class loader. Further, don’t use `new File(resource.getFile())`. You should not assume that the class files are deployed on the default filesystem. – Holger Aug 11 '20 at 13:45
  • Thank you for your answers: I have a couple of questions: 1. what do you mean by "It requires using a module-path instead of a class-path"? 2. "you should not assume that the class files are deployed on the default filesystem": the classes I want to load are either in the library in which I'm doing the scan, or in the project that uses this library. Do you see any problems? thank you – MauroT Aug 11 '20 at 14:14
  • do you mean what is described here? https://stackoverflow.com/questions/46288170/is-it-possible-to-mix-class-path-and-module-path-in-javac-jdk-9 – MauroT Aug 11 '20 at 14:24
  • 1
    You can not use a `File` to describe a resource in a jar file, for example. The link you’ve provided is useful. It may help you understanding what’s going wrong or at least, what information you need to add to your question about the way you run the software… – Holger Aug 11 '20 at 14:53
  • Solution can be found here: https://stackoverflow.com/questions/41932635/scanning-classpath-modulepath-in-runtime-in-java-9/45612376#45612376 – MauroT Aug 25 '20 at 11:17
  • And here is a library: https://github.com/classgraph/classgraph – MauroT Aug 26 '20 at 13:32

0 Answers0