2

I have been looking for a while for practical examples to understand Maven relative paths best practices to get Resources, however I got confused, hoping you could please support me to understand what are best practices to get Resources and how to apply to a concrete example:

Concrete Example:

Structure Say I have the following structure and trying to get a resource(located in resources) from a class in the folder planning, so basically I am trying to create a String of a relative path that is consistent with maven execution:

├───.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 

Class RunCapacityPlanning that gets the resource I am currently using the following quick fix

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()); } 

The above code is builded with mvn package and the file exists(Do not print the message).

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> ... 

Approaches Here are some potential approaches I have found:

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

To test this approach, here is what I tried:

From this I understand that I should add this to my POM

 <properties> <project.basedir>somepath</project.basedir> ... </properties> 
  • What should I add in this somepath? I have tested leaving somepath blank and trying to print in my class to understand, however it shows cannot be resolved.
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. Use getResource Basically I tested modify the main file:
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()); } 

The above after mvn package java -cp target/CapacityPlan-1.0-SNAPSHOT.jar com.moga.planning.RunCapacityPlanning throws:

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

Do anybody knows what I am doing wrong in this approach?

Thanks so much in advance

1 Answer 1

1

The Point here is:
The resources are resolved using the Class Path, and not along your project directory layout. This means that resource resolution start below
src/[main|test]/[java|resources]/

The best way to resolve a resource ist to look it up by

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

This way it does not matter it that resource is in a plain directory or inside a jar.

"the resource relative path" can start with a /. In that case it is resolved relative to the CLASSPATH root. If it does not start wit / it is resolved relative to the current package.

In your example it the folder planning is what you want you could either use

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

or

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

ATTENTION!

Always use forward slashes (/) in path names. Java handles them correctly on windows too.

Sign up to request clarification or add additional context in comments.

6 Comments

Thank you @Timothy, I tested the approach but as I am trying to get the resource from a static context, (given this [post] (stackoverflow.com/questions/53641486/…) . I have used the following File file = new File(RunCapacityPlanning.class.getResource("/com/moga/planning/paramsGeneral.txt").toURI());//compiles, but throws java.lang.IllegalArgumentException: URI is not hierarchical.
I have found this post. However as I try InputStream input = RunCapacityPlanning.class.getClassLoader().getResourceAsStream("/com/moga/planning/paramsGeneral.txt"); System.out.println("Available bytes in the file: " + input.available());//prompts a "java.lang.NullPointerException). I think i might be missing something or overcomplicating.
RunCapacityPlanning.class.getClassLoader().getResourceAsStream() behaves different than RunCapacityPlanning.class.getResourceAsStream()!
"as I am trying to get the resource from a static context" -- you can assign the resource from a static initializer. Of cause the class variable cannot be final in that case...
Thank you, I did not notice the difference. Just to make sure I understood, by assigning the resource from a static initializer you mean this RunCapacityPlanning.class.getResource("/com/moga/planning/paramsGeneral.txt").toURI()), right? Would you suggest another alternative to the Exception raised java.lang.IllegalArgumentException: URI is not hierarchical?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.