Java EE 6: controlling startup of managed beans with dependencies: CDI, EJB - ejb-3.0

I just read the very nice explanation of the various managed beans and their relations on Java EE 6 #javax.annotation.ManagedBean vs. #javax.inject.Named vs. #javax.faces.ManagedBean and as i face a annoying problem in my application i want to know if it is possible to control or influence the way how and when beans are started.
In my Java EE application I use EJB, CDI and JSF2 as view technology. Via SPI a service from a third party is booted and it configures a job executor which starts jobs and handles other timer relevant stuff. One job is immediately executed when the job executor finished its bootstrapping. This job uses CDI inject to get access to some beans and one of these beans make use of an EJB.
The problem is now that most of the time the Java EE 6 server (JBoss 7.1.1) starts the EJB is still not available then the job tries to access it. An exceptions is thrown and the job fails and the service is build to deactivate that failed job. Well, deactivating a faild job seems to be not too bad. The only solution for the job to get up and running again is to undeploy it and to redeploy it again. Which is a manual task unfortunately and it can not be done programmatically.
And, to make things bad: in rare cases this does not happen.
So, my question now is: can i somehow control the initialisation and deployment of the EJB and CDI beans so that i can ensure that all EJB beans are initialzed before the CDI beans are initialized?
I have set initialize-in-order to true in the EARs application.xml and set the sequence of the EJBs so that they get initialized they way i need them (EJB core, then EJB business, then WAR), but the CDI based service is placed as JAR in the lib folder.

Excerpt from Java EE 6 Tutorial with some modifications:
#Singleton
#Startup
public class BeanA { ... }
#Qualifier
#Target({FIELD, PARAMETER})
#Retention(RUNTIME)
public #interface EjbStarted {}
#Singleton
#Startup
#DependsOn("BeanA", "BeanB", "BeanC")
public class LastBean {
#Inject #EjbStarted Event<String> event;
#PostConstruct
public void startService() {
// At this moment PrimaryBean is ready for use
event.fire("LastBean");
}
}
public class CDIService {
public void start(#Observes #EjbStarted String name) {
if("LastBean".equals(name)) {
startService();
}
}
}
UPDATE: While thinking about the problem, I somehow forgot that you want the initialization order in CDI beans, so the answer is somewhat out of context, sorry about that :)
UPDATE 2: Added how to make a CDI service start after EJBs

Related

ApplicationContext in Spring Boot [duplicate]

This question already has answers here:
application context. What is this?
(4 answers)
What is Application context and bean factory in spring framework [duplicate]
(1 answer)
Closed 3 years ago.
I have a Spring Boot app and it's running with Spring Data, MySQL, Spring Security and MVC. The app is running for me just as fine.
However, I keep hearing about ApplicationContext a lot and I was wondering when do I need to use it and would like to know what it does. Can someone give me an example and an overview of ApplicationContext and its use?
ApplicationContext is a core interface that Spring framework built on. If you're building a Spring application, you're already using the ApplicationContext. You can have great insight about this from Spring Framework Reference Documentation. As per this document, Spring framework consists with these modules;
The Context (spring-context) module builds on the solid base provided
by the Core and Beans modules: it is a means to access objects in a
framework-style manner that is similar to a JNDI registry. The Context
module inherits its features from the Beans module and adds support
for internationalization (using, for example, resource bundles), event
propagation, resource loading, and the transparent creation of
contexts by, for example, a Servlet container. The Context module also
supports Java EE features such as EJB, JMX, and basic remoting. The
ApplicationContext interface is the focal point of the Context module.
spring-context-support provides support for integrating common
third-party libraries into a Spring application context, in particular
for caching (EhCache, JCache) and scheduling (CommonJ, Quartz).
Spring ApplicationContext also inherits BeanFactory super-interface. So technically ApplicationContext is capable of doing all the things, BeanFactory interface is capable and much more. BeanFactory interface along with ApplicationContext provide the backbone of the Spring IoC container (Core container). Which is Bean management for your application.
The interface org.springframework.context.ApplicationContext
represents the Spring IoC container and is responsible for
instantiating, configuring, and assembling the aforementioned beans.
The container gets its instructions on what objects to instantiate,
configure, and assemble by reading configuration metadata. The
configuration metadata is represented in XML, Java annotations, or
Java code. It allows you to express the objects that compose your
application and the rich interdependencies between such objects.
ApplicationContext uses eager loading mechanism. So, every bean declared in your application, initialize right away after the application started and after, this ApplicationContext scope is pretty much read-only.
Initiate a Spring IoC container with custom bean definitions is pretty much staright forward.
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"daos.xml"});
Following file shows this daos.xml file content;
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="accountDao"
class="org.springframework.samples.jpetstore.dao.jpa.JpaAccountDao">
<!-- additional collaborators and configuration for this bean go here -->
</bean>
<bean id="itemDao" class="org.springframework.samples.jpetstore.dao.jpa.JpaItemDao">
<!-- additional collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions for data access objects go here -->
</beans>
After that you can access the beans define in the .xml like this;
JpaItemDao obj = (JpaItemDao) factory.getBean("itemDao");
These instances are now being initialized and managed by the ApplicationContext. But most users prefer to use #Bean annotation define beans to do the binding and #Autowired annotation to do the dependency injection. So, no need to manually feed a bean .xml to custom initialized ApplicationContext.
#Configuration
class SampleConfig {
#Bean
public JpaItemDao getJpaItemDao() {
return new JpaItemDao();
}
}
and inject in;
#Component
class SampleComponent {
#Autowired
private JpaItemDao itemDao;
public void doSomething() {
itemDao.save(); // Just an example.
}
}
Besided the bean management, ApplicationContext does some other important thing in the Spring core container. As per ApplicationContect javadoc, they are;
Bean factory methods for accessing application components. Inherited from ListableBeanFactory.
The ability to load file resources in a generic fashion. Inherited from the ResourceLoader interface.
The ability to publish events to registered listeners. Inherited from the ApplicationEventPublisher interface.
The ability to resolve messages, supporting internationalization. Inherited from the MessageSource interface.
Inheritance from a parent context. Definitions in a descendant context will always take priority. This means, for example, that a
single parent context can be used by an entire web application, while
each servlet has its own child context that is independent of that of
any other servlet.
Also, checkout the sub-interfaces of ApplicationContext that specifically designed for work on different use cases like WebApplicationContext.
ApplicationContext is a core concept (arguably the most important one) of spring used also in spring boot of course but and ideally hidden from the programmers in both cases, meaning that the programmer should not directly interact with it in a business code of the application.
Technically its an interface that has many implementations, the relevant one is picked depending on in which environment you're running and how do you configure the application.
So does it do? Its a class that basically is a registry of all the beans that spring has loaded. In general, starting up the spring mean finding the beans to load and putting them in the application context (this is relevant for singletons only, prototype-scopes beans are not stored in the ApplicationContext).
Why does spring need it?
For many reasons, to name a few:
To manage lifecyle of the beans (when the application shuts down, all beans that have a destroy method should be called)
To execute a proper injection. When some class A depends on class B spring should inject class B into class A. So by the time of creating the class A, class B should already be created, right? So spring goes like this:
Creates B
Puts B into application context (registry)
Creates A
For injection goals: gets B from the application context and injects into A
// an illustration for the second bullet
class B {}
class A {
#Autowired
B b;
}
Now there are other things implemented technically in application context:
Events
Resource Loading
Inheritance of application contexts (advanced stuff, actually)
However now you have an overview of what it is.
Spring boot application encapsulates the application context but you can still access it from many places:
in the main method when the application starts it returns an application context]
you can inject it into configuration if you really need
its also possible to inject the application context into the business bean, although we shouldn't really do so.
In simple words:
Spring is popular for dependency Injection.
So all the bean definitions(Objects) will be created by the spring and maintained in the container. So all the bean life cycle will be taken care by spring container.
So ApplicationContext is a interface It has different implementations will be there to initialize the spring container.
So ApplicationContext is the reference to Spring Container.
Some popular implementations are:
AnnotationConfigWebApplicationContext,
ClassPathXmlApplicationContext,
FileSystemXmlApplicationContext,
XmlWebApplicationContext.
Reference: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/ApplicationContext.html

Spring, Run task once when application started

My application is based on spring boot.
I want to create a task which should be run only once after application has been started.
Currently, I am looking into two solutions:
Using #Scheduled and boolean property which should determine whether the logic shold be run or not.
#Scheduled
public void method(){
if(method_run_propery){
//do something;
}
}
Using Quartz. But I have not used before.
Please, tell me what is the best approach to use in this case.
Spring has a #PostConstruct annotation to do exactly that. Runs once the bean has been initialized and all dependencies added.
If it has to be run once immediately after application is initialized, I would simply start it from the init method of a singleton bean. Spring ensures that at be time it will be run all dependant beans will have been initialized.
For example, assuming a Java annotation Spring configuration you could use something like:
#Bean(init_method="init")
class TaskLauncher {
#Autowired DependantBeanClass dependant Bean;
...
public void init() {
// execute or start the task, eventually using the autowired dependant beans
...
}
}
When the context is refreshed, Spring autowire everything, initializes the dependant beans and then will call once the init method of the TaskLauncher bean.
No need for #Scheduler nor Quartz if you only need to start something at Spring initialization time
One of the ways is to implement ApplicationListener
Once spring context is initialized, Your class which implements ApplicationListener
which will then have onApplicationEvent method will be invoked, your logic can go in this method.

Injecting spring beans into legacy web app POJOs [duplicate]

This question already has answers here:
Why is my Spring #Autowired field null?
(21 answers)
Closed 7 years ago.
In order to provide POJOs in my legacy web app (Tomcat 8.0.26) with the ability to send ActiveMQ messages I've taken the recommendation to introduce Camel (2.15.2) / Spring (4.2.1) into the app to purely for the purpose of managing pooled MQ connections. I'm hoping there isn't an easier way.
Doing things the Spring way I'm thinking everything would need to be based around an MVC architecture with HTTP servlet aware controllers having access to the servlet context and therefore the Spring context in order to inject beanFactory beans into classes annotated with #Controller and #Service (and in fact there must be a Spring #Controller class that enables Spring to inject the #Service class.
However, as I've stated this is legacy code that will not be using the spring web framework.
After much pain it seems that the only way I can get beanFactory beans injected into my POJOs is to go the AspectJ and Weaving route. Before I go down this road can someone tell me that this is currently the best approach (what I've read describing this solution is from 2011 Can't get Spring to inject my dependencies - Spring Newbie) ? Can you point me to documentation and a working example?
Many thanks.
1) aspectj with #Configurable
In your #Configuration annotated class/es
you can add some more annotations
#Configuration
#EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.ENABLED)
#EnableSpringConfigured
#EnableAspectJAutoProxy
to enable aspectj and the #Configurable annotation,
you need to import the aspectj lib to your project and add the spring tomcat instrumentable java agent in your tomcat lib folder (give a look here, it exaplains how to configure tomcat) http://docs.spring.io/spring-framework/docs/2.5.6/api/org/springframework/instrument/classloading/tomcat/TomcatInstrumentableClassLoader.html
this is not going to help you if you are going to create your pojos using "new"
MyPojo p = new MyPojo(); // no black magic for this, you will need to satisfies the dependencies yourself) but that would be helpful for example when you load some entities through a framework like hibernate and you want to inject something into them.. #Configurable it's an option that can be evaluated in those cases, for what you describe I would rather not use it.
2) You can have some static methods that uses some static set spring-beans and use them from your pojos, something like
class Util{
private static SprintBeanWithJmsSupport x;
public static setSpringBeanToHandleJmsMessages(SprintBeanWithJmsSupport x){
Util.x = x;
}
public static sendJmsMessage(JmsMessage m){
x.sendMessage(m)
}
}
and you can go with Util.sendJmsMessage(...)
this is a bit shitty but it does the work, I don't personally like this approach
3) set your spring beans in your pojo when they need to use them (maybe behind some nice interfaces that suit your domain)
if you go with spring mvc you will likely end up having some controllers that will use some services (generally they handle security / db access and are the entry point to start the "use cases"), as everything wthin these layers is handled by spring it will be very simple to pass the spring-bean to handle jms messaging to your pojos, this seems to me quite a nice way to handle the problem
I went mostly based on memory and something may not be completely accurate, plus my english is .. what it is, so hope this can be helpful anyway.

How to use OSGI service inside Vaadin web application running in Jboss AS 7

I'm new to OSGI and currently trying to use it to create modular web application. Web application itself is created using Vaadin 6.
I following this WIKI article at Vaadin web site: Creating Modular Vaadin application with OSGI
Steps I've did so far:
- created OSGI bundle for module service (simple service which tracks other osgi modules a.k.a. plugins) and deployed it to jboss.
- created vaadin application, just a stub.
OSGI service supposed to be injected to Servlet class, like:
#WebServlet(urlPatterns="/*")
public static class Servlet extends AbstractApplicationServlet {
#Resource(mappedName="vaadin-moduleService")
ModuleService moduleService;
#Override
protected Class<? extends Application> getApplicationClass() {
return ModuleDemoApp.class;
}
#Override
protected Application getNewApplication(HttpServletRequest request) throws ServletException {
return new ModuleDemoApp(moduleService);
}
}
Now the question - how this service can be injected here? Currently I'm just getting NULL pointer, so DI doesn't work. From article referred above:
Note, that the servlet has a moduleService field annotated with the
#Resource annotation. One of the interesting features of GlassFish 3
is that it is possible to inject references to OSGi services into all
container managed Java beans, even though they are not actually
running in the OSGi container themselves. Thus, in this case, GlassFish
will find the module service we define in the previous section and inject it.
According to this Glassfish will do all the magic internally and automatically. Anyone aware of how to get it done using JBoss7?
Unfortunately didn't find any good (for newbie) explanation on how anything running inside of OSGI container can be referenced outside of it... Suppose that converting of the web application itself to OSGI bundle is not required to acomplish what I need. Is this true?
Thanks a lot.
The documentation states that the JavaEE component can get the BundleContext injected as a #Resource. If that works, then you can track your module service through a ServiceTracker.
I saw another example of using Vaadin together with OSGi here.

Am I allowed to declare a lifecycle interceptor on an interceptor?

I have my business bean defined thus:
#Local
#Interceptors(BusinessInterceptor.class})
public class MyBean implements SomeBean { ... }
And then I want my BusinessInterceptor to be configured with Spring's SpringBeanAutowiringInterceptor:
#Interceptors(SpringBeanAutowiringInterceptor.class)
public class BusinessInterceptor {
#Autowired
private SomeSpringBean someSpringBean;
}
Is this allowed/legal? I'm getting errors (NPEs, mostly) suggesting that the fields in BusinessInterceptor have not been initialized properly.
I doubt this can work. If I understand well your scenario, you have basically two DI containers, one is Spring and the other the app. server itself. Each one manages different elements. The BusinessInterceptor is created by the app. server which is unaware of Spring -- the #Autowired bean is then not set.
( Note that Spring and EJB3 have become quite similar now. You can have the same functionalities as EJB with Spring. Spring has indeed declarative transactions, dependency injection and AOP facilities similar to EJB3 interceptors (these are the main managed features). On the other hand, EJB3 is now so lightweight that there isn't really a compelling reason to use Spring with with EJB3. See Future of enterprise Java: full stack Spring or full stack Java EE. But this does not answer the question, and is just a little digression of mine :)

Resources