2016-02-20 2 views
1

У меня есть проект с несколькими модулями. В одном модуле (A) я пытаюсь получить доступ к ресурсам другого модуля (B). Модуль B определяется как зависимость в модуле A. Я написал несколько тестов, проверяющих, могу ли я получить доступ к файлам. Когда я запускаю тесты в IntelliJ, все проходит. Когда я запускаю mvn test, все работает. Когда я запускаю mvn install или mvn package, те же тесты не пройдут, и сборка завершится с ошибкой.Загрузка файла ресурсов из другого модуля. Maven test works, maven install/package не будет

В модуле AI пытается получить доступ к ресурсу следующим образом:

ClassOfModuleB.class.getResource("/fileOfModuleB").getFile() 

Я нашел некоторые вопросы, которые перечислены здесь: Java: How to read file from different module? и здесь: How to really read text file from classpath in Java

Я попробовал все комбинации, однако, каждый раз тест проходит в тесте IntelliJ/mvn, и он не пройдет в пакете mvn install/mvn.

+1

Ha. Вы не можете получить доступ к ресурсу в качестве «файла», но только как «InputStream». Ваша проблема '.getFile()' есть проблема. – Tunaki

+0

Но почему это работает в 'mvn test'? – sisu

+1

Это я понятия не имею. Но я уверен, что это твоя проблема. – Tunaki

ответ

0

Как отметил khmarbaise, дизайн этого приложения полностью испорчен. Я нашел уродливое обходное решение, но это заставляет все работать и хорошо проверяется. Основная проблема заключается в том, что разные модули должны иметь доступ к тем же файлам. К сожалению, файлы не могут обрабатываться как потоки (что значительно упростит работу), поскольку сторонним библиотекам нужен фактический дескриптор файла. И получение этого (.getFile()) является проблемой, о которой уже сказал Тунаки. Причина, по которой он работал в mvn test, заключается в том, что эти тесты выполняются до того, как приложение будет упаковано. Наблюдая за путём .getResource(), он показывает изменение на jar://, когда он упакован, что делает невозможным получение фактических ручек файлов, так как больше нет файлов. Тем не менее, можно получить InputStreams.

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

private File copyResourceIntoTempFile(String resource, File target) throws IOException { 
    InputStream input = getClass().getResourceAsStream(resource); 

    OutputStream out = new FileOutputStream(target); 
    int read; 
    byte[] bytes = new byte[1024]; 

    while ((read = input.read(bytes)) != -1) { 
     out.write(bytes, 0, read); 
    } 
    //target.deleteOnExit(); 


    if (!target.exists()) { 
     throw new FileNotFoundException("Error: File " + target + " not found!"); 
    } 

    return target; 
} 

Также можно перебирать файлы в директории:

InputStream in = this.getClass().getResourceAsStream(resource); 
     BufferedReader rdr = new BufferedReader(new InputStreamReader(in)); 
     String line; 
     while ((line = rdr.readLine()) != null) { 
      this.copyResourceIntoTempFile(resource+"/"+line, new File(dir, line)); 
     } 
     rdr.close(); 

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

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