【问题标题】:.getResource("/filename") returns null when maven packaging is pom.getResource("/filename") 当maven打包为pom时返回null
【发布时间】:2020-12-11 06:54:50
【问题描述】:

我有一个带有子模块的 Maven 项目,使用 Java 11 在 IntelliJ 中开发。

除非 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.xml 中删除 pom 打包语句,重新启动,程序运行。

我的资源文件位于标准位置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 打包,如何加载资源?

【问题讨论】:

    标签: java maven java-11 java-9


    【解决方案1】:

    看起来你的父 pom 中有你的源代码。

    父 pom(带有子模块)必须有 pom 包装,不能有 java 源代码。见this question

    您应该将您的代码移动到一个新的子模块中。

    【讨论】:

      【解决方案2】:

      包含源代码的项目或模块必须根据您的要求将包装为 jar/war。它不能被包装成 pom。通常,当您具有多模块项目结构并且子模块将打包为 jar/war 时,将 pom 打包与父模块一起使用。所以在你的情况下,如果你有多模块项目结构,你的父包装将是“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 9 或更高版本的 Java 模块几乎没有关系。但通常情况下,它们或多或少是相同的,对吧?
      • 是的,与java版本没有区别。我刚刚为示例添加了属性标记,以提到这些属性或某些依赖项在父 pom 中使用,这些属性通常由子模块使用。想想如果你有 10 个项目,并且在所有项目的 pom.xml 中,你必须添加公共属性或依赖项。那是代码的重复。所以摆脱我们在多模块项目中使用父pom。
      猜你喜欢
      • 2014-12-24
      • 2015-07-04
      • 2010-10-12
      • 2014-07-14
      • 2021-12-15
      • 2014-12-07
      • 1970-01-01
      相关资源
      最近更新 更多