简体   繁体   中英

Reading resource file uber jar build with maven-shade-plugin

I have a simple project that reads the resource .yaml file:

var yamlObjectMapper = new ObjectMapper(new YAMLFactory());
var classLoader = Application.class.getClassLoader();
var file = new File(Objects.requireNonNull(classLoader.getResource("config.yaml")).getFile());
var appConfig = yamlObjectMapper.readValue(file, ApplicationConfig.class);

So it works fine from the IDE. Now I want to build an executable uber JAR that will include all the resources inside. I'm using maven-shade-plugin .

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
        </resource>
    </resources>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.2.1</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <minimizeJar>true</minimizeJar>
                        <transformers>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                <mainClass>mypackage.Application</mainClass>
                            </transformer>
                        </transformers>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

So I'm expecting the resources files to be included in the jar. And when I'm executing jar tf myapplication-0.0.1-SNAPSHOT.jar I can see that inside the jar there is file config.yaml . However when I try to run it with java -jar I receive the java.io.FileNotFoundException with message that config.yaml cannot be found.

Here is the solution provided to me by Andrea Boccacci . Here is his answer that he alow me to post here:

Your file is inside a jar file so you can't access it from File class try to use getResourceAsStream and then swap to readValue(InputStream, Class) if there's such an API. if not you can write the input stream to an actual temp file then call readValue(File, Class) and then delete the extracted file.

So here is how my code looks right now and it works:

var yamlObjectMapper = new ObjectMapper(new YAMLFactory());
var classLoader = Application.class.getClassLoader();
var resource = classLoader.getResourceAsStrean("config.yaml");
var appConfig = yamlObjectMapper.readValue(resource, ApplicationConfig.class);

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