Spring не может найти файл конфигурации bean xml, когда он существует
Я пытаюсь сделать свой первый компонент весной, но у меня возникла проблема с загрузкой контекста. У меня есть файл конфигурации XML bean-компонента в src / main / resources.
Я получаю следующее IOException:
Исключение в потоке "main" org.springframework.beans.factory.BeanDefinitionStoreException: IOException при синтаксическом анализе XML-документа из ресурса пути к классу [src/main/resources/beans.xml]; вложенное исключение
java.io.FileNotFoundException: ресурс пути к классу [src / main / resources / beans.xml] не может быть открыт, потому что он не существует
но я не понимаю, так как я делаю следующий тест кода:
File f = new File("src/main/resources/beans.xml");
System.out.println("Exist test: " + f.exists());
что дает мне правду! resources
находится в пути к классам. В чем дело?
25 ответов
Спасибо, но это не было решением. Я выяснил, почему это не работает для меня.
Так как я сделал объявление:
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Я думал, что я буду ссылаться на корневой каталог проекта, когда там был файл beans.xml. Затем я поместил файл конфигурации в src / main / resources и изменил инициализацию на:
ApplicationContext context = new ClassPathXmlApplicationContext("src/main/resources/beans.xml");
это все еще было IO Exception.
Затем файл был оставлен в src / main / resources /, но я изменил объявление на:
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
и это решило проблему - может быть, это будет кому-то полезно.
спасибо и ура!
Редактировать:
Так как я получил много людей за решение и у меня был первый опыт работы со Spring в качестве студента несколько лет назад, я чувствую желание коротко объяснить, почему это работает.
Когда проект компилируется и упаковывается, все файлы и подкаталоги из 'src / main / java' в проекте попадают в корневой каталог упакованного jar (артефакт, который мы хотим создать). То же правило применяется к 'src / main / resources'.
Это соглашение соблюдается многими инструментами, такими как maven или sbt, в процессе построения проекта (примечание: в качестве конфигурации по умолчанию!). Когда код (из поста) находился в рабочем режиме, он не мог найти ничего подобного "src/main/resources/beans.xml" из-за того, что beans.xml был в корне jar (скопирован в / beans.xml в созданном jar/ear/war).
При использовании ClassPathXmlApplicationContext правильное объявление местоположения для определений bean-компонентов xml, в данном случае, было "/beans.xml", так как это путь, по которому он принадлежит в jar, а затем в classpath.
Это можно проверить, распаковав jar с архиватором (то есть rar) и просмотрев его содержимое в структуре каталогов.
Я бы рекомендовал читать статьи о classpath как дополнительные.
Попробуй это:
new ClassPathXmlApplicationContext("file:src/main/resources/beans.xml");
file: префикс указывает на ресурсы файловой системы, а не на classpath.
Путь к файлу может быть относительным или системным (/home/user/Work/src...)
У меня также была похожая проблема, но из-за немного другой причины, поэтому поделитесь здесь на случай, если это может кому-нибудь помочь.
Расположение моего файла
Как я использовал
ClassPathXmlApplicationContext("beans.xml");
Есть два решения
- Извлеките beans.xml из пакета и поместите в пакет по умолчанию.
- Укажите имя пакета при его использовании, а именно.
ClassPathXmlApplicationContext("com/mypackage/beans.xml");
Это потому, что applicationContect.xml или any_filename.XML не размещены по правильному пути.
Шаги по устранению неполадок
1: Добавьте файл XML в папку ресурсов.
2: если у вас нет папки ресурсов. Создайте его, перейдя по новой, щелкнув правой кнопкой мыши на проекте new > Source Folder, назовите его как ресурс и поместите под него XML-файл.
src/main/resources
является исходным каталогом, вы не должны ссылаться на него напрямую. Когда вы создаете / упаковываете проект, содержимое будет скопировано в правильное место для вашего classpath. Затем вы должны загрузить его так
new ClassPathXmlApplicationContext("beans.xml")
Или вот так
new GenericXmlApplicationContext("classpath:beans.xml");
Используй это ApplicationContext context = new FileSystemXmlApplicationContext("Beans.xml");
Обратите внимание, что первый applicationContext загружается как часть web.xml
; который упоминается ниже.
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>META-INF/spring/applicationContext.xml</param-value>
</context-param>
<servlet>
<servlet-name>myOwn-controller</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>META-INF/spring/applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Где, как показано ниже, код также пытается создать еще один applicationContext.
private static final ApplicationContext context =
new ClassPathXmlApplicationContext("beans.xml");
Увидеть разницу между beans.xml
а также applicationContext.xml
И если appliationContext.xml
под <META-INF/spring/>
объявил с <import resource="beans.xml"/>
тогда это appliationContext.xml
загружает beans.xml
в том же месте META-INF/spring
из appliationContext.xml
,
В то время как; в коде; если объявлено как ниже
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Это выглядит на beans.xml WEB-INF/classes
ИЛИ в затмении src/main/resources
,
[Если вы добавили beans.xml
в src/main/resources
тогда это может быть помещено в WEB-INF/classes
при создании ВОЙНЫ.]
Таким образом, всего два файла ищутся.
Я решил эту проблему, добавив поиск по пути к классам при импорте в applicationContext.xml
как ниже
<import resource="classpath*:beans.xml" />
и убрал линию ClassPathXmlApplicationContext("beans.xml")
в коде Java, так что будет загружен только один ApplicationContext.
Вы посмотрели на каталог src. XML-файл действительно существует там. Но посмотрите на каталог class или bin/build, где установлены все ваши выходные классы. Я подозреваю, что вам понадобится только путь resources/beans.xml для использования.
Я подозреваю, что вы создаете.war/.jar и, следовательно, это уже не файл, а ресурс в этом пакете. Вместо этого попробуйте ClassLoader.getResourceAsStream(String path).
В Spring все исходные файлы находятся внутри src/main/java. Аналогично, ресурсы обычно хранятся внутри src / main / resources. Так что держите ваш весенний конфигурационный файл в папке ресурсов.
Убедитесь, что у вас есть запись ClassPath для ваших файлов в src / main / resources.
В.classpath проверьте следующие 2 строки. Если они отсутствуют, добавьте их.
<classpathentry path="src/main/java" kind="src"/>
<classpathentry path="src/main/resources" kind="src" />
Итак, если у вас есть все на месте, приведенный ниже код должен работать.
ApplicationContext ctx = new ClassPathXmlApplicationContext ("Spring-Module.xml");
Gradle: v4.10.3
IDE: IntelliJ
Я столкнулся с этой проблемой при использовании gradle для запуска моей сборки и тестирования. Копирование applicationContext.xml повсюду не помогло. Даже указание полного пути, как показано ниже, не помогло!
context = new ClassPathXmlApplicationContext("C:\\...\\applicationContext.xml");
Решение (по крайней мере для gradle) заключается в том, как gradle обрабатывает ресурсы. Для моего проекта gradle я выложил рабочую область, как это определено на https://docs.gradle.org/current/userguide/java_plugin.html
При запуске теста с использованием заданного по умолчанию набора задач gradle включает шаг "processTestResources", который ищет ресурсы теста в C: \..... \ src \ test \ resources (Gradle услужливо предоставляет полный путь).
Ваш файл.properties и applicationContext.xml должны находиться в этом каталоге. Если каталог ресурсов отсутствует (как это было в моем случае), вам нужно создать его и скопировать туда файл (ы). После этого простое указание имени файла работало просто отлично.
context = new ClassPathXmlApplicationContext("applicationContext.xml");
Beans.xml или file.XML размещены по неправильному пути. Вы должны добавить XML-файл в папку ресурсов, если у вас есть проект Maven. src -> main -> java -> ресурсы
Я сделал противоположность большинству. Я использую Force IDE Luna Java EE и поместил свой файл Beans.xml в пакет; тем не менее, я предшествовал строке Beans.xml - для аргумента ClassPathXMLApplicationContext - относительным путем. Итак, в моем основном приложении, которое обращается к файлу Beans.xml, у меня есть:
ApplicationContext context =
new ClassPathXmlApplicationContext("com/tutorialspoin/Beans.xml");
Я также заметил, что как только я переместил файл Beans.xml в пакет из папки src, в левом нижнем углу значка XML-файла появилось изображение Bean, которого не было, когда этот xml-файл находился вне пакета. Это хороший показатель, позволяющий мне знать, что теперь XML-файл bean-компонентов доступен ClassPathXMLAppllicationsContext.
У меня была аналогичная проблема в IntelliJ, я пытался переместить файл и добавить соответствующийfilePath
но я все еще получалIOException
.
Я создал внутри еще одну папку с именем resources .src/main/resources
и переместилconfig.xml
файл там.
И изменилсяfileName
как внутри
ApplicationContext context = new ClassPathXmlApplicationContext("config.xml");
И это сработало.
Вот что сработало для меня:
new ClassPathXmlApplicationContext("classpath:beans.xml");
Я использую IntelliJ и столкнулся с той же проблемой. Вот как я это решил:
1. Добавлен импорт ресурсов, как показано ниже, в класс приложения Spring вместе с другими видами импорта:
@ImportResource("applicationContext.xml")
2. Пила IDE показывает:
Cannot resolve file 'applicationContext.xml'
а также предлагая пути, по которым он ожидает файл (это были не ресурсы, где изначально хранился файл applicationContext.xml)
3. Скопировал файл в ожидаемое место, и исключение было устранено.
Снимок экрана ниже для удобства использования:
Но если вы хотите сохранить его в ресурсах, перейдите по этой замечательной ссылке ниже и добавьте путь к ресурсам, чтобы его можно было найти. С этим параметром исключение разрешается без @ImportResource, описанного выше:
Я хотел бы добавить еще один момент к ответу Даврутовича. Если папка src/main/resources не создана, вам необходимо сначала создать ее, а затем поместить туда XML-файл конфигурации bean-компонента.
Ссылка: https://www.topjavatutorial.com/frameworks/maven/missing-srcmainresources-in-maven-project/
используй этоClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
и сохраните файл applicationContext.xml в папке src, что означает отсутствие одного уровня в вашем пакете. он будет применим в конфигурации аннотаций Spring и конфигурации Spring XML.
Делюсь своим случаем и тем, как я его отлаживал, возможно, кому-то поможет:
это будет иметь значение только в том случае, если вы сначала проверили, что у вас действительно есть
resources
папка в правильном месте и правильно названа
- создайте где-нибудь временную папку, желательно из любых проектов git (например,
mkdir playground
) и переместитесь туда (cd playground
) - скопируйте туда java-архив (например,
cp /path/to/java.war .
), в котором отсутствует beans.xml - распаковать (например
unzip java.war
на убунту) - найдите, есть ли там какие-либо файлы .xml (например, в WEB-INF/classes) (в процессе распаковки должен отображаться список распаковываемых файлов, большинство из них, вероятно, будут другими зависимостями в виде архивов, это не имеет значения)
- если вы не видите beans.xml, просто прочитайте другие файлы .xml (например,
cat root-config.xml
), вы можете найти что-то подобное там или подобное, там вы можете найти что-то другое<import resource="somethingelse.xml">
записи или ничего. - если это так, это означает, что у вас есть этот файл ( здесь ), присутствующий в проекте, или, если нет, продолжайте подниматься по родительским проектам туда, откуда упаковывается архив. Найдите этот файл, добавьте
<import resource="beans.xml">
и бегиmvn package
.
Теперь проверьте исправление, выполнив шаги в 1.-5. должен получиться этот файл (root-config.xml
здесь) в недавно упакованном архиве с определенным файлом beans.xml, и после его развертывания он должен работать.
Я испытывал эту проблему, и это сводило меня с ума; В конечном итоге я обнаружил в своем файле POM.xml следующее, что стало причиной проблемы:
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
Если эта проблема все еще ставит вас в тупик, и вы разрабатываете с использованием Eclipse, взгляните на эту ошибку Eclipse: файлы ресурсов из "src / main / resources" неправильно включены в classpath
Решением, похоже, является рассмотрение свойств проекта, пути сборки Java, исходных папок. Удалить /src/main/resources
режиссёр и добавь ещё раз. Это заставляет Eclipse напоминать о необходимости скопировать эти файлы в путь к классам.
Эта ошибка повлияла на меня, когда я использовал "Неон" релиз Eclipse. (И было очень сложно, пока я не понял простое исправление, только что описанное)
Следуй этим шагам:
Я хочу получить доступ к config.xml по адресу «src/main/java/org/example/App.java».
Так,
Создавать
resources
папка вsrc/main
Теперь создайте или вставьте XML-файл в этот каталог.
Перестройте проект, и все готово.
Я не был уверен, чтобы написать это, но, возможно, кто-то сэкономит несколько часов:
mvn clean
может сделать работу, если вся ваша конфигурация уже идеальна!
Я застрял в этой проблеме какое-то время и пришел к следующему решению
- Создайте класс ApplicationContextAware (который является классом, реализующим ApplicationContextAware)
В ApplicationContextAware мы должны реализовать только один метод
public void setApplicationContext(контекст ApplicationContext) выбрасывает BeansException
Расскажите контексту Spring об этом новом компоненте (я называю его SpringContext)
bean id="springContext" class="packe.of.SpringContext" />
Вот фрагмент кода
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class SpringContext implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
this.context = context;
}
public static ApplicationContext getApplicationContext() {
return context;
}
}
Затем вы можете вызвать любой метод контекста приложения вне контекста Spring, например
SomeServiceClassOrComponent utilityService SpringContext.getApplicationContext(). GetBean(SomeServiceClassOrComponent .class);
Надеюсь, это решит проблему для многих пользователей