Запуск Gradle: getClass().getClassLoader().getResource() возвращает Null

Я пытаюсь импортировать файл для использования в моем простом проекте Java. В настоящее время я использую IntelliJ в качестве IDEE и Gradle для создания проекта.

Проблема:

Когда я пытаюсь проверить, загружает ли программа ресурсы, используя URL url = getClass().getClassLoader().getResource(filePath); функция, передавая «src/main/resources/File» в качестве аргумента, она работает нормально, поскольку я создаю приложение (используя Gradle) и запускаю его через IntelliJ. Однако, когда я пытаюсь заставить его работать с классом, запущенным через терминал, задача FAIL, потому что она не может найти файл ресурсов, поскольку функция возвращает Null. Вот мое дерево путей:

├── build
│   ├── classes
│   │   └── java
│   │       └── main
│   │           └── it
│   │               └── uni
│   │                   └── cs
│   │                       └── name
│   │                           └── progettofinaledatemplate
│   │                               ├── controller
│   │                               ├── models
│   │                               └── view
│   ├── distributions
│   ├── generated
│   │   └── sources
│   │       ├── annotationProcessor
│   │       │   └── java
│   │       │       └── main
│   │       └── headers
│   │           └── java
│   │               └── main
│   ├── libs
│   ├── resources
│   │   └── main
│   │       └── it
│   │           └── uni
│   │               └── cs
│   │                   └── name
│   │                       └── progettofinaledatemplate->resources files
│   ├── scripts
│   └── tmp
│       ├── compileJava
│       │   └── compileTransaction
│       │       ├── backup-dir
│       │       └── stash-dir
│       └── jar
├── gradle
│   └── wrapper
└── src
    └── main
        ├── java
        │   └── it
        │       └── uni
        │           └── cs
        │               └── name
        │                   └── progettofinaledatemplate
        │                       ├── controller
        │                       ├── models
        │                       └── view
        └── resources
            └── it
                └── uni
                    └── cs
                        └── name
                            └── progettofinaledatemplate->resources files

Извините, если повторил уже существующую тему, но не нашел решения.

Что я пробовал:

  • Проверено наличие файла в пути к файлу
  • перестроил проект через Build > Rebuild Project
  • использовал абсолютный путь
  • попытался проверить, что в оценку включены ресурсы с:
sourceSets {
    main {
        resources {
            srcDir 'src/main/resources'
        }
    }
}

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

Jon Skeet 22.08.2024 18:13

Для начала не используйте имя «filePath» в getResource(filePath). Перестаньте думать об этом как о файле; это ресурс. Когда вы создаете свое приложение, все, что находится в каталоге resources, помещается в корень вашего jar-файла. У вас должна быть возможность получить доступ к своему ресурсу, используя getResource("/File") (то есть оставьте бит src/main/resources).

k314159 22.08.2024 18:18

Вы почти никогда не захотите иметь такой уровень вложенности в ресурсы. Нет необходимости зеркально отображать дерево пакетов.

g00se 22.08.2024 18:31

Спасибо за ответы, я использовал getResource("/FileName"); , но все равно возвращаю Null. Однако на этот раз запуск приложения через IntelliJ вернет значение Null. Я уверен, что проблема не в формате ресурса. Еще раз спасибо @k314159

Luca Porfiri 22.08.2024 18:49

Вы используете неправильный URL для загрузки ресурсов. Измените путь к URL-адресу, который будет полностью соответствовать вашим запросам. Это ответ на вашу проблему.

Roman C 22.08.2024 19:18

Было бы полезно, если бы вы указали фактическое имя файла, а не какой-то загадочный заполнитель.

g00se 22.08.2024 19:19

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

k314159 22.08.2024 19:30
srcDir 'src/main/resources' лишнее. Это уже исходный каталог по умолчанию для ресурсов в основном исходном наборе. Также обратите внимание, что srcDir добавляет только исходный каталог, а не заменяет существующие.
Slaw 22.08.2024 19:38

Пусть x.txt будет ресурсом, находящимся на листе вашего дерева ресурсов, а класс, из которого вы к нему получаете доступ, будет называться X. Код, который я бы использовал: URL u = X.class.getResource("/main/it/uni/cs/name/progettofinaledate‌​mplate/x.txt"); Теперь вы можете увидеть причину моего комментария о чрезмерном вложении.

g00se 22.08.2024 19:41

@g00se, если ресурс находится в том же пакете в каталоге ресурсов, что и класс, из которого вы его загружаете, вы можете не указывать путь к пакету. Таким образом, наличие ресурсов в структуре пакета дает некоторую выгоду.

k314159 22.08.2024 19:44

Это правда. Но этот шаблон, по крайней мере, «всегда» будет работать, поэтому я бы привел его в первую очередь.

g00se 22.08.2024 19:45

Обратите внимание, что ClassLoader::getResource принимает только абсолютные пути, но без ведущих /. Это отличается от Class::getResource. И обратите внимание, что каталог src/main/resources никогда не будет частью этого пути (если только вы не делаете какие-то странные и нетрадиционные вещи). Считайте каталог resources «корнем». Однако имейте в виду, что при поиске ресурсов действительно важен путь к классу/модулю, а не исходные каталоги. По умолчанию задача run будет включать build/resources/main в путь к классам для немодульных проектов.

Slaw 22.08.2024 19:45

Извините, не хотел быть загадочным. Чтобы уточнить, это конкретный путь, который я использую: URL url = this.getClass().getResource("it/uni/cs/name/progettofinaleda‌​template/Tracciato3.‌​txt");

Luca Porfiri 22.08.2024 19:53

Здесь используется Class::getResource. В этом методе абсолютные пути обозначаются ведущим /. Если нет начального /, то путь определяется относительно местоположения класса (т. е. его пакета). Что будет, если поставить ведущий /? Или что произойдет, если вы просто используете "Tracciato3.txt" (при условии, что класс, возвращаемый getClass(), находится в пакете it.uni.cs.name.progettofinaledatemplate).

Slaw 22.08.2024 19:54

URL-адрес = this.getClass().getResource("it/uni/cs/name/progettofinaleda‌​template/Tracciato3.‌​txt"); Было бы нормально, если бы имя пакета this было относительно правильным. Лично я считаю, что безопаснее и менее сомнительно использовать абсолютную форму, которую я уже дал.

g00se 22.08.2024 23:29
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
15
58
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Решение, которое работало с моим приложением:

Выслушав множество полезных советов, я удалил вложенность файлов ресурсов, учитывая имя файла «Tracciato3.txt» и X — класс, который я использовал, я переместил файл «Tracciato3.txt» из:

src/main/resources/it/uni/cs/name/progettofinaledatemplate/Tracciato3.txt

к

src/main/resources/Tracciato3.txt

теперь, если я использую

URL url = X.class.getClassLoader().getResource("Tracciato3.txt");

он не возвращает ноль, вместо этого он получает правильный URL-адрес.

У меня это сработало, поэтому я надеюсь, что это будет полезно

Другие вопросы по теме