Spring не може знайти файл конфігурації bean xml, коли він існує


76

Я намагаюся зробити свій перший компонент навесні, але у мене виникла проблема із завантаженням контексту. У мене є конфігураційний XML-файл компонента в 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знаходиться в шляху до класу. Що не так?


Як ви завантажуєте контекст?
Олександр М

Відповіді:


165

Дякую, але це не було рішення. Я зрозумів, чому це не працює для мене.

Оскільки я зробив декларацію:

ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

Я думав, що звернусь до кореневого каталогу проекту, коли там є файл beans.xml. Потім я помістив файл конфігурації в src / main / resources і змінив ініціалізацію на:

ApplicationContext context = new ClassPathXmlApplicationContext("src/main/resources/beans.xml");

це все ще був виняток IO.

Потім файл залишили в src / main / resources /, але я змінив декларацію на:

ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

і це вирішило проблему - можливо, це комусь буде корисно.

дякую і вітаю!

Редагувати:

Оскільки у мене багато людей стикається з рішенням і мав перший досвід роботи з Весною ще студентом кілька років тому, я відчуваю бажання коротко пояснити, чому це працює.

Коли проект компілюється та пакується, усі файли та підкаталоги з 'src / main / java' у проекті переходять у кореневий каталог упакованої jar (артефакт, який ми хочемо створити). Те саме правило застосовується до 'src / main / resources'.

Це домовленість, яку поважають багато інструментів, таких як maven або sbt, в процесі побудови проекту (примітка: як конфігурація за замовчуванням!). Коли код (із допису) був у робочому режимі, він не зміг знайти нічого подібного до "src / main / resources / beans.xml" через те, що beans.xml знаходився у кореневій частині jar (скопійований у / beans .xml у створеному jar / ear / war).

При використанні ClassPathXmlApplicationContext, належним чином декларація про розташування для xml-визначень бобів була "/beans.xml", оскільки це шлях, куди він належить у jar, а пізніше в classpath.

Це можна перевірити, розпакувавши банку за допомогою архіватора (тобто rar) і побачити її вміст зі структурою каталогів.

Я б рекомендував читати статті про шлях до занять як додаткові.


Я не бачу різниці між ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");іApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Флоріан Ф

1
@FlorianF різниці немає. Різниця полягає в тому, де розміщується файл, що описано в повідомленні.
dawrutowicz

2
Я бачу, як ви переходите beans.xmlна, src/main/resources/beans.xmlа потім знову на beans.xml. Дякую.
Флоріан F

Ви не повинні мати src на шляху до класу. Коли ви будуєте проект, ці ресурси будуть упаковані в іншому місці.
OrangeDog

1
Привіт, якщо ми запускаємо цю банку з командного рядка, вона, схоже, працює не так, як очікувалося (чудово працює на eclipse).
Дхрув Сінгхал

58

Спробуйте це:

new ClassPathXmlApplicationContext("file:src/main/resources/beans.xml");

файл: точка префікса до ресурсів файлової системи, а не шлях до класу.

шлях до файлу може бути відносним або системним (/ home / user / Work / src ...)


1
ну, краще зберігати ресурси в classpath, ніж жорстко закодовані, але дякую, однак. Я не мав досвіду з CP того часу :-)
dawrutowicz

1
Можливо, краще використовувати FileSystemXmlApplicationContext для файлів.
romnempire

я маю подібну проблему, і це рішення працювало для мене.
Авдхут

20

У мене також була подібна проблема, але через трохи іншу причину, тому поділіться тут на випадок, якщо це може комусь допомогти.

Розташування мого файлу

Файл beans.xml

Як я користувався

ClassPathXmlApplicationContext("beans.xml");

Є два рішення

  1. Вийміть beans.xml з упаковки та покладіть у стандартний пакет.
  2. Вкажіть назву пакета під час його використання, а саме.

ClassPathXmlApplicationContext("com/mypackage/beans.xml");


1
ну, правда сказати. Посилання "com / mypackage / beans.xml" таке саме, як "/com/mypackage/beans.xml", оскільки "com / mypackage / beans.xml" є відповідним шляхом, який використовує "/" (root) для побудови абсолютного шляху.
dawrutowicz

7

src/main/resourcesє вихідним каталогом, ви не повинні посилатися на нього безпосередньо. Коли ви будуєте / пакуєте проект, вміст буде скопійовано у правильне місце для вашого шляху до класу. Потім слід завантажити його так

new ClassPathXmlApplicationContext("beans.xml")

Або ось так

new GenericXmlApplicationContext("classpath:beans.xml");

7

Це тому, що applicationContect.xml або any_filename.XML не розміщено належним чином.

Усунення несправностей Кроки

1: Додайте файл XML до папки ресурсів.

2: Якщо у вас немає папки ресурсів. Створіть його, навігацією по новому клацніть правою кнопкою миші проект new> Source Folder, назвіть його ресурсом і розмістіть під ним ваш XML-файл.



3

Ви переглянули каталог src. Файл xml справді існує. Але подивіться на каталог class або bin / build, де встановлені всі ваші вихідні класи. Я підозрюю, що для використання вам знадобиться лише шлях ресурсу / beans.xml


3

Я підозрюю, що ви створюєте .war / .jar і, отже, це вже не файл, а ресурс у цьому пакеті. Спробуйте натомість ClassLoader.getResourceAsStream (шлях рядка) .


Привіт ... Вибачте, що запитали трохи пізно, але чи можете Ви, будь ласка, детальніше розповісти про те, як перетворити з потоку вводу в контекст програми? На даний момент я намагаюся запустити виконуваний файл jar, але він каже, що не може завантажити xml-файл bean, оскільки він не існує.
Друв Сінгхал

3

Зверніть увагу, що перший 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>

Де, як показано нижче, код також намагається створити ще один додатокContext.

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.


2

Навесні всі вихідні файли знаходяться всередині 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");


1

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#sec:java_project_layout

При запуску тесту з використанням набору завдань gradle за замовчуванням передбачено крок "processTestResources", який шукає тестові ресурси в C: \ ..... \ src \ test \ resources (Gradle корисно надає повний шлях).

Ваш файл .properties та applicationContext.xml повинні знаходитись у цьому каталозі. Якщо каталогу ресурсів немає (як це було в моєму випадку), вам потрібно створити його, скопіювавши туди файли. Після цього просто вказівка ​​назви файлу працювало чудово.

context = new ClassPathXmlApplicationContext("applicationContext.xml");

0

Я зробив протилежне більшості. Я використовую 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 в зернах доступний за допомогою ClassPathXMLAppllicationsContext.


0

Це те, що мені вдалося:

  new ClassPathXmlApplicationContext("classpath:beans.xml");

Привіт, це спрацювало і у мене, але проблема полягає в тому, що файл jar створюється, jar для мене не працює .. Я маю на увазі, я отримую NoClassDefFoundError, коли я намагаюся запустити файл jar, коли я запускаю програму в eclipse оскільки Java працює без помилок, не знаю, як це вирішити
sailaja

0

Якщо ця проблема все ще хвилює вас, і ви розробляєте за допомогою Eclipse, подивіться на цю помилку Eclipse: файли ресурсів з "src / main / resources" неправильно включені до шляху до класу

Рішенням, здається, є погляд на властивості проекту, шлях побудови Java, вихідні папки. Видаліть /src/main/resourcesкаталог і додайте його знову. Це спричиняє нагадування Eclipse про необхідність копіювати ці файли до шляху до класу.

Ця помилка вплинула на мене при використанні випуску Eclipse "Neon". (І було дуже неприємно, поки я не зрозумів просте виправлення, щойно описане)


0

Я стикався з цією проблемою, і це зводило мене з розуму; Врешті-решт, я знайшов у своєму POM.xml наступне, що було причиною проблеми:

<resources>
    <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
        <includes>
            <include>**/*.properties</include>
        </includes>
    </resource>
</resources>

0

Я не був впевнений, що написав це, але, можливо, хтось заощадить кілька годин:

mvn clean

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


0

Я затримався в цьому питанні на деякий час і прийшов до наступного рішення

  1. Створіть клас ApplicationContextAware (який є класом, що реалізує ApplicationContextAware )
  2. У ApplicationContextAware ми маємо реалізувати лише один метод

    public void setApplicationContext (контекст ApplicationContext) кидає BeansException

  3. Розкажіть про весняний контекст про цей новий боб (я називаю його 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);
    

Сподіваюся, це вирішить проблему для багатьох користувачів


0

Beans.xml або file.XML не розміщено належним чином. Якщо у вас є проект Maven, слід додати файл XML у папку ресурсів. src -> main -> java -> ресурси

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.