如何从 META-INF 目录加载属性文件?
how to load a properties file from the META-INF directory?
运行 JAR
执行时使用的 properties
文件最好属于 META-INF
是否正确? Maven
.
的概念是为了适应标准目录布局 specified
假设需要该结构,如何从 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;
}
}
这在 relation to using init
properly from gradle and based on general 信息中。
我尝试删除前导 /
作为 suggested -- 结果与上面相同。
您没有义务将您的属性文件存储在 META-INF 中,事实上,这样做甚至不是很常见(至少以我的经验而言)。为了支持这一论点,Java JAR Specification 没有在 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
执行时使用的 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;
}
}
这在 relation to using init
properly from gradle and based on general 信息中。
我尝试删除前导 /
作为 suggested -- 结果与上面相同。
您没有义务将您的属性文件存储在 META-INF 中,事实上,这样做甚至不是很常见(至少以我的经验而言)。为了支持这一论点,Java JAR Specification 没有在 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);
}
}
}