Подтвердить что ты не робот

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

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

У меня есть все мои ресурсы в выделенной папке /src/main/resources, которая является частью пути сборки в Eclipse. Файлы ссылаются с помощью

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

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

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

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

4b9b3361

Ответ 1

Содержимое папок ресурсов Maven копируется в целевые/классы и оттуда в корень результирующего файла Jar. Это ожидаемое поведение.

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

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

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

Ответ 2

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

Ответ 3

Как только вы упакуете 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;
}

Ответ 4

Проблема заключается в том, что в среде IDE getClass(). getResource ( "Путь" ); Строка не является CASE SENSITIVE при доступе к файлу, но при запуске из банки. Проверьте свою капитализацию по каталогу по сравнению с файлом. Он работает. Также, если вы попробуете новый файл (getClass(). GetResource ( "Путь" ), файл не будет доступен для чтения вне IDE.

Ответ 5

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

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

Ответ 6

Если вы добавляете каталог ресурсов в файл jar (поэтому он находится в папке /resources в банке, и если /src/main находится в вашем пути сборки в eclipse, вы должны иметь возможность ссылаться на ваш файл как

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

Что должно работать в обеих средах.

Ответ 7

Просто скопируйте файл во временный каталог.

String tempDir = System.getProperty("java.io.tmpdir");
File file = new File(tempDir.getAbsolutePath(), "filename.txt");
if (!file.exists()) {
     InputStream is = (getClass().getResourceAsStream("/filename.txt"));
     Files.copy(is, file.getAbsoluteFile().toPath());
}