This.getClass(). getClassLoader(). getResource ( "..." ) и NullPointerException
Я создал минимальный проект maven с одним дочерним модулем в гелиях eclipse.
В папке src/test/resources я поместил один файл "install.xml". В папке src/test/java я создал один пакет с одним классом, который делает:
@Test
public void doit() throws Exception {
URL url = this.getClass().getClassLoader().getResource("install.xml");
System.out.println(url.getPath());
}
но когда я запускаю код как junit 4 unit test, я просто получаю исключение NullPointerException. Это проработало миллион раз. Любые идеи?
Я следил за этим руководством:
http://www.fuyun.org/2009/11/how-to-read-input-files-in-maven-junit/
но все равно получите ту же ошибку.
Ответы
Ответ 1
Когда вы используете
this.getClass().getResource("myFile.ext")
getResource
попытается найти ресурс относительно пакета.
Если вы используете:
this.getClass().getResource("/myFile.ext")
getResource
будет рассматривать его как абсолютный путь и просто вызовет загрузчик классов, как если бы вы это сделали.
this.getClass().getClassLoader().getResource("myFile.ext")
Причина, по которой вы не можете использовать ведущий /
в пути ClassLoader
, состоит в том, что все пути ClassLoader
являются абсолютными и поэтому /
не является допустимым первым символом в пути.
Ответ 2
tul,
- Когда вы используете
.getClass().getResource(fileName)
, он считает, что
Местоположение файла имя_файла - это то же местоположение вызывающего
класс.
- Когда вы используете
.getClass().getClassLoader().getResource(fileName)
, это
считает, что расположение файлаName является корнем - другими словами
bin
.
Источник:
package Sound;
public class ResourceTest {
public static void main(String[] args) {
String fileName = "Kalimba.mp3";
System.out.println(fileName);
System.out.println(new ResourceTest().getClass().getResource(fileName));
System.out.println(new ResourceTest().getClass().getClassLoader().getResource(fileName));
}
}
Выход:
Kalimba.mp3
file:/C:/Users/User/Workspaces/MyEclipse%208.5/JMplayer/bin/Sound/Kalimba.mp3
file:/C:/Users/User/Workspaces/MyEclipse%208.5/JMplayer/bin/Kalimba.mp3
Ответ 3
Это должно быть getResource("/install.xml");
Имена ресурсов относятся к тому, где находится класс getClass(), например. если ваш тест org/example/foo/MyTest.class
, то getResource("install.xml")
будет выглядеть в org/example/foo/install.xml
.
Если ваш install.xml
находится в src/test/resources
, он находится в корневом пути пути к классу, поэтому вам нужно добавить имя ресурса с помощью /
.
Кроме того, если он работает только иногда, возможно, это связано с тем, что Eclipse очистил выходной каталог (например, target/test-classes
), и ресурс просто отсутствует в пути к среде выполнения. Убедитесь, что с помощью представления Navigator для Eclipse вместо проводника пакетов. Если файлы отсутствуют, запустите цель mvn package
.
Ответ 4
У меня была такая же проблема со следующими условиями:
- Файлы ресурсов находятся в том же пакете, что и исходные файлы java, в исходной папке java (
src/test/java
).
- Я строю проект с maven в командной строке, а сборка завершилась неудачей при тестировании с помощью
NullPointerException
.
- Командная строка не копировала файлы ресурсов в папку
test-classes
, что объясняло отказ сборки.
- Когда вы собираетесь затмевать после сборки командной строки и повторите тесты в eclipse, я также получил
NullPointerException
в eclipse.
- Когда я очищал проект (удалял содержимое целевой папки) и перестраивал проект в Eclipse, тест выполнялся правильно. Это объясняет, почему он запускается, когда вы начинаете с чистого проекта.
Я исправил это, поместив файлы ресурсов в папку ресурсов в тесте: src/test/resources
, используя ту же структуру пакета, что и исходный класс.
Кстати, я использовал getClass().getResource(...)
Ответ 5
Когда eclipse запускает тестовый пример, он будет искать файл в target/classes, а не src/test/resources. Когда ресурс будет сохранен, eclipse должен скопировать его из src/test/resources в target/classes, если он изменился, но если по какой-то причине этого не произошло, вы получите эту ошибку. Убедитесь, что файл существует в target/classes, чтобы убедиться, что это проблема.
Ответ 6
Я думаю, что столкнулся с той же проблемой, что и ваш. Я создал простой проект mvn и использовал "mvn eclipse: eclipse" для установки проекта eclipse.
Например, мой исходный файл "Router.java" находится в "java/main/org/jhoh/mvc". И Router.java хочет прочитать файл "маршруты", который находится в "java/main/org/jhoh/mvc/resources"
Я запускаю "Router.java" в eclipse, а консоль eclipse получила NullPointerExeption.
Я установил pom.xml с этим параметром, чтобы все файлы *.class java bytecode находились в каталоге сборки.
<build>
<defaultGoal>package</defaultGoal>
<directory>${basedir}/build</directory>
<build>
Я пошел в каталог "build/classes/org/jhoh/mvc/resources", и нет "маршрутов". Eclipse DID NOT скопировать "маршруты" в "build/classes/org/jhoh/mvc/resources"
Я думаю, вы можете скопировать свой "install.xml" в ваш каталог *.class bytecode, НЕ в каталог исходного кода.
Ответ 7
У меня была такая же проблема, что и проект с Maven.
Вот как я его исправил: я просто помещал источники (изображения, музыку и другие материалы) в каталог ресурсов:
src/main/resources
Я создал ту же структуру для пакетов в каталоге ресурсов.
Например:
Если мой класс включен
com.package1.main
В каталоге ресурсов я помещаю один пакет с тем же именем
com.package1.main
Поэтому я использую
getClass().getResource("resource.png");
Ответ 8
Еще одна вещь, чтобы посмотреть, что это разрешило для меня:
В проекте Eclipse/Maven у меня были классы Java в src/test/java
, в которых я использовал шаблон this.getClass().getResource("someFile.ext");
для поиска ресурсов в src/test/resources
, где файл ресурсов находился в одном месте пакета в источнике ресурсов в качестве тестового класса в папке источника теста. Все еще не удалось найти их.
Щелкните правой кнопкой мыши на исходной папке src/test/resources
, "Путь сборки", затем "настройте фильтры включения/исключения"; Я добавил новый фильтр включения **/*.ext
, чтобы убедиться, что мои файлы не очищаются; мои тесты теперь могут найти файлы ресурсов.