使用Maven-shade-plugin读取资源文件uber jar构建

时间:2018-11-28 10:44:20

标签: java maven jar executable-jar maven-shade-plugin

我有一个简单的项目,该项目读取资源.yaml文件:

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

因此在IDE中可以正常工作。现在,我想构建一个可执行的uber JAR,它将包含内部的所有资源。我正在使用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>

因此,我希望资源文件包含在jar中。当我执行jar tf myapplication-0.0.1-SNAPSHOT.jar时,我可以看到jar中有文件config.yaml。但是,当我尝试使用java -jar运行它时,收到java.io.FileNotFoundException并显示一条消息,提示找不到config.yaml

1 个答案:

答案 0 :(得分:0)

这是 Andrea Boccacci 向我提供的解决方案。这是他允许我在这里发布的答案:

您的文件位于jar文件中,因此您无法从File类访问该文件,请尝试使用getResourceAsStream,如果有这样的API,请交换为readValue(InputStream, Class)。 如果不是,则可以将输入流写入实际的临时文件,然后调用readValue(File, Class),然后删除提取的文件。

因此,这是我的代码现在的外观及其工作方式:

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