.getResource("/filename") возвращает null, когда упаковка maven является pom

У меня есть проект Maven с подмодулем, разработанный в IntelliJ с использованием Java 11.

Если файл pom.xml не содержит <packaging>pom</packaging>, есть предупреждение о том, что

'packaging' with value 'jar' is invalid. Aggregator projects require 'pom' as packaging.

Но когда для упаковки установлено значение «pom», файл ресурсов, который мне нужен, не может быть загружен; возвращается нулевое значение и генерируется исключение. Из метода main():

    URL resource = getClass().getResource("/fx/gui.fxml");
    Objects.requireNonNull(resource);

С другой стороны, иногда субмодуль не находится, если только я не прошу pom-упаковку. Затем я делаю следующее: запрашиваю упаковку pom, запускаю программу и наблюдаю, как она терпит неудачу, удаляю инструкцию упаковки pom из pom.xml, запускаю снова, и программа работает.

Мой файл ресурсов находится в стандартном месте src/main/resources/fx/gui.fxml. Это местоположение также указано в файле pom:

<build>
    <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
    <testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
    <resources>
        <resource>
            <directory>${project.basedir}/src/main/resources</directory>
        </resource>
    </resources>
</build>

Пожалуйста, помогите мне понять, что происходит. Нужна ли мне упаковка pom и как с ее помощью можно загрузить ресурсы?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
230
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Похоже, у вас есть исходный код в родительском файле pom.

Родительский pom (с подмодулями) должен иметь упаковку как pom и не может иметь исходный код Java. Смотрите этот вопрос

Вы должны переместить свой код в новый подмодуль.

Проект или модуль, содержащий исходный код, должен иметь упаковку jar/war в соответствии с вашими требованиями. Это не может быть упаковка как pom. Обычно упаковка pom используется с родительским модулем, когда у вас многомодульная структура проекта, а подмодули будут иметь упаковку как jar/war. Итак, в вашем случае, если у вас многомодульная структура проекта, ваша родительская упаковка будет "pom", и все подмодули (содержащие исходный код) должны иметь jar/war. Примечание. У вашего родительского модуля не должно быть исходного кода, если он есть, переместите исходный код в подмодуль. Многомодульная структура проекта в основном используется там, где есть общие зависимости, а артефакты могут использоваться в нескольких подмодулях, чтобы можно было удалить дублирование. Как показано ниже.

parent pom.xml

<?xml version = "1.0" encoding = "UTF-8"?>
<project xmlns = "http://maven.apache.org/POM/4.0.0"
         xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.abc.test</groupId>
    <artifactId>testartifact</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <properties>
        <java.version>1.8</java.version>
    </properties>

     <modules>
        <module>rest-services</module>
     </modules>

</project>

Submodule pom.xml

<project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.abc.test</groupId>
        <artifactId>testartifact</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <artifactId>rest-services</artifactId>
    <name>rest-services</name>
 
    <dependencies>
        <dependency>
        </dependency>
    </dependencies>

 </project>

Спасибо за ваше объяснение. Я вижу, что в вашем примере кода используется Java 1.8. Кажется, что правило упаковки (pom для родительского модуля, без кода) практически не имеет ничего общего с Java-модулями Java 9 или более поздней версии. Но обычно они более или менее одинаковы, верно?

Helge 11.12.2020 14:48

да, разницы с версией java нет. Я только что добавил тег свойств для примера, чтобы упомянуть, что такие свойства или некоторые зависимости используются в родительском pom, которые являются общими для использования подмодулем. Например, подумайте, есть ли у вас 10 проектов, и в pom.xml всего проекта вы должны добавить эти общие свойства или зависимость. Это дублирование кода. Так что избавьтесь от того, что мы используем родительский pom в многомодульном проекте.

P.Sanjay 11.12.2020 19:11

Другие вопросы по теме