Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何从META-INF目录加载属性文件?_Java_Maven_Gradle_Jar_Meta Inf - Fatal编程技术网

Java 如何从META-INF目录加载属性文件?

Java 如何从META-INF目录加载属性文件?,java,maven,gradle,jar,meta-inf,Java,Maven,Gradle,Jar,Meta Inf,运行的JAR在执行过程中使用的properties文件最好属于META-INF是否正确?其概念是通过Maven与标准目录布局相匹配 假设需要这种结构,那么如何从META-INF加载properties文件 thufir@doge:~/NetBeansProjects/json_parser$ thufir@doge:~/NetBeansProjects/json_parser$ java -jar build/libs/json_parser-all.jarAug 18, 2017 6:44:

运行的
JAR
在执行过程中使用的
properties
文件最好属于
META-INF
是否正确?其概念是通过
Maven
与标准目录布局相匹配

假设需要这种结构,那么如何从
META-INF
加载
properties
文件

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$ 
及有关守则:

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;
    }
}
这是为了正确使用gradle提供的基于信息的
init


我尝试删除前导的
/
,结果与上面相同。

您没有义务将属性文件存储在META-INF中,事实上,这样做并不常见(至少在我的经验中)。为了支持此争用,在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
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);
        }
    }
}

“说运行JAR在执行过程中使用的属性文件最好属于META-INF是正确的吗?”。我认为不应该。IMHO
META-INF
应该包含关于JAR本身的信息(因此pom.properties和pom.xml Maven放进去),这样框架/应用服务器就可以更好地了解如何处理这个问题(想想OSGi的MANIFEST.MF,META-INF/EJBJAR.xml…)。也就是说,它只是另一个包,因此加载属性文件的方式应该与加载.TL的方式相同;不,我会的,谢谢你挖掘官方文件。仍然想知道为什么Maven会有这样的惯例。也许它更倾向于战争文件,但出于某种原因,他们已经将其推广。我觉得很奇怪。(我的尝试有一个小错误:顺便说一句,这是固定的。)