【问题标题】:properties file not found within web application在 Web 应用程序中找不到属性文件
【发布时间】:2014-11-30 20:30:26
【问题描述】:

我正在尝试从我的 Web 应用程序(一个简单的 Servlet 应用程序)调用 JAR 文件中存在的方法。以下是该方法用于访问属性文件的代码:

InputStream inputStream = 
            ClassLoader.getSystemClassLoader()
                       .getResourceAsStream("demo.properties");

properties.load(inputStream);

当使用我的 Web 应用程序调用此方法时,我得到了 NullPointerException

java.lang.NullPointerException
    at java.util.Properties$LineReader.readLine(Unknown Source)
    at java.util.Properties.load0(Unknown Source)
    at java.util.Properties.load(Unknown Source)

此异常的可能原因是:我的 Web 应用程序无法找到 demo.properties 文件,因此 inputStreamNULL 并引发此异常。

请告诉我:

  1. 如何解决此异常。

  2. 我是否需要在我的基于 Web 的应用程序中手动放置属性文件?如果是,那么在我的 Web 应用程序中将这个 demo.properties 文件放置在何处以解决此异常。

【问题讨论】:

  • demo.properties 目前在 jar 中的什么位置?
  • src 文件夹是一个项目文件夹。生成的.jar 中的文件在哪里?
  • 反编译器?不是压缩包吗?
  • @Brandon 反编译器将打开 zip 存档(当然也会反编译类文件)
  • 我认为您使用了错误的类加载器。系统类加载器(通常)不会看到您的 Web 应用程序类,而只会处理核心 Java 类,如 java.lang.*、java.util.* 等。

标签: java jakarta-ee servlets web-applications web


【解决方案1】:

系统类加载器只知道核心 Java 库,例如 java.lang.、java.util. 等中的库。

您希望使用查看该 JAR 文件的相同类加载器来加载属性文件,该类加载器可能与加载您的类的类加载器相同。

试试这样的:

public class PropertyFileTest {
    public void loadProperties() {
        InputStream inputStream = PropertyFileTest.class.getResourceAsStream("/demo.properties");

        properties.load(inputStream);
        // do something with properties to see if it worked or not.
    }
}

请注意,我使用了 Class.getResourceAsStream,它将为您使用该类的类加载器:

http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html

【讨论】:

  • 从您的评论中我可以理解的是:我的 Web 应用程序正在使用 <ClaccName>.class.getResourceAsStream 加载器来加载 jar 中存在的类文件,因此 jar 文件也应该使用相同的类来加载属性字段 - 正确吗?
  • 我是说加载你的类的类加载器应该是可以加载属性文件的同一个类加载器。系统类加载器对您的 JAR 文件一无所知,因此对您的类 OR 属性文件一无所知。
  • 我相信我糊涂了!!!我正在从 jar 文件访问 properties 文件。我的Web Application 正在通过调用 jar 文件方法来访问 jar 文件(我不是直接在我的 Web 应用程序中调用属性文件,而是使用 jar 文件本身来调用它)。
  • 我不清楚“调用属性文件”或“调用 jar 文件方法”是什么意思。您是否尝试过上述方法,看看是否有效?
  • 感谢您的帮助,我得到了您的输入。
【解决方案2】:

ClassLoader 无法识别属性文件的位置。

使用此代码:

String path  = AbcServiceImpl.class.getClassLoader().getResource("abc.properties").getFile().toString();
path = path.replace("%20", " ");
File f = new File(path);

【讨论】:

    【解决方案3】:

    类加载器将传递的字符串解释为绝对路径,因此就好像它是/demo.properties(但不要对ClassLoader.getResource 使用标题斜线)。所以打开战争并寻找/WEB-INF/classes/demo.properties。这必须区分大小写。

    您可能(通常)对替代品感兴趣:

    • MyServletClass.class.getResourceAsStream("/demo.properties") -- 更好;
    • ResourceBundle bundle = ResourceBundle.get("demo");
    • /WEB-INF/web.xml中使用Servlet的init参数。

    【讨论】:

    • @SotiriosDelimanolis 我试图用“好像它是”和“但从不使用 ClassLoader 的斜线”来表达。
    • 在这种情况下,您可以使用SomeJarClass.class.getResourceAsStream("/demo.properties")。不同之处在于 ClassLoader 与类加载器搜索类路径(几个 jar)处于某种层次结构中,而直接使用该类处理一个 jar,更直接。
    • 好的,这意味着您要求我更改当前访问 Jar 文件中的属性文件的方式。我需要使用ClassName.class.getResourceAsStream 方法而不是使用ClassLoader.getSystemClassLoader() .getResourceAsStream 方法,对吗?请确认我是否理解正确。
    • 就像下面的答案
    • 是的,顺便说一句,系统类加载器似乎也有注释警告。我认为@Brandon 确实值得接受,如果这能解决问题。
    猜你喜欢
    • 1970-01-01
    • 2012-03-07
    • 2016-05-04
    • 1970-01-01
    • 1970-01-01
    • 2015-08-07
    • 1970-01-01
    • 2015-08-28
    • 2011-06-25
    相关资源
    最近更新 更多