it-swarm.com.ru

Как правильно ссылаться на файл ресурса для JAR и отладки?

У меня неприятная проблема со ссылками на ресурсы при использовании проекта Maven и файлов Jar ...

Все мои ресурсы хранятся в отдельной папке/src/main/resources, которая является частью пути сборки в Eclipse. На файлы ссылаются, используя 

getClass().getResource("/filename.txt")

Это хорошо работает в Eclipse, но не работает в файле Jar - там ресурсы расположены в папке прямо под корнем jar ...

Кто-нибудь знает «лучшую практику» для ссылки на файл как в JAR, так и (!) В Eclipse?

Правка: Проблема в том, что, хотя ресурсы фактически находятся в JAR в папке «resources» на верхнем уровне, вышеуказанный метод не может найти файл ...

37
Patrick

Содержимое папок ресурсов Maven копируется в target/classes и оттуда в корень получившегося файла Jar. Это ожидаемое поведение.

Я не понимаю, в чем проблема в вашем сценарии. Ссылка на ресурс с помощью getClass().getResource("/filename.txt") начинается с корня пути к классу, независимо от того, является ли он (или его элемент) target/classes или корнем JAR. Единственная возможная ошибка, которую я вижу, это то, что вы используете неправильную ClassLoader.

Убедитесь, что класс, использующий ресурс, находится в том же артефакте (JAR), что и ресурс, и выполните ThatClass.class.getResource("/path/with/slash") или ThatClass.class.getClassLoader().getResource("path/without/slash").

Но кроме этого: если это не работает, вы, вероятно, делаете что-то не так в процессе сборки. Можете ли вы проверить, что ресурс находится в JAR?

16
Sean Patrick Floyd

У меня была похожая проблема .. После полного дня попытки каждой комбинации и отладки я попробовал getClass (). GetResourceAsStream ("resources/filename.txt") и заставил его наконец работать .. Больше ничего не помогло.

18
andjelko

После того, как вы упакуете JAR, ваши файлы ресурсов больше не будут файлами, а будут потоковыми, поэтому getResource не будет работать!

Используйте getResourceAsStream.

Чтобы получить содержимое «файла», используйте https://commons.Apache.org/proper/commons-io/javadocs/api-release/org/Apache/commons/io/IOUtils.html :

static public String getFile(String fileName)
{
        //Get file from resources folder
        ClassLoader classLoader = (new A_CLASS()).getClass().getClassLoader();

        InputStream stream = classLoader.getResourceAsStream(fileName);

        try
        {
            if (stream == null)
            {
                throw new Exception("Cannot find file " + fileName);
            }

            return IOUtils.toString(stream);
        }
        catch (Exception e) {
            e.printStackTrace();

            System.exit(1);
        }

        return null;
}
16
Thomas Decaux

Может быть, этот метод может помочь в некоторых ситуациях.

public static File getResourceFile(String relativePath)
{
    File file = null;
    URL location = <Class>.class.getProtectionDomain().getCodeSource().getLocation();
    String codeLoaction = location.toString();
    try{
        if (codeLocation.endsWith(".jar"){
            //Call from jar
            Path path = Paths.get(location.toURI()).resolve("../classes/" + relativePath).normalize();
            file = path.toFile();
        }else{
            //Call from IDE
            file = new File(<Class>.class.getClassLoader().getResource(relativePath).getPath());
        }
    }catch(URISyntaxException ex){
        ex.printStackTrace();
    }
    return file;
}
0
gbii