2013-11-22 7 views
11

У меня есть простая структура: файл jar данных, содержащий пакет данных, и файл службы jar, который запускает службу с использованием данных. Чтобы упростить замену данных, я их разделяю, а путь к классам service.jar содержит каталог, в котором находится data.jar.Доступ к ресурсам из другого файла jar

В пределах service.jar я использую getResource для загрузки файлов данных. Это работает, если файлы данных находятся непосредственно в папке, но не удается, когда они находятся внутри data.jar;

Это не удается:

all 
+ globalclasspath 
| + data.jar 
| + mine.properties 
+ daemons 
    + service.jar 

jsvc -cp globalclasspath:daemons/service.jar (...) 

MyClass.class.getClassLoader().getResource("mine.properties"); // <-- null 

Но это работает:

all 
+ globalclasspath 
| + mine.properties 
+ daemons 
    + service.jar 

jsvc -cp globalclasspath:daemons/service.jar (...) 

MyClass.class.getClassLoader().getResource("mine.properties"); // <-- not null 

Я не хочу, чтобы изменить путь к классам (если я не могу изменить его на что-то общее, не зависит от имя файла данных jar), но я в порядке с изменением строки getResource (я пробовал /data/mine.properties и /data.jar/mine.properties безрезультатно). Есть ли изменения, которые я могу сделать, чтобы ресурсы могли быть загружены из контейнера?

ответ

5

Решение 1

Используйте подстановочные путь к классам.

jsvc -cp globalclasspath/*:daemons/service.jar (...) 

См "How to use a wildcard in the classpath to add multiple jars?"

Решение 2

Для чтения данных в баночках не на пути к классам, используйте URLClassLoader. Общий алгоритм таков:

  1. Найти список JAR в каталоге globalclasspath.
  2. Создайте URLClassLoader из этого списка JAR.
  3. Посмотрите ресурс, который вы хотите от экземпляра URLClassLoader.

Чтобы найти JARs на пути к классам, я использовал ResourceList из статьи StackOverflow "Get a list of resources from classpath directory."

public class MyClass { 
    /** 
    * Creates a {@code URLClassLoader} from JAR files found in the 
    * globalclasspath directory, assuming that globalclasspath is in 
    * {@code System.getProperty("java.class.path")}. 
    */ 
    private static URLClassLoader createURLClassLoader() { 
     Collection<String> resources = ResourceList.getResources(Pattern.compile(".*\\.jar")); 
     Collection<URL> urls = new ArrayList<URL>(); 
     for (String resource : resources) { 
      File file = new File(resource); 
      // Ensure that the JAR exists 
      // and is in the globalclasspath directory. 
      if (file.isFile() && "globalclasspath".equals(file.getParentFile().getName())) { 
       try { 
        urls.add(file.toURI().toURL()); 
       } catch (MalformedURLException e) { 
        // This should never happen. 
        e.printStackTrace(); 
       } 
      } 
     } 
     return new URLClassLoader(urls.toArray(new URL[urls.size()])); 
    } 

    public static void main(String[] args) { 
     URLClassLoader classLoader = createURLClassLoader(); 
     System.out.println(classLoader.getResource("mine.properties")); 
    } 
} 

Я побежал следующую команду:

java -cp globalclasspath:daemons/service.jar MyClass 

терминал вывода:

jar:file:/workspace/all/globalclasspath/data.jar!/mine.properties 
1

Вы пробовали getResourceAsStream как предложено здесь:

how-to-a-read-file-from-jar-in-java

+0

К сожалению, я на самом деле с помощью 'getResourceAsStream' уже (я написал' getResource', потому что я не был я не знал о какой-либо разнице, и это казалось более простым) – Dave

Смежные вопросы