0

I've done my research, but I just really can't get it to work. I'm using Spring Boot with Maven. Thymeleaf and jquery for my frontend.

My directory:

project-system/ ├── mvnw ├── mvnw.cmd ├── pom.xml ├── src │ ├── main │ │ ├── java │ │ │ └── rigor │ │ │ └── io │ │ │ └── projectsystem │ │ │ ├── rush │ │ │ │ ├── TemporaryController.java │ │ │ └── ProjectSystemApplication.java │ │ └── resources │ │ ├── application.properties │ │ ├── MOCK_DATA.json │ │ ├── static │ │ └── templates │ │ ├── index.html │ │ └── records.html 

Inside TemporaryController, I'm doing this operation:

list = new ObjectMapper().readValue(new File("./src/main/resources/MOCK_DATA.json"), new TypeReference<List<POJO>>() {}); 

So with this, I'm able to access the MOCK_DATA.json under the resources directory.

But now, I want to package it into a jar. This is proving a bit troublesome for me. Here's my build in my pom file:

<build> <plugins> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>2.6</version> <executions> <execution> <id>copy-resources</id> <phase>validate</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory>${basedir}/target/classes/src/main</outputDirectory> <includeEmptyDirs>true</includeEmptyDirs> <resources> <resource> <directory>${basedir}/src/main/</directory> <filtering>false</filtering> </resource> </resources> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> <mainClass>rigor.io.projectsystem.ProjectSystemApplication</mainClass> </manifest> </archive> </configuration> </plugin> </plugins> </build> 

And the resulting target directory this gives me is:

├── target │ ├── classes │ │ ├── application.properties │ │ ├── MOCK_DATA.json │ │ ├── rigor │ │ │ └── io │ │ │ └── projectsystem │ │ │ ├── rush │ │ │ │ ├── TemporaryController.class │ │ │ └── ProjectSystemApplication.class │ │ ├── src │ │ │ └── main │ │ │ ├── java │ │ │ │ └── rigor │ │ │ │ └── io │ │ │ │ └── projectsystem │ │ │ │ ├── rush │ │ │ │ │ ├── TemporaryController.java │ │ │ │ └── ProjectSystemApplication.java │ │ │ └── resources │ │ │ ├── application.properties │ │ │ ├── MOCK_DATA.json │ │ │ ├── static │ │ │ └── templates │ │ │ ├── index.html │ │ │ └── records.html │ │ └── templates │ │ ├── index.html │ │ └── records.html │ ├── generated-sources │ │ └── annotations │ ├── generated-test-sources │ │ └── test-annotations │ ├── maven-archiver │ │ └── pom.properties │ ├── maven-status │ │ └── maven-compiler-plugin │ │ ├── compile │ │ │ └── default-compile │ │ │ ├── createdFiles.lst │ │ │ └── inputFiles.lst │ │ └── testCompile │ │ └── default-testCompile │ │ ├── createdFiles.lst │ │ └── inputFiles.lst │ ├── surefire-reports │ │ ├── rigor.io.projectsystem.ProjectSystemApplicationTests.txt │ │ └── TEST-rigor.io.projectsystem.ProjectSystemApplicationTests.xml │ ├── test-classes │ │ └── rigor │ │ └── io │ │ └── projectsystem │ │ ├── ProjectSystemApplicationTests$1.class │ │ └── ProjectSystemApplicationTests.class │ ├── project-system-0.0.1-SNAPSHOT.jar │ └── project-system-0.0.1-SNAPSHOT.jar.original 

As you can see, there are some redundancies that are happening, and when I try to run the jar file, it gives me a java.io.FileNotFoundException: ./src/main/resourfces/MOCK_DATA.json (No such file or directory)

2 Answers 2

1

You cannot treat internal jar resource as a regular file, you need to ask classloader to do it for you, and the path would be relative to top level of the jar (so you want just to ask classloader to load "MOCK_DATA.json" without any paths), or to /resources folder. This is how to do it:

Classpath resource within jar

BTW. /src/main/resources folder is automatic in maven unless you need to configure filtering etc other then defaults :)

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

3 Comments

I tried not coping the resources folder via maven plugin, but they're not put inside a resources directory. So I just want to clarify, the MOCK_DATA.json should be under the resources folder, then remove the maven-resources-plugin artifact i have in my pom, then use the classloader? I'm trying this but it's not working. ClassLoader is not finding my MOCK_DATA.json
Scratch just what I said. I'm now using getClass().getClassLoader().getResourceAsStream. It's good now.
@RigoSarmiento regarding the resources plugin what I wanted to say is : when the resource is in /src/main/resources in your project, then you dont need to declare the plugin because that one is default. Unless you want some specific plugin configuration. If you want additional resource directory or change the path to something else, then the plugin configuration would be necessary
1

If you're trying to read from a .jar, then

new File("./src/main/resources/MOCK_DATA.json"

will NOT work. Instead, you need Class.getResourceAsStream() or equivalent.

Here is an example:

https://www.tutorialspoint.com/java/lang/class_getresourceasstream.htm

 ... try { // input stream InputStream is = this.getClass().getResourceAsStream(MY-RESOURCE); BufferedReader br = new BufferedReader(new InputStreamReader(is)); ... is.close(); } catch(Exception e) { System.out.println(e); } 

Here are some additional details: How getClassLoader().getResourceAsStream() works in java

1 Comment

Your solution clarified things even more. Thanks!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.