【问题标题】:Maven relative path best practicesMaven 相对路径最佳实践
【发布时间】:2021-09-07 02:12:37
【问题描述】:

我一直在寻找实际示例来了解获取资源的 Maven 相对路径最佳实践,但是我很困惑,希望您能支持我了解什么是获取资源的最佳实践以及如何应用于具体例子:

具体例子

结构 假设我有以下结构并试图从文件夹规划中的一个类中获取一个资源(位于资源中),所以基本上我正在尝试创建一个与 maven 执行一致的相对路径的字符串:

├───.settings
├───images
├───src
│   ├───main
│   │   ├───java
│   │   │   └───com
│   │   │       └───moga
│   │   │           ├───planning --->Trying to get a resource from here
│   │   │           ├───population
│   │   │           │   ├───chromossome
│   │   │           │   ├───gene
│   │   │           │   └───initialpopulation
│   │   │           └───utils
│   │   └───resources
│   │       └───com
│   │           └───moga
│   │               └───planning
│   │                   └───sample
│   └───test
│       ├───java
│       │   └───com
│       │       └───moga
│       │           ├───planning
│       │           └───population
│       │               ├───chromossome
│       │               └───gene
│       └───resources
│           └───com
│               └───moga
│                   └───planning <-- Resource that I want to get is here
│                       └───sample
└───target
    ├───classes
    │   └───com
    │       └───moga
    │           ├───planning
    │           │   └───sample
    │           ├───population
    │           │   ├───chromossome
    │           │   ├───gene
    │           │   └───initialpopulation
    │           └───utils
    ├───generated-sources
    │   └───annotations
    ├───generated-test-sources
    │   └───test-annotations
    ├───maven-archiver
    ├───maven-status
    │   └───maven-compiler-plugin
    │       ├───compile
    │       │   └───default-compile
    │       └───testCompile
    │           └───default-testCompile
    ├───surefire-reports
    └───test-classes
        └───com
            └───moga
                ├───planning
                │   └───sample
                └───population
                    ├───chromossome
                    └───gene

获取资源的类 RunCapacityPlanning 我目前正在使用以下快速修复

Path pathCapacityPlanningGeneral = Paths.get(System.getProperty("user.dir"),
        "src","test","resources","com","moga","planning","paramsGeneral.txt");
File file = new File(pathCapacityPlanningGeneral.toString());
if (!file.exists()) {
    System.out.println("File Do not exist");
    System.out.println(pathCapacityPlanningGeneral.toString());
}

以上代码是用mvn包构建的,文件存在(不打印信息)。

POM

...
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>
...

方法 以下是我发现的一些潜在方法:

  1. Maven Official
    File file = new File( path );
    if ( !file.isAbsolute() )
    {
        file = new File( project.getBasedir(), file );
    }
    

为了测试这种方法,我尝试了以下方法:

来自this 我知道我应该将此添加到我的 POM 中

  <properties>
<project.basedir>somepath</project.basedir>
...
  </properties>

  • 我应该在这个 somepath 中添加什么? 我已经测试了将 somepath 留空并尝试在我的课堂上打印以理解,但它显示无法解决。
public static void main(String[] args) throws IOException {
    // 1) Approach 1
    // $ cannot be resolved to a variable,
    // project cannot be resolved
    System.out.println(${project.baseDir});
  1. 使用 getResource 基本上我测试了修改主文件:
URL pathCapacityPlanningGeneral =
        RunCapacityPlanning.class.getResource("paramsGeneral.txt");
File file = new File(pathCapacityPlanningGeneral.toString());
if (!file.exists()) {
    System.out.println("File Do not exist");
    System.out.println(pathCapacityPlanningGeneral.toString());
}

以上mvn package java -cp target/CapacityPlan-1.0-SNAPSHOT.jar com.moga.planning.RunCapacityPlanning 后抛出:

File Do not exist
jar:file:/C:/Users/.../capacityplan/target/capacityplan-1.0-SNAPSHOT.jar!/com/moga/planning/paramsGeneral.txt

有人知道我在这种方法中做错了什么吗?

提前非常感谢

【问题讨论】:

    标签: java maven path


    【解决方案1】:

    这里的重点是:
    资源是使用 类路径 解析的,而不是沿着您的项目目录布局。这意味着资源解析从以下
    src/[main|test]/[java|resources]/

    开始

    解决资源的最佳方法是查找它

    new File(getClass()
              .getResource("the resource relative path")
              .toURI()) 
    

    这样,资源是在普通目录中还是在 jar 中都没有关系。

    “资源相对路径”可以以/ 开头。在这种情况下,它是相对于 CLASSPATH 根进行解析的。如果它不是以/ 开头的,它会相对于当前包进行解析。

    在您的示例中,文件夹 planning 是您想要使用的文件夹

    // from package "planning" one level up
    new File(getClass()
                .getResource("../plannung")
                .toURI()) 
    

    // from CLASSPATH root decending
    new File(getClass()
                .getResource("/com/moga/plannung")
                .toURI()) 
    

    注意!

    始终在路径名中使用正斜杠 (/)。 Java 也能在 Windows 上正确处理它们。

    【讨论】:

    • 谢谢@Timothy,我测试了这种方法,但是当我试图从静态上下文中获取资源时,(鉴于此 [post] (stackoverflow.com/questions/53641486/…)。我使用了以下文件文件= new File(RunCapacityPlanning.class.getResource("/com/moga/planning/paramsGeneral.txt").toURI());//编译,但抛出java.lang.IllegalArgumentException:URI不是分层的。
    • 我找到了这个post。但是,当我尝试 InputStream input = RunCapacityPlanning.class.getClassLoader().getResourceAsStream("/com/moga/planning/paramsGeneral.txt"); System.out.println("文件中的可用字节数:" + input.available());//提示“java.lang.NullPointerException)。我想我可能遗漏了什么或过于复杂。
    • RunCapacityPlanning.class.getClassLoader().getResourceAsStream() 的行为与 RunCapacityPlanning.class.getResourceAsStream() 不同!
    • “因为我正在尝试从静态上下文中获取资源” -- 您可以从 静态初始化程序中分配资源。当然,在这种情况下,类变量不能是final...
    • 谢谢,我没有注意到区别。只是为了确保我理解,通过从静态初始化程序分配资源,您的意思是这个 RunCapacityPlanning.class.getResource("/com/moga/planning/paramsGeneral.txt").toURI()),对吗?你会建议另一种方法来替代引发的异常 java.lang.IllegalArgumentException: URI is not hierarchy?
    猜你喜欢
    • 2021-11-20
    • 1970-01-01
    • 2018-02-28
    • 1970-01-01
    • 2014-09-22
    • 2012-05-12
    • 2014-11-21
    • 2011-08-19
    • 1970-01-01
    相关资源
    最近更新 更多