Injecting EJB 3 into Spring Bean - spring

I am trying to inject EJB into Spring (3.1.2) service (both in different WARs)
Both are very simple (methods removed to simplify example):
EJB:
#Remote
public interface MyBean {
}
#Singleton
public class MyBeanImpl implements MyBean{
}
Service:
#Service
public class MyServiceImpl implements MyService{
}
At first sight thing is very simple, but I tried:
#EJB(lookup = "java:global/ejbApp/MyBeanImpl!com.my.MyBean")
private MyBean myBean;
and it didin't work. Then I also tried:
#EJB(mappedName = "java:global/ejbApp/MyBeanImpl!com.my.MyBean")
private MyBean myBean;
And
#Resource(mappedName = "java:global/ejbApp/MyBeanImpl!com.my.MyBean")
private MyBean myBean;
but neither worked.
I managed to inject my EJB using:
<jee:jndi-lookup id="myBean" jndi-name="java:global/ejbApp/MyBeanImpl!com.my.MyBean" />
in my spring configuration and in the service:
#Autowired
private MyBean myBean;
But I really dont like this solution. I would like to have my JNDI path in some annotation to be able to do e.g:
#EJB(lookup = MyBean.JNDI_NAME)
private MyBean myBean;

We have found quite nice and simple solution.
Into spring configuration file one has to put:
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor">
<property name="alwaysUseJndiLookup" value="true" />
</bean>
And that enables spring to search for the beans annotated with #Resource in JNDI.
So now one can do:
#Resource(mappedName = MyBean.JNDI_NAME)
private MyBean myBean;

Are you aiming to get rid of XML or to have JNDI name in annotation? If the former, I haven't tested it, but should work:
#Configuration
public class EjbCfg {
#Bean
public JndiObjectFactoryBean myBean() {
JndiObjectFactoryBean factory = new JndiObjectFactoryBean();
factory.setJndiName(MyBean.JNDI_NAME);
return factory;
}
}
Now you can simply inject:
#Autowired
private MyBean myBean;

Related

#Autowired not working in spring Integration

In service implementation,with help of #Autowired i am injecting CollectInfo object in serviceImpl but i am getting NullPointerException.
package net.group.cts.service.serviceImpl;
#Service
public class EmployeeImpl implements EmployeeService {
#Autowired
CollectInfo info;
public void processData(){
info.getName();
}
}
package net.group.cts.model;
#Component
public class CollectInfo (){
String name;
public String getName(){
name = name + "Mr.";
return name;}
}
}
Xmlconfig.xml
<context:annotation-config/>
<context:component-scan base-package="net.group.cts"/>
<bean id="info" class="net.group.emp.model.CollectInfo "/>
You cannot inject a bean in a class if this class is not a Spring bean.
EmployeeImpl is not annotated with any Spring bean stereotype such as #Component or #Service.
Add one of them on EmployeeImpl and ensure that the two classes are located inside the package scanned by Spring <context:component-scan base-package="net.group.emp.service"/>
and it should be ok.
Besides, both annotating a bean with #Component :
#Component
public class CollectInfo (){...}
and configuring it in the Spring xml configuration :
<bean id="info" class="net.group.emp.model.CollectInfo "/>
is redundant. It will finally create two beans : one name collectInfo and another named info.
I advise you to favor annotation over xml configuration as it is possible (it is the very most of cases).

Understanding Spring #Configuration classes as BeanDefinitions generators

Classes annotated with #Configuration are equivalente to define beans using traditional Spring XMLs with <bean> elements.
If I understand well, every #Bean defined generates a BeanDefinition that Spring will use to generate a bean, doesn't it?
Now suppose that I autowired the ApplicationContext and access one of its beans:
#Configuration
public class SomeConfig{
#Autowired
private ApplicationContext ac;
#Bean
public MyBean myBean(){
AnotherBean ab = (AnotherBean) ac.getBean("someBean");
MyBean mb = new MyBean(ab);
return mb;
}
}
Am I really accessing a bean or a BeanDefinition? This has implications, I don't want the container to start creating all the beans during the BeanDefinition stage.
If instead I #Autowire a bean, am I actually autowiring a bean or a BeanDefinition?
#Configuration
public class SomeConfig{
#Autowired
private AnotherBean ab;
#Bean
public MyBean myBean(){
MyBean mb = new MyBean(ab);
return mb;
}
}

Spring: Autowired is null in ejb class

I have the following situation:
#Controller
public class myController {
#Autowired
private IProxy service;
public ModelAndView init(HttpServletRequest request, HttpServletResponse response) throws Exception {
List<String> list = service.getName();
}
}
Then my Service is define as follow:
public interface IProxy {
public List<String> getName();
}
Proxy class is responsible for the lookup to the remote bean
#Service("service")
public class Proxy implements IProxy {
...
public List<String> getName() {
return myClass.getName();
}
And the implementation is the following:
#Interceptors(interceptor.class)
#Stateless
#Resource(name = "java:/db")
#Remote(MyClassRemote.class)
public class MyClassImpl extends MyEjb implements MyClassRemote{
#PersistenceContext(unitName = "db")
private EntityManager em;
#Resource
private SessionContext sctx;
#Autowired
public IMyRepo myRepo;
#Override
public List<String> getName() {
try {
return myRepo.getName(em);
}
catch (Exception ex) {
ex.printStackTrace();
throw ex;
}
finally {}
}
So, the problem is that here myRepo is null. I don't know why because IMyRepo and his implementation are always located within the path scanned by Spring.
Just one clarification: MyRepo class that implements IMyRepo is annotated with #Repository.
Any idea?
you can inject spring beans in EJB using Spring interceptors, as explained here in the official documentation. Basically you'll need to adjust your class as follows:
// added the SpringBeanAutowiringInterceptor class
#Interceptors({ interceptor.class, SpringBeanAutowiringInterceptor.class })
#Stateless
#Resource(name = "java:/db")
#Remote(MyClassRemote.class)
public class MyClassImpl extends MyEjb implements MyClassRemote{
// your code
}
You'll also need to define the context location in a beanRefContext.xml file (with your own application context file):
application-context.xml version
<bean id="context"
class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg>
<list>
<value>application-context.xml</value>
</list>
</constructor-arg>
</bean>
Java Configuration version:
<bean id="context"
class="org.springframework.context.annotation.AnnotationConfigApplicationContext">
<constructor-arg>
<list>
<value type="java.lang.Class">com.your.app.Configuration</value>
</list>
</constructor-arg>
</bean>
Spring beans and EJB are two different things, you can't just inject a Spring bean in an EJB, because that EJB is no Spring bean, so Spring doesn't know there is a field which should be injected by Spring (unless you use some fancy AOP stuff, which can enable injection into non-Spring-managed beans).

How to autowire a generic bean in spring

How to autowire a generic bean in spring?
I have a dao implement as follows:
#Transactional
public class GenericDaoImpl<T> implements IGenericDao<T>
{
private Class<T> entityClass;
#Autowired
private SessionFactory sessionFactory;
public GenericDaoImpl(Class<T> clazz) {
this.entityClass = clazz;
}
...
}
Now I want to autowired the DaoImpl like this:
#Autowired
GenericDaoImpl<XXXEntity> xxxEntityDao;
I config in the spring xml:
<bean id="xxxEntityDao" class="XXX.GenericDaoImpl">
<constructor-arg name="clazz">
<value>xxx.dao.model.xxxEntity</value>
</constructor-arg>
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
But I doesn't work, How should I config it? or a good practice about generic Dao implement?
Work with your interfaces instead of implementations
Do not use #Transactional in your persistent layer as it is much more likely that it belongs to your service layer.
Those being said, it might make more sense to extend the generic dao and autowire that. An example would be something like :
public interface UserDao extends GenericDao<User> {
User getUsersByNameAndSurname(String name, String surname);
... // More business related methods
}
public class UserDaoImpl implements UserDao {
User getUsersByNameAndSurname(String name, String surname);
{
... // Implementations of methods beyond the capabilities of a generic dao
}
...
}
#Autowired
private UserDao userDao; // Now use directly the dao you need
But if you really really want to use it that way you have to declare a qualifier :
#Autowired
#Qualifier("MyBean")
private ClassWithGeneric<MyBean> autowirable;
There is an alternative way.
I change the GenericDaoImpl<T> to a common class without Generic but use the generic in function
level, and the entityClass can be configured in spring xml.

Spring autowired annotation with java timertask

Autowired annotation doesn't work. I thought there must be a problem with Timertask or run method. My other classes working fine(I mean Autowired annotation initialize genericService without any problem) but in this class genericService value is null. Is there any idea?
public class UsersUpdateTask extends TimerTask {
#Autowired
GenericService genericService;
#Override
public void run() {
//genericService.save() gives null pointer.
}
}
My applicationContext definition;
<bean id="usersUpdateTask" class="myPackage.UsersUpdateTask">
</bean>
<bean id="genericLogger" class="utilPack.Logger">
</bean>
<bean id="genericService" class="servicePack.GenericService">
This class working perfectly;
public class Logger implements Serializable {
#Autowired
private GenericService genericService; //works fine
.....
}
There is a method in another class to call UsersUpdateTask's run method;
public void updateUsersList(){
timer.schedule(new UsersUpdateTask(), 1000, 60*60*1000);
}
Well there it is
timer.schedule(new UsersUpdateTask(), 1000, 60*60*1000);
you're creating the object yourself. Spring can't autowire objects it doesn't control or process. Use the injected UsersUpdateTask bean.

Resources