I can't understand how serialization works in session scoped JSF managed beans. Why is implementation of Serializable interface important while creating a session scoped JSF managed bean?
#SessionScoped beans are ultimately stored in the user's HTTP session.
This means that when a Java EE deployment implements a session preservation scheme (for example, tomcat will attempt to save current sessions to a .ser file on server shutdown, if the deployer so chooses), those session-scoped beans would also be part of the payload that will be persisted.
A session scoped bean that isn't serializable becomes a problem here as it renders the entire HTTP session that it is a part of, un-persistable (any attempt to serialize an object that contains an unserializable member will cause a NotSerializableException, except with some special handling)
Incidentally, that means that even if your session-scoped bean implements Serializable, all its member variables must either be serializable or be marked transient.
In short, the entire object graph of a given HTTP session that is liable to be persisted via serialization, must either be marked as serializable or transient
Read more:
Why does Java have transient fields?
JavaBean recommendations on serialization
Just extending the answer of kolossus. Most of Servlet Containers like Tomcat may use an strategy of storing the Session data to physical memory, in case if restart or web app reload.
Well the usual way to store/persist Java instances/Objects is using ObjectoutputStream, which indeed requires the Object/instance to be persisted, to implement the Serializable interface.
You can see that its mentioned in Tomcat docs that:
Whenever Apache Tomcat is shut down normally and restarted, or when an
application reload is triggered, the standard Manager implementation
will attempt to serialize all currently active sessions to a disk file
located via the pathname attribute. All such saved sessions will then
be deserialized and activated (assuming they have not expired in the
mean time) when the application reload is completed.
Link for doc.
Related
I an Currently working on a javaEE project that uses weld Cdi implementations.i wasvassign a task to analyse memory leaks and memory management in our appplication. I am Confuse on following aspect about garbage collector and cdi proxy object. i have Cdi Session scoped LoginController bean. when tow or more than two user login than on doubt respective number of LoginController bean get created.If This Login Controller bean is inject to somer other bean and when that other bean is accessed that a proxy to Login Controller is created and trhe request is processed.No matter how many LoginController is created only single instance of Proxy object of LoginController is Created.
Since LoginController bean get garbage collected when the session timeout.But Proxy to Login Controller is never garbage collected once it is created even id all Login Controller beans get garbage collected . i want to know Why..?
The proxy object is created once at runtime to represent the bean created by CDI. There are references at the session level between the sessions (session id's) and the instances behind each of those proxies. The proxy is what is passed around, and is essentially always there.
This is why, for instance, you need to explicitly destroy dependent scoped beans that you manually inject. Their proxies would be around forever.
Going through an abstract in a book, I came across this:
On the server side, the state can be stored as a shallow copy or as a
deep copy. In a shallow copy, the state is not serialized in the
session. By default, JSF Mojarra uses shallow copy.
I seriously couldn't understand this.
Since in the above case, we will have-
javax.faces.STATE_SAVING_METHOD set to server,
and an input hidden field javax.faces.ViewState with a value somewhat like this "2870966362946771868:-8449289062699033744".
Obviously, the server must have maintained internally an state corresponding to the above hidden field.
But going by the abstract, if the state is not serialized in the session, then where it is?
Furthermore, I have noticed one thing that if my Managed bean(ViewScoped) is not implementing marker interface Serializable with STATE_SAVING_METHOD set to server, then in Mojarra, the NotSerializablEexception doesn't occur, while in MyFaces it does.
But going by the abstract, if the state is not serialized in the session, then where it is?
It exist of references to instances already in the HTTP session which in turn is not necessarily serialized.
The key context param for this is javax.faces.SERIALIZE_SERVER_STATE which defaults in MyFaces to true and in Mojarra to false. When set to true, you will sooner see NotSerializableException on artifacts which are mistakenly not Serializable. Otherwise, you're dependent on server configuration. For example, Tomcat by defaults serializes the entire HTTP session including all its attribtues during a server restart. Some servers, particularly those running in cluster, can even be configured to serialize entire HTTP sessions during runtime. In such cases you would also see NotSerializableException during restart or failover.
Mojarra has plans to make javax.faces.SERIALIZE_SERVER_STATE setting default to true as per 2.3, particularly because this setting would proactively prevent unforeseen developer mistakes such as assigning non-serializable instances of JSF artifacts such as UIComponent or even FacesContext as properties of a non-requestscoped bean. It would otherwise result in problems as Stuck thread at UIComponent.popComponentFromEL, Java Threads at 100% CPU utilization using richfaces UIDataAdaptorBase and its internal HashMap and java.lang.IllegalStateException at com.sun.faces.context.FacesContextImpl.assertNotReleased.
On the other hand, in older MyFaces versions, this setting broke EJBs injected in serializable managed beans due to the wrong classloader being used to resolve EJB proxies during deserialization. This was fixed in MyFaces 2.0.15 and 2.1.9 as per MyFaces issue 3581. See also #EJB in #ViewScoped #ManagedBean causes java.io.NotSerializableException.
I have a simple jsf 2.1 that used to work fine on Java EE 6 using primefaces 3.4.
When I migrated to glassfish 4.0 and primefaces 5.1 I've got the following exceptions each time I redeploy the project on Netbeans:
java.io.NotSerializableException: org.primefaces.model.DefaultStreamedContent
java.io.NotSerializableException: org.primefaces.component.datatable.DataTable
Even if this exception is thrown, the project is deployed and run correctly!
What could be wrong?
You've declared those types as a property of a view or session scoped managed bean. You should absolutely not do that. You should declare them as a property of a request scoped bean.
View and session scoped beans must be Serializable because view scoped beans are reused/shared across multiple requests on the same view in the same session, and session scoped beans are reused/shared across multiple requests in the same session. Anything tied to a specific HTTP session must be Serializable, because it enables the server to store sessions on disk, so it could be shared among other servers in a cluster, or survive server restarts.
The DefaultStreamedContent (and the InputStream it is wrapping, if any) may absolutely not be created and assigned as a view/session scoped bean property, not only because it's not serializable, but also because it can be read only once. You need to create this in the getter method only. This is indeed a rather special case which is fleshed out further in this answer: Display dynamic image from database with p:graphicImage and StreamedContent
The DataTable is a JSF component which you most likely referenced via binding attribute. It may absolutely not be assigned as a view/session scoped bean property, because UI components are inherently request scoped. Reusing the same UI component instance across multiple restored views in the same session may cause its state being shared across multiple requests (NOT threadsafe thus!) and/or potential "Duplicate Component ID" errors. See also a.o. How does the 'binding' attribute work in JSF? When and how should it be used?
NotSerializableException is thrown when an instance of a class must implement the Serializable interface.
If the class that throws the exception does not belong to a third-party library, find the class and make it implement the serializable interface.
If you do not want to serialize the objects in the class, you can mark the objects as transient, to make the serializable runtime ignore the objects.
You can read about it here
I want a method in a session scoped backing bean to be called after a user logs in. How can I do that?
Environment: Spring Security 3.0.x, Spring 3.0.x and JSF 1.2. The backing beans are managed by Spring.
Background: Sessions are created even without login. My session scoped bean holds settings, that are initially set to default values. After login I want to update the session state to the preferences stored in the database for that particular user. To achieve that I imagined an interface or even simpler an annotated (e.g. #PostLogin) method, but so far I have not found anything like that.
It would be OK if that method is called on every principal change, i.e. also on logout. It would also be acceptable if the whole bean is destructed and recreated on login, though my other session scoped beans should survive.
What I have found so far is:
ApplicationListener<AuthenticationSuccessEvent>: The listener apparently needs to be application scoped, and I can't get access to my session scoped bean in it. #Autowired plus scope proxy don't work. The injected object is broken; it does not contain its dependencies although the real backing bean does.
<form-login authentication-success-handler-ref="..">: haven't tried this, but I need the method to be called independent of the used login procedure. Other than form based we support remember me and programmatic login (e.g. automatically logged in after password forgotten process).
Answering my own question:
ApplicationListener was the right track, however #Autowired was not.
I defined an interface with one method, that is implemented by my session scoped bean. The (singleton scoped) event listener class then uses ApplicationContext.getBeansOfType(..) to find the session beans by that interface and invokes the interface's method on each of them.
I'm developing a java EE web app using JSF with a shopping cart style process, so I want to collect user input over a number of pages and then do something with it.
I was thinking to use an EJB 3 stateful session bean for this, but my research leads me to believe that a SFSB is not tied to a client's http session, so I would have to manually keep track of it via an httpSession, some side questions here . . .
1) Why is it called a session bean, as far as I can see it has nothing to do with a session, I could achieve the same by storing a pojo in a session.
2) What's the point of being able to inject it, if all I'm gonna be injecting' is a new instance of this SFSB then I might as well use a pojo?
So back to the main issue I see written all over that JSF is a presentation technology, so it should not be used for logic, but it seems the perfect option for collecting user input.
I can set a JSF session scoped bean as a managed property of all of my request beans which means it's injected into them, but unlike a SFSB the JSF managed session scoped bean is tied to the http session and so the same instance is always injected as long as the http session hasn't been invalidated.
So I have multiple tiers
1st tier) JSF managed request scoped beans that deal with presentation, 1 per page.
2nd tier) A JSF managed session scoped bean that has values set in it by the request beans.
3rd tier) A stateless session EJB who executes logic on the data in the JSF session scoped bean.
Why is this so bad?
Alternative option is to use a SFSB but then I have to inject it in my initial request bean and then store it in the http session and grab it back in each subsequent request bean - just seems messy.
Or I could just store everything in the session but this isn't ideal since it involves the use of literal keys and casting . etc .. etc which is error prone. . . and messy!
Any thoughts appreciated I feel like I'm fighting this technology rather than working with it.
Thanks
Why is it called a session bean, as far as I can see it has nothing to do with a session, I could achieve the same by storing a pojo in a session.
From the old J2EE 1.3 tutorial:
What Is a Session Bean?
A session bean represents a single
client inside the J2EE server. To
access an application that is deployed
on the server, the client invokes the
session bean's methods. The session
bean performs work for its client,
shielding the client from complexity
by executing business tasks inside the
server.
As its name suggests, a session bean
is similar to an interactive session.
A session bean is not shared--it may
have just one client, in the same way
that an interactive session may have
just one user. Like an interactive
session, a session bean is not
persistent. (That is, its data is not
saved to a database.) When the client
terminates, its session bean appears
to terminate and is no longer
associated with the client.
So it has to do with a "session". But session not necessarily means "HTTP session"
What's the point of being able to inject it, if all I'm gonna be injecting' is a new instance of this SFSB then I might as well use a pojo?
Well, first of all, you don't inject a SFSB in stateless component (injection in another SFSB would be ok), you have to do a lookup. Secondly, choosing between HTTP session and SFSB really depends on your application and your needs. From a pure theoretical point of view, the HTTP session should be used for presentation logic state (e.g. where you are in your multi page form) while the SFSB should be used for business logic state. This is nicely explained in the "old" HttpSession v.s. Stateful session beans thread on TSS which also has a nice example where SFSB would make sense:
You may want to use a stateful session
bean to track the state of a
particular transaction. i.e some one
buying a railway ticket.
The web Session tracks the state of
where the user is in the html page
flow. However, if the user then gained
access to the system through a
different channel e.g a wap phone, or
through a call centre you would still
want to know the state of the ticket
buying transaction.
But SFSB are not simple and if you don't have needs justifying their use, my practical advice would be to stick with the HTTP session (especially if all this is new to you). Just in case, see:
Stateless and Stateful Enterprise Java Beans
Stateful EJBs in web application?
So back to the main issue I see written all over that JSF is a presentation technology, so it should not be used for logic, but it seems the perfect option for collecting user input.
That's not business logic, that's presentation logic.
So I have multiple tiers (...)
No. You have probably a client tier, a presentation tier, a business tier, a data tier. What you're describing looks more like layers (not even sure). See:
Can anybody explain these words: Presentation Tier, Business Tier, Integration Tier in java EE with example?
Spring, Hibernate, Java EE in the 3 Tier architecture
Why is this so bad?
I don't know, I don't know what you're talking about :) But you should probably just gather the multi page form information into a SessionScoped bean and call a Stateless Session Bean (SLSB) at the end of the process.
1) Why is it called a session bean, as far as I can see it has nothing to do with a session, I could achieve the same by storing a pojo in a session.
Correction: an EJB session has nothing to do with a HTTP session. In EJB, roughly said, the client is the servlet container and the server is the EJB container (both running in a web/application server). In HTTP, the client is the webbrowser and the server is the web/application server.
Does it make more sense now?
2) What's the point of being able to inject it, if all I'm gonna be injecting' is a new instance of this SFSB then I might as well use a pojo?
Use EJB for transactional business tasks. Use a session scoped managed bean to store HTTP session specific data. Neither of both are POJO's by the way. Just Javabeans.
Why shouldn't I use a JSF SessionScoped bean for logic?
If you aren't taking benefit of transactional business tasks and the abstraction EJB provides around it, then just doing it in a simple JSF managed bean is indeed not a bad alternative. That's also the normal approach in basic JSF applications. The actions are however usually to be taken place in a request scoped managed bean wherein the session scoped one is been injected as a #ManagedProperty.
But since you're already using EJB, I'd question if there wasn't a specific reason for using EJB. If that's the business requirement from upper hand, then I'd just stick to it. At least, your session-confusion should now be cleared up.
Just in case you're not aware of this, and as a small contribution to the answers you have, you could indeed anotate a SFSB with #SessionScoped, and CDI will handle the life cycle of the EJB... This would tie an EJB to the Http Session that CDI manages. Just letting you know, because in your question you say:
but my research leads me to believe that a SFSB is not tied to a client's http session, so I would have to manually keep track of it via an httpSession, some side questions here . . .
Also, you could do what you suggest, but it depends on your requirements, until CDI beans get declarative transaction support or extended persistence contexts etc, you'll find yourself writing a lot of boilerplate code that would make your bean less clean. Of course you can also use frameworks like Seam (now moving to DeltaSpike) to enhance certain capabilities of your beans through their extensions.
So I'd say yes, at first glance you may feel it's not necessary to use a stateful EJB, but certain use cases may be better solve through them. If a user adds a product to his cart, and another user adds this same product later, but there is only one unit in stock, who gets it? the one who does the checkout faster? or the one who added it first? What if you want to access your entity manager to persist a kart in case the user decides to randomly close his browser or what if you have transactions that spawn multiple pages and you want every step to be synchronized to the db? (To keep a transaction open for so long is not advisable but maybe there could be a scenario where this is needed?) You could use SLSB but sometimes it's better and cleaner to use a SFSB..