JDK 9+ BuiltinClassLoader ModuleReference Resolution将使用类路径(而不是Jar)来查找资源

时间:2018-04-05 13:56:23

标签: java intellij-idea java-9 java-10

在我的IDE上下文中执行main方法时,我遇到了JPMS jdk.internal.loader。BuiltinClassLoader的问题(我使用的是IntelliJ 2018.1)。

如果使用标准方法(如

)在模块类中加载资源
 MyMainClass.class.getResourceAsStream("/some-resource")

资源找不到,因为ModuleReference不是jar,而是类路径,例如

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

nameToModule 地图中的所有其他条目如下所示:

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]"

当然,在类中永远不会找到资源,但如果位置是jar根,则可能是这样。

这是一个错误还是我错过了什么?

1 个答案:

答案 0 :(得分:0)

这是与IDE相关的编译器输出问题。该项目使用gradle构建。 gradle构建的默认输出将创建如下目录结构:

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

但是,要在JPMS项目中运行测试或执行main方法,gradle无法正常工作。我使用内置的IntelliJ编译器生成与gradle完全不同的输出结构。默认值如下所示:

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

必须使用Build Project(ctrl + F9)重建项目,以便在出现变化时生成此输出结构。在这种情况下,我认为缺少的“some-resource”尚未复制到IntelliJ输出结构中(可能是因为我还没有重建项目),所以BuiltinClassLoader不会在那里找到它。将资源复制到名为“classes”的目录(与JAR相同)可能会让人感到困惑,但这就是它的完成方式。

IDE根本不使用Gradle构建输出...这也会对必须添加到IDE设置的任何编译器选项(如--add-modules)产生影响,即使它们是在gradle构建中指定的脚本。 ...