Когда у меня есть следующий код, который пытается получить доступ к ресурсу:
foo / Main.java
package foo;
import java.io.*;
public class Main{
public static void main(String... args) throws IOException{
try(BufferedReader in = new BufferedReader(new InputStreamReader(
Main.class.getClassLoader().getResourceAsStream("foo/res.txt")))){
for(String line = in.readLine(); line!=null; line=in.readLine()){
System.out.println("Line : " + line);
}
System.out.println("EOF");
}
}
}
скомпилируйте это:
javac foo/Main.java -d build/classes/
и добавьте файл ресурсов, тогда я получу что-то вроде этого:
foo/
|--Main.java
`--build
|--classes
| `--foo
| `--Main.class
`--resources
`--foo
`--res.txt
и после запуска, выполнив следующую команду:
java -cp "build/classes:build/resources" foo.Main
Я получу ожидаемый результат, например:
Line : This is a
Line : test!
EOF
Но проблема возникает, когда я делаю проект модульным. Я добавил простейший module-info.java вот так:
module-info.java
module bar {
}
и скомпилируйте его:
javac foo/Main.java module-info.java -d build/classes/
тогда я получу следующую файловую структуру:
module-info.java
foo/
|--Main.java
`--build
|--classes
| |--module-info.class
| `--foo
| `--Main.class
`--resources
`--foo
`--res.txt
Но когда я выполняю класс, набирая команду
java -p "build/classes/;build/resources/" -m bar/foo.Main
Я получаю сообщение об ошибке, в котором говорится, что ресурс не найден.
Exception in thread "main" java.lang.NullPointerException
at java.base/java.io.Reader.<init>(Reader.java:167)
at java.base/java.io.InputStreamReader.<init>(InputStreamReader.java:72)
at bar/foo.Main.main(Main.java:7)
Как я могу получить доступ к ресурсам изнутри модуля?
Редактировать: Обратите внимание, что в этом вопросе конкретно задается вопрос, как получить доступ к ресурсам в «развернутом» модуле (модуле, который не был упакован как файл JAR). Ключевой деталью здесь является то, что в разнесенном модуле папка ресурсов не рассматривается автоматически как часть модуля, если специально не исправлено в командной строке в соответствии с комментарием @Alan Bateman.
Это делает вопрос не дубликатом "Головоломка Java 9 - доступ к файлам ресурсов из внешних модулей". Этот вопрос включает в себя предоставление доступа к файлам ресурсов от одного неразорванного модуля другому неразорванному модулю.
Этот вопрос тоже не дублирует "Как работать с ресурсами в модулях Java 9". Этот вопрос связан с ситуацией, когда один «главный» модуль не может получить доступ к ресурсам, связанным с тестированием, размещенным в нем с помощью «--add-patch», из-за того, что папки ресурсов, связанных с тестированием, не включаются в Gradle.
Этот вопрос тоже не дублирует "Расположение файлов системных ресурсов модуля Java 9". Этот вопрос включает в себя, как заставить модуль обращаться к папке ресурсов, которая находится за пределами собственного исходного дерева модуля.
Существующий вопрос, который, вероятно, наиболее близок к дублированию, - это, вероятно, «Куда попадают файлы ресурсов в проекте Gradle, который создает модуль Java 9?», Который подробно описывает пару связанных сценариев и его стоит прочитать, если у вас возникли проблемы с этой проблемой.
Спасибо за ваш ответ. Я искал в Google, но не смог найти вариант --patch-module
, это очень помогло. Я уверен, что в данном случае мне нужна настоящая команда java -p build/classes --patch-module bar=build/resources -m bar/foo.Main
, потому что я должен указать имя моего модуля в опции --patch-module
. Однако он по-прежнему не работает и выдает тот же NPE, что ресурс не был найден. В какой момент я ошибаюсь?
Да, опечатка в комментарии, это должен был быть --patch-module bar=build/resources
для исправления панели модулей, чтобы включить ресурсы в дерево сборки / ресурсов. Другая проблема заключается в том, что код должен быть Main.class.getResourceAsStream ("res.txt") или Main.class.getResourceAsStream ("/ foo / res.txt"). Это связано с тем, что модули по умолчанию инкапсулируют свои ресурсы.
Это сработало!! Большое спасибо, и мне очень жаль, что я опубликовал повторяющийся вопрос. Я не знал, что есть два способа получить ресурсы ...
@nullpointer, можешь ли ты вызвать по этой мете по твоему дублирующему голосу meta.stackoverflow.com/q/376384/578411
Вам нужна команда
java -p build/classes --patch-module m=build/resources -m bar/foo.Main
. Это связано с тем, что разнесенный модуль требует, чтобы классы и ресурсы модуля находились в одном дереве каталогов. У вас не возникнет этой проблемы, когда вы упакуете модуль как файл JAR, поскольку классы и ресурсы будут в файле JAR.