【问题标题】:FileNotFoundException starting jar - can't see file in resources folderFileNotFoundException 启动 jar - 在资源文件夹中看不到文件
【发布时间】:2014-11-01 07:44:36
【问题描述】:

我希望我的应用程序独立于操作系统。因此,我的 config.properties 和日志文件存储在资源文件夹中,我通过相对路径获取这些资源。 这是我的项目结构。

这是我的 AppConfig 类:

public final class AppConfig {

private static final String RELATIVE_PATH_TO_PROPERTIES = "./src/main/resources/config.properties";
public static final String RELATIVE_LOG_PATH = "./src/main/resources/err_action.log";

private static Properties props = initProperties();
public static final String HOST = props.getProperty("ip_address");

public static final int PORT = Integer.valueOf(props.getProperty("port"));
public static final int MAX_USERS = Integer.valueOf(props.getProperty("max_number_of_users"));
public static final int NUM_HISTORY_MESSAGES = Integer.valueOf(props.getProperty("last_N_messages"));

private static Properties initProperties() {
    Properties properties = null;
    try (FileInputStream input = new FileInputStream(RELATIVE_PATH_TO_PROPERTIES)) {
        properties = new Properties();
        properties.load(input);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return properties;
}
}

如您所见,我指定了属性和日志文件的相对路径。 我用 maven 创建 jar,当我运行它时,我收到

java.io.FileNotFoundException: ./src/main/resources/err_action.log(没有这样的文件或目录)

UPD 这是我的 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0          http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>chat</groupId>
<artifactId>Client-Chat</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<properties>
    <java_version>1.8</java_version>
</properties>
<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
                <source>${java_version}</source>
                <target>${java_version}</target>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>nikochat.com.app.Main</mainClass>
                        <!--<mainClass>nikochat.com.app.RunClient</mainClass>-->
                    </manifest>
                </archive>
            </configuration>
        </plugin>

    </plugins>
</build>
</project>

我使用 Intellij Idea 并运行 maven package 命令,其结果是下一个输出:

[INFO] 正在扫描项目... [INFO] -------------------------------------------------- ---------------------- [INFO] 未命名的建筑物 - chat:Server-Chat:jar:1.0 [INFO]
任务段:[包] [信息] -------------------------------------------------- ---------------------- [INFO] [resources:resources {execution: default-resources}] [WARNING] 使用平台编码(实际上是 UTF-8)复制过滤后的资源, 即构建依赖于平台! [INFO] 复制 2 个资源 [INFO] [compiler:compile {execution: default-compile}] [INFO] Nothing to 编译 - 所有类都是最新的 [INFO] [resources:testResources {execution: default-testResources}] [警告] 使用平台编码 (实际上是UTF-8)复制过滤的资源,即构建是平台 依赖! [INFO] 跳过不存在的资源目录 /home/nikolay/IdeaProjects/Chat/src/test/resources [信息] [compiler:testCompile {execution: default-testCompile}] [INFO] 没有 编译 - 所有类都是最新的 [INFO] [surefire:test {execution: default-test}] [INFO] Surefire 报告目录: /home/nikolay/IdeaProjects/Chat/target/surefire-reports

----------------------------------- -------- 测试 -------------------------------------------------- ----- 运行 AppConfigTest 测试运行:2,失败:0,错误:0,跳过:2,时间 经过:0.129 秒

结果:

测试运行:2,失败:0,错误:0,跳过:2

[INFO] [jar:jar {execution: default-jar}] [INFO] 构建 jar: /home/nikolay/IdeaProjects/Chat/target/Server-Chat-1.0.jar [信息] -------------------------------------------------- ---------------------- [信息] 构建成功 [信息] -------------------------------------------------- ---------------------- [INFO] 总时间:11 秒 [INFO] 完成时间:Mon Sep 08 09:47:18

EEST 2014 [INFO] 最终内存:18M/154M [INFO]

一开始我创建了 Server-Chat jar 来运行应用程序的服务器部分,然后我将 artifactId 更改为 Client-Chat 并清单 mainClass 以创建应用程序的客户端部分。 我在终端输入命令中运行的两个部分: java -jar Server-Chat-1.0.jarjava -jar Client-Chat-1.0.jar 分别。

这是服务器的输出:

java.io.FileNotFoundException: config.properties(没有这样的文件或目录) 在 java.io.FileInputStream.open(Native Method)

和客户:

eaProjects/Chat/target $ java -jar Client-Chat-1.0.jar java.io.FileNotFoundException: config.properties (没有这样的文件或目录)

【问题讨论】:

  • 你是用maven来创建jar的吗?
  • 请记住,当您说相对路径时,它将与您的类文件相关,而不是您的源文件。
  • 是的,我正在使用 maven。
  • 不需要指定这些路径; Maven 将 src/main/resources 中的任何 ia 复制到您的 jar 中的主文件夹中,但此外,该路径中的文件直接在您的 classpath 中可用,因此您可以在不指定任何文件夹的情况下加载它。这些文件夹结构仅用于代码源组织,但不一定是最终 jar 的文件夹结构。

标签: java jar resources filenotfoundexception platform-independent


【解决方案1】:

下面的代码应该允许加载位于资源文件夹中的config.properties文件,该文件在构建后部署到jar文件的根目录:

public final class AppConfig {

private static final String RELATIVE_PATH_TO_PROPERTIES="config.properties";
...
private static Properties initProperties() {
    Properties properties = null;

    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    FileInputStream input =    classLoader.getResourceAsStream(RELATIVE_PATH_TO_PROPERTIES);
    try {
        properties = new Properties();
        properties.load(input);
    } catch (IOException e) {
        e.printStackTrace();
    }
    ...
    return properties;
    }
}

IOW 以下代码允许从 jar 应用程序的类路径加载文件:

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
FileInputStream input = classLoader.getResourceAsStream(<relative path of the file located in the jar app>);

【讨论】:

    【解决方案2】:

    src/main/resources 是拥有资源文件的 maven 约定。当 maven 构建 jar/war 工件时,它会将 src/main/resources 中的所有文件/目录添加到生成的工件的类路径

    运行时没有可用的 src/main/resources

    在您的情况下,您可以更新您的程序以读取这些文件,而无需提供任何路径。如下所示

    private static final String RELATIVE_PATH_TO_PROPERTIES = "config.properties";
    public static final String RELATIVE_LOG_PATH = "err_action.log";
    

    【讨论】:

    • 我试着照你说的做,但仍然收到 java.io.FileNotFoundException: config.properties (No such file or directory)
    • 也许我需要从 jar 中读取文件?我看到了放在根文件夹 "/" 中的 jar、属性和日志文件的结构。我将配置类中的路径更改为: /config.properties /err_action.log 现在我收到 FileNotFoundException: /err_action.log (Permission denied)
    • 也许有另一种解决方案可以制作一个独立于平台的应用程序来避免这个权限被拒绝错误?
    • 是的,你是对的。我在写入日志文件时遇到了一些问题,这就是应用无法运行的原因。
    猜你喜欢
    • 1970-01-01
    • 2011-12-18
    • 2020-05-27
    • 2015-12-17
    • 1970-01-01
    • 1970-01-01
    • 2012-09-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多