I'm working on web application that uses a database storage system and I chose to keep the dataAccess-applicationcontext seperate from the rest. However when I run the following line of code it says it does not exist.
ApplicationContext ac = new ClassPathXmlApplicationContext("dataAccess-applicationContext.xml", UsageDataDAO.class);
I have even moved the xml file to the same directory only to get the same error as posted below.
nested exception is java.io.FileNotFoundException: class path resource [com/foobar/bar/foo/dataAccess-applicationContext.xml] cannot be opened because it does not exist
Any Idea what is going on here?
This is hard to debug without all of the details, but it has to be one of two issues.
First, the file really isn't in your classpath. This is a web application, so you should consider how your particular servlet container works when you're checking the classpath. For example, in a servlet environment, WEB-INF is not in the classpath, but WEB-INF/classes is.
Second, the file is in your classpath, but you're referring to it incorrectly. Based on the information that you provided already, I don't think this is the case, but this possibility can be expanded on later.
Regardless, why are you trying to load a file manually? You should reference the configs in your web.xml. If you provide more details about how you're running your web application, then we can help you with this part. In the meantime, this example might be enough information. It illustrates how to configure the root spring container that's shared by all of the Servlets and Filters in the container (configuring a specific Servlet requires a slightly different approach):
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config1.xml, /WEB-INF/config2.xml</param-value>
</context-param>
please edit your file name with underscore dataAccess_applicationContext.xml instead dataAccess-applicationContext.xml. And try again.
Try with the classpath*: prefix . "classpath*:dataAccess-application-context.xml" if it is in the root classpath else use "classpath*:/folderName/dataAccess-application-context.xml"
Your 2nd parameter to:
ApplicationContext ac =
new ClassPathXmlApplicationContext("dataAccess-applicationContext.xml",
UsageDataDAO.class);
Includes UsageDataDAO.class. According to the spring javadoc for this class, this is requesting the context search start in com/foobar/bar/foo/.
Instead put dataAccess-applicationContext.xml in WEB-INF/classes and try:
ApplicationContext ac =
new ClassPathXmlApplicationContext("dataAccess-applicationContext.xml");
UsageDataDAO myDao = (UsageDataDAO) ac.getBean("MyDaoBeanName");
Related
I need to load a file from within a directory in the root of a WAR using Spring
This is the directory structure
rootOfWar
--static-dir
---- my-file.css
--WEB-INF
---- classes
.....
It is a normal WAR.
In a Spring #RestController I need to be able to read and write to my-file.css file. What is the best way to get the File, ServletContextResource or?
More Details
- The location of the file is out of my control I cannot move the file.
- The jee container is Tomcat.
- The Spring version is current 4.1.6
- The Spring environment is not using XML only annotations with WebApplicationInitializer, WebMvcConfigurerAdapter and an annotation configuration class.
Is there another way to do this like specify a file as a resource in the configuration so that it is loaded by the frame work and accessible within the application?
Basically I have JEE knowledge but my Spring knowledge on best practices concerning read/write are lacking.
If you need to modify a file you should not make it part of the WAR. Store it somewhere outside the web package and reference it there. Everything else will lead to problems, especially when you deploy to Websphere which is often run in a restricted environment where writes are rejected.
But I consider overwriting files in the web path bad design, because you are likely to run into caching issues. Better write a servlet that generates the CSS you need. If you would be able to name the content that should overwrite your css file, you are also able to render this dynamically.
Something like this may be already sufficient:
#RequestMapping(value = "/my.css", produces = "text/css;charset=UTF-8")
public String showCss() {
return "<here goes your css>";
}
(This is written from my memory and not tested).
The good thing is that you can modify the css any time you want and even set caching information as needed.
I am a bit familiar with Spring framework but am still having lots of question concerning use of spring from project architectural view point. Now I am setting up Spring 3 and a Maven web application and am willing to try out all the the fancy component-scan's and autowiring features however this is where I get confused.
I am trying to break the project into sub-modules. And at some point these sub-modules may include something-context.xml in classpath*:resource/META-INF, like for instance when I will want to define a datSource related stuff in a separate module. So that's fine spring let's you load context files from within class-paths of all of the jars.
But here is where it gets vague - say I am using component scan. I am obviously using spring DispatcherServlet and it needs a servlet context to be loaded, and then there is a global application context parameter specified in web.xml contextConfigLocation.
So now servlet context config has a component-scan feature enabled for com.mycom.project.controllers and context loaded in the global contextConfigLocation has a context loaded with component scan feature for package com.mycom.project also searches for classpath*:META-INF/spring/*-context.xml.
So my question is - does this load controller's twice given that component scan is used for a for com.mycom.project.controllers and com.mycom.project? Or is it all loaded into one huge container and the contextConfigLocation parameter for either DispatcherServlet or global declaration is sort of access issue ? As in DispatcherServlet will reach only what's defined in servlet-context.xml but won't be able to use anything else?
And if my assumption is wrong, could I have a suggestion on how to manage multi-module project issues?
Thanks.
Yes, you might run into trouble. See this link for how to solve your problem.
#Service are constructed twice
The way you proceed when creating modules seems valid to me. You have a context.xml file for each module and all will get loaded once you load the application. Your modules are self-contained and can also be used in different environments. That's pretty much the way I'd also do it.
In most of the Java projects using Spring, I find this entry in web.xml which is executed at server start-up:
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
What is the purpose of Log4jConfigListener?
In my legacy project I can also see this setting. However when i dive into the code I do not find anything special done in this class or further classes called internally by this class. I am sure there must be some good purpose behind putting above code snippet and I am missing it.
In every class which putting the logs in file here is the entry
private static final Log log = LogFactory.getLog(PoolManagerImpl.class);
log.debug("Number of connection pools to create = ["
+ connection.size() + "]");
Even if I comment out my web.xml entry, logging works fine. So what is it's purpose?
The Log4jConfigListener initialises the Log4j "subsystem" as soon the webapplication starts up, as opposed to "lazily configuring" it as soon as it is needed.
In my opinion, the main advantage of explicitly initializing log4j via the Log4JConfigListener is that it allows you to configure the location of the log4j configuration file through using servlet context parameters; depending on how the application is deployed, this may make it possible for the configuration to be changed at runtime by some kind of admin user without having to dig around inside the exploded WAR directory .
See the javadoc for Log4jConfigListener, and more importantly Log4jWebConfigurer, as it does the real work.
I just learned that I could retrieve parameters and other stuff from "ServletContext" (i.e. by overriding contextInitialized).
Reading tomcats context doc reveals that I could set parameters via web.xml (used as default values) and then overwrite them with an [context].xml file.
First question: is this a good way to set default properties and let server administrators overwrite them?
First is there an overview that shows all kinds of attributes/parameters that are available with it's tag used in tomcats context xml, the tag used in web xml, how the retrieve it from within java and a use case / example for what kind of stuff a parameter should be used?
By toying around with it I am facing the following problem: If I deploy the web app via tomcats web interface the [context].xml is completly ignored (console states that it is deployed but 2nd is null)
To cut a long story short: how to properly use web.xml and [context].xml - the link below isn't much help.
Well first off, declaring (servlet/application) context attributes via web.xml is better, as this is the official Java EE supported way, so if you declare them like this they will work when you deploy your app in other App Servers other than Tomcat.
Second, I believe the Tomcat rule for overriding param values is:
if you have a $CATALINA_BASE/conf/context.xml and you have the same attribute declared in it and in web.xml, the one in web.xml will have priority
if you have a $CATALINA_BASE/conf/context.xml as well as a context.xml file inside your application (in the META-INF directory) both with the same parameter, the one in the META-INF/context.xml will have priority.
Finally, if you have all three files decalring the same parameter, the one in the web.xml will have priority.
In ASP.NET, there is web.config which can hold application-wide settings. Is there a corresponding file (residing outside of the war or jar archive) for a Java EE Servlet?
What I need is some place to point out a configuration file, which currently holds four attributes which in turn, taken together, leads to the database where the rest of the data and configuration is stored. (Server, database, username and password.) These values need to be easy to change without repackaging and redeploying the entire application, hence the configuration file, but hardcoding the path to the configuration file in the application (even if it is as a constant) seems far from optimal.
Any hints? I've tried Google but found very little that seemed relevant - and what I did find appeared hideously over-engineered for my needs.
In ASP.NET, there is web.config which can hold application-wide settings. Is there a corresponding file (residing outside of the war or jar archive) for a Java EE Servlet?
That's the web.xml. You can define settings as <context-param> entries.
<context-param>
<param-name>foo</param-name>
<param-value>bar</param-value>
</context-param>
It's available by ServletContext#getInitParameter(). The ServletContext is in turn available anywhere.
String foo = getServletContext().getInitParameter("foo"); // Contains "bar"
You can also access it by EL.
#{initParam.foo} <!-- prints "bar" -->
What I need is some place to point out a configuration file, which currently holds four attributes which in turn, taken together, leads to the database where the rest of the data and configuration is stored. (Server, database, username and password.) These values need to be easy to change without repackaging and redeploying the entire application, hence the configuration file, but hardcoding the path to the configuration file in the application (even if it is as a constant) seems far from optimal.
As per the emphasis, I'd use a properties file for this particular purpose which is then placed in a path outside the WAR. You just need to add this path to the Java runtime classpath. Then you can obtain it as classpath resource:
Properties properties = new Properties();
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("filename.properties"));
// ...
However, with the particular sole purpose to serve a DB connection, you're indeed better off with a servletcontainer-managed datasource as answered by Qwerky. All you possibly would need to configure is then just the datasource name.
If this is a web app then you'd be better served configuring the database connection as a resource on the server, then getting your app to retrieve it using JNDI. Your app server will have documentation on how to do this, its a basic task.
99% of serious web apps do this, the other 1% should.
You can have your application load an arbitrary external file by simply passing the path as a command-line parameter (to the servlet container startup script). Then store the values in the ServletContext