Java 在同级目录中加载外部属性文件
以下场景Java 在同级目录中加载外部属性文件,java,maven,properties,classpath,maven-assembly-plugin,Java,Maven,Properties,Classpath,Maven Assembly Plugin,以下场景 ./ config/ application.properties lib/ properties-loader-0.0.1-SNAPSHOT.jar acme.sh properties-loader-0.0.1-SNAPSHOT.jar是一个带有清单文件的可执行jar。 jar中有一个包com.acme.lab,只包含类 使用完全限定名com.acme.lab.PropertiesLoader 脚本acme.sh执行以下命令: java -cp etc/ap
./
config/
application.properties
lib/
properties-loader-0.0.1-SNAPSHOT.jar
acme.sh
properties-loader-0.0.1-SNAPSHOT.jar
是一个带有清单文件的可执行jar。
jar中有一个包com.acme.lab
,只包含类
使用完全限定名com.acme.lab.PropertiesLoader
脚本acme.sh
执行以下命令:
java -cp etc/application.properties:./lib/properties-loader-0.0.1-SNAPSHOT.jar com.acme.lab.PropertiesLoader
我正在尝试从PropertiesLoader
类访问属性文件。我读了这篇文章,但在访问属性文件时仍然存在问题
System.out.println(this.getClass().getResourceAsStream("../etc/application.properties"));
System.out.println(this.getClass().getResourceAsStream("etc/application.properties"));
System.out.println(this.getClass().getResourceAsStream("/etc/application.properties"));
System.out.println(this.getClass().getResourceAsStream("application.properties"));
System.out.println(this.getClass().getClassLoader().getResourceAsStream("../etc/application.properties"));
System.out.println(this.getClass().getClassLoader().getResourceAsStream("etc/application.properties"));
System.out.println(this.getClass().getClassLoader().getResourceAsStream("/etc/application.properties"));
System.out.println(this.getClass().getClassLoader().getResourceAsStream("application.properties"));
try {
System.out.println(ResourceBundle.getBundle("etc.application"));
System.out.println(ResourceBundle.getBundle("application"));
} catch(MissingResourceException e) {
// do nothing
}
所有这些调用都无法加载文件
我只知道错误与类路径有关,但似乎找不到它。我在上创建了一个示例maven项目,它重新创建了问题。资源是从它们的类路径根解释的。在您的情况下,当您像这样运行程序时:
java -cp etc/application.properties:./lib/properties-loader-0.0.1-SNAPSHOT.jar
java -cp etc:./lib/properties-loader-0.0.1-SNAPSHOT.jar
根是
/etc/application.properties
/lib/properties-loader-0.0.1-SNAPSHOT.jar
java -cp etc/application.properties:./lib/properties-loader-0.0.1-SNAPSHOT.jar
java -cp etc:./lib/properties-loader-0.0.1-SNAPSHOT.jar
然后,您可以将程序中的属性文件读取为:
Thread.currentThread().getContextClassLoader().getResourceAsStream("application.properties");
作为旁注,最好在类路径设置中使用完全限定的路径
*编辑* 这是一个说明资源加载的工作示例:
mkdir props; cd props
mkdir etc; touch etc/application.properties
mkdir test; vi test/PropLoader.java
将此内容粘贴到编辑器中,然后保存:
package test;
import java.io.InputStream;
public class PropLoader {
public static void main(String[] args) {
try {
final String path;
if(args.length == 1) path = args[0].trim();
else path = "etc/application.properties";
final InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(path);
if(is == null) throw new RuntimeException("Failed to load " + path + " as a resource");
else System.out.printf("Loaded resource from path: %s\n", path);
} catch(Exception e) {
e.printStackTrace();
}
}
}
并测试:
javac test/PropLoader.java
java -cp . test.PropLoader
输出是从路径etc/application加载的
资源。属性
资源是从它们的类路径根解释的。在您的情况下,当您像这样运行程序时:
java -cp etc/application.properties:./lib/properties-loader-0.0.1-SNAPSHOT.jar
java -cp etc:./lib/properties-loader-0.0.1-SNAPSHOT.jar
根是
/etc/application.properties
/lib/properties-loader-0.0.1-SNAPSHOT.jar
java -cp etc/application.properties:./lib/properties-loader-0.0.1-SNAPSHOT.jar
java -cp etc:./lib/properties-loader-0.0.1-SNAPSHOT.jar
然后,您可以将程序中的属性文件读取为:
Thread.currentThread().getContextClassLoader().getResourceAsStream("application.properties");
作为旁注,最好在类路径设置中使用完全限定的路径
*编辑* 这是一个说明资源加载的工作示例:
mkdir props; cd props
mkdir etc; touch etc/application.properties
mkdir test; vi test/PropLoader.java
将此内容粘贴到编辑器中,然后保存:
package test;
import java.io.InputStream;
public class PropLoader {
public static void main(String[] args) {
try {
final String path;
if(args.length == 1) path = args[0].trim();
else path = "etc/application.properties";
final InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(path);
if(is == null) throw new RuntimeException("Failed to load " + path + " as a resource");
else System.out.printf("Loaded resource from path: %s\n", path);
} catch(Exception e) {
e.printStackTrace();
}
}
}
并测试:
javac test/PropLoader.java
java -cp . test.PropLoader
输出是从path:etc/application.properties加载的
资源
我是否正确理解classpath参数应该只包含路径和jar,以便从那里加载子资源?我也支持您的解决方案,但它仍然将null
作为InputStream返回。是的,您的类路径应该只包含路径
和归档(JAR)。我编辑了我的答案,加入了一个例子,如果你严格遵循,这个例子应该会起作用。我可以遵循你的例子。感谢您的澄清。我在生产中仍然遇到问题,ContextClassCloader
在SystemClassLoader
工作时失败。可能是某个组件替换了类加载器吗?我是否正确地理解了classpath参数应该只包含路径和jar,以便可以从那里加载子资源?我也支持您的解决方案,但它仍然将null
作为InputStream返回。是的,您的类路径应该只包含路径
和归档(JAR)。我编辑了我的答案,加入了一个例子,如果你严格遵循,这个例子应该会起作用。我可以遵循你的例子。感谢您的澄清。我在生产中仍然遇到问题,ContextClassCloader
在SystemClassLoader
工作时失败。可能是某个组件取代了类加载器吗?@drhirsch我认为标签maven assembly plugin
可能比assemblies
在这种情况下更合适。当然,将其更改为您认为合适的-但是assembly
,就像以前一样,是错误的。事实上,正是这个标签,把我带到这里来的是机器代码。每个标签都有一个描述-如果你不确定,请阅读。忘记我可以自己更改它。谢谢你的提示。@drhirsch我认为标签maven assembly plugin
在这种情况下可能比assemblies
更合适。当然,把它改成你认为合适的-但是assembly
,就像以前一样,是错误的。事实上,正是这个标签,把我带到这里来的是机器代码。每个标签都有一个描述-如果你不确定,请阅读。忘记我可以自己更改它。谢谢你的提示。