We are planning to change Managed Beans to CDI beans. We used below code to invoke Service class in managed Bean.
#ManagedProperty("#{userService}")
private UserService userService; and setter method
For CDI bean, I replaced #ManagedProperty with #inject as shown below, and it is throwing following exception.
#SessionScoped
#Named
public class LoginController implements Serializable {
#Inject
private UserService userService;
}
org.apache.webbeans.exception.WebBeansDeploymentException: Passivation capable beans must satisfy passivation capable dependencies.
UserService is a plain interface with unimplemented methods and UserServiceImpl implements UserService interface. Please see below:
public interface UserService {
public List<User> getUserList();
}
public class UserServiceImpl implements UserService {
private UserDao userDao;
public List<User> getUserList() {
return userDao.getUserList();
}
}
Please let me know me how to invoke service interface in CDI beans?
Reading BalusC's answer on Spring JSF integration: how to inject a Spring component/service in JSF managed bean? tells me it is supposed to be supported that your Spring bean userService should be injected into your CDI bean LoginController.
But your UserServiceImpl is not Serializable which in CDI context means it is not passivation capable.
This is also what your Exception tells.
So either make your LoginController #RequestScoped instead of #SessionScoped so itself and #Injected children do not require to be passivation capable (aka Serializable).
Or make your UserServiceImpl and DAO Implementations Serializable (which imho is somewhat odd?).
Related
Spring #Autowired
I have a doubt on Spring #Autowired annotation.Please Help...
In Spring mvc ,when I tried #Autowired in this order
Controller--->Service--->Dao
ie,In Controller I autowired Service Class Object , In Service Class Autowire Dao Object.
This Injection chain works perfectly.
Similliarly In strutrs2+Spring ,I applied #Autowired Annotation in this way
Action--->Service-->Dao
This Injection chain also works fine.
If I call a funtion from outside this chain (eg:Custom Taglib class (from jsp)) to funtion in Service class Then in this Service class the Autowired dao object is null(ie,this call braks the chain).
My questions is
Is this #Autowired works in a Injection chain Only?
Beans that have #Autowired fields only have them set if they are sent through the Spring Bean Postprocessor -- that is, like you said, if you autowire them yourself. That is a big reason that constructor injection is much more preferred than field injection. Instead of doing
#Service
public class MyService {
#Autowired
private MyDao dao;
...
}
you should do
#Service
public class MyService {
private final MyDao dao;
#Autowired
public MyService(MyDao dao) {
this.dao = dao;
}
}
That way, when you're in a situation where you can't rely on a service to be post-processed (as in your case of using the jsp tag library), you can simply instantiate a new instance with a MyDao object and be on your merry way.
I've been facing the problem of Circular dependency in spring.
Public class UserServiceImpl implements UserService{
#Autowired
private RoleService roleService;
}
Public class RoleServiceImpl implements RoleService{
#Autowired
private UserService userService;
}
Is there any solution to deal with this problem, But I still want to use #Autowired. Other solutions might be to wire them manually. Or by using bean awares or by using bean post processor.
The working solution was to add default-lazy-init="true" to the
application config xml file
Details are here.
This question already has answers here:
Spring JSF integration: how to inject a Spring component/service in JSF managed bean?
(4 answers)
Closed 6 years ago.
I tried union Spring 3(MVC) with JSF 2. I have some experience in Spring and JSF, but never tried to join them before. In the end I have 2 files
#ManagedBean(name = "userBean")
#Scope
#Component
public class someBean {
#Autowired
private TestService testService;
public void printString() {
System.out.println(testService.getString());
}
}
and
#ManagedBean(name = "studentBean")
#Scope
#Component
public class StudentBean {
#Autowired
private TestService testService;
public void printString() {
System.out.println(testService.getString());
}
}
For these file I have right configuration for spring, jsf, and web.xml. And have .xhtml page where I start printString() for 'someBean' and for 'StudentBean'. I have the NPE in first case and 'some string' in the console in second case.
The reason is simple - different bean names in the Spring context and JSF. all problems finished after
#Component => #Component("userBean")
public class someBean {
In the debug I saw that
private TestService testService;
#Autowired
public void setTestService(TestService testservice) {
this.testService = testService;
}
When JSF bean is creating testService sets not null, but it is null during JSF lifecycle when
public void pringString() {
testService.blah();
}
testService is null. It is what I can't understand. Has someone deep knowledge the Spring and JSF to describe this situation in details?
Both JSF and Spring can act as bean containers. The #ManagedBean annotation instructs the JSF managed bean facility to create a new instance of the class, and manage it under the given name. The #Component annotation instructs the Spring ApplicationContext to create a new instance of the class, and manage it under the given name. That is, both JSF and Spring create an instance of that class, the JSF one is reachable through EL, but the Spring one gets its dependencies injected (because, being a spring annotation, #Autowired is not understood by the JSF managed bean facility).
So you have a choice: Use the JSF managed bean facility for everything (which I would not recommend, as it is rather limited), use CDI for everything (which is an option, but does not use Spring), or use Spring for everything (which I usually do), by removing the #ManagedBean annotation, and making Spring beans accessible through EL by registering a SpringBeanFacesELResolver in your faces-config.xml. The Spring reference manual describes this in section 19.3.1.
I had the same issue, it was due to the property name of #ManagedBean annotation.My backing bean looks like this
#Component
#ManagedBean(name="mainBean")
#SessionScoped
public class MainManagedBean{...}
As you can see, the name given to the bean (mainBean) is different to the default name (mainManagedBean) that the backing bean should have.
I have fixed the issue by setting the property name to "mainManagedBean". My bean becomes like this:
#Component
#ManagedBean(name="mainManagedBean")
#SessionScoped
public class MainManagedBean{...}
I wish this can help you
I believe the reason why testService is null is because testService has not been instantiated yet when managed bean is being constructed. So you can use #PostConstruct to inject Spring beans into a managed bean.
#ManagedBean(name = "userBean")
#Scope
#Component
public class someBean {
#Autowired
private TestService testService;
public void printString() {
System.out.println(testService.getString());
}
#PostConstruct
private void init() {
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
ServletContext servletContext = (ServletContext) externalContext.getContext();
WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext).
getAutowireCapableBeanFactory().
autowireBean(this);
}
}
#Service
public class TestService {
......
}
I am using Spring in my Java Application, all the #Autowired annotations working until now.
Simplified example would be:
#Component
public class MyBean implements MyInterface {
...
}
#Component
public class MyOtherBean {
#Autowired
private MyBean myBean;
...
}
Once I try to start the Application, I get:
java.lang.IllegalArgumentException: Can not set MyBean field MyOtherBean.myBean to $ProxyXX
The interface contains just two public simple methods and the class implements them.
Both classes are public and have public default constructor. (I even tried to instantiate them in tests.
Once I remove the implements section, everything works correctly.
What can be wrong with the implementation of the interface? What is $ProxyXX?
I suspect the issue is that Spring is injecting an AOP proxy which implements MyInterface - possibly for the purposes of transaction management or caching. Are any of MyBean's methods annotated #Transactional or annotated with any other annotation?
Ideally you'd probably want to reference MyBean by it's interface type - which should resolve the issue.
#Component
public class MyOtherBean {
#Autowired
private MyInterface myBean;
...
}
If you have more than one bean implementing MyInterface then you an always qualify your bean by name.
#Component
public class MyOtherBean {
#Autowired
#Qualifier("myBean")
private MyInterface myBean;
...
}
By default, Spring uses Java dynamic proxies to implement AOP when the bean implements an interface. The easiest and cleanest way to solve your problem is to make program on interfaces, and inject theinterface insted of the concrete class:
#Component
public class MyOtherBean {
#Autowired
private MyInterface myBean;
...
}
See http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/htmlsingle/#aop-proxying for how to force Spring to always use CGLib.
I am using Spring for my DI.
Is there an equivalent of #ManagedProperty? I want to inject the value from one view scoped bean into another one on the next page.
e.g
#Component
#Scope("view")
public class Page1Bean(){
private String value;
}
#Component
#Scope("view")
public class Page2Bean(){
#ManagedProperty(value = #{page1Bean}") //doesnt work in Spring
private Page1Bean bean;
}
#Resource or #Autowired should work. #Resource is the Java EE implementation, #Autowired is the spring specific annotation. I can't find the reference now, but it seems like I read once to prefer #Resource over #Autowired.
here's a blog post I found that talks about #Inject vs. #Resource vs. #Autowired
http://blogs.sourceallies.com/2011/08/spring-injection-with-resource-and-autowired/#more-2350