web-dev-qa-db-ja.com

存在する場合、SpringはBean xml構成ファイルを見つけることができません

Springで最初のBeanを作成しようとしていますが、コンテキストのロードで問題が発生しました。 src/main/resourcesにBeanの構成XMLファイルがあります。

次のIOExceptionが表示されます。

スレッド「メイン」の例外org.springframework.beans.factory.BeanDefinitionStoreException:クラスパスリソース[src/main/resources/beans.xml]からXMLドキュメントを解析するIOException。ネストされた例外は

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はクラスパスにあります。どうしましたか?

65
dawrutowicz

ありがとう、しかしそれは解決策ではなかった。なぜ私にとってうまくいかなかったのかがわかりました。

宣言したので:

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");

そしてそれは問題を解決しました-たぶんそれは誰かにとって役立つでしょう.

感謝と乾杯!

編集:

私は多くの人々に解決策を賞賛し、数年前に学生としてSpringを初めて経験したことがあるので、なぜそれが機能するのかをすぐに説明したいと思っています。

プロジェクトがコンパイルおよびパッケージ化されると、プロジェクトの「src/main/Java」からのすべてのファイルとサブディレクトリは、パッケージ化されたjar(作成するアーティファクト)のルートディレクトリに移動します。同じ規則が「src/main/resources」にも適用されます。

これは、プロジェクトを構築する過程でmavenやsbtのような多くのツールによって尊重される慣習です(注:デフォルトの構成として!)。 (投稿からの)コードが実行モードのとき、beans.xmlがjarのルート(/ beansにコピーされている)のため、「src/main/resources/beans.xml」のようなものを見つけることができませんでした作成されたjar/ear/warの.xml)。

ClassPathXmlApplicationContextを使用する場合、beans xml定義の適切な場所の宣言は、この場合、「/ beans.xml」でした。これは、jarおよびそれ以降のクラスパスに属するパスであるためです。

アーカイバ(つまりrar)でjarを解凍することで確認でき、ディレクトリ構造でその内容を確認できます。

クラスパスに関する記事を補足として読むことをお勧めします。

135
dawrutowicz

これを試して:

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

ファイル: プレフィックスは、クラスパスではなく、ファイルシステムリソースを指します。

ファイルパスは相対またはシステム(/ home/user/Work/src ...)

46

私も同様の問題を抱えていましたが、原因が少し異なるため、ここで共有することで誰にも役立つ場合があります。

私のファイルの場所

beans.xml file

私が使用していた方法

ClassPathXmlApplicationContext("beans.xml");

2つのソリューションがあります

  1. Beans.xmlをパッケージから取り出し、デフォルトパッケージに入れます。
  2. 使用中にパッケージ名を指定しますviz。

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

18
Kalher

src/main/resourcesはソースディレクトリです。直接参照しないでください。プロジェクトをビルド/パッケージ化すると、コンテンツがクラスパスの正しい場所にコピーされます。次に、このようにロードする必要があります

new ClassPathXmlApplicationContext("beans.xml")

またはこのように

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

それを使用するApplicationContext context = new FileSystemXmlApplicationContext("Beans.xml");

4
Deep Shah

Srcディレクトリを見ました。 XMLファイルは確かにそこに存在します。しかし、すべての出力クラスが設定されているクラスまたはbin/buildディレクトリを見てください。使用するにはresources/beans.xmlパスのみが必要だと思います。

3
Michael Z

.war/.jarを作成しているため、ファイルではなく、そのパッケージ内のリソースであると思われます。代わりに ClassLoader.getResourceAsStream(String path) を試してください。

3
Brian Agnew

これは、applicationContect.xmlまたはany_filename.XMLが適切なパスに配置されていないためです。

トラブルシューティングの手順

1:リソースフォルダーの下にXMLファイルを追加します。

2:リソースフォルダーがない場合。新しいプロジェクトを右クリックして[ソース]フォルダーに移動し、新しいフォルダーを作成して、名前をresourceとしてXMLファイルを配置します。

2
Gani

Springでは、すべてのソースファイルはsrc/main/Java内にあります。同様に、リソースは通常src/main/resources内に保持されます。したがって、spring構成ファイルはresourcesフォルダー内に保管してください。

Src/main/resources内にもファイルのClassPathエントリがあることを確認してください。

.classpathで、次の2行を確認します。不足している場合は追加します。

<classpathentry path="src/main/Java" kind="src"/>
<classpathentry path="src/main/resources" kind="src" />

そのため、すべてが揃っている場合、以下のコードが機能するはずです。

ApplicationContext ctx = new ClassPathXmlApplicationContext( "Spring-Module.xml");

2
Shashesh

最初の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>

以下のように、コードはもう1つのapplicationContextを作成しようとします。

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

beans.xmlapplicationContext.xmlの間の difference を参照してください

また、appliationContext.xmlの下の<META-INF/spring/><import resource="beans.xml"/>で宣言されている場合、このappliationContext.xmlbeans.xmlの同じ場所META-INF/springの下でappliationContext.xmlをロードしています。

どこにコード内;以下のように宣言されている場合

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

これは、Eclipse WEB-INF/classessrc/main/resources ORでbeans.xmlを探しています。

[beans.xmlsrc/main/resourcesを追加した場合、WARの作成中にWEB-INF/classesに配置される可能性があります。]

したがって、完全に2つのファイルが検索されます。

以下のようにapplicationContext.xmlでインポートする際にクラスパスルックアップを追加することにより、この問題を解決しました。

<import resource="classpath*:beans.xml" />

ロードされたApplicationContextが1つだけになるように、JavaコードのClassPathXmlApplicationContext("beans.xml")行を削除しました。

1

私はほとんどの反対をしました。 Force IDE Luna Java EEを使用しており、Beans.xmlファイルをパッケージ内に配置しました。ただし、ClassPathXMLApplicationContext引数のBeans.xml文字列の前に相対パスを付けました。だから私のメインアプリケーションで-Beans.xmlファイルにアクセスするもの-私は持っています:

    ApplicationContext context = 
         new ClassPathXmlApplicationContext("com/tutorialspoin/Beans.xml");

また、Beans.xmlファイルをsrcフォルダーからパッケージに移動するとすぐに、このxmlファイルがパッケージ外にある場合は存在しなかったXMLファイルアイコンの左下にBeanイメージがありました。これは、Beans xmlファイルがClassPathXMLAppllicationsContextによってアクセス可能になったことを知らせる良い指標です。

0
user1548875

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はこのディレクトリに存在する必要があります。 resourcesディレクトリが存在しない場合(私の場合のように)、そこにファイルをコピーして作成する必要があります。この後、ファイル名を指定するだけでうまくいきました。

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

私はこの問題を経験していましたが、それは私を夢中にさせていました。最終的に、POM.xmlに次の問題があることがわかりました。これが問題の原因でした。

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

私はそれを書くことを確信していませんでしたが、おそらく誰かが数時間を節約します:

mvn clean

あなたの設定全体がすでに完璧であれば、仕事をするかもしれません!

0
İsmail Yavuz

それでもこの問題に悩まされ、Eclipseを使用して開発している場合は、次のEclipseバグを参照してください。 「src/main/resources」のリソースファイルがclasspath に正しく含まれていない

解決策は、プロジェクトのプロパティ、Javaビルドパス、ソースフォルダを調べることです。 /src/main/resources dirを削除して、再度追加します。これにより、これらのファイルをクラスパスにコピーする必要があることをEclipseに通知します。

このバグは、Eclipseの「Neon」リリースを使用しているときに影響を受けました。 (そして、今説明した簡単な修正に気付くまで、とてもイライラしていました)

0
Geeb

これは私のために働いたものです:

  new ClassPathXmlApplicationContext("classpath:beans.xml");
0
Sushrut Rathi