2014-09-26 2 views
0

여러 모듈이있는 Java 응용 프로그램이 있으며 각 모듈에는 jar 파일이 있습니다. 각 jar 파일은 META-INF/props이라는 동일한 폴더 구조를 따릅니다. Java에서 와일드 카드를 사용하여 여러 개의 jar 파일의 META-INF/props에있는 모든 등록 정보 파일을로드하는 방법이 있습니까?와일드 카드로 여러 jar의 리소스로드

뭔가

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

나는이 방법은 와일드 카드를 허용하지 않습니다 및 스트림의 배열을 반환하지 않는 것을 알고 있지만, 이런 식으로 뭔가를 할 수

같은?

+0

아니요. 반환 할 ['ClassLoader # findResources'] (http://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html#findResources (java.lang.String))을 사용할 수 있습니다. 클래스 경로 내에서 같은 이름의 모든 자원을 열거하지만 여전히 정규화 된 경로와 이름을 기대합니다. – MadProgrammer

답변

1

아니요, 표준/신뢰할 수있는 방법은 없습니다. 어떤 라이브러리는 ClassLoader.getResources 구현의 일반적인 패턴을 활용합니다 (특히 "file :"또는 "jar : file :"URL을 반환 함). 리소스 조회시 와일드 카드를 지원할 수 있습니다. 예를 들어, Wildcards in application context constructor resource paths은 Spring이 어떻게하는지 설명하고, 몇 가지주의 사항 ("이식시의 영향", "Classpath * : 이식성", "와일드 카드와 관련된 참고 사항")을 나열합니다.

+0

그래, 그 봄이 와일드 카드 로딩을 ​​지원한다는 것을 알았습니다. 그게 제가 질문 한 이유입니다. 자바가 있다고 생각합니다. 클래스 패스를 스캔하는 메카니즘을 구축했습니다. –

+0

대답은 그렇지 않다는 것입니다. 환경에 대한 가정을 기꺼이한다면 에뮬레이트 할 수 있습니다. –

+0

@Puru 나는 ​​경량의 유물로 리소스 로딩을 분리하기 위해 Spring과 관련된 문제를 제기했다 : https://jira.spring.io/browse/SPR-12508 원한다면 투표하십시오. –

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(); 
}