简体   繁体   中英

Access files within resource directory in maven generated jar

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)

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 :)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM