Spring ClassPathXmlApplicationContext loading xml - java

Now I want to load applicationContext.xml by ClassPathXmlApplicationContext, my working folder structure is src/main/java; src/main/resources/applicationContext.xml;
My code is
ApplicationContext ctx =
new ClassPathXmlApplicationContext("src/main/resources/applicationContext.xml");
Throw cannot be opened because it does not exist,but
ApplicationContext ctx =
new ClassPathXmlApplicationContext("applicationContext.xml");
is ok, Why is it happen?

ClassPathXmlApplicationContext will look for specific file from the classpath. From the Java Build Path -> Source section, you can see the source folders: src/main/java, src/main/resources, src/test/java. They will be used as classpath by the java applicaiton.
So if you pass applicationContext.xml as parameter, jvm will look for this file from the above 3 folders. src/main/resources/beanConfigurationName.xml will lead jvm to look for "src/main/resources/beanConfigurationName.xml" from classpath.

Related

Spring Boot project can't find Hibernate.cfg.xml when run as executable jar

I see that issues with the hibernate.cfg.xml not being found when SessionFactory is being set up is a somewhat common occurrence, but my question here is somewhat specific. My project works fine when run in Eclipse, even when I move the hibernate.cfg.xml around; I can leave it at the source level and do this:
Configuration configuration = new Configuration();
configuration = new Configuration();
configuration.configure();
Or I can move it to a different location and define it this way:
Configuration configuration = new Configuration();
configuration = new Configuration();
configuration.configure("/path/to/hibernate.cfg.xml");
Both ways work in Eclipse. However, when I build an executable jar to run the application elsewhere, when it launches it complains:
Initial SessionFactory creation
failed.org.hibernate.internal.util.config.ConfigurationException: Could not
locate cfg.xml resource [hibernate.cfg.xml]
org.hibernate.internal.util.config.ConfigurationException: Could not locate
cfg.xml resource [hibernate.cfg.xml]
I understand (or I think I do) that the reason for this is that the hibernate.cfg.xml isn't getting included in the jar itself and so even when the path is defined it can't find it but am not sure how to fix it. I think if I can get the file into the jar then it may work (maybe the classpath also needs an entry for this?) but I'm actually not sure how to do so.
It mainly depends on whether you are using a framework or not and if yes the which framework you are using. If you are not using any framework then keeping hibernate.cfg.xml file in your root path can be fine. But Because of urge in standardising the coding process, frameworks usually expect the file in your resources folder.But in your case you should give the path to that configuration file not relative to the root folder but entire path.
I think you are using absolute path here:
configuration.configure("/path/to/hibernate.cfg.xml");
Instead of that you should use classpath loader. Something like this :
Resource r = new ClassPathResource("hibernate.cfg.xml")
String path = r.getURI().getPath();
configuration.configure(path);
This should work after packaging jar.

Spring class path resource [applicationContext.xml] cannot be opened because it does not exist

I'm placing applicationContext.xml in the same directory and package as my Java classes.
Doing the following to read it:
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Yet I am consistently met with:
IOException parsing XML document from class path resource [applicationContext.xml]; nested exception is java.io.FileNotFoundException
Which I do not get: The file is there, in the same directory as the classes. They're even compiled to /out and I can see it's all there.
I've tried putting it in src/resources/applicationContext.xml but to no avail.
Spring will look for it in the root of the classpath ...
The "same directory and package as my Java classes" is not at the root of your classpath
src/resources is not on your classpath at all
If you put it in src/main/resources then it will be (1) on your classpath and (2) in the root of your classpath.
I resolved this problem, as changing
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
to
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("packagename/applicationContext.xml");
My XML file also resides in the same package as my java classes exist.

ClassPathXmlApplicationContext error, Spring framework

I have encountered a problem when it comes to the Springs framework, which leads to that the communication between the server and the database does not work.
The project that I created is a Spring project, then refactored to Maven.
At this line in the code:
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("projectName/spring.xml");
I get this error:
Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [projectName/spring.xml]; nested exception is java.io.FileNotFoundException: class path resource [projectName/spring.xml] cannot be opened because it does not exist
But it does exist. And I've tried solutions for this problem such as writing ClassPathXmlApplicationContext("spring.xml") instead. This doesn't help however, since then Spring automatically looks in the folder src/main/resources. This doesn't work for me since my project structure doesn't allow me to add this folder and put a XML-file in it. If I try to create this folder, then it is automatically put inside the Java-resources folder, and Eclipse won't allow me to put XML in there.
This is how my project looks:
enter image description here
Is there a way for me to declare where Spring should look for this spring.xml-file?
The ClassPathXmlApplicationContext assumes that the file is on your classpath (Javy describes how to do load a resource from your classpath).
If you want to load the configuration from your file system (as you're doing), you might want to consider using FileSystemXmlApplicationContext instead. Using this mechanism to load your context you can pass a file system location as you're currently doing.
new ClassPathXmlApplicationContext(this.getClass().getResource("/spring.xml").getPath())
try the code above
hope that helped
Spring doesn't look at the src/main/resources, it looks at the classpath.
If you write projectName/spring.xml you need to have this file in bin/projectName/spring.xml or build/projectName/spring.xml. Where bin or build your build folder.
If you build a jar, this file should be in the jar!projectName/spring.xml.
For the web-application this file should be in the WEB-INF/classes/projectName/spring.xml.
If you add src/main/resources at the class path, then content of this folder will be in the build folder. Maven adds src/main/resources at the class path automatically.
Sometimes you should rebuild (clean) your project in the IDE to have such files in the build folder.
Use "FileSystemXmlApplicationContext" as
ApplicationContext context = new FileSystemXmlApplicationContext("spring.xml");

Loading a jar's context.xml from classpath

I'm trying to load an application context which is inside a jar as a plugin. I use this to load the context:
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath*:**my-context.xml");
When I load the jar through pom.xml, it works fine.
Then I add it directly in the classpath using eclipse instead of maven to avoid to compile every time (ultimate goal is the shared lib folder in tomcat, not working too). Now spring is unable to find it and return a default context (no exception)
I checked that it's correctly insert in the classpath using:
InputStream in1 = this.getClass().getClassLoader().getResourceAsStream("my-context.xml");
It works.
I checked logs. Using the pom.xml, spring is correctly searching in the jar
Searching directory [...target\classes\META-INF\maven\x.y.z] for files matching pattern [...\x.y.z/target/classes/**/my-context.xml]
Searching directory [...ehealth.poc.module1] for files matching pattern [D:/JRB/Projects/Vivates/workspaces/default/extcom/ehealth.poc.module1/target/classes/**/ecm-context.xml]
...
Resolved location pattern [classpath*:**/my-context.xml] to resources [file [...\target\classes\my-context.xml]]
Loading XML bean definitions from file [...\target\classes\my-context.xml]
...
In the second case, nothing in the log about my jar.
Why spring does not have the same behavior when I use maven or directly the classpath? I maven doing something else than simple adding dependencies location in the classpath?
Finally, we found the solution on eclipse.
The problem comes from the ** in
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath*:**my-context.xml");
It looks like ** doesn't scan the .jar files. Setting the direct path is working :
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:my-context.xml");

Reference file relative to Jar deployment location

How do I reference an external beans.xml file based on its relative location to where my jar file is deployed? This is what I have now, which doesn't work:
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("../beans.xml");
I want it out of the classpath so I can change things without redeploying, but relative to the deployed location of the jar so that it will work no matter where I put the jar and the beans.xml in the file system, as long as they are correctly situated relative to each other.
This is Spring btw, if that helps.
Thanks!
An application context file must be on the classpath to allow ClassPathXmlApplicationContext to work. To use a relative path you would have to use FileSystemXmlApplicationContext.
ApplicationContext context = new FileSystemXmlApplicationContext("../beans.xml");
You can import the external beans configuration file in your spring-config.xml you can import the extends
<beans ...>
<import resource="file:/path/to/external/config.xml"/>
</beans>
The above Spring config will import /path/to/external/config.xml. Having an external file will allow you to configure beans without having to rebuilding your main war/jar.
In your Java code, you can load it as follows:
ApplicationContext context = new ClassPathXmlApplicationContext("config.xml");
and the config.xml file should be in:
project-classpath/config.xml
More about loading external configuration files, you can find here

Categories