Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/6.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 在同级目录中加载外部属性文件_Java_Maven_Properties_Classpath_Maven Assembly Plugin - Fatal编程技术网

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
它们都不包含application.properties文件(作为子资源)。如果您这样修改命令:

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
它们都不包含application.properties文件(作为子资源)。如果您这样修改命令:

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
,就像以前一样,是错误的。事实上,正是这个标签,把我带到这里来的是机器代码。每个标签都有一个描述-如果你不确定,请阅读。忘记我可以自己更改它。谢谢你的提示。