Can not open beans.xml (config file) because does not exist - java

Exception in thread "main"
org.springframework.beans.factory.BeanDefinitionStoreException:
IOException parsing XML document from class path resource
[com/main/beans.xml]; nested exception is
java.io.FileNotFoundException: class path resource
[com/main/beans.xml] cannot be opened because it does not exist
ApplicationContext context =
new ClassPathXmlApplicationContext("com/main/beans.xml");
I have tried before with
ApplicationContext context =
new FileSystemXmlApplicationContext("src/main/java/com/main/beans.xml");
And it works well.
How to do that relative to the classpath?
Note: classpath is in the build path
In the example I'm following, it has the following structure and it works
Project structure
Classpath
ApplicationContext context =
new ClassPathXmlApplicationContext("com/caveofprogramming/spring/test/beans/beans.xml");

Here's the file structure I normally use, which works fine. As #M.Deinum said, you'll want to put your xml file in a src/main/resources. I normally put to the it in a complete package path with the resources so during compile time, maven will add all the resources to same path as the corresponding classes that use them.
resources get copied to the class package when you do the above
public class App {
public static void main(String[] args) {
ApplicationContext context
= new ClassPathXmlApplicationContext("com/underdogdevs/stackmaven/beans.xml");
Hello hello = (Hello) context.getBean("hello");
hello.sayHello();
}
}
Works fine for me. If you're wondering why you still need to use the complete package name when the xml is already in the same class packages, its it will first be searched for in the class root
UPDATE
put the package with the bean.xml into the src/main/resources. It should work with the path your using.
UPDATE 2
"Yes, it worked. But why is it working the example, I'm following as well. If the beans.xml is out of src/main/resources .. I can't find out how that works? *
The thing is, the Spring container will look from the class root. It has nothing to with the resources folder. The resources is a convenience dir for maven projects to build to your class path. The reason the tutorial works, is that the beans.xml is in a package, that will get put into the class path in the build, as seen below. It is only preferred to use a resources, but a package` will also build to the class path.

Related

Spring boot test: #Sql annotation Unable to locate sql files placed in src/test/resources

I didn't want to load the entire Spring Boot configuration for unit-testing my DAO layer, and therefore created a nested configuration class to suppress default configurations. But when I try to specify SQL scripts for it to run before tests, its unable to find them.
Here's the code:
package com.test.customer.controller;
..
#RunWith(SpringRunner.class)
#JdbcTest
#Sql({"data.sql"})
public class InterviewInformationControllerTest {
#Configuration
static class TestConfiguration{
}
#Test
public void testCustomer() {
// code
}
}
I get the error: Cannot read SQL script from class path resource [com/test/customer/controller/data.sql]; nested exception is java.io.FileNotFoundException: class path resource [com/test/customer/controller/data.sql] cannot be opened because it does not exist
I've tried placing the file at both src/main/resources (not preferred) as well as at src/test/resources (which I prefer)
Note: I'm running the Unit test from inside Eclipse by doing Run as -> JUnit test.
Edit: Added the static keyword to the configuration class
your inner configuration class will not work unless you add a static keyword before its definition. However you should know that for the #Sql annotation
Path Resource Semantics
Each path will be interpreted as a Spring Resource. A plain path — for
example, "schema.sql" — will be treated as a classpath resource that
is relative to the package in which the test class is defined. A path
starting with a slash will be treated as an absolute classpath
resource, for example: "/org/example/schema.sql". A path which
references a URL (e.g., a path prefixed with classpath:, file:, http:,
etc.) will be loaded using the specified resource protocol.
So try to prefix the value inside #Sql with classpath: like this :
#Sql(scripts={"classpath:data.sql"})
Good luck!
Check your out directory of the module. While creating directory in resources, if you have named it directly with the namespace like com.gakshintala.bookmybook, it takes that name completely as the directory name, so the out also contains this directory under resources with name com.gakshintala.bookmybook. PFB right vs wrong. The top is right and bottom is wrong.
Spring always looks for nested directory resources->com->gakshintala->bookmybook.
So create that directory structure.

Using Spring #PropertySource in a Maven submodule

In a Spring-boot application, I was having a single module and I was able to inject a configuration file, e.g. "my.properties", that was located in src/main/resources as follows:
#Configuration
#PropertySource("/my.properties")
public class MyConf{
}
Everything was ok, but then I created submodules and now I moved that configuration file in a submodule. When I start the main application I gedt the following exception:
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [com.myapp.MainApplication]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/home/jeanvaljean/workspace/mainmodule/secondarymodule/my.properties]
As I see, I can solve the issue by writing
#PropertySource("/src/main/resources/my.properties")
Doing this, the path is correct and the file can be loaded.
Anyway, that is an horrible solution, and I'm pretty sure that there is a more elegant and flexible alternative. Any solution?
Spring has a few different implementations of how to find a resource. By using the prefix classpath: you are telling Spring to search for the resource in all the classpath, rather than in the classes that are bundled with your application.
Depending on the ApplicationContenxt, Spring will use a different default Resource class. It looks like in your case, Spring was instantiating a FileSystemResource, which only finds files available on the filesystem with either relative or absolute paths (but not inside jars!). My rule of thumb is to never prefix something if it's in the same module/component/jar, and always prefix it with classpath: if I know it's in a different module/component/jar (some people get mad at this :).
You can read a more in the Spring Documentation - Resources

how to load application-context.xml using #ContextConfiguration annotation

My project structure is as below:
src/main/java -> contains java classes
src/main/resources/spring/context/application-context.xml
src/test/java -> contains J-unit test
I would like to use #ContextConfiguration annotation to load my application-context.xml
How can I load this file and how can I make sure that all beans are loaded?
I tried it using classpath and file. But nothing works for me.
I am confused when to use classpath and file. Some one please help me with this.
Thanks in advance.
#ContextConfiguration("classpath:/spring/context/application-context.xml") should work.
In conventional Maven project layout, src/main/resources contains classpath resources, therefore you should use classpath: or no prefix at all, because classpath: should be a default one in this case.
If it still doesn't work, perhaps something is wrong with your project configuration and files from src/main/resources doesn't appear in the classpath.
If context loads successfully, all beans in it should be loaded as well, otherwise context will fail to load.
Try with:
ApplicationContext APPLICATION_CONTEXT = new ClassPathXmlApplicationContext("/spring/context/application-context.xml");
If it does not work, try putting application-context.xml directly in src/main/resources and then load it with
ApplicationContext APPLICATION_CONTEXT = new ClassPathXmlApplicationContext("application-context.xml");

Spring Maven unitTest applicationContext loading wrong file

.I have a project that has a spring-config.xml file in src/main/webapp/WEB-INF and an applicationContext.xml file in src/test/resources. I also have an abstract test base class for my unit tests in src/test/java looks something like:
#ContextConfiguration(locations = {"classpath:/applicationContext.xml"})
public abstract class AbstractTestBase extends AbstractTransactionalJUnit4SpringContextTests {
//Common code and fields
}
All my unit tests extends this AbstractTestBase which points to the context within the src/test/resources or should. The problem arises when running my unit tests it is pulling in the spring-config.xml file.
There are other projects my team is working on that have the same file structure, same app context setup, and run as intended, but even when I have each file in the project side by side I don't see where their file runs and this one doesn't.
I am new to spring so I don't know what it is I should be looking for.
Are there any situations where Spring or Maven would not take the app context I'm handing it given all files exist? Is there anything I might be missing?
EDIT: corrected to reflect that one file is a spring-config file.
"classpath:/applicationContext.xml" should look under src/test/resources.
But it should be noticed that using that syntax will load the first one it finds and then stop as mentioned by '#chrylis'.
I once had similar problem.
You must have been using an IDE. There must have been applicationContext.xml file in your target/test-classes/ (in Eclipse IDE) in your project directory that is a copy of your xml file under src/main/webapp/WEB-INF or xml file like it.

Grails config of Spring beans in different files

Grails have cofig for spring bean called resources.groovy. And as i understand from docs it allows you to include another file, using loadBeans(%path%)
I'm tried with this:
println 'loading application config ...'
// Place your Spring DSL code here
beans = {
loadBeans("classpath:security") //i'm tried with "spring/security" and "spring/security.groovy" also
}
but when grails is running it log following error:
Caused by: org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Error evaluating bean definition script: class path resource [security] cannot be opened because it does not exist
Offending resource: class path resource [security]; nested exception is java.io.FileNotFoundException: class path resource [security] cannot be opened because it does not exist
at grails.spring.BeanBuilder.loadBeans(BeanBuilder.java:470)
at grails.spring.BeanBuilder.loadBeans(BeanBuilder.java:424)
at resources$_run_closure1.doCall(resources.groovy:13)
at resources$_run_closure1.doCall(resources.groovy)
... 45 more
Script security.groovy is exists at grails-app/conf/spring and compiled by grails maven plugin into target/classes/security.class.
Directory target/resources/spring is empty at this time
How i can configure Grails or grails-maven-plugin to copy this config files, not compile it into classes?
p.s. this problem also presents when i try to include config scripts using grails.config.locations = [ %path% ] inside conf/Config.groovy, my groovy scripts compiles into classes and because of it, grails config builder can't find them :(
Did you try:
println 'loading application config ...'
// Place your Spring DSL code here
beans = {
loadBeans("classpath:*security.groovy")
}
(this should load all Groovy files on the classpath ending with security.groovy and parse them into bean definitions).
Update: Found an interesting thread with this message as reference and my understanding is that one trick is to use ant in scripts/_Events.groovy to copy the .groovy file to the classesDirPath dir and then simply use:
beans = {
// load spring-beans for db-access via spring-jdbc-template
loadBeans('security.groovy')
// load some other spring-beans
...
}
This looks like a hack to get things working in both the war and when running run-app though. Not sure how things "should" be done (if this even makes sense).

Categories