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...)

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

Расположение моего файла

файл beans.xml

Как я использовал

ClassPathXmlApplicationContext("beans.xml");

Есть два решения

  1. Извлеките beans.xml из пакета и поместите в пакет по умолчанию.
  2. Укажите имя пакета при его использовании, а именно.

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.

Убедитесь, что файл beans.xml находится в папке ресурсов.

У меня была аналогичная проблема в 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, описанного выше:

/questions/34915355/kak-dobavit-katalog-v-classpath-v-profile-zapuska-prilozheniya-v-intellij-idea/34915373#34915373

Я хотел бы добавить еще один момент к ответу Даврутовича. Если папка 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папка в правильном месте и правильно названа

  1. создайте где-нибудь временную папку, желательно из любых проектов git (например,mkdir playground) и переместитесь туда (cd playground)
  2. скопируйте туда java-архив (например,cp /path/to/java.war .), в котором отсутствует beans.xml
  3. распаковать (напримерunzip java.warна убунту)
  4. найдите, есть ли там какие-либо файлы .xml (например, в WEB-INF/classes) (в процессе распаковки должен отображаться список распаковываемых файлов, большинство из них, вероятно, будут другими зависимостями в виде архивов, это не имеет значения)
  5. если вы не видите beans.xml, просто прочитайте другие файлы .xml (например,cat root-config.xml), вы можете найти что-то подобное там или подобное, там вы можете найти что-то другое<import resource="somethingelse.xml">записи или ничего.
  6. если это так, это означает, что у вас есть этот файл ( здесь ), присутствующий в проекте, или, если нет, продолжайте подниматься по родительским проектам туда, откуда упаковывается архив. Найдите этот файл, добавьте<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».

Так,

  1. Создаватьresourcesпапка вsrc/main

  2. Теперь создайте или вставьте XML-файл в этот каталог.

Перестройте проект, и все готово.

Я не был уверен, чтобы написать это, но, возможно, кто-то сэкономит несколько часов:

mvn clean

может сделать работу, если вся ваша конфигурация уже идеальна!

Я застрял в этой проблеме какое-то время и пришел к следующему решению

  1. Создайте класс ApplicationContextAware (который является классом, реализующим ApplicationContextAware)
  2. В ApplicationContextAware мы должны реализовать только один метод

    public void setApplicationContext(контекст ApplicationContext) выбрасывает BeansException

  3. Расскажите контексту 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;
  }
}
  1. Затем вы можете вызвать любой метод контекста приложения вне контекста Spring, например

    
    SomeServiceClassOrComponent utilityService SpringContext.getApplicationContext(). GetBean(SomeServiceClassOrComponent .class);
    

Надеюсь, это решит проблему для многих пользователей

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