using quartz in a web app with spring - java

I've created a small console application to see how quartz work and it was easy to create an applicationcontext object inside the main method to get the cron run. OK now I'm in a real project managed by maven and which is using cron jobs defined in some of the modules. Each of the module has his own spring config file. I had 3 of the modules using quartz so it was setup in each of the spring config file. The web app module is the one who has the dependency of each of the modules.
Now i had few concerns:
should I created the applicationcontext as in the console project or it's supposed to be loaded. If yes, where am I supposed to load it.
based on research on the Internet I did on line I use MethodInvokingJobDetailFactoryBean for easy unit testing. And now that I have to use the CronExpression class to test the getNextValidTimeAfter, I still don't know how to organize it properly
Can anyone give me a hand. I'd really appreciate it. Thanks for reading

As per comment, the question is closer to "How to load Spring application context file(s) for a Web application".
According to Section 3.8.5, "Convenient ApplicationContext instantiation for web applications", you can register an ApplicationContext using the ContextLoaderListener as follows (add this to your web.xml file):
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/daoContext.xml /WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- or use the ContextLoaderServlet instead of the above listener
<servlet>
<servlet-name>context</servlet-name>
<servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
-->

Related

Java Spring: Trying to configure webflow by xml, can't find dispatcher-servlet.xml

I am just starting out trying to see what spring flow is about.This book that i have is describing how i have to configure the dispathcer-servlet.xml and create some flows in there.
Problem is i cannot find this dispatcher-servlet.xml file in my java spring application to start the configuration.Where is it?
I searched on here and on google but i only find people who already have n dispatcher-servlet.xml file and they are asking how to configure it.
Any help would be greatly appreciated!
You don't need dispatcher-servlet.xml to configure DispatcherServlet. It's just a default name Spring will look for if not defined. You can define config in contextConfigLocation init-param when defining DispatcherServlet in web.xml. Or, if you have single DispatcherServlet, you can use global spring xml configuration. If you have a working java spring application, look for
<context-param>
<param-name>contextConfigLocation</param-name>
...
</context-param>
or
<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
...
</servlet>
in your web.xml
If you don't find it in web.xml, you will have to configure it yourself. I also think that the book might be for webflow 1.x. Try using official Spring Webflow reference, it's a good starting point, and is up-to-date:
https://docs.spring.io/spring-webflow/docs/current/reference/html/
Specifically, for Dispatcher servlet configuration look at this chapter:
https://docs.spring.io/spring-webflow/docs/current/reference/html/spring-mvc.html#spring-mvc-config-web.xml

How Spring Ioc container interacts with Tomcat container

I am familiar with the Spring Framework and have done some work in it.
In one of my interviews, I was asked "there is a web application deployed in Apache Tomcat; tell me how does the "Tomcat container" (used for servlets) interact with "Spring IoC container" (used for Spring beans)?"
I couldn't understand what the interviewer meant by that and was left speechless. Can someone please clarify what this question was about and what a reasonable answer to it might be?
A spring web-app will define a Spring Dispatcher Servlet in its config, the apache tomcat container will initialise this servlet, the dispatcher servlet in turn initialises the application context. There is no direct interaction between the tomcat container and the Spring IOC container.
There are two primary aspects of linking Spring with Servlets. First you have to load a Spring application context, and second you need to expose those Spring-loaded objects to the Servlet. There are many ways to do this, and frameworks like CXF have built-in support for Spring.
But one of the most basic mechanisms is to use a ContextLoaderListener to load the application context and a HttpRequestHandlerServlet to initialize the servlet.
Here's a simple example:
web.xml:
<web-app>
...
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>servletBean</servlet-name>
<servlet-class>org.springframework.web.context.support.HttpRequestHandlerServlet</servlet-class>
</servlet>
...
</web-app>
And in /WEB-INF/applicationContext.xml:
<beans>
..
<!-- Note: YourServletClass must implement HttpRequestHandler -->
<bean id="servletBean" name="servletBean" class="yournamespace.YourServletClass">
...
</bean>
...
</beans>
Spring apps declare a DispatcherServlet as part of the application configuration. The DipatcherServlet is a child class of HttpServlet and hence represents the servlet for the container. The DispatcherServlet also creates a WebApplicationContext. Spring maintains an IOC container for each WebApplicationContext (there can be multiple servlets in an app). There can also be a root ApplicationContext, which is created by the ContextLoaderListener. The root ApplicationContext is a parent of all WebApplicationContext(s) in a web app. The IOC container of ApplicationContext is available to all WebApplicationContext(s).
The ServletContext remains the single mode of interaction for all web containers.

About /WEB-INF/applicationContext.xml

This is driving me nuts. And this has been probably asked before but....
I've started recently with Tapestry for a Hibernate-Spring-Tapestry project. I used a maven archetype for Hibernate/Tapestry and then added Spring integration but this is giving more problems than I thought.
Currently I'm stuck with this, after adding the right tapestry-spring integration dependency and after changing the filter in /WEB-INF/web.xml I can't get jetty to run. This is because it can't find /WEB-INF/applicationContext.xml, mostly because I don't have that file in my project.
I just want to know what it should contain so I can move on to my next noob error.
EDIT: I've replaced the default Tapestry5 filter with
<filter>
<filter-name>app</filter-name>
<filter-class>org.apache.tapestry5.spring.TapestrySpringFilter</filter-class>
</filter>
Full web.xml -> http://pastebin.com/KgPTDrmC
TapestrySpringFilter works by retrieving the WebApplicationContext created and initialized by Spring's ContextLoaderListener (which you should also have). The applicationContext.xml file is a Spring XML bean declaration file which the ContextLoaderListener can use to create that WebApplicationContext.
The beans that go in it depend on your application.

i am not able to monitor the spring application through javamelody

I am not able to monitor spring application through java-melody.
Can some one help me on java-melody with spring configuration?
when I pass the URL of spring application in java-melody then I should be able to see the monitoring window.
If your application is maven managed then just add javamelody dependency to you pom
<dependency>
<groupId>net.bull.javamelody</groupId>
<artifactId>javamelody-core</artifactId>
<version>1.55.0</version>
</dependency>
If its not maven managed, then you can simply download and copy javamelody.jar and jrobin-x.jar to your WEB-INF/lib directory.
Once you have this, make sure you've defined java meleody filters in your web.xml
<filter>
<filter-name>monitoring</filter-name>
<filter-class>net.bull.javamelody.MonitoringFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>monitoring</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>net.bull.javamelody.SessionListener</listener-class>
</listener>
Above should give you basic monitoring at http://<host>:<port>/<context_root>/monitoring
For batch and business facaded you can follow the links as posted by #Pantelis. If you want to monitor SQLs executed, you can follow this link on the User guide - https://code.google.com/p/javamelody/wiki/UserGuide#7._JDBC
Hope this helps
JavaMelody user guide: https://code.google.com/p/javamelody/wiki/UserGuide
Basic configuration steps that you need:
Add javamelody.jar and jrobin-x.jar in your classpath
Add in your web.xml the monitoring filter and session listener as defined there: https://code.google.com/p/javamelody/wiki/UserGuide#2._web.xml_file
You can define the business facades (eg service layer) in the Spring application context: https://code.google.com/p/javamelody/wiki/UserGuide#9._Business_facades_(if_Spring)
You can also configure any batch jobs in the Spring application context: https://code.google.com/p/javamelody/wiki/UserGuide#13._Batch_jobs_(if_Quartz)
With steps 1 and 2 you will have a very basic performance report. I suggest that you read the user guide first.

WEB-INF/myproject-servlet.xml versus WEB-INF/web.xml

I spent few days fixing bugs in my Spring project. For really long time, my main problems in error log were:
Bean already exists
I have got two files:
WEB-INF/myproject-servlet.xml
WEB-INF/web.xml
in first one, I can put following input (let's assume I have got an application to manage animals in zoo):
<context:component-scan base-package="com.my.package.animals" />
with that (as well as I understand) we are enabling Spring beans auto-discovery. So now, when we run our application, Spring will take all classes from this package, later it will go through all config files in resources directory and will inititliaze all beans (placed in config files, which are associated with a given package).
The second one, web.xml includes lines like this
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/myproject-servlet.xml</param-value>
</context-param>
I can also put path to my config files, for instance:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:animals-config.xml</param-value>
</context-param>
So now, I have 'auto-detecting' in myproject-servlet.xml and I have got context-param in web.xml for the same objects.
My question is, is it possible, that errors "Bean already exists" are coming from this? I am almost sure that yes, I checked all beans ids and there is no duplicates.
So I have another question. What is a good approach of doing that? When I create new config file, where I should inform my application about that? In myproject-servlet.xml or web.xml. I really need to clean up my application and I will start with that.
I checked some examples and people rather do not put more than one <context-param> in web.xml file Simple example
Thank you in advance
Ok, I am really close to solve my problem.
Let's assume I have got two packages:
com.my.pckg.a
com.my.pckg.b
with classes
com.my.pckg.a.ClassA
com.my.pckg.b.ClassB
I added in myproject-servlet.xml following line:
<context:component-scan base-package="com.my.pckg.a" />
I have got a config file myconfig.xml and inside I have got beans based on classes ClassA and ClassB.
Let's say we have got beans with ids as follows:
ClassA: ida1, ida2
ClassB: idb1, idb2
So, I am running my jetty server and the question is:
Which beans will be initialized? I declared only package com.my.pckg.a, so from myconfig.xml, spring should load only ida1 and ida2 but this file includes also beans for another class.
So finally... ?
Finally, I suppose I find a problem. In web.xml file I have got a line:
<context:component-scan base-package="com.dirty.pckg" />
in this package I have got a class DirtyClass with #Controller annotation. One of the fields of this class is:
private static ApplicationContext context = new ClassPathXmlApplicationContext("dirty-config.xml");
So, when my application is getting up, Spring takes DirtyClass (because it has #) and maps it. Because os static modifier of context it triggers reading dirty-config.xml. That's way I could not understand why my code behaves in strange way.
The web.xml file is the configuration of your web application. It is not related to Spring.
The contextConfigLocation context-param is the one spring listener use to search for Spring configuration files. It is spring related.
You can have multiple spring configuration files that you register in your web.xml but these files must not define the same bean (bean id must be different). You can also have only one spring configuration file that will it self include other configuration files as described here : http://www.mkyong.com/spring/load-multiple-spring-bean-configuration-file/
Answer to the other question :
When you added the component scan, you ask spring to scan the package com.my.pckg.a for annotation like #Service, #Component, ... The component scan is not a filter for the rest of the configuration it is a configuration itself. So the fact that you added component scan, will not change the behaviour of myconfig.xml. Both ida1, ida2 and idb1, idb2 will be instanciated.
I don't really get what you are trying to accomplished with your configuration files. Maybe if you explain your needs, we could help you set up the right config for you.
web.xml is configuration file. It has classes(like listeners, filters,filter-mapping, servlet,servlet-mapping), resources and configuration(like context param, diplayname, error-page, session-config) of the application and how the web server uses them to handle web requests. When the web server receives a request for the application, it uses web.xml to map the URL of the request to the code that is supposed to handle the request.
Coming to what should be in web.xml and what should be in myproject-servlet.xml:
1)In Spring, ApplicationContext can be hierarchical. One ApplicationContext can have multiple child ApplicationContexts and can only have one parent. Beans in child ApplicationContext can access the beans in parent.
2)DispatcherServlet dispatches requests to handlers(controllers), with configurable handler mappings, view resolution configuration(what view template you use for the application for example jsp).
Keeping the two points in mind, our web.xml should be like:
<!--Root web application context(Parent context) - beans for service or persistence layer should be in this -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:service-layer-beans.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<!--DispatcherServlet loads its configuration into its own context(chile context) and refers Root web application context as a parent, so it have access to beans in parent context and can override it but not vice versa.-->
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/myproject-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>

Categories