Java
openjdk 11 2018-09-25
Gradle
Gradle 4.10.2
IntelliJ
IntelliJ IDEA 2018.2.4 (Community Edition)
Build #IC-182.4505.22, built on September 18, 2018
OS
Windows 10
|-build.gradle
`-src/main/
|-java/
| |-module-info.java
| `-foo/
| `-Foo.java
`-resources/
`-resource.txt
build.gradle
apply plugin: "application"
sourceCompatibility = 11
targetCompatibility = 11
compileJava.options.encoding = "UTF-8"
mainClassName = "foo/foo.Foo"
compileJava {
doFirst {
options.compilerArgs = [
"--module-path", classpath.asPath
]
classpath = files()
}
}
run {
doFirst {
jvmArgs = [
"--module-path", classpath.asPath,
"--module", mainClassName
]
classpath = files()
}
}
module-info.java
module foo {
exports foo;
}
Foo.java
package foo;
import java.net.URL;
public class Foo {
public static void main(String[] args) throws Exception {
URL resource = Foo.class.getResource("/resource.txt");
System.out.println("resource=" + resource);
}
}
> gradle run
resource=null
-- /resource.txt
cannot be obtained and becomes null
--Same result when imported into IntelliJ
--By the way, you can get it without any problem with Eclipse (Photon).
--In Gradle and IntelliJ, the build results of src / main / java
and src / main / resources
are output to different directories.
gradle build result
|-build
: |-classes/java/main/
: | `-foo/
: | `-Foo.class
: |
: |-resources/main/
: : `-resource.txt
IntelliJ build results
|-out/production/
: |-classes/
: | `-foo/
: | `-Foo.class
: |
: `-resources/
: `-resource.txt
--At this time, check how the module path is set.
Foo.java
package foo;
import java.net.URL;
import java.util.stream.Stream;
public class Foo {
public static void main(String[] args) throws Exception {
System.out.println("[jdk.module.path]");
Stream.of(System.getProperty("jdk.module.path")
.split(";"))
.map(p -> " " + p)
.forEach(System.out::println);
URL resource = Foo.class.getResource("/resource.txt");
System.out.println("resource=" + resource);
}
}
Gradle execution result
[jdk.module.path]
...\build\classes\java\main
...\build\resources\main
resource=null
IntelliJ execution result
[jdk.module.path]
...\out\production\classes
...\out\production\resources
resource=null
--Each is set in the module path
--In other words, I feel that the resources
directory is treated as a separate module from the foo
module.
--If you put a directory without module-info.class
in the module path, will it be treated as an anonymous module? ?? ??
--In the case of a jar file, the module name is resolved from the file name and it is treated as an automatic module, but in the case of a directory, I do not know what happens.
--And when you check the JavaDoc for Class.getResource (String)
, it explains:
If this class is in a named Module, ** this method will try to find resources in the module **. (Omitted) This method returns null ** if the resource is a non- ".class" resource in a package that is ** not open to the calling module **.
getResource(String) | Class | Java 10
--That is, Class.getResource (String)
will only try to find the resources in the module to which the class belongs.
--If the resource is another module, the package must be open (ʻopensspecified?) --If
resourcesis treated as an anonymous module, I feel like I can't access the anonymous module from the named module. --At least the class is inaccessible --I don't know exactly if the resources are also inaccessible --By the way, in the case of Eclipse, both
src / main / java and
src / main / resourcesare output under
bin / main`.
--In case of Gradle, IntelliJ, files under src / main / resources
directory are output to directory different from the compilation result under src / main / java
.
--The output destinations of src / main / java
and src / main / resources
will be specified in the module path as separate directories.
--src / main / resources
is treated as a different module than src / main / java
(probably an anonymous module?)
--Class.getResource (String)
seems to basically only be able to access resources in the same module or in an open module
--Therefore, files placed under src / main / resources
cannot be read as resources.
Expected to the last.
Can't access resource with Java 10 – IDEs Support (IntelliJ Platform) | JetBrains
It seems that some people are in trouble with the same thing.
The final method explained here is that the output destination of src / main / resources
should be the same as the output destination of src / main / java
.
build.gradle
apply plugin: "application"
+ apply plugin: 'idea'
sourceCompatibility = 11
targetCompatibility = 11
compileJava.options.encoding = "UTF-8"
mainClassName = "foo/foo.Foo"
+ sourceSets {
+ main {
+ output.resourcesDir = java.outputDir
+ }
+ }
+
+ idea.module.outputDir file("out/production/classes")
compileJava {
doFirst {
options.compilerArgs = [
"--module-path", classpath.asPath
]
classpath = files()
}
}
run {
doFirst {
jvmArgs = [
"--module-path", classpath.asPath,
"--module", mainClassName
]
classpath = files()
}
}
--Adjusting the output destination of IntelliJ and the output destination of Gradle respectively
Gradle execution result
> gradle run
[jdk.module.path]
...\build\classes\java\main
resource=file:/.../build/classes/java/main/resource.txt
IntelliJ execution result
[jdk.module.path]
...\out\production\classes
resource=file:/.../out/production/classes/resource.txt
--Resources can now be accessed by aligning the output destinations of src / main / resources
.
Recommended Posts