【问题标题】:Resource from src/main/resources not found after building with maven使用 maven 构建后未找到来自 src/main/resources 的资源
【发布时间】:2019-09-23 05:35:47
【问题描述】:

您好,我在我的 java 应用程序中使用来自 src/main/resources 的配置文件。我在我的课堂上读它是这样的:

new BufferedReader(new FileReader(new File("src/main/resources/config.txt")));

所以现在我使用 maven 使用 mvn assembly:assembly 构建它。这是我的 pom.xml 中的一点:

<plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <finalName>TestSuite</finalName>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <mainClass>com.some.package.Test</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>

所以当我运行我的应用程序时,我得到了这个错误:

src\main\resources\config.txt (The system cannot find the path specified)

但是当我右键单击我组装好的罐子时,我可以在里面看到它,有人知道我做错了什么吗?

【问题讨论】:

    标签: java maven maven-2


    【解决方案1】:

    来自src/main/resources 的资源将被放到类路径的根目录中,因此您需要以如下方式获取资源:

    new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("/config.txt")));
    

    您可以通过查看 maven 生成的 JAR/WAR 文件来验证,因为您会在存档的根目录中找到 config.txt

    【讨论】:

    • 您能否在答案中添加一点文字,解释 Maven 做了什么导致了这种差异?那将是一个很大的帮助。谢谢。
    • 如前所述,Maven 将来自src/main/resources 的资源放入类路径的根目录中,因此JAR 文件中没有src/main/resources 目录——同理,.class 文件不存在在名为src/main/java 的目录中。这有意义吗?
    • 如果您在静态上下文中,那么您也可以使用“Thread.currentThread().getContextClassLoader()”而不是“getClass()”。
    【解决方案2】:

    FileReader 读取文件系统上的文件。

    也许您打算使用类似的东西从类路径加载文件

    // this will look in src/main/resources before building and myjar.jar! after building.
    InputStream is = MyClass.class.getClassloader()
                         .getResourceAsStream("config.txt");
    

    或者您可以在读取之前从 jar 中提取文件。

    【讨论】:

    • src/main/resources 不起作用,因为它们将被复制到 target/classes 文件夹并打包到 jar 中。
    • 我已经更正了。谢谢你。如果你的类路径中有. 但原因不正确,它会起作用。即它读取原件而不是副本。
    • @beny23 这可能比使用始终查看根/顶层的getClassLoader() 更简单。
    【解决方案3】:

    您放入 src/main/resources 的资源将在构建过程中复制到可以使用以下方式访问的目标/类:

    ...this.getClass().getResourceAsStream("/config.txt");
    

    【讨论】:

    • 你需要getClass(),因为this不太可能是Class类型。
    【解决方案4】:

    一旦我们构建了 jar,资源文件就会在 BOOT-INF/classestarget/classes 文件夹下,在类路径中,使用下面的方法和将 src/main/resources 下的文件作为方法调用 getAbsolutePath("certs/uat_staging_private.ppk") 传递,即使我们可以放置这个Utility类中的方法,调用Thread实例将被加载ClassLoader以从类路径中获取资源。

     public String getAbsolutePath(String fileName) throws IOException {
          return Thread.currentThread().getContextClassLoader().getResource(fileName).getFile();
      }
    

    我们可以将以下标签添加到 pom.xml 中的标签中,以包含这些资源文件以构建目标/类文件夹

    <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.ppk</include>
                </includes>
            </resource>
    </resources>
    

    【讨论】:

    • 很高兴听到@Joey587
    【解决方案5】:

    我认为程序集插件将文件放在类路径上。 JAR 中的位置与您在磁盘上看到的位置不同。解压生成的 JAR 文件并查看文件所在的位置。

    【讨论】:

      【解决方案6】:

      您可以将src/main/resources/直接替换为classpath:

      因此,对于您的示例,您将替换这一行:

      new BufferedReader(new FileReader(new File("src/main/resources/config.txt")));
      

      通过这一行:

      new BufferedReader(new FileReader(new File("classpath:config.txt")));
      

      【讨论】:

        猜你喜欢
        • 2013-05-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-05
        • 2013-08-04
        相关资源
        最近更新 更多