【问题标题】:Project throwing IOException (File Not Found) when jar is run运行 jar 时项目抛出 IOException (File Not Found)
【发布时间】:2016-03-14 08:47:03
【问题描述】:

我使用 Eclipse 在 java 中创建了一个项目。

这是项目结构:

当我在 Eclipse 中将项目作为 java 应用程序运行时,它运行得非常好。

现在,我需要将其导出为 jar。因此,我使用此链接上第 3 个答案中描述的方法创建了 jar(由 Fever 回答):

Failing to run jar file from command line: “no main manifest attribute”

这是jar tf EventLogger.jar的输出:

META-INF/MANIFEST.MF
com/
com/project/
com/project/eventLogger/
com/project/eventLogger/KafkaConsumerGroup.class
com/project/eventLogger/KafkaProducer.class
com/project/eventLogger/ConsumeConfig.class
com/project/eventLogger/ConsumerThread.class
com/project/eventLogger/Formatter.class
com/project/eventLogger/Execute.class
com/project/eventLogger/Config.class
com/project/eventLogger/package-info.class
com/project/eventLogger/ProdConfig.class
com/project/eventLogger/FormatConfig.class
resources/
resources/Config.properties
resources/ConsumerConfig.properties
resources/FormatterConfig.properties
resources/ProducerConfig.properties
resources/log4j.properties

这是清单文件:

Manifest-Version: 1.0
Built-By: vishrant
Class-Path: lib/json-simple-1.1.1.jar lib/junit-4.10.jar lib/hamcrest-
 core-1.1.jar lib/kafka_2.9.2-0.8.2.2.jar lib/jopt-simple-3.2.jar lib/
 kafka-clients-0.8.2.2.jar lib/log4j-1.2.16.jar lib/lz4-1.2.0.jar lib/
 metrics-core-2.2.0.jar lib/slf4j-api-1.7.6.jar lib/snappy-java-1.1.1.
 7.jar lib/slf4j-log4j12-1.6.1.jar lib/zkclient-0.3.jar lib/zookeeper-
 3.4.6.jar lib/jline-0.9.94.jar lib/netty-3.7.0.Final.jar lib/scala-li
 brary-2.9.2-RC3.jar
Build-Jdk: 1.8.0_74
Created-By: Maven Integration for Eclipse
Main-Class: com.project.eventLogger.Execute

而且,这里是个例外:

java.io.FileNotFoundException: ConsumerConfig.properties (No such file or directory)
    at java.io.FileInputStream.open0(Native Method)
    at java.io.FileInputStream.open(FileInputStream.java:195)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at com.project.eventLogger.ConsumeConfig.loadPropertiesFile(ConsumeConfig.java:34)
    at com.project.eventLogger.ConsumeConfig.<clinit>(ConsumeConfig.java:42)
    at com.project.eventLogger.Execute.main(Execute.java:18)
Exception in thread "main" java.lang.ExceptionInInitializerError
    at com.project.eventLogger.Execute.main(Execute.java:18)
Caused by: java.lang.NullPointerException
    at com.project.eventLogger.ConsumeConfig.<clinit>(ConsumeConfig.java:47)
    ... 1 more

看到异常,很明显它无法加载ConsumerConfig.properties,这是在ConsumeConfig.java中完成的。

这里是ConsumeConfig.java

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Properties;

/**
 * @author vishrant
 *
 */
public class ConsumeConfig {

    public static String zookeeper;
    public static String balance;
    public static String bootstrap_servers;
    public static String zk_session_to;
    public static String zk_sync;
    public static String auto_commit;
    public static String[] topics;
    private static String kafka_bin;
    private static final String PROPERTIES_FILE_PATH = "src/main/resources/ConsumerConfig.properties";

    private static Properties loadPropertiesFile() throws IOException {
        Properties properties = new Properties();
        InputStream in = new FileInputStream(PROPERTIES_FILE_PATH);
        properties.load(in);
        return properties;
    }

    static {
        Properties property = null;
        try {
            property = loadPropertiesFile();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        zookeeper = property.getProperty("ZOOKEEPER");
        balance = property.getProperty("BALANCE");
        bootstrap_servers = property.getProperty("BOOTSTRAP_SERVERS");
        zk_session_to = property.getProperty("ZK_SESSION_TO");
        zk_sync = property.getProperty("ZK_SYNC_TIME");
        auto_commit = property.getProperty("AUTO_COMMIT_INTERVAL");
        topics = property.getProperty("CONSUMER_TOPICS").split(",");
        kafka_bin = property.getProperty("KAFKA_BIN_PATH");
    }
}

谁能告诉我这是什么问题以及如何解决?

当在 Eclipse 中运行时,它运行得非常好。

编辑1:

现在,例外是:

Exception in thread "main" java.lang.ExceptionInInitializerError
    at com.project.eventLogger.Execute.main(Execute.java:18)
Caused by: java.lang.NullPointerException
    at java.util.Properties$LineReader.readLine(Properties.java:434)
    at java.util.Properties.load0(Properties.java:353)
    at java.util.Properties.load(Properties.java:341)
    at com.project.eventLogger.ConsumeConfig.loadPropertiesFile(ConsumeConfig.java:35)
    at com.project.eventLogger.ConsumeConfig.<clinit>       (ConsumeConfig.java:42)
    ... 1 more

第 35 行:

props.load(resourceStream);

这是现在的代码:

private static final String PROPERTIES_FILE_PATH = "ConsumerConfig.properties";

private static Properties loadPropertiesFile() throws IOException {
    ClassLoader loader = Thread.currentThread().getContextClassLoader();
    Properties props = new Properties();
    InputStream resourceStream = loader.getResourceAsStream(PROPERTIES_FILE_PATH);
    props.load(resourceStream);
    return props;
}

【问题讨论】:

  • jar 中的对象是 not 文件,您不能使用基于文件的 API(例如 FileInputStream)来访问它们。看Class.getResourceAsStream
  • 现在您可以复制粘贴应该可以使用的方法。否则肯定是配置有问题或者Resources他所在的文件夹不可用。
  • 是的...@VikrantKashyap,这确实是问题所在。我将路径更改为 resources/ConsumerConfig.properties 并且成功了。
  • 你能告诉我为什么会出现这个问题。我应该如何制作罐子才能使结构良好。

标签: java eclipse maven jar properties


【解决方案1】:

我认为原因如下:

  • 没有为 maven 项目正确创建 jar 文件,因为目录 resources 通常不会按原样复制到 target 目录,即,而不是 李>

资源/Config.properties

它应该看起来像没有 resources 目录:

配置属性

直接在jar文件的根目录下。

  • 第二点是您在代码中使用了以下内容

私有静态最终字符串 PROPERTIES_FILE_PATH = "src/main/resources/ConsumerConfig.properties";

此路径在您的 IDE(在本例中为 Eclipse)之外不会看到,因为 src/main/resources 不应存在于 jar 文件中,正如您在 jar 文件列表中看到的那样.

  • 最后一点是,您应该像 Vikrant Kashyap 已经指出的那样使用类加载器的 getResourceAsStream()。

【讨论】:

  • 感谢您指出我的 jar 结构中的问题。我将代码中的路径从ConsumerConfig.properties 更改为resources/ConsumerConfig.properties,效果很好。
  • 你能告诉我为什么会出现这个问题。我应该如何制作罐子才能使结构良好。
  • 你应该只使用 mvn package 并且jar文件将在目标目录下创建。
  • 还有一点:您也可以在 Eclipse 中创建 jar 文件:右键单击 pom.xml 文件并单击 Run As > Maven install,然后正确jar 文件将在 *target 目录中创建。
  • 谢谢。第一个效果很好。 (没有尝试第二次)
【解决方案2】:

试试这个

// Change Your File Path First.
private static final String PROPERTIES_FILE_PATH = "ConsumerConfig.properties";

private static Properties loadPropertiesFile() throws IOException {
    Properties properties = new Properties();

    // First way to load ResourceAsStream.
    // ClassLoader loader = Thread.currentThread().getContextClassLoader();
    // InputStream resourceStream = loader.getResourceAsStream(PROPERTIES_FILE_PATH);
    // Second way to load ResourceAsStream.
    InputStream resourceStream = ConsumeConfig.class.getResourceAsStream(PROPERTIES_FILE_PATH);
    properties.load(resourceStream);
    return properties;
}

【讨论】:

  • resourceName 应该是路径还是只是名称?
  • 它应该只是一个文件名而不是绝对路径,因为在 Maven 资源文件夹只是一个虚拟文件夹。如果我们部署为 war,它将不会出现在 War File 中
  • 用这个替换你的方法..你可能不会出错
  • 是的......我做了所有这些。我之前试过这是一个单独的项目,它不是 maven ......也许这就是它不起作用的原因。
  • 现在,在这个项目中,我已经编辑了所有内容,并且在运行 Eclipse 时效果很好。但同样,当我创建 jar 时,它在同一行上给出了一个新的 (NullPointer) 异常。
猜你喜欢
  • 1970-01-01
  • 2011-11-01
  • 2015-02-08
  • 1970-01-01
  • 1970-01-01
  • 2014-03-22
  • 2011-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多