Нужна помощь со странной проблемой Class # getResource () - PullRequest
4 голосов
/ 14 января 2010

У меня есть какой-то устаревший код, который читает файл конфигурации из существующего jar-файла, например:

URL url = SomeClass.class.getResource("/configuration.properties");
// some more code here using url variable
InputStream in = url.openStream();

Очевидно, это работало раньше, но когда я выполняю этот код, URL-адрес действителен, но в третьей строке я получаю IOException, говоря, что не могу найти файл. URL-адрес похож на «file:jar:c:/path/to/jar/somejar.jar!configuration.properties», поэтому он не похож на проблему с classpath - Java хорошо знает, где находится файл ..

Приведенный выше код является частью задачи ant и завершается ошибкой при выполнении задачи.

Довольно странно - я скопировал код и файл jar в отдельный класс, и он работает, как и ожидалось, файл свойств доступен для чтения.

В какой-то момент я изменил код задачи ant на

URL url = SomeClass.class.getResource("/configuration.properties");
// some more code here using url variable
InputStream in = SomeClass.class.getResourceAsStream("/configuration.properties");

и теперь это работает - до тех пор, пока не произойдет сбой в другом классе, где реализован подобный шаблон доступа ..

Почему это могло сработать раньше, почему оно терпит неудачу сейчас? Единственное отличие, которое я вижу на данный момент, состоит в том, что старая сборка была сделана с использованием Java 1.4, а я сейчас пробую ее с Java 6.

Обход

Сегодня я установил Java 1.4.2_19 на сервер сборки и заставил его использовать ant. К моему совершенно разочаровывающему удивлению: проблема исчезла. Мне кажется, что Java 1.4.2 может обрабатывать URL-адреса этого типа, в то время как Java 1.6 не может (по крайней мере, в моем контексте / среде).

Я все еще надеюсь на объяснение, хотя я сталкиваюсь с работой по переписыванию частей кода для использования Class # getRessourceAsStream, который вел себя намного стабильнее ...

Ответы [ 4 ]

2 голосов
/ 17 января 2010

Типичная реализация ClassLoader.getResourceAsStream:

public InputStream getResourceAsStream(String name) {
    URL url = getResource(name);
    try {
        return url != null ? url.openStream() : null;
    } catch (IOException e) {
        return null;
    }
}

Class.getResource и getResourceAsStream ведут себя одинаково друг с другом.

Похоже, вы используете странный и неработающий подкласс ClassLoader, или в ваших тестах есть какая-то ошибка.

1 голос
/ 20 января 2011

используйте urlConnection.setUseCaches (false), поскольку это задача муравья, которая, вероятно, не будет разветвлена ​​в отдельном процессе. URL-адреса кэшируют файлы (или JarFile в этом случае) ... если файлы меняются из-за сборки, вы получаете довольно похожее поведение.

вы можете захотеть закрыть измененные файлы jar, используя useCaches (true), JarURLConnection.getJarFile (). Close ()

Иногда мне хотелось бы, чтобы работа с Jar / Zip была немного лучше

ура

1 голос
/ 14 января 2010

Он работает с getresourceasstream, потому что он находится в пути к классам, но не работает с URL, возможно, из-за того, что URL не в порядке.

Я не знаю, если URL, который создает getResource, не в порядке, или нет правильного обработчика протокола (не будет ли file:jar:c:/myjar.jar!configuration.properties или что-то подобное (с двумя двоеточиями?)

0 голосов
/ 14 января 2010

В некоторых версиях Java есть ошибки при использовании файловых URL-адресов, содержащих пробелы. «/ path / to / jar», вероятно, не является вашим реальным путем, поэтому я, по крайней мере, предполагаю, что это то, с чем вы столкнулись. Ваш код по крайней мере в теории хорошо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...