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);
Related
I have a #ApplicationScoped bean in my Helidon MP microservice, is there a way to force the creation of the bean at server startup instead at first method call?
I need this bean ready and running just after server startup but every attempt I made it's inconclusive
I found a way to solve it.
If your bean observes the initialization of ApplicationScoped it will be instantiated during startup phase. It's a trick but it works fine.
public void init(#Observes #Initialized(ApplicationScoped.class) Object init) {
}
My java web application that uses spring for dependency injection is packaged in an EAR and is deployed in Jboss 7, but has no EJB. The application is installed on two load balancing machines. I need to schedule a method to run daily, but that method can't run at the same time on both instances.
I tried to use Spring's Scheduling annotations, but the problem is that, as there is load balancing, the scheduled method runs twice (once in each cluster).
What is the best way to do this in Jboss 7? Can someone help me ?
The method to be scheduled looks like the one below.
public synchronized void processor() {
LOGGER.info("start");
//processing logic
LOGGER.info("the end");
}
Thanks a lot!!!
Well, considering the requirements: two or more apps and they need to be synchronized, you need either #Singleton or #Stateless EJB, described here.
Invoking it via the timer service, then it needs to be an EJB with #Timer on some method and if you use #Scheduled or such on a method, then it will invoke that method
On this case a Singleton is recommended, otherwise, you might end up with multiple instances of the same timer running.
Example
#Example
private void init()
{
ScheduleExpression Expression = new ScheduleExpression();
#This means twice per hour {0,2,4, ... 22} ~ since it ends on 23h:
expression.second(0).minute(0).hour(*/2).month(*).dayOfWeek(*);
stopTimer();
Timer timer = service.createCalendarTimer(exp);
}
Any other suggestion seems to add too much complexity.
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.
I am following the Using the Timer Service tutorial to build a simple scheduled execution. Trying the automatic approach and using WildFly 8.1.0 Final for it.
Session Bean
#Singleton
#Startup
public class HelloJob {
private static final Logger logger = Logger.getLogger(HelloJob.class);
public HelloJob() {
logger.error(">>> Hello Job Created.");
}
#Schedule(second="*")
public void sayHello() {
logger.error(">>> Server Hello!");
}
}
On deploy the class is properly instantiated printing the >>> Hello Job Created. message, but the method sayHello() is never called.
According to the tutorial the #Schedule(second="*") means that it should execute every second.
Setting an attribute to an asterisk symbol (*) represents all
allowable values for the attribute.
Also only stateful session beans are not allowed for timers, and I am using a singleton, which is also used in the example.
The timer service of the enterprise bean container enables you to
schedule timed notifications for all types of enterprise beans except
for stateful session beans.
Use #Schedule(second="*", minute="*", hour="*").
the default values for hour and minute are "0" which can be quite irritating and effectively forces you to set these.
This question already has answers here:
Eager / auto loading of EJB / load EJB on startup (on JBoss)
(2 answers)
Closed 6 years ago.
I'm looking for an entry point in an EJB deployed on JBoss.
Servlets have the load-on-startup tag to use in its web.xml.
I'm searching for similar init() functionality for an EJB.
That didn't exist for EJB until 3.1. With EJB 3.1 you can use a singleton bean to simulate that:
From Application Startup / Shutdown Callbacks:
#Startup
#Singleton
public class FooBean {
#PostConstruct
void atStartup() { ... }
#PreDestroy
void atShutdown() { ... }
}
Otherwise, you will need to rely on the good old trick to use a ServletContextInitializer.
There are some application-specific extension, e.g. lifecycle listener for Glassfish. Maybe there's such a thing for JBoss.
But if I were you I would try to rely on standard features as much as possible. The problem with non-standard extension is that you never know exactly what can be done or not, e.g. can you start transaction or not, etc.
This article describes seven different ways of invoking functionality at server startup. Not all will work with JBoss though.
Seven ways to get things started. Java EE Startup Classes with GlassFish and WebLogic
If you're targeting JBoss AS 5.1, and you don't mind using the JBoss EJB 3.0 Extensions, you can build a service bean to bootstrap your EJB. If your service implements an interface annotated with the #Management annotation and declares a method with the signature public void start() throws Exception, JBoss will call this method when it starts the service. You can then call a dedicated init() method on the EJB you want to initialize:
#Service
public class BeanLauncher implements BeanLauncherManagement
{
#EJB private SessionBeanLocal sessionBean;
#Override
public void start() throws Exception
{
sessionBean.init();
}
}
#Management
public interface BeanLauncherManagement
{
public void start() throws Exception;
}
More information on this, including additional life-cycle events, can be found here.
Managed Beans can be used to do some process at JBoss startup, you have to add entry of that managed bean in configuration file.
You should be able to add the following line to the top of the method you want to run at startup:
#Observer("org.jboss.seam.postInitialization")