本文介绍了使用可执行Jar时找不到Spring-Boot资源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我再次面临一个奇怪的问题,希望这里有人能提供帮助.

again I face a strange issue and hope someone here can help.

我有一个spring boot后端模块,在eclipse中运行良好,当在application.java中启动main时,应用程序是可执行的.一切都很好.

I have a spring boot backend module, what works in eclipse well and application is executeable when starting main in application.java. Everything fine.

我的应用程序使用src/main/resources文件夹中包含的csv文件将示例数据导入数据库.如前所述,在Eclipse中启动时一切正常.

My application makes import of example data to database using csv-files what is included in src/main/resources folder. As mentioned, when starting in eclipse everything works.

现在,我想将其作为可执行jar执行,该应用程序开始启动,然后启动失败,因为找不到csv文件.它打印出的路径,在哪里寻找文件的路径都是正确的,并且csv文件位于其中包含的jar中.

Now I would like to execute it as executable jar, the application begins to start and then it failed to start, because it cannot find the csv files. The path what it prints out, where it looked for the files, is correct and the csv files are in the jar included.

该模块的Pom如下所示:

The Pom of the module looks like follows:

<project>
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>at.company.bbsng</groupId>
        <artifactId>bbsng-import</artifactId>
        <version>0.1.0-SNAPSHOT</version>
    </parent>

    <artifactId>bbsng-import-backend</artifactId>
    <name>bbsng-import-backend</name>

    <properties>
        <start-class>at.company.bbsng.dataimport.Application</start-class>
    </properties>


    <dependencies>

        <!-- SPRING ... -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-batch</artifactId>
            <!-- EXCLUDE LOGBACK AND USE LOG4J -->
            <exclusions>
                <exclusion>
                    <artifactId>spring-boot-starter-logging</artifactId>
                    <groupId>org.springframework.boot</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- COMMONS ... -->

        ...

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

在属性文件中配置csv文件的路径如下:

Path to csv-files are configured in propery files as follows:

# EXAMPLE PATH
csv.path=config/csv/

java配置文件部分如下:

The part of java config file is as follows:

  ...

  @Value("${csv.path}")
  private String csvExamplePath;

  @Bean
  public Resource addressResource() {
    return new ClassPathResource(csvExamplePath + CSV_ADDRESS);
  }

    ...

在jar中,文件位于路径

In the jar the files are located at path

\config\csv\

Stacktrace:

Stacktrace:

Caused by: java.io.FileNotFoundException: class path resource [config/csv/Company.csv] cannot be resolved to absolute file path because it does not reside in th
e file system: jar:file:/C:/Development/Projekte/bbsng/trunk/import/backend/target/bbsng-import-backend-0.1.0-SNAPSHOT.jar!/config/csv/Company.csv
        at org.springframework.util.ResourceUtils.getFile(ResourceUtils.java:207)
        at org.springframework.core.io.AbstractFileResolvingResource.getFile(AbstractFileResolvingResource.java:52)
        at at.compax.bbsng.dataimport.app.source.company.CompanyGenerator.init(CompanyGenerator.java:28)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java

同样,从Eclipse启动应用程序时,它可以按预期工作,只有可执行的jar会抱怨缺少csv文件以及jar中已经存在的文件.

Again, the application works as expected when starting it from eclipse, only executable jar complains about missing csv-files, what are in jar already.

任何线索都很好.

推荐答案

好的,我已经找到了真正的问题和解决方案.

Okay, already I found the real problem and the solution.

首先,应用程序使用了正确的csv文件路径,但是当使用可执行jar时,还有另一个问题,我在下面的链接中找到了该文件. Stackoverflow-Link

First, the application use the correct path to the csv files, but there is another issue when using an executable jar what I found under following link. Stackoverflow-Link

在我遇到可执行jar之前,我使用以下解决方案来获取CSV文件(问题是getFile()):

Before I come to issue with executable jar I used following solution for getting CSV-File (Issue is getFile()):

final List<String> resourceLines = FileReadUtils.readLines(specialisationResource.getFile());
for (final String line : resourceLines) {
  data.add(getNewTransientSpecialisation(line));
}

但是在可执行的jar中,我无法将资源用作文件,我需要将其用作流,请参见上面提供的链接.所以我需要更改代码.如果您更喜欢使用本机Java,则可以执行以下操作:

But in executeable jar I cant use my resource as file, I need to use it as stream, see provided link above. So I needed to change my code. If you prefer using native java, you can do follows:

final InputStream inputStream = specialisationResource.getInputStream();
final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

String line;
while ((line = bufferedReader.readLine()) != null) {
    data.add(getNewTransientSpecialisation(line));
}

我更喜欢使用框架并使用如下所示的apache commons:

I prefer using frameworks and use apache commons like follows:

final List<String> resourceLines = IOUtils.readLines(specialisationResource.getInputStream());
for (final String line : resourceLines) {
    data.add(getNewTransientSpecialisation(line));
}

所以请记住,不要使用File()来获取资源,始终使用流确实可以避免从一开始就出现该问题:-)

So just remember, don't use File() for getting resource, always use stream do avoid that issue from beginning :-)

希望能帮助到某人.

这篇关于使用可执行Jar时找不到Spring-Boot资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 13:57