Is there anyway to capture weblogic termination event and trigger a Java function?
My weblogic version is V10.0
Thank you,
You could imlement a javax.servlet.ServletContextListener
public class MyServletContextListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent e) {
}
public void contextDestroyed(ServletContextEvent e) {
}
}
and add it to the web.xml.
<listener>
<listener-class>MyServletContextListener</listener-class>
</listener>
There you can handle the shutdwn of the weblogic container.
Related
I build a web application with JSPs and in my servlet I have:
public class MyServlet extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
init();
HttpSession session = request.getSession(true);
//more code...
}
}
Till now my serlvet is called, when the JSP page calls it like <a href="MyServlet..">. What I want is whenever the application starts, the servlet to be executed as well. I could have a button in my 1st page like "START" and there to call the servlet.. But, can I avoid this?
Whatever you want done on startup should be done by a class implementing ServletContextListener, so you should write such a class, for example:
public class MyContextListener
implements ServletContextListener{
#Override
public void contextDestroyed(ServletContextEvent arg0) {
//do stuff
}
#Override
public void contextInitialized(ServletContextEvent arg0) {
//do stuff before web application is started
}
}
Then you should declare it in web.xml:
<listener>
<listener-class>
com.whatever.MyContextListener
</listener-class>
</listener>
You can configure it in Tomcat's web.xml (or corresponding configuration files in similar servers), like below using the tag <load-on-startup> :
<servlet>
<servlet-name>MyOwnServlet</servlet-name>
<servlet-class>MyServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
In my point of view, a good way is to implement a Servlet Context Listener. It listens to application startup and shutdown.
public class YourListener implements javax.servlet.ServletContextListener {
public void contextInitialized(ServletContextEvent sce) {
}
public void contextDestroyed(ServletContextEvent sce) {
}
}
And then, you configure the listener in your web.xml () or with the #WebServletContextListener annotation.
How to write and implement simple cronjob class in GWT?
It doesn't have any error but I need to know how to run the server class at time of apache starts.
Simply use ServletContextListener that will be called on the context initialization single time at time of server starts.
Put your logic inside contextInitialized() method.
web.xml
<listener>
<listener-class>com.x.y.z.AppServletContextListener</listener-class>
</listener>
Listener
public class AppServletContextListener implements ServletContextListener {
#Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
...
}
#Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
...
}
}
i hava aclass InitApp
#Component
public class InitApp implements ServletContextListener {
#Autowired
ConfigrationService weatherConfService;
/** Creates a new instance of InitApp */
public InitApp() {
}
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println(weatherConfService);
}
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}
and listener in web.xml:
<listener>
<listener-class>com.web.Utils.InitApp</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
the confService print --> null
what the problem?
A couple of ideas came to me as I was having the same issue.
First one is to use Spring utils to retrieve the bean from the Spring context within the listener:
Ex:
#WebListener
public class CacheInitializationListener implements ServletContextListener {
/**
* Initialize the Cache Manager once the application has started
*/
#Override
public void contextInitialized(ServletContextEvent sce) {
CacheManager cacheManager = WebApplicationContextUtils.getRequiredWebApplicationContext(
sce.getServletContext()).getBean(CacheManager.class);
try {
cacheManager.init();
} catch (Exception e) {
// rethrow as a runtime exception
throw new IllegalStateException(e);
}
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
// TODO Auto-generated method stub
}
}
This works fine if you only have one or two beans. Otherwise it can get tedious. The other option is to explicitly call upon Spring's Autowire utilities:
#WebListener
public class CacheInitializationListener implements ServletContextListener {
#Autowired
private CacheManager cacheManager;
/**
* Initialize the Cache once the application has started
*/
#Override
public void contextInitialized(ServletContextEvent sce) {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
try {
cacheManager.init();
} catch (Exception e) {
// rethrow as a runtime exception
throw new IllegalStateException(e);
}
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
// TODO Auto-generated method stub
}
}
The caveat in both these solutions, is that the Spring context must by loaded first before either of these can work. Given that there is no way to define the Listener order using #WebListener, ensure that the Spring ContextLoaderListener is defined in web.xml to force it to be loaded first (listeners defined in the web descriptor are loaded prior to those defined by annotation).
By declaring
<listener>
<listener-class>com.web.Utils.InitApp</listener-class>
</listener>
in your web.xml, you're telling your container to initialize and register an instance of InitApp. As such, that object is not managed by Spring and you cannot #Autowired anything into it.
If your application context is set up to component-scan the com.web.Utils package, then you will have a InitApp bean that isn't registered as a Listener with the container. So even though your other bean will be #Autowired, the servlet container won't ever hit it.
That is the trade-off.
There are workarounds to this if you use programmatic configuration with a ServletContainerInitializer or a WebApplicationInitializer for servlet 3.0. You wouldn't use #Autowired, you would just have setter/getter that you would use to set the instance.
Here's an example
class SpringExample implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
WebApplicationContext context = ...;
SomeBean someBean = context.getBean(SomeBean.class);
CustomListener listener = new CustomListener();
listener.setSomeBean(someBean);
// register the listener instance
servletContext.addListener(listener);
// then register DispatcherServlet and ContextLoaderListener, as appropriate
...
}
}
class CustomListener implements ServletContextListener {
private SomeBean someBean;
public SomeBean getSomeBean() {
return someBean;
}
public void setSomeBean(SomeBean someBean) {
this.someBean = someBean;
}
#Override
public void contextInitialized(ServletContextEvent sce) {
// do something with someBean
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
Note that Spring has some custom implementation of WebApplicationInitializer that are quite sophisticated. You really shouldn't need to implement it directly yourself. The idea remains the same, just deeper in the inheritance hierarchy.
#WebListener
public class StartupListener implements ServletContextListener {
#Autowired
private MyRepository repository;
#Override
public void contextDestroyed(ServletContextEvent event) {
}
#Override
public void contextInitialized(ServletContextEvent event) {
AutowireCapableBeanFactory autowireCapableBeanFactory = WebApplicationContextUtils.getRequiredWebApplicationContext(event.getServletContext()).getAutowireCapableBeanFactory();
autowireCapableBeanFactory.autowireBean(this);
repository.doSomething();
}
}
As others have said this listener observes by the web servlet(tomcat) context (Not the Spring Container) and is notified of servlet startup/shutdown.
Since it is created by the servlet outside of the Spring container it is not managed by Spring hence #Autowire members is not possible.
If you setup your bean as a managed #Component then Spring will create the instance and the listener wont register with the external servlet.
You cannot have it both ways..
One solution is the remove the Spring annotations and manually retrieve your member from the Spring Application context and set your members that way.
ie
public class InitApp implements ServletContextListener {
private ConfigrationService weatherConfService;
private static ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:web-context.xml");
#Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
weatherConfService = applicationContext.getBean(ConfigrationService.class);
System.out.println(weatherConfService);
}
#Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}
With current versions of Spring Boot 2, you can also register Servlets, filters, and listeners as Spring beans and use autowired components normally:
Registering Servlets, Filters, and Listeners as Spring Beans
Any Servlet, Filter, or servlet *Listener instance that is a Spring bean is registered with the embedded container. This can be particularly convenient if you want to refer to a value from your application.properties during configuration.
More info here Register #WebListeners in a way that allows them to register servlets and filters.
This means that you simply have to annotate your ServletContextListener as #Comonent.
Since Spring Boot 2.4 using #WebListener does not work anymore, mentioned in the release notes.
A side-effect of this change is that the Servlet container now creates the instance of the WebListener and, therefore, dependency injection such as with #Autowired can no longer be used. In such cases, #Component should be used instead.
I have a web application in Java (Netbeans). And I have a function that should be called exactly while running the web application, without putting it into the static method main.
I really don't have any idea about how to do.
Thank you in advance.
Create a class that implements ServletConextListener :
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class ListenToMeFirst implements ServletContextListener {
#Override
public void contextDestroyed(ServletContextEvent arg0) {
}
#Override
public void contextInitialized(ServletContextEvent arg0) {
// Run me First while deploying!!!
}
}
Don't forget to put it in your web.xml file :
<listener>
<listener-class>path.to.yourListenerClass.ListenToMeFirst</listener-class>
</listener>
I have a Wicket Web Application running in Tomcat. The application uses Spring (via org.springframework.web.context.ContextLoaderListener) to initialise the application. This is all well and good for start up, but what I would also like is to receive some sort of notification that the Context is being destroyed so that I can shutdown spawned threads. Is there a way of receiving such a notification? I've included excerpts from my application to aid your understanding of my question.
web.xml extract
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:com/mysite/web/spring/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
Spring applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="MyWebService" class="com.mysite.web.MyWebApp">
</bean>
</beans>
MyWebApp.java extract
public class MyWebApp extends org.apache.wicket.protocol.http.WebApplication {
private MyWebServiceServiceAPI webservice =
MyWebServiceAppImpl.getMyWebService();
public MyWebServiceWebApp() {
}
#Override
public void init() {
super.init();
webservice.start();
}
}
MyWebServiceAppImpl.java extract
public class MyWebServiceAppImpl extends ServiceImpl
implements MyWebServiceServiceAPI {
// The ServiceImpl implements the Callable<T> interface
private static MyWebServiceServiceAPI instance;
private List<Future<ServiceImpl>> results =
new ArrayList<Future<ServiceImpl>>();
private ExecutorService pool = Executors.newCachedThreadPool();
private MyWebServiceAppImpl() {
super(.....);
}
public synchronized static MyWebServiceServiceAPI getMyWebService() {
if (instance == null) {
instance = new MyWebServiceAppImpl();
instance.start();
}
return instance;
}
#Override
public synchronized void start() {
if (!started()) {
pool.submit(this);
super.start();
}
}
Yes, you can implement your own ContextListener.
package myapp;
public class MyContextListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent arg0) {
//called when context is started
}
public void contextDestroyed(ServletContextEvent arg0) {
//called context destroyed
}
}
You need to add that listener to your web.xml
<listener>
<listener-class>myapp.MyContextListener</listener-class>
</listener>