Use of start method in ClassPathXmlApplicationContext - java

I have following code in one my team projects:
this.context = new ClassPathXmlApplicationContext("test_spring.xml");
this.task = ((Task)this.context.getBean("task"));
this.context.registerShutdownHook();
this.context.start();
I have never before seen "start" method being called and i dont understand whats the need of start method?
Spring Documentation says:
Start this component. Should not throw an exception if the component is already running.
In the case of a container, this will propagate the start signal to all components that apply.
But i dont understand what does it imply. Can someone explain what can go wrong if start method is not called or how does it helps?

Spring provides a ApplicationListener interface to listen for various ApplicationEvents. One such event is the ContextStartedEvent. You can create a bean of some class that implements ApplicationListener<ContextStartedEvent>.
When you invoke start(), the ApplicationContext will publish such an event and all ApplicationListener beans registered for ContextStartedEvent (they get registered automatically if found in the context) will get notified.
If you don't call start(), they will not get notified.

Related

Cancel timer in lifecycle callback of singleton bean

I have an Java EE project running Wildfly 10.1 Final.
I am creating some timers programmatically using javax.ejb.TimerService like this:
timerService.createTimer(new Date(), null);
And now, I am trying to cancel those timers the next time the project is deployed, because they are still there every time I re-deploy the project, or restart the server.
I tried to use a Singleton Startup bean for that, like this:
#Startup
#Singleton
public class TimerKiller {
#PostConstruct
public void killTimers() {
timerService.getAllTimers().forEach(timer -> timer.cancel());
}
#Resource
TimerService timerService;
}
But, I get an exception:
java.lang.IllegalStateException: WFLYEJB0325: Cannot invoke timer
service methods in lifecycle callback of non-singleton beans
This is the last exception in the stack trace (the last Caused By).
I can't seem to understand what does this mean. I tried googling but nothing comes up.
Did you use javax.ejb.Singleton or javax.inject.Singleton. Make sure you are using javax.ejb.Singleton.
You can also use a e.g. SingleActionTimer and specify it as non-persistent:
TimerConfig tc = new TimerConfig(null, false);
timerService.createSingleActionTimer(new Date(), tc);

Why has an #ApplicationScoped bean a new instance in the BeforeShutdown phase of my CDI extension ?

I would like to make some clean up on a bean when I shutdown a CDI application. For example, I would like to close an IO connection. Of course, here, the bean is marked as #ApplicationScoped.
To manage this I wrote an extension and observe the BeforeShutdown event, and then I select my bean to call a clean up method :
public void beforeShutdown(#Observes BeforeShutdown beforeShutdown) {
SomeBean obj = CDI.current().select(SomeBean.class).get();
obj.cleanup();
}
My problem is that I have access to a new instance in this method. Not the instance I got in the whole application.
If you want to see this instance problem, I've made a repo on github to show it : https://github.com/hasalex/cdi-extension-demo.
So I have 2 questions :
Why do I get a new instance ?
Is there an other way to cleanup my bean at the end of the application ? (in SE and in WildFly environments)
look here: http://docs.jboss.org/cdi/spec/1.1.EDR1/html/spi.html#provider
11.5.4. BeforeShutdown event
The container must fire a final event after it has finished processing requests and destroyed all contexts.
Maybe you want to use #PreDestroy: http://docs.oracle.com/javaee/6/tutorial/doc/gmgkd.html
Annotate the declaration of the method with the javax.annotation.PreDestroy annotation.
CDI calls this method before starting to destroy the bean.

How to properly shutdown executor services with Spring?

I have a command line application that uses a Spring-managed bean that's composed of a java ExecutorService created with:
ExecutorService service = Executors.newFixedThreadPool(4);
Now, I want my service to shutdown when my application shuts down, so I made my bean implement the DisposableBean interface and have a destroy method such as:
public void destroy(){
service.shutdown();
}
Then I might be tempted to do something like register a shutdown hook on the Spring context. However I found out (the hard way, i.e., in a pre-production release) that this doesn't work: the shutdown hook doesn't get called before the ExecutorService.shutdown() method is called, causing a classic catch 22 problem (it does get called on interruption, i.e., if I hit Ctrl-C while the application is running). This escaped my unit tests because for some reason it seems to work fine from within JUnit, which is still puzzling me: what does JUnit do differently?
The solution I found so far is to explicitly call ApplicationContext.close() right before I exit my main function. I was wondering if there was a better solution to this and what are the best practices for having flexible thread pools managed by Spring. Also what if my bean is not directly managed by Spring but is created by a bean managed by Spring? Should I just cascade the calls to destroy()? Wouldn't this be very error prone?
I appreciate any comments, suggestions, further reading, RTFMs, magic recipes.
Thanks!
Are you aware that this:
ExecutorService service = Executors.newFixedThreadPool(4);
can be replaced with this:
<bean id="service" class="java.util.concurrent.Executors"
factory-method="newFixedThreadPool" destroy-method="shutdown">
<constructor-arg value="4"/>
</bean>
The spring context then manages, more directly, the shutdown of your executor service--and it can be more easily reused.
Per official Spring documentation, when using annotation-based configuration, for destroyMethod field of #Bean, Spring's default behavior is to automatically invoke public, no-arg methods named close or shutdown when the application context is being closed.
As a convenience to the user, the container will attempt to infer a
destroy method against an object returned from the #Bean method. For
example, given an #Bean method returning an Apache Commons DBCP
BasicDataSource, the container will notice the close() method
available on that object and automatically register it as the
destroyMethod. This 'destroy method inference' is currently limited to
detecting only public, no-arg methods named 'close' or 'shutdown'. The
method may be declared at any level of the inheritance hierarchy and
will be detected regardless of the return type of the #Bean method
(i.e., detection occurs reflectively against the bean instance itself
at creation time).
To re-iterate, this is the default behavior for annotation-driven configuration when a destroy method is not explicitly set. If this behavior is undesired explicitly setting destroy method to an empty string will disable this "feature":
To disable destroy method inference for a particular #Bean, specify an
empty string as the value, e.g. #Bean(destroyMethod=""). Note that the
DisposableBean and the Closeable/AutoCloseable interfaces will
nevertheless get detected and the corresponding destroy/close method
invoked.
On the other hand, when using XML configuration, this is not the default behavior... To achieve parity, destroy-method can be explicitly set to (inferred). Refer to the Destruction callbacks and Default initialization and destroy methods sections in the official docs for details.
Consider using Spring's TaskExecutor, which can be configured with a thread pool.
http://static.springsource.org/spring/docs/3.0.x/reference/scheduling.html
Just want to add the config based ExecutorService bean creation to #Keith's answer
#Bean("fixedThreadPool")
public ExecutorService fixedThreadPool() {
return Executors.newFixedThreadPool(THREAD_POOL_SIZE);
}

How to wait to another bundle?

I am developing an OSGi application which is composed by several bundles. All of them depend on the EventAdmin one. However, one specific plug-in has to start up a scheduled task as soon as the bundled is started (i.e. in the start method of the activator). The problem is that the event admin service is not still registered and I should wait for the deployment of this. I would not like to do this through the config properties file, therefore, is there any operation to do this without the properties file of Felix?
Thanks a lot in advance
There is no start ordering in OSGi ... get over it ... Though there are mechanisms to influence the initial start ordering, the problem is that any bundle can stop at any time. So the ONLY solution is to actually handle your dependency on Event Admin.
With Declarative Services (DS), this is actually very little work. Also, please forget bundle activators, they are bundle singletons and are thus a bad idea. So in DS you would do the following (using the annotations):
#Component(immediate=true)
public class MyTask extends Thread {
EventAdmin ea;
public void run() {
while ( !isInterrupted()) {
// do something
ea.postEvent(...);
}
}
#Activate void activate() { this.start();}
#Deactivate void deactivate() { this.interrupt(); }
#Reference void setEventAdmin(EventAdmin ea) { this.ea = ea;}
}
There are rare cases you should not use DS and are stuck with Bundle-Activators, but they are rare and should become rarer. If you're stuck with such a really bad case, then you can also create a service tracker in the Bundle Activator start method and track Event Admin services. Once you get one, you create a thread to run your code. When the service disappears you interrupt the thread. However, this is a much more complex solution.
There are also other service dependency manager but I strongly recommend Declarative Services with their annotations.
I have used iPOJO for this. It is designed to be used in felix & karaf. This library understands the lifecycle and dependencies of components and you will be notified via #Validate and #Invalidate methods when a components dependencies are available or one or more goes away.
It also support #Bind and #Unbind when an implementation of a service (an interface) appears or disappears. This make subscriptions much simpler.
You have a listener to a service and this component #Provides an interface to be called. The central event register will then be called on its #Bind method when such a component appears and #Unbind when it goes away for any reason.
I suspect iPOJO should do all the dependency management and binding you need.

Best way to force Spring shutdown from a bean?

My application uses a Spring DefaultMessageListenerContainer to process incoming messages. The main method of the app already registers a shutdown hook.
Question is this: what is the best way to force the application context to shut down?
If I throw a RuntimeException in the message listener, it is handled by the container, and not passed on. Is calling System.exit acceptable? Do I pass along the ApplicationContext to every class that needs to shut down, so I can call close() on it?
You can cast your application context to ConfigurableApplicationContext and call close() on it. At least that's what happens when the context is shut down in a web-application environment, in cases the servlet context is destroyed.
If you want to get ahold of the ApplicationContext, your bean may implement ApplicationContextAware
Another option is to inject (or autowire with #Autowired) the application context:
#Inject
private ApplicationContext ctx;

Categories