Ресурс не загружается при экспорте в виде JAR

#java #url #filesystems #classpath #classloader

#java #url #файловые системы #путь к классу #classloader

Вопрос:

Используя следующий код для установки системного свойства:


     ClassLoader classLoader = StartMain.class.getClassLoader();

    URL resource = classLoader.getResource("com/myname/lib/chromedriver/chromedriver.exe");

    File f = new File("Driver");

    if (!f.exists()) {

        f.mkdirs();

    }

    File chromeDriver = new File("Driver"   File.separator   "chromedriver.exe");

    if (!chromeDriver.exists()) {

        chromeDriver.createNewFile();

        org.apache.commons.io.FileUtils.copyURLToFile(resource, chromeDriver);

    }
  

Это отлично работает, когда я запускаю конфигурацию своего приложения в своей IDE, IntelliJ. Однако, когда я создаю JAR и пытаюсь использовать это вне IntelliJ, URL ресурса возвращается как null. Почему это так?

Ответ №1:

Переход через ваш classloader является рискованным. Вероятно, это не объясняет вашу проблему, но может; в любом случае, этот альтернативный способ сделать это короче, проще, более идиоматичен, работает во всех местах, где работает ваш take, и работает в большем количестве мест для загрузки:

Лучший способ извлечения подобных ресурсов выглядит следующим образом:

 StartMain.class.getResource("/com/myname/lib/chromedriver/chromedriver.exe");
  

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

Любая форма будет искать запись:

 /com/myname/lib/chromedriver/chromedriver.exe
  

внутри того же jar, который StartMain.class находится. Если его там нет, то это, очевидно, не сработает — исправьте свою сборку, чтобы она была включена. Во время ‘runtime’ в пути к классу может находиться какая-то папка, которая разрешила бы этот файл; если эта папка затем не будет помещена в ваш jar во время сборки, это объяснило бы, почему она работает в IDE, но не в другом месте.

ПРИМЕЧАНИЕ: обычно вам не нужны никакие утилиты apache. Например, есть InputStream, transferTo который также может сделать это однострочным (вместо этого извлекать getResourceAsStream ).