如何从META-INF目录加载属性文件? [英] how to load a properties file from the META-INF directory?

查看:251
本文介绍了如何从META-INF目录加载属性文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否正确地说,在 JAR 执行过程中使用的属性最好属于 META-INF ?符合标准目录布局的概念指定 Maven



假设需要结构, properties META-INF ?

加载的文件

  thufir @ doge:〜/ NetBeansProjects / json_parser $ 
thufir @ doge:〜/ NetBeansProjects / json_parser $ java -jar build / libs / json_parser-all.jarAug 18,2017 6:44:24 AM net。 bounceme.doge.json.Main main
INFO:开始
8月18日2017年6:44:24 net.bounceme.doge.json.Main run
INFO:其实
2017年8月18日上午6时44分24秒net.bounceme.doge.json.PropertiesReader tryGetProps
INFO:属性
8月18日2017年6:44:24 net.bounceme.doge.json.PropertiesReader getProps
INFO:属性
线程main中的异常java.lang.NullPointerException $ java.util.Properties中的$ b $ $ $ LineReader.readLine(Proper tie.java:434)
在java.util.Properties.load0(Properties.java:353)$ b $在java.util.Properties.load(Properties.java:341)
在net .bounceme.doge.json.PropertiesReader.getProps(PropertiesReader.java:26)
at net.bounceme.doge.json.PropertiesReader.tryGetProps(PropertiesReader.java:16)
at net.bounceme.doge .json.Main.run(Main.java:18)
at net.bounceme.doge.json.Main.main(Main.java:12)
thufir @ doge:〜/ NetBeansProjects / json_parser $
thufir @ doge:〜/ NetBeansProjects / json_parser $ jar tf build / libs / json_parser-all.jarMETA-INF /
META-INF / MANIFEST.MF
META-INF / maven /
META-INF / maven / javax.json /
META-INF / maven / javax.json / javax.json -api /
META-INF / maven / javax.json / javax.json -api / pom.properties
META-INF / maven / javax.json / javax.json -api / pom.xml
javax /
javax / json /
javax / json /Json.class
javax / json / JsonArray.class
javax / json / JsonArrayBuilder.class
javax / json / JsonBuilderFactory.class
javax / json / J sonException.class
javax / json / JsonMergePatch.class
javax / json / JsonNumber.class
javax / json / JsonObject.class
javax / json / JsonObjectBuilder.class
javax / json / JsonPatch $ Operation.class
javax / json / JsonPatch.class
javax / json / JsonPatchBuilder.class
javax / json / JsonPointer.class
javax / json /JsonReader.class
javax / json / JsonReaderFactory.class
javax / json / JsonString.class
javax / json / JsonStructure.class
javax / json / JsonValue $ ValueType.class
javax / json / JsonValue.class
javax / json / JsonValueImpl.class
javax / json / JsonWriter.class
javax / json / JsonWriterFactory.class
javax / json / spi /
javax / json / spi / JsonProvider.class
javax / json / stream /
javax / json / stream / JsonCollectors.class
javax / json / stream / JsonGenerationException.class
javax / json / stream / JsonGenerator.class
javax / json / stream / JsonGeneratorFactory.class
javax / json / stream / JsonLocation.class
javax / json / stream / JsonParser $ Event.class
javax / json / stream / JsonParser.class
javax / json / stream / JsonParserFactory.class
javax / json / stream / JsonParsingException.class
module-info.class
net /
net / bounceme /
net / bounceme / doge /
net / bounceme / doge / json /
net / bounceme / doge / json / Main.class
net /bounceme/doge/json/Marshaller.class
net / bounceme / doge / json / PropertiesReader.class
net / bounceme / doge / json / JsonReader.class
json.json
properties.properties
META-INF / properties.properties
thufir @ doge:〜/ NetBeansProjects / json_parser $
thufir @ doge:〜/ NetBeansProjects / json_parser $ jar tf build / libs / json_parser -all.jar | grep properties.properties
properties.properties
META-INF / properties.properties
thufir @ doge:〜/ NetBeansProjects / json_parser

和相关的代码:

  package net.bounceme.doge以.json; 

import java.io.IOException;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

public class PropertiesReader {

private static final Logger log = Logger.getLogger(PropertiesReader.class.getName());

公共属性tryGetProps(String propertiesFileName){
log.info(propertiesFileName);
属性properties = new Properties();
尝试{
properties = getProps(propertiesFileName);
} catch(IOException ex){
Logger.getLogger(PropertiesReader.class.getName()).log(Level.SEVERE,null,ex);
}
返回属性;


私有属性getProps(String propertiesFileName)抛出IOException {
log.info(propertiesFileName);
属性properties = new Properties();
properties.load(PropertiesReader.class.getResourceAsStream(/ META-INF /+ propertiesFileName));
log.info(properties.toString());
返回属性;


这是在关系在gradle中根据 init >。 com / q / 6683375/262852>一般信息。



我尝试将 / 删除为建议 - 与上述结果相同。

解决方案

您无需储存META-INF中的属性文件,实际上它甚至不常见(至少在我的经验中)。为了支持这个争论, Java JAR规范不包含META-INF预期内容中的属性文件。

下面的代码展示了从JAR加载属性的几种方法,不管它们是是否在META-INF中。



给定一个包含以下内容的JAR文件:

  jar -tvf properties.jar 
0 Fri Aug 18 15:35:52 IST 2017 META-INF /
68 Fri Aug 18 15:35:52 IST 2017 META-INF / MANIFEST .MF
4 Fri Aug 18 15:35:32 IST 2017 META-INF / bProps.properties
4 Fri Aug 18 15:35:18 IST 2017 aProps.properties

您可以加载 aProps.properties bProps.properties 像这样:

  @Test $ b $ public void canWriteAndRead()throws IOException {
ClassLoader systemClassLoader = ClassLoader.getSyst emClassLoader();
//这个工程
loadProperties(systemClassLoader.getResource(aProps.properties));
//这个工程
loadProperties(systemClassLoader.getResource(META-INF / bProps.properties));
//这不起作用
loadProperties(systemClassLoader.getResource(/ aProps.properties));
//这不起作用
loadProperties(systemClassLoader.getResource(/ META-INF / bProps.properties));

ClassLoader classLoader = getClass()。getClassLoader();
//这个工程
loadProperties(classLoader.getResource(aProps.properties));
//这个工程
loadProperties(classLoader.getResource(META-INF / bProps.properties));
//这不起作用
loadProperties(classLoader.getResource(/ aProps.properties));
//这不起作用
loadProperties(classLoader.getResource(/ META-INF / bProps.properties));

//这个工程
loadProperties(getClass()。getResourceAsStream(/ aProps.properties));
//这个工程
loadProperties(getClass()。getResourceAsStream(/ META-INF / bProps.properties));
//这不起作用
loadProperties(getClass()。getResourceAsStream(aProps.properties));
//这不起作用
loadProperties(getClass()。getResourceAsStream(META-INF / bProps.properties));

$ b private void loadProperties(InputStream incoming)throws IOException {
if(incoming!= null){
Properties properties = new Properties();
properties.load(incoming);
for(String s:properties.stringPropertyNames()){
System.out.println(s);
}

}

private void loadProperties(URL incoming)抛出IOException {
if(incoming!= null){
属性properties = new Properties();
properties.load(incoming.openStream());
for(String s:properties.stringPropertyNames()){
System.out.println(s);
}
}
}


Is it correct to say that properties files used in execution by a running JAR best belong in META-INF? The notion being to fit with the Standard Directory Layout specified by Maven.

Assuming that structure is desired, how is the properties file loaded from META-INF?

thufir@doge:~/NetBeansProjects/json_parser$ 
thufir@doge:~/NetBeansProjects/json_parser$ java -jar build/libs/json_parser-all.jarAug 18, 2017 6:44:24 AM net.bounceme.doge.json.Main main
INFO: starting
Aug 18, 2017 6:44:24 AM net.bounceme.doge.json.Main run
INFO: actually
Aug 18, 2017 6:44:24 AM net.bounceme.doge.json.PropertiesReader tryGetProps
INFO: properties
Aug 18, 2017 6:44:24 AM net.bounceme.doge.json.PropertiesReader getProps
INFO: properties
Exception in thread "main" 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 net.bounceme.doge.json.PropertiesReader.getProps(PropertiesReader.java:26)
    at net.bounceme.doge.json.PropertiesReader.tryGetProps(PropertiesReader.java:16)
    at net.bounceme.doge.json.Main.run(Main.java:18)
    at net.bounceme.doge.json.Main.main(Main.java:12)
thufir@doge:~/NetBeansProjects/json_parser$ 
thufir@doge:~/NetBeansProjects/json_parser$ jar tf build/libs/json_parser-all.jarMETA-INF/
META-INF/MANIFEST.MF
META-INF/maven/
META-INF/maven/javax.json/
META-INF/maven/javax.json/javax.json-api/
META-INF/maven/javax.json/javax.json-api/pom.properties
META-INF/maven/javax.json/javax.json-api/pom.xml
javax/
javax/json/
javax/json/Json.class
javax/json/JsonArray.class
javax/json/JsonArrayBuilder.class
javax/json/JsonBuilderFactory.class
javax/json/JsonException.class
javax/json/JsonMergePatch.class
javax/json/JsonNumber.class
javax/json/JsonObject.class
javax/json/JsonObjectBuilder.class
javax/json/JsonPatch$Operation.class
javax/json/JsonPatch.class
javax/json/JsonPatchBuilder.class
javax/json/JsonPointer.class
javax/json/JsonReader.class
javax/json/JsonReaderFactory.class
javax/json/JsonString.class
javax/json/JsonStructure.class
javax/json/JsonValue$ValueType.class
javax/json/JsonValue.class
javax/json/JsonValueImpl.class
javax/json/JsonWriter.class
javax/json/JsonWriterFactory.class
javax/json/spi/
javax/json/spi/JsonProvider.class
javax/json/stream/
javax/json/stream/JsonCollectors.class
javax/json/stream/JsonGenerationException.class
javax/json/stream/JsonGenerator.class
javax/json/stream/JsonGeneratorFactory.class
javax/json/stream/JsonLocation.class
javax/json/stream/JsonParser$Event.class
javax/json/stream/JsonParser.class
javax/json/stream/JsonParserFactory.class
javax/json/stream/JsonParsingException.class
module-info.class
net/
net/bounceme/
net/bounceme/doge/
net/bounceme/doge/json/
net/bounceme/doge/json/Main.class
net/bounceme/doge/json/Marshaller.class
net/bounceme/doge/json/PropertiesReader.class
net/bounceme/doge/json/JsonReader.class
json.json
properties.properties
META-INF/properties.properties
thufir@doge:~/NetBeansProjects/json_parser$ 
thufir@doge:~/NetBeansProjects/json_parser$ jar tf build/libs/json_parser-all.jar | grep properties.properties
properties.properties
META-INF/properties.properties
thufir@doge:~/NetBeansProjects/json_parser$ 

and the relevant code:

package net.bounceme.doge.json;

import java.io.IOException;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

public class PropertiesReader {

    private static final Logger log = Logger.getLogger(PropertiesReader.class.getName());

    public Properties tryGetProps(String propertiesFileName) {
        log.info(propertiesFileName);
        Properties properties = new Properties();
        try {
            properties = getProps(propertiesFileName);
        } catch (IOException ex) {
            Logger.getLogger(PropertiesReader.class.getName()).log(Level.SEVERE, null, ex);
        }
        return properties;
    }

    private Properties getProps(String propertiesFileName) throws IOException {
        log.info(propertiesFileName);
        Properties properties = new Properties();
        properties.load(PropertiesReader.class.getResourceAsStream("/META-INF/" + propertiesFileName));
        log.info(properties.toString());
        return properties;
    }
}

This is in relation to using init properly from gradle and based on general information.

I tried removing the leading / as suggested -- same result as above.

解决方案

You're not obliged to store your properties files in META-INF, indeed it's not even very common to do so (in my experience at least). In support of this contention the Java JAR Specification doesn't include properties files amongst the expected contents of META-INF.

The code below shows several approach to loading properties from a JAR, whether they are in META-INF or not.

Given a JAR file with this content:

jar -tvf properties.jar
   0 Fri Aug 18 15:35:52 IST 2017 META-INF/
  68 Fri Aug 18 15:35:52 IST 2017 META-INF/MANIFEST.MF
   4 Fri Aug 18 15:35:32 IST 2017 META-INF/bProps.properties
   4 Fri Aug 18 15:35:18 IST 2017 aProps.properties

You can load aProps.properties and bProps.properties like so:

@Test
public void canWriteAndRead() throws IOException {
    ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
    // this works
    loadProperties(systemClassLoader.getResource("aProps.properties"));
    // this works
    loadProperties(systemClassLoader.getResource("META-INF/bProps.properties"));
    // this does not work
    loadProperties(systemClassLoader.getResource("/aProps.properties"));
    // this does not work
    loadProperties(systemClassLoader.getResource("/META-INF/bProps.properties"));

    ClassLoader classLoader = getClass().getClassLoader();
    // this works
    loadProperties(classLoader.getResource("aProps.properties"));
    // this works
    loadProperties(classLoader.getResource("META-INF/bProps.properties"));
    // this does not work
    loadProperties(classLoader.getResource("/aProps.properties"));
    // this does not work
    loadProperties(classLoader.getResource("/META-INF/bProps.properties"));

    // this works
    loadProperties(getClass().getResourceAsStream("/aProps.properties"));
    // this works
    loadProperties(getClass().getResourceAsStream("/META-INF/bProps.properties"));
    // this does not work
    loadProperties(getClass().getResourceAsStream("aProps.properties"));
    // this does not work
    loadProperties(getClass().getResourceAsStream("META-INF/bProps.properties"));
}

private void loadProperties(InputStream incoming) throws IOException {
    if (incoming != null) {
        Properties properties = new Properties();
        properties.load(incoming);
        for (String s : properties.stringPropertyNames()) {
            System.out.println(s);
        }
    }
}

private void loadProperties(URL incoming) throws IOException {
    if (incoming != null) {
        Properties properties = new Properties();
        properties.load(incoming.openStream());
        for (String s : properties.stringPropertyNames()) {
            System.out.println(s);
        }
    }
}

这篇关于如何从META-INF目录加载属性文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆