Как получить доступ к каталогу ресурсов для вызывающей программы на Java

1

У меня есть библиотека, которая используется программой. Эта библиотека загружает специальный каталог в папку ресурсов.

в библиотеке у меня есть метод

public class DataRegistry{

    public static File getSpecialDirectory(){
        String resourceName = Thread.currentThread().getContextClassLoader().getResource("data").getFile().replace("%20", " ");
        File file = new File(resourceName);
        return file;
    }

}

в моей программе у меня есть основной метод

public static void main(String args[]){
    System.out.println(Data.getSpecialDirectory());
}

Когда я запускаю getSpecialDirectory() в тесте junit в программе данных, ресурс извлекается, и все хорошо.

Когда я запускаю getSpecialDirectory() в основном методе вне программы данных (импортированный jar), я получаю каталог данных jars, а не каталог, который ожидает программа, выполняющая поток.

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

Для ясности:

(библиотека) Строка 15 этого файла: https://gist.github.com/AnthonyClink/11275442

(Использование) Линия 31 этого файла: https://gist.github.com/AnthonyClink/11275661

Мои поры могут иметь к этому какое-то отношение, поэтому обмен ими, вероятно, важен:\

(Библиотека) https://github.com/Clinkworks/Neptical/blob/master/pom.xml

(Использование) https://github.com/Clinkworks/Neptical-Maven-Plugin/blob/master/pom.xml

  • 0
    Что вы пытаетесь достичь? Получить путь к папке относительно вашего класса DataMojo?
Теги:
jar
classloader

4 ответа

1
Лучший ответ
  1. Вам нужен каталог, из которого была загружена программа Java? Можешь попытаться

    Файл f = новый файл ("."). GetCanconicalFile();

  2. Или, если вы хотите, чтобы все места могли попробовать разобрать путь класса из System.env или использовать загрузчик классов по умолчанию

  3. Если вам нужна директория относительно баночки, из которой были загружены ваши классы: Цитата из http://www.nakov.com/blog/2008/06/11/finding-the-directory-where-your-java-class- файлы будут загружены, с /

    URL classesRootDir = getClass(). GetProtectionDomain(). GetCodeSource(). GetLocation();

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

Файл: /C: /Documents %20and %20Settings/Администратор/рабочее пространство /TestPrj/bin/

В веб-приложении он возвращает следующее:

Файл: /C: /Tomcat/WebApps/MyApp/WEB-INF/классы/

FYI Это может быть применимо, если запущенная программа идентификатора пользователя не может читать все папки: http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getProtectionDomain%28%29

  1. или передать объект.class вызывающего класса в качестве параметра и получить его загрузчик классов
  • 1
    Вы никогда не должны использовать объекты java.io.File для чтения содержимого jar-ресурсов или веб-ресурсов. Это зависит от того, что сервер приложений разрывает ваш файл WAR при развертывании, а многие из них этого не делают вообще. Сервлет и JDK API предоставляют другие механизмы для этого.
  • 0
    Как это делает это? "getClass (). getProtectionDomain (). getCodeSource (). getLocation ()" может быть войной? угадайте, нужно проверить, является ли объект файла файлом или директорией, а иначе взять родительский объект?
Показать ещё 1 комментарий
5
  1. Maven использует целевые/классы и каталоги целевых/тестовых классов для составления класса, используемого для запуска модульных тестов. Содержимое ваших ресурсов src/main/resources и src/test/resources копируется в эти места вместе с скомпилированными java-источниками (файлы.class).
  2. java.lang.ClassLoader.getResource возвращает java.net.URL.
  3. В тестовой ситуации класса ClassLoader.getResource возвращает файл://schemed URL, и ваш код работает должным образом.
  4. Когда ваш код выполняется при упаковке в файле jar, ClassLoader.getResource больше не возвращает файл://schemed URL. Это невозможно, потому что ресурс больше не является отдельным объектом в файловой системе - он зарывается внутри файла jar. То, что вы на самом деле получаете, это jar: file://schemed URL.
  5. jar: URL-адреса недоступны через объект [java.io.File].

Если вам нужно только прочитать содержимое ресурса, вы должны использовать java.lang.ClassLoader.getResourceAsStream(...) и прочитать содержимое.

Обратите внимание, что обновление содержимого ресурсов загрузчика классов невозможно.

  • 0
    я думаю, что он хочет родительскую папку, а затем захватить некоторые другие ресурсы, относящиеся к этой папке - в подкаталог с именем data
  • 0
    +1. Для подробного объяснения, почему это не может быть сделано.
Показать ещё 2 комментария
1

Насколько я знаю, нет никакой гарантии, что у вас есть каталог для ваших ресурсов. Java предоставляет методы для получения ресурса в качестве InputStream, но ничего, что может легко получить файл для ресурса, хотя можно получить URL-адрес для данного ресурса.

Если вам нужен специальный рабочий каталог в вашем приложении, я рекомендую передать его как системное свойство, параметр программы, параметр веб-приложения или что-то еще, что позволяет узнать, где находятся ваши файлы приложений. Вы даже можете заполнить этот каталог ZIP файлом, который вы укажете в качестве ресурса в своем приложении, поскольку библиотеки ZIP в Java действительно принимают входные потоки в качестве параметров.

0

Хотя пользователь @tgkprog прав, и его ответ правильный, я едва ли могу представить, что вы действительно хотите, что вы, кажется, попросили и что он правильно ответил в (3). Измените свой вопрос и объясните

  • какой результат должен выглядеть, если имя resourceName будет напечатано на консоли,
  • если вы действительно хотите местоположение JAR файла (в моем тестовом примере это будет что-то вроде файла: /C: /Users/Alexander/.m2/repository/com/clinkworks/neptical/0.0.1-SNAPSHOT/data, что не имеет смысл, потому что вы не хотите читать или даже писать в локальный кеш Maven),
  • или, возможно, вам захочется прочитать ресурс непосредственно из файла JAR или любого другого местоположения, например текущего рабочего каталога и т.д.

В противном случае я боюсь, что нет хорошего способа ответить на вопрос.

  • 0
    Я думаю, что это будет в локальном кеше maven, если ваш запуск из IDE ... в развернутом приложении может быть любым каталогом, если вы добавили этот путь к classpath
  • 0
    Что ж, стабильное решение должно работать во всех средах и не предполагать конкретный сценарий развертывания во время выполнения - по крайней мере, тот, который оригинальный автор даже не описал. Таким образом, мой запрос для более подробного объяснения.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню