We use JSF within our presentation layer. Most classes looks like this:
#Named
#SessionScoped
public class MyHandler implements Serializable {
#Inject
private MyHelper helper;
#EJB
private transient MyFacade myFacade;
...
}
In general an JSF handler has one transient reference to an facade. The facade connects the presentation layer with our service layer. Helper classes will almost be injected through cdi.
JSF serializes the state of an handler but what happens on deserialization? Are the references automagically be restored? How could I check this or tell JSF to serialize/deserialize an managed jsf bean(testing)?
As per spec all (relevant) CDI-managed dependencies are proxied and the proxies are required to be passivable, so there is no problem with de-/serialization :)
[...] Finally, client proxies may be passivated [...]
Related
I am trying to Inject ServletContext in my dependant scope class but it always gives the failure.
java.lang.IllegalStateException: No CXF message usable for JAX-RS #Context injections in that thread so can't use interface javax.servlet.ServletContext
I am not able to undestand the reason that why can't I inject it here. I am using a producer method and when inside producer method,I try to access ServletContext obj then it gives above exception. I have also checked if the Injected servlet context is null but it is not null. But When I call any method using it for example sc.getContextPath() it gives the above exception. Below is the code snippet:
#Dependent
public class AuthContexthandler {
#Context
ServletContext sc;
#Produces
JWTAuthContextInfo getInfo() {
try{
System.out.println(sc.getContextPath()); //here I get the above mentioned error
//rest of the code
}catch(Exception e){
e.printStackTrace();
}
}
}
you must use #inject instead of #Context.
you can use #Context to inject object instances related to the context of HTTP requests into to JAX-RS source class and as AuthContextHandler(as #Christoph Böhme said) is not a JAX-RS source class so you cannot use #Context
but as http://docs.jboss.org/weld/reference/latest/en-US/html_single/ says:
An object bound to a lifecycle context is called a bean. CDI includes
built-in support for several different kinds of bean, including the
following Java EE component types:
managed beans, and EJB session beans. Both managed beans and EJB
session beans may inject other beans. But some other objects, which
are not themselves beans in the sense used here, may also have beans
injected via CDI. In the Java EE platform, the following kinds of
component may have beans injected:
message-driven beans,
interceptors,
servlets,
servlet filters and
servlet event listeners,
JAX-WS service endpoints and handlers,
JAX-RS resources,
providers and javax.ws.rs.core.Application subclasses, and
JSP tag handlers and tag library event listeners.
it means you also can use #Inject annotation in your JAX-RS source class.
there are also some predefined Beans in CDI such as ServletContext that you can use #inject annotation to inject them.
https://docs.jboss.org/seam/3/servlet/latest/reference/en-US/html/injectablerefs.html
https://docs.oracle.com/javaee/7/tutorial/cdi-adv004.htm
I am using Spring and JSF 2.0.
This is how my class look like
#ManagedBean(name = "userLogin", eager = true)
#SessionScoped
public class UserLogin
in this class I am using the following property
#Autowired
#ManagedProperty(value = "#{userService}")
private UserService userService;
And this is how my userService looks like
#Service ("userService")
In a framework like struts , I can use the userService without setters and getters , as its been named as a service.
Please tell how to use this without setters and getters , as I feel like its kind of a overhead.
Basically I just want to get rid of getters and setters for the userService as its a Spring bean.
Regards
Rashen
#ManagedProperty(value = "#{userService}") probably does nothing here, since UserService is not a JSF managed bean (judging from the code in your comment). You are combining two dependency injection strategies, where you only need one (setter is required for #ManagedProperty).
If you remove #ManagedProperty and leave only #Autowired, I think it should work.
I'm trying to create a scalable JSF application.
I would like to save view states on client side but I have troubles with ViewScoped ManagedBean with CDI Injected attributes.
SomeService.java :
#Singleton
public class SomeService {
// ...
}
SomeBean.java
#ManagedBean
#ViewScoped
public class SomeBean implements Serializable {
#Inject
private SomeService someService;
}
Unfortunately glassfish fails to serialize someService which I don't want to be serializabled but re-injected.
I tried to make it transient which ends up to a NullPointerException when accessing someService after de-serialization.
What shall I do?
I'm aware that I could use CDI ViewScoped with Seam Faces or CODI but I want to minimize at most dependencies.
I could also wait for JEE7 which will provide #ViewScoped for CDI but we won't be using JEE7 before months.
UPDATE :
I just wanted to add that I was using embedded EJB bundled in a jar which is itself linked to my war.
NotSerializableException's stack trace has the following message :
com.company.core.service.__EJB31_Generated__SomeService__Intf____Bean__
I don't like to self respond to my own questions but after some more research I found that it was a bug in Mojarra 2.1.6 (I'm using Glassfish 3.1.2.2) which is now solved in Mojarra 2.1.20.
To update Mojarra you just need to download a fresher version (eg: https://maven.java.net/content/repositories/releases/org/glassfish/javax.faces/2.1.20/javax.faces-2.1.20.jar) and place it in the $GLASSFISH/modules directory as javax.faces.jar.
I need to inject a singleton bean into the session bean. Below are the corresponding classes. The problem is that the injected object is always null. I tried all of the JNDI lookup strings which my JBoss 7.0.1 server showed me during startup (i.e. JNDI bindings for session bean named GlobalBean in deployment unit subdeployment .. of deployment .. are as follows: ..). I also tried commenting out the #EJB annotation in GlobalBean.java and also tried to use the "ejb/GlobalBean" during injection. However, no luck. What could be the reason? Thx.
GlobalBean.java:
#Startup
#Singleton
#Remote(GlobalBeanRemote.class)
#EJB(name="ejb/GlobalBean", beanName="GlobalBean", beanInterface=GlobalBeanRemote.class)
#ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
public class GlobalBean implements GlobalBeanRemote
{
// CODE
}
SessionBean.java:
#Stateful
public class SessionBean extends ParentBean
{
#EJB(name="java:module/GlobalBean!project.framework.interfaces.GlobalBeanRemote")
private GlobalBeanRemote globalBeanAPI3;
// CODE
}
In your SessionBean class try changing name attribute of #EJB to mappedName.
#EJB(mappedName="java:module/GlobalBean!project.framework.interfaces.GlobalBeanRemote")
This will, of course, only work if your two beans are in the same module.
Update
Given that your beans are in separate modules, try using the java:app namespace:
#EJB(mappedName="java:app ...")
The java:app namespace is used to look up local enterprise beans packaged within the same application. That is, the enterprise bean is packaged within an EAR file containing multiple Java EE modules. JNDI addresses using the java:app namespace are of the following form:
java:app[/module name]/enterprise bean name[/interface name]
Also try removing GlobalBean's #EJB annotation. #EJB is used to define a dependency.
I have been developing my web-app using JPA 2.0 implementation EclipseLink 2.2.0. I finally got around to running multi-threaded code and I got this exception:
java.lang.IllegalStateException: Attempting to execute an operation on a closed EntityManager.
The objects that have all the javax.persistence calls in my application are defined as application scoped, like this:
#Model
#ApplicationScoped
public class LocationControl implements Serializable {
#PersistenceContext private EntityManager em;
#Resource private UserTransaction utx;
// etc
And of course all the managed beans (usually RequestScoped or ConversationScoped) that want to access the data base do so like this:
#Inject private LocationControl lc;
So my question is this: Did I get that Exception through the use of #ApplicationScoped DAO? I had thought that it would be more efficient that way, since the container would not have to be continually re-creating this object on every request if it did not have a scope, and the DAO has no state of its own. However if the EntityManager and UserTransaction object have to be separate instances for each user, then that would be a problem.
Alternatively, I could use syncrhonized on the DAO methods, but I think that would cause thread lockups in the container (GlassFish).
Any advice appreciated.
#Model annotation was originally created to annotate request scoped beans, here is how it's defined:
#Named
#RequestScoped
#Stereotype
#Target({TYPE, METHOD, FIELD})
#Retention(RUNTIME)
public #interface Model {}
You can of course override '#RequestScoped' with another annotation but '#ApplicationScoped' it's not a good choice as everyone in the application would modify the state of the same injected EntityManager. I think it would be best to leave it #RequestScoped in most cases, sometimes, for example for a login/logout data bean '#SessionScoped' could be an option but I cannot see a scenario for '#ApplicationScoped' dao.
If you don't want to use #Model at all and you use full Java EE container, then the stateless EJB ,as BalusC said, would be a great option for Dao too.