EJBs seem to be loaded lazily - whenever accessed.
However, I want to initialize them eagerly - i.e. whenever the container starts-up. How is this achieved (in JBoss in particular)
This topic gives some hints, but isn't quite satisfactory.
As of EJB 3.1, singleton beans can be notified of module start and stop:
#Singleton
#Startup
public class StartupBean {
#PostConstruct
private void postConstruct() { /* ... */ }
#PreDestroy
private void preDestroy() { /* ... */ }
}
Prior to EJB 3.1, there is no standard, EJB-only solution. I'd suggest adding a WAR to your EAR and using a servlet-context-listener.
According to Adam Bien's Real World Java EE Patterns - Rethinking Best Practices (see a summary of the patterns) and the Service Starter pattern, it is indeed as bkail suggests
with Java EE 6 = EJB 3.1 use #Singleton with #Startup (and perhaps also with #DependsOn)
prior to that the only standard and portable way is to use the Servlet API, e.g. a HttpServlet starting the EJBs in its init() method and load-on-startup set to 1 in web.xml.
Related
Well, i'm trying to use RequestedScoped beans inside a Quartz Job, see:
public class JobRoboFtp implements Job {
#Inject
private AcervoVideoService acervoVideoService;
#Inject
private ConfiguracaoService configuracaoService;
#Inject
private FtpManager ftpManager;
But i got always:
No active contexts for scope type javax.enterprise.context.RequestScoped
Well, If i change this Services to #Dependent scope everything works but i would like to use RequestedScope. There is any way ?
Since you didn't say much about versions, I am going to assume some of the latest versions of Weld 2.x (or even 3.x) - then there is a way. I also assume you are talking about SE environment, as otherwise request scope would auto-activate during requests.
If we are talking CDI 1.2 (Weld 2.x) then you need to add explicit dependency on Weld API and make use of it. The dependency is org.jboss.weld:weld-api and the functionality you are looking for is #ActivateRequestContext interceptor binding. If you are looking for a link to Weld docs, its here - note that this was added in Weld 2.4!
The principle is simple - it intercepts method calls and activated context when entering the method, then destroys it when you exit the method.
#ActivateRequestContext
public void myMethod() {
// any content in here will have request context ACTIVE
doAwesomeThings();
}
If we are talking about CDI 2.0/Weld 3.x - then the very same approach was adapted by CDI (Weld version works there as well). You can read about it here.
Is there a simple way to execute code just after CDI has bootstrapped ?
Actually I've got an #ApplicationScopped bean which I want to be instanciated just after CDI has bootstrapped, is there a simple way to do that ?
There's quite a few solutions but to me there's only two that does not feel hacky. I am not sure if Java EE 7 solved this somehow though, could not find anything when I googled.
Use #Startup from EJB. This is best if you can use EJB
Use the Servlet Module from deltaspike with #Observes #Initialized ServletContext context
http://deltaspike.apache.org/servlet.html
From this blog post:
Only recently, with the CDI 1.1 version; may 2013 (Java EE 7); you have the possibility to receive a CDI event when the container is ready.
public class CDIStartup {
public void postConstruct(#Observes #Initialized(ApplicationScoped.class) Object o) {
// CDI Ready
}
}
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")
I've got a NullPointerException using EJB3 in a J2SE environment (without EJB3 container)
Briefly, I've got a stateless bean implementing an interface.
When I call it in another class like in a main, a NullPointerException is triggered.
Sample:
#stateless
#Local(IMyInterface.class)
public class myBean implements IMyInterface{...}
public class Main{
#EJB
IMyInterface myInterface;
public static void main(String[] args){
Result result = myInterface.myBeanMethod(); // Exception happens here
}
}
I guess I miss some initialization stuff because the EJB is null when I first try to use it...
Thanks for your help,
EJBs can't work without a container. The dependencies (#EJB) are injected if the beans are instantiated by the container. If you are the one instantiating them, it is your responsibility to set the dependencies.
Furthermore, you are trying to use a non-static variable from a a static method - this won't even compile.
While you can use JPA (which is part of EJB 3) "Entity Beans" (actually, POJOs) in a J2SE environment, you can't use Session Beans without a container and you can't benefit from injection of resources using the #Resource or the more specialized #EJB and #WebServiceRef annotations in a non-managed environment, i.e. a container. In other words, only managed components support injection (Servlets, JSF Managed beans, EJB components, etc).
So, in your case, you'll need to:
Deploy your Session Bean in a Java EE container (like JBoss, GlassFish, WebLogic, etc)
Lookup the remote EJB using explicitly its global JNDI name. The code will look like that:
Foo foo = (Foo) new InitialContext().lookup("FooEJB");
A few additional remarks:
With EJB 3.0, the global JNDI name is container dependent so I can't tell you what it will be exactly (EJB 3.1 finally introduced "portable global JNDI names").
You'll need to set up the JNDI environment (which is container dependent) for the lookup either by providing a jndi.properties on the class path or by using the InitialContext(Hashtable) constructor.
You'll need to provide the application server "client library" on the class path of the client (which is obviously specific to each product).
Search for previous questions or open a new one if you need more specific guidance.
I have a stateless EJB (3) that uses internal cache which is refreshed automatically every 24 hours. I would like to expose a MBean method to be able to force cache expiration or even cache reload on this EJB via JMX console on Jboss 4.2.
Can someone share an example on how to code this scenario? I'm totally new to JMX when it comes to creating my own beans.
Should I create an MBean that calls my EJB or is it possible to expose a specific EJB method as an Mbean interface by using annotation on EJB itself?
EJB looks like this:
#Stateless
#Local(BusinessCalendar.class)
public class BusinessCalendarBean implements BusinessCalendar {
synchronized private LocalDateKitCalculatorsFactory getCalculatorFactory() {
LocalDateKitCalculatorsFactory ldkc = (LocalDateKitCalculatorsFactory) CacheService.get(CACHE_KEY);
if (ldkc == null) {
ldkc = getCalculatorFactory();
CacheService.put(CACHE_KEY, ldkc);
}
return ldkc;
}
public function expireCache() {
// I would like to expose this as JMX managed method
}
...
}
Update:
This is surely valid for WildFly 10+, jBOSS EAP 6.x or 7.x. But I suspect the mechanisms are no longer proprietary and shall work very similarly in other app servers.
JBoss specific annotations #Service / #Management were removed when JavaEE 6 standardized Singletons. A MBean (always a singleton so that all JMX clients see the same consistent JMX data application-wide) becomes an EE6+ Singleton exposed via JMX as follows:
define an interface with a name ending in "...MXBean" (compulsory)
create a #Singleton and #Startup class that implements this interface
define #PostConstruct and #PreDestroy methods to register/unregister the MBean
the register/unregister code is like:
objectName = new javax.management.ObjectName("com.acme.example.jmx:type=" + this.getClass().getName());
platformMBeanServer = java.lang.management.ManagementFactory.getPlatformMBeanServer();
platformMBeanServer.registerMBean(this, objectName);
The getters/setters defined in your "...MXBean" interface become JMX attributes, other methods are mapped to operations as specified in JMX Specifications under "lexical design patterns"
Have you looked at the online JBoss configuration guide yet? This may be of some help:
http://www.redhat.com/docs/en-US/JBoss_Enterprise_Application_Platform/4.2.0.cp08/html/Server_Configuration_Guide/EJB3_Services-Message_Driven_Beans.html