2015-11-23 4 views
0

У меня есть два проекта:Groovy: Classpath ресурсов Загрузка не работает Ресурсы Внутри Dependency Фляг

  1. Main: M
  2. Зависимость: D

Project D имеет подкаталог 'XSD' где он имеет несколько файлов XSD, которые он использует для проверки.

Это кусок кода в проекте D, который извлекает эти XSD файлы:

private List<StreamSource> retrieveSchemaDefinitionsFromClasspath(String classpathXsdDir, String schemaDefinitionFilePattern) { 
    ClasspathResourceManager resourceManager = new ClasspathResourceManager() 
    List<String> schemaDefinitionFileNames = resourceManager.getReader(classpathXsdDir).text.split() 
    schemaDefinitionFileNames.findAll { it ==~ schemaDefinitionFilePattern }.collect { 
    new StreamSource(resourceManager.getReader("$classpathXsdDir/$it")) 
    } 
} 

Теперь этот кусок кода работает хорошо, когда я запускаю тестов.

Однако, когда я использую проект D как зависимость внутри проекта М, я получаю NullPointerException на этой линии вышеуказанного способа:

List<String> schemaDefinitionFileNames = resourceManager.getReader(classpathXsdDir).text.split() 

Я смотрел на этот ответ: Load jar file contained within another jar file not working, который указывает на JarClassLoader turorial: http://docs.oracle.com/javase/tutorial/deployment/jar/jarclassloader.html

Однако, из того, что я мог собрать из учебника JarClassLoader, похоже, что мне нужно указать имя банки.

Но я хочу, чтобы иметь возможность без проблем использовать барабан зависимости, созданный проектом D, в любом проекте, не беспокоясь о том, какой проект/jar D выполняет загрузку его ресурсов.

Итак, что является лучшим способом подойти к этой проблеме?

Спасибо!

+0

Что вы используете для управления зависимостями? Например, есть простые способы сделать это с Maven. – danehammer

+0

@ danehammer Я использую gradle для управления зависимостями. Итак, артефакт jar, созданный проектом D, установлен в моем репозитории maven, и он объявляется как зависимость внутри проекта M build.gradle. –

ответ

1

Вы можете использовать Class#getResource(String), чтобы сделать то, что я думаю, что вы собираетесь. Он часто используется в шаблонах поиска услуг, например, для поиска реализаций SPI.

Опасайтесь, поиск по классам может очень медленно проходить в больших дорожках классов. Скорее всего, вы хотите кешировать ответ вечно. В некоторых случаях это может быть слишком медленным (особенно если оно не загружается загрузочной областью вашего кода).

+0

Привет, @danehammer, я изменил метод на использование метода this.getClass(). GetResourceAsStream (...) (менеджер ClasspathResource использует .getClass(). GetClassLoader(). GetResourcesAsStream (...)), и у меня есть в основном та же проблема. Когда я распечатываю то, что находится в '/', используя getClass(). GetResourceAsStream (...) ', каталог, который я ищу, не существует. И все же, когда я «расстегиваю -l» мой батончик зависимости, он становится там. –

+0

Я думаю, что нашел проблему. Это связано с тем, что я пытаюсь динамически собрать все файлы в каталоге «xsd». Кажется, что это работает в моих тестовых случаях, но когда я использую код в качестве упакованной зависимости jar, похоже, нет способа перечислить содержимое «каталога». Вы знаете, есть ли способ сделать это? В противном случае мне просто нужно будет жестко закодировать имена файлов. –

+0

Итак, какие тестовые примеры выполняют по-разному в отношении загрузчиков классов? Связи doc я указал, что он делегирует загрузчик классов, поэтому, возможно, вы получите другой загрузчик классов в тестовом сценарии.Возможно, вы можете пропустить делегирование и сразу вызвать Системную (например, показ документа). Или, может быть, groovy и gradle делают что-то еще с загрузкой классов, и вам нужно делегировать их. – danehammer