我有一个包含多个模块的Java应用程序,每个模块都有一个jar
文件。
每个jar文件都遵循名为META-INF/props
的相同文件夹结构。在java中是否有一种方法可以使用通配符加载`META-INF /多个jar的道具中的所有属性文件?
像
这样的东西 ClassLoader.getSystemResourceAsStream("META-INF/props/*.properties");
我知道这个方法不接受通配符并且不返回数组流,但是可以做这样的事情吗?
答案 0 :(得分:2)
不,没有标准/可靠的方法来做到这一点。一些库利用了ClassLoader.getResources实现的常见模式(具体来说,它们通常总是返回“file:”或“jar:file:”URL),以便在资源查找中支持通配符。例如,Wildcards in application context constructor resource paths解释了Spring如何做到这一点,并列出了几个警告(“对可移植性的影响”,“Classpath *:可移植性”,“与通配符有关的注释”)。
答案 1 :(得分:0)
我写了一些代码来解决这个限制。
我从类路径中读取所有条目并确定它是文件夹还是JAR文件,然后在" META_INF / props"中查找条目。如果条目是属性,我加载它。
下面是代码,它没有改进,但它提供了一般的想法。
try{
URL[] urls = ((URLClassLoader) LoaderTest.class.getClassLoader()).getURLs();
HashMap<String, Properties> mapProperties = new HashMap<String, Properties>();
for(URL url: urls){
File file = new File(url.getFile());
if(file.isDirectory()){
System.out.println("Directory: " +file.getName());
File propFolder = new File(file.getAbsolutePath() + "/META-INF/props");
if (propFolder.exists() && propFolder.isDirectory()){
for(File f: propFolder.listFiles()){
if(f.getName().endsWith("properties") || f.getName().endsWith("props")){
Properties props = new Properties();
props.load(new FileReader(f));
String appName = props.getProperty("load.global.props.appName");
if(appName != null){
if( mapProperties.get(appName) == null) {
mapProperties.put(appName, props);
} else {
mapProperties.get(appName).putAll(props);
}
}
}
}
}
} else if (file.getName().endsWith("jar")){
System.out.println("Jar File: " + file.getName());
JarFile jarFile = null;
try{
jarFile = new JarFile(file);
Enumeration<JarEntry> entries = jarFile.entries();
while ( entries.hasMoreElements() ){
JarEntry entry = entries.nextElement();
if ( entry.getName().startsWith("META-INF/props") &&
(entry.getName().endsWith("properties") ||
entry.getName().endsWith("props"))){
System.out.println("Prop File: " + entry.getName());
Properties props = new Properties();
props.load(jarFile.getInputStream(entry));
String appName = props.getProperty("load.global.props.appName");
if(appName != null){
if( mapProperties.get(appName) == null) {
mapProperties.put(appName, props);
} else {
mapProperties.get(appName).putAll(props);
}
}
}
}
} finally {
if ( jarFile != null ) jarFile.close();
}
}
}
} catch(Exception e){
e.printStackTrace();
}