0

I have run into a snag with the JPMS jdk.internal.loader.BuiltinClassLoader when executing main methods in the context of my IDE (I use IntelliJ 2018.1).

If a resource is loaded in an in module class using a standard method like

 MyMainClass.class.getResourceAsStream("/some-resource")

The resource is not found because the ModuleReference is not a jar, but a class path, e.g.

 [module org.ubl.scb, location=file:///home/christopher/IdeaProjects/systematik-catalogue-builder/web-anno/out/production/classes/]

All of the other entries in the nameToModule Map look like this:

key = "logback.core"
value = "[module logback.core, location=file:///home/christopher/.m2/repository/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3.jar]"

Of course, a resource will never be found in classes, but it could be if the location is the jar root.

Is this a bug or am I missing something?

  • 3
    The code snippet will find /some-resource if it's in the root directory of the module. If resources are in a different output tree then the IDE can patch the module with `--patch-module`. There is no requirement that resources be in a JAR file. – Alan Bateman Apr 05 '18 at 15:30

1 Answers1

0

This is an IDE related compiler output issue. The project uses a gradle build. The default output for a gradle build will create a directory structure like this:

build
 -classes
   -java
      -main
       module-info.class  
 -libs
 -resources

However, to run tests or to execute main methods in a JPMS project, gradle does not work (yet). I use the built-in IntelliJ compiler which generates a completely different output structure than gradle. The default looks like this:

out
  -production
    -classes
       -some/package/name
       some-resource
       module-info.class

One must rebuild a project using the Build Project (ctrl + F9) to generate this output structure if something changes. In this case, I suppose that the missing "some-resource" had not yet been copied into the IntelliJ output structure (probably because I had not rebuilt the project yet), so the BuiltinClassLoader would not find it there. It is perhaps confusing that resources are copied into a directory called "classes", (which is identical to the JAR), but that is how it is done.

The Gradle build output is not used at all by the IDE... This also has consequences for any compiler options like --add-modules that must be added to the IDE settings, even if they are specified in the gradle build script. ...