How do I automatically trigger Java function to stop Quartz scheduler jobs when I deploy/undeploy/redeploy JEE5 application in Glassfish.
Implement ServletContextListener and hook on contextDestroyed().
Basic example:
public class Config implements ServletContextListener {
public void contextInitialized(ServletContextEvent event) {
// Write code here which should be executed on webapp startup.
}
public void contextDestroyed(ServletContextEvent event) {
// Write code here which should be executed on webapp shutdown.
}
}
and register it as a <listener> in web.xml.
<listener>
<listener-class>com.example.Config</listener-class>
</listener>
Once you get to JAVA EE-6+, annotate a class with #WebListener and implement ServletContextListener on that class to get a shutdown notification. No need to deal with web.xml. See here
Related
Within my Servlet-based application, I would like to log events for startup and shutdown.
I've tried to implement the ServletContextListener interface to do this:
public class DiagnosticListener
implements ServletContextListener {
private static final Logger LOG = LogManager.getLogger(DiagnosticListener.class);
#Override
public void contextInitialized( final ServletContextEvent sce ) {
LOG.info("Context initialized.");
}
#Override
public void contextDestroyed( final ServletContextEvent sce ) {
LOG.info("Context destroyed.");
}
}
The initialized event is logged as expected, but the destroyed event never appears. I am assuming this is to do with how log4j2 manages its lifecycle using a similar listener, that logging infrastructure is no longer available during this event.
Is there a way to log an event for the application being shut down?
We clashed against a similar issue with Logback.
You have to write your own web.xml to fix that, because there's no alternatives to define listeners order.
We disabled the LogbackServletContextListener with:
<context-param>
<param-name>logbackDisableServletContainerInitializer</param-name>
<param-value>true</param-value>
</context-param>
then add the LogbackServletContextListener by hand as the first listener:
<listener>
<listener-class>ch.qos.logback.classic.servlet.LogbackServletContextListener</listener-class>
</listener>
and then all the other listeners.
No idea about log4j, but I think there's something similar...
edit: yes, there is:
<context-param>
<param-name>isLog4jAutoInitializationDisabled</param-name>
<param-value>true</param-value>
</context-param>
source: https://logging.apache.org/log4j/2.x/manual/webapp.html
If you configured Log4j's ServletContextListener before yours in web.xml then Log4j should be initialized before your ServletContextListener and be shutdown after yours is.
I would like to use a MySQL Connection Pool with a Jersey REST service.
For performance reasons I don't want to create single MySQL connections each time a Jersey resource method is called. Instead I would like to create a ConnectionPool at startup-time of the server and then borrow and return connections when the service resource methods are executed.
Where would be the best place to put the initialization of the ConnectionPool within the Jersey REST framework?
Create a class and implement the ServletContextListener interface.
package com.example.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class MyAppServletContextListener
implements ServletContextListener{
#Override
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("ServletContextListener destroyed");
}
//Run this before web application is started
#Override
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("ServletContextListener started");
}
}
Put it in the deployment descriptor.
<web-app ...>
<listener>
<listener-class>
com.example.listener.MyAppServletContextListener
</listener-class>
</listener>
</web-app>
For more details check this link
Recently, I've reapackaged my java spring application to become a WAR file for deployment in tomcat. After some testing I noticed, that public static void main(String[] args) is not executed. Some necessary initialization of my application is done in main. Is there something like a main method in a WAR file? What is the appropiate place in a WAR file to run some initialization?
You can add a listener to your web.xml file:
<listener>
<description>Application startup and shutdown events</description>
<display-name>Test</display-name>
<listener-class>com.package.package.StartClass</listener-class>
</listener>
public class StartClass implements ServletContextListener {
#Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
//Context destroyed code here
}
#Override
public void contextInitialized(ServletContextEvent servletContextEvent)
{
//Context initialized code here
}
}
Well, You will have to create a listener in your web.xml that will be invoked by container at the time of startup.
<listener>
<listener-class>com.rdv.example.WebAppContext</listener-class>
</listener>
And this class will be implementing ServletContextListener
public class WebAppContext implements ServletContextListener {
public void contextInitialized(ServletContextEvent servletContextEvent) {
// Do your processing that you are trying to do in main method.
}
I've found another way, that is independent of spring and tomcat: The #PostConstruct annotation. In code:
#PostConstruct
public void init() {
// initialization code goes here
}
This method gets executed whether I run my application standalone or in tomcat.
For more information see How to call a method after bean initialization is complete?
or Init method in Spring Controller (annotation version)
I'm using a framework to deal with some request, now, I can start it from a main function like this:
public Main{
public static void main(String[] args) {
//init the framework
Init initer = new Init();
initer.initFramework();
//start my besiness code below
}
}
now I need to package my project in a war format and put it into tomcat, how can I be able to excute the initialization code?
When you start a war-file in Tomcat using servlet 2.3 or higher you can use the web.xml file to declare listeners.
<listener>
<listener-class>test.MyListener</listener-class>
</listener>
This listener should implement the ServletContextListener interface. Listeners gets notified of lifecycle changes (such as when the servlet context has been initialized). The listener can be implemented to run your initialization code as illustrated below:
public class MyListener implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent event) {
Init initer = new Init();
initer.initFramework();
}
#Override
public void contextDestroyed(ServletContextEvent event) {
// destroy stuff
}
}
If you are running the war-file in a servlet 3 environment there might not even be a web.xml file. In that case the #WebListener annotation can be used to indicate that your component should be called. The JavaDoc for #WebListener can be found here but basically what you need to do is to add the annotation to your listener.
Just implement org.springframework.web.WebApplicationInitializer and that's it, no xml.
I need to remove temp files on Tomcat startup, the pass to a folder which contains temp files is in applicationContext.xml.
Is there a way to run a method/class only on Tomcat startup?
You could write a ServletContextListener which calls your method from the contextInitialized() method. You attach the listener to your webapp in web.xml, e.g.
<listener>
<listener-class>my.Listener</listener-class>
</listener>
and
package my;
public class Listener implements javax.servlet.ServletContextListener {
public void contextInitialized(ServletContext context) {
MyOtherClass.callMe();
}
}
Strictly speaking, this is only run once on webapp startup, rather than Tomcat startup, but that may amount to the same thing.
You can also use (starting Servlet v3) an annotated aproach (no need to add anything to web.xml):
#WebListener
public class InitializeListner implements ServletContextListener {
#Override
public final void contextInitialized(final ServletContextEvent sce) {
}
#Override
public final void contextDestroyed(final ServletContextEvent sce) {
}
}
I'm sure there must be a better way to do it as part of the container's lifecycle (edit: Hank has the answer - I was wondering why he was suggesting a SessonListener before I answered), but you could create a Servlet which has no other purpose than to perform one-time actions when the server is started:
<servlet>
<description>Does stuff on container startup</description>
<display-name>StartupServlet</display-name>
<servlet-name>StartupServlet</servlet-name>
<servlet-class>com.foo.bar.servlets.StartupServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>