【问题标题】:Loading resources from multiple jars with wild card使用通配符从多个 jar 加载资源
【发布时间】:2014-11-20 22:31:07
【问题描述】:

我有一个包含多个模块的 Java 应用程序,每个模块都有一个 jar 文件。 每个 jar 文件都遵循名为 @987654323 的相同文件夹结构@Java 中有没有办法使用通配符加载多个 jar 的 `META-INF/props 中的所有属性文件?

有点像

ClassLoader.getSystemResourceAsStream("META-INF/props/*.properties");

我知道这个方法不接受通配符并且不返回流数组,但是可以做这样的事情吗?

【问题讨论】:

  • 并非如此。您可以使用ClassLoader#findResources,它将返回类路径中所有同名资源的Enumeration,但这仍然需要一个完全限定的路径和名称

标签: java jar classloader


【解决方案1】:

不,没有标准/可靠的方法可以做到这一点。一些库利用 ClassLoader.getResources 实现的常见模式(特别是,它们通常总是返回“file:”或“jar:file:”URL)以支持资源查找中的通配符。例如,Wildcards in application context constructor resource paths 解释了 Spring 是如何做到这一点的,它列出了几个注意事项(“对可移植性的影响”、“类路径*:可移植性”、“与通配符有关的注释”)。

【讨论】:

  • 是的,我知道spring支持通配符加载,这就是我问这个问题的原因,我认为Java已经内置了扫描类路径的机制。
  • 答案是没有。如果你愿意对环境做出假设,你可以效仿。
  • @Puru 我向 Spring 提交了一个问题,以将他们的资源加载分离到一个轻量级工件中:jira.spring.io/browse/SPR-12508如果你愿意,请投票。
【解决方案2】:

我写了一些代码来解决这个限制。

我从类路径中读取所有条目并确定它是文件夹还是 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();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-19
    • 1970-01-01
    • 2014-02-05
    • 2013-01-16
    • 2014-10-11
    • 1970-01-01
    • 1970-01-01
    • 2018-06-03
    相关资源
    最近更新 更多