this.getClass (). getClassLoader (). getResource ("...") и исключение NullPointerException - PullRequest
53 голосов
/ 27 сентября 2010

Я создал минимальный проект maven с одним дочерним модулем в eclipse helios.

В папке 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, я просто получаю NullPointerException.Это работало нормально миллион раз.Любые идеи?

Я следовал этому руководству:

http://www.fuyun.org/2009/11/how-to-read-input-files-in-maven-junit/

, но все равно получаю ту же ошибку.

Ответы [ 8 ]

89 голосов
/ 17 августа 2011

Когда вы используете

this.getClass().getResource("myFile.ext")

getResource попытается найти ресурс относительно пакета. Если вы используете:

this.getClass().getResource("/myFile.ext")

getResource будет трактовать его как абсолютный путь и просто вызовет загрузчик классов, как если бы вы это сделали.

this.getClass().getClassLoader().getResource("myFile.ext")

Причина, по которой вы не можете использовать начальный / в пути ClassLoader, заключается в том, что все пути ClassLoader являются абсолютными и поэтому / не является допустимым первым символом в пути.

33 голосов
/ 29 ноября 2011

tul,

  • Когда вы используете .getClass().getResource(fileName), он считает, что местоположение fileName совпадает с местоположением вызывающего класса.
  • Когда вы используете .getClass().getClassLoader().getResource(fileName)он считает, что расположение файла - это корневая папка - другими словами 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
18 голосов
/ 27 сентября 2010

Это должно быть 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), а ресурс просто отсутствует в пути к классам во время выполнения.Убедитесь, что вы используете представление Навигатора Eclipse вместо Проводника пакетов.Если файлы отсутствуют, запустите цель mvn package.

4 голосов
/ 30 октября 2013

Когда eclipse запускает контрольный пример, он ищет файл в target / classes, а не в src / test / resources. Когда ресурс сохранен, eclipse должен скопировать его из src / test / resources в target / classes, если он изменился, но если по какой-то причине этого не произошло, вы получите эту ошибку. Убедитесь, что файл существует в target / classes, чтобы убедиться, что это проблема.

4 голосов
/ 22 мая 2012

У меня была та же проблема со следующими условиями:

  • Файлы ресурсов находятся в том же пакете, что и исходные файлы Java, в исходной папке Java (src/test/java).
  • Я строю проект с maven в командной строке, и сборка не удалась в тестах с NullPointerException.
  • Сборка командной строки не скопировала файлы ресурсов в папку test-classes, котораяобъяснил сбой сборки.
  • Когда я собирался затмить после сборки командной строки и перезапустить тесты в Eclipse, я также получил NullPointerException в Eclipse.
  • Когда я очистил проект (удалилсодержимое целевой папки) и перестройте проект в Eclipse, чтобы тест был выполнен правильно.Это объясняет, почему он запускается при запуске с чистым проектом.

Я исправил это, поместив файлы ресурсов в тестовую папку ресурсов: src/test/resources, используя ту же структуру пакета, что и исходный класс.

Кстати, я использовал getClass().getResource(...)

1 голос
/ 16 мая 2013

Я думаю, что столкнулся с той же проблемой, что и ваша. Я создал простой проект 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 с этим параметром, чтобы все файлы Java-байт-кода * .class находились в каталоге сборки.

<build>
    <defaultGoal>package</defaultGoal>
    <directory>${basedir}/build</directory>
<build>

Я зашел в каталог "build / classes / org / jhoh / mvc / resources", и "маршрутов" нет. Eclipse НЕ скопировать "маршруты" в "build / classes / org / jhoh / mvc / resources"

Я думаю, что вы можете скопировать ваш "install.xml" в каталог * .class, НЕ в каталоге исходного кода.

0 голосов
/ 03 февраля 2015

Еще одна вещь, на которую стоит посмотреть, решила для меня это:

В проекте Eclipse / Maven у меня были классы Java в src/test/java, в которых я использовал шаблон this.getClass().getResource("someFile.ext"); для поиска ресурсовв src/test/resources, где файл ресурса находился в том же месте пакета в папке источника ресурсов, что и класс теста в папке источника теста.Он все еще не смог найти их.

Щелкните правой кнопкой мыши на исходной папке src/test/resources, Build Path, затем «настройте фильтры включения / исключения»;Я добавил новый фильтр включения **/*.ext, чтобы убедиться, что мои файлы не очищаются;мои тесты теперь могут найти их файлы ресурсов.

0 голосов
/ 18 июня 2012

У меня была такая же проблема, работая над проектом с Maven. Вот как я это исправил: я просто поместил источники (изображения, музыку и другие материалы) в каталог ресурсов:

src/main/resources

Я создал такую ​​же структуру для пакетов в каталоге ресурсов. Например:

Если мой класс включен

com.package1.main

В каталог ресурсов я положил один пакет с тем же именем

com.package1.main

Так что я использую

getClass().getResource("resource.png");
...