Xpages: managedBean is constantly "losing" global Domino Session object - java

I'm in the process of building a managedBean for an Xpages application. Currently the bean is registered in faces-config at view scope because I need it to re-initialize on every page load (see below). The bean's constructor initializes several class variables whose values are referenced all over the entire class's code. One of those variables is a Domino session object, another example is the current document datasource:
private Session session;
private DominoDocument ds;
Both are initialized within the constructor as
session=DominoUtils.getCurrentSession();
ds=(DominoDocument) resolveVariable(dsName);
(resolveVariable is an internal helper method; don't think I need to explain that here)
Apart from the constructor and the various helper methods there are also some other public methods within the same class that are called on button clicks. Most of those additional methods make use of the same document datasource, as well as the current session object.
What's happening is that my additional methods can access and use the global datasource object (ds) but if they try to access the global session object an error is thrown; further down the stack trace I find what seems to cause the error:
NotesException: Object has been removed or recycled
There's no recycling at all in my code right now, the session object must get lost somewhere on the way.
As a workaround I started passing the session object from SSJS into each method as in
public void testMethod(Session s){
System.out.println("my name is " + s.getEffectiveUserName());
}
Which is working fine. But why is it that the bean object keeps forgetting the global session while it can remember all the other objects and variables?
BTW: I tried to bind my managedBean to a session scope but that doesn't help at all. And yes, I even restarted the entire server after making that change...

All Domino objects coming from the runtime are recycled at the end of every request. If you want to access any of them, you should re-fetch them from the environment when they're needed and not store references within your mean (you could use transient refs, but you wouldn't gain much). So the quick fix is to replace each use of the session in your class with that DominoUtils.getCurrentSession() call.

Related

Create a single instance of HashMap in Java throughout the session

I am working on a project wherein I need to store a set of keys and values throughout the session of the program execution. Meaning when the server is up, I want to have a map which stores data and is same for multiple requests made in that session.
So for creating this map, should I make a static Map or create a singleton bean for it and use autowiring? Which is better?
I used the static map, but noticed that even after stopping the server and running it again, the map instance was having values from previous session, instead it should have been null in the beginning of the request. The objects were not getting destroyed properly.
Does this behavior is improved if I'll use beans?
You have to define what is a Session.
Usually, in a Web project, a Session is related to an HTTP Session. These are managed in Spring by #Scope(value = WebApplicationContext.SCOPE_SESSION). The Bean will have a proxy, managing the instances of your Service automatically.
In this case, you do not want to use a Static Map. Indeed, a static object is global to your program, and only one instance will exist at any time, like a Singleton.
If you define a Session as the start and end of your server process, then fine.
So for creating this map, should I make a static Map or create a singleton bean for it and use autowiring?
This is close to the same thing. The only difference is how it will be instantiated. A static Map will be created by the JVM as soon as your Class is loaded. A Singleton Bean will be created by Spring at the first use.
The main advantage of the Bean, in your case, is the Inversion of Control for your Unit Tests.
I used the static map, but noticed that even after stopping the server and running it again, the map instance was having values from previous session
Usually, an object will lose its data when the server is closed, unless your Map has been Serialized by the server and stored in a session file on the disk. Maybe you should try to move your static Map to its own Class.
Does this behavior is improved if I'll use beans?
No, the behavior will be the same.
Don't forget that, as a singleton, your Map must be synchronized with Collections.synchronizedMap(). Otherwise, you will have surprises when using it.

EJB: what does maintaining state across method calls mean?

"Stateful: These beans can hold client state across method invocations. This is possible with the use of instance variables declared in the class definition. The client will then set the values for these variables and use these values in other method calls."
What does maintaining state across method calls mean ?
sorry for the noobness of my question.
You can think of it as the HttpSession on a web application. What you save on HttpSession is available across different requests to the web server. Likewise what you store as class variables in a session EJB is available across different method invocations done on the same session EJB.
Refer:
Lookup returns new instance of Stateful session bean
http://www.javaworld.com/article/2071724/java-web-development/ejb-fundamentals-and-session-beans.html
Statefullness is bad when it comes to concurrency. For Example you have one Statefull Bean, UserRegistrationBean which stores email then if two users try to register at the same time in a race condition one user overwrite the other one's email.
Statefullness requires synchronized access to the state which is costly.

External thread callback to a session scoped Spring bean

I have a Spring Web MVC application where i need to use an external device driver which returns information in an asynchronous manner every time the device gathers some new data. We need to pass an object at the begging to the start read method. This object implements an API defined interface which declares the callback method.
The problem raises when this callback method needs to manipulate some bean in Spring's session scope. Because the callback gets called in the Thread of the driver when the callback implementation wants to access a Spring bean it yields an exception saying that the current thread is not in Spring's managed scope.
I'm wondering if there's any way to make the object which is implementing the callback interface into some kind of proxy which knows information about the context of the session which constructed it so this way it can invoke bean methods through Spring's context object?
I think you are approaching the problem from the wrong side. I guess you want the device driver callback to put some results in the user session. But this is not enough to display that data, so (guessing again) probably some long-polling is involved, looking into the session through session-scoped bean.
With this assumption I advice you to generate some sort of unique requestId every time you call the back-end driver and put that requestId both in the HTTP session and in the callback. When the callback is called, it pushes the results into some sort of map, where key is the assigned requestId. Now the client (who knows the requestId as well) can look into the map and fetch the results. You must remember about the synchronization (which is also the case with normal HttpSession).
If you have some more advanced way of notifying clients (Comet? WebSockets?) this can also be done in this callback.
Note that technically you can pass an instance of HttpSession object into the callback instance (but as you can see this does not work with Spring session-scoped beans) but passing session around doesn't seem like a good design. It is simply better to provide a level of indirection. What if, in the future, you would like to reuse that code with command-line or desktop client?

Singleton Object Created for each Request

I want to create a singleton object whose scope is basically only the request. This will be used to collect the errors and we need to send error whenever we send the response back.
Can anyone provide pointers toward this thing?
I am also using spring.
I tried using Spring container singleton object scope session or request but still my object is holding values from the earlier request
I am using this error object with AspectJ. Will that may cause problem on static binding?
how about
//sync this code
if(request.getAttribute("someKey") == null){
// create object and set it
}
If you set the Object life cycle in the Spring container to be per request then it should only exist for that HttpRequest.
Generally for direct injection containers like Spring when you set the object life cycle or object scope to be per request then it should create an new instance of the object for each http request that it recieves.
If it is not doing this then I would assume that it is more than likely something to do with your configuration.
Singleton is the defualt for the spring container when creating beans I think so you have to specifically set the object scope to per request.
Bean Scopes
http://static.springsource.org/spring/docs/2.5.x/reference/beans.html
I'm not sure that singleton is what you want here - if two requests arrived concurrently they would share the singleton object, and their errors will get mixed up.
Is it possible to create an object to hold the errors and put that in to a ThreadLocal object. The scope of the object will be constrained by the request, and access to it in the ThreadLocal object is easily achieved from within your application without having to pass a refernce to the object around.
You can use ThreadLocal.

.java terms and random words clarification

Im really new to java, jsf, jsp, and I need to learn how it works quickly. So the website Im using to practise has some terms etc that I dont know what they mean and Im hoping somebody can explain what they mean and how/what they are used for:)
Requestscoped
Applicationscoped
Sessionscoped
EntityManager
and could someone walk me through what these lines do?
#RequestScoped
public class Dao {
#DataRepository
#Inject
private EntityManager entityManager;
First of all, in Java (5 and higher), "things" starting with a # (e.g. #Deprecated) are called annotations.
Annotations provide data about a
program that is not part of the
program itself. They have no direct
effect on the operation of the code
they annotate.
Your JavaBeans needs to be configured to a scope if you want to use it in JSF (Definitions can be found here).
#RequestScoped: Objects with this scope are visible from the start of the request until the end
of the request. Request scope starts at the beginning of a request and ends when the
response has been sent to the client. If the request is forwarded, the objects are visible
in the forwarded page, because that page is still part of the same request/response
cycle. Objects with request scope can use other objects with none, request, session,
or application scope. If you have to think it in terms of servlet, the managed bean is stored in the HttpServletRequest until the end of the request (when the response is sent to the client). After that, the bean no longer exists in the request.
#SessionScoped: An object with session scope is visible for any request/response cycle that
belongs to a session. Objects with this scope have their state persisted between
requests and last until the object or the session is invalidated. Objects with session
scope can use other objects with none, session, or application scope. Basically, these objects are stored in a HttpSession (refer to Servlets again). Each session has a session ID (known as JSESSIONID) that the bean is associated with.
ApplicationScoped: An object with application scope is visible in all request/response cycles
for all clients using the application, for as long as the application is active. In terms of Servlet, this could be, managed bean stored in a ServletConfig.
#NoneScoped: Objects with this scope are not visible in any JSF page. When used in the configuration file, they indicate managed beans that are used by other managed beans in the application. Objects with none scope can use other objects with none scope.
For EntityManager, this is associated with persistence context. It is used to create and remove persistent entity instances, to find entities by their primary key identity, and to query over all entities. For more, refer to the JPA (Java Persistence API) Specification, or Hibernate.
#Inject, means that the instance is injectable. They follow the infamous crase word of Depency Injection or Inversion of Control (IOC). What this basically mean, is that when the resource (in your case EntityManager entityManager is needed, the JEE container instantiates the resource for you (without you needed to instantiate it directly through e.g. a constructor, etc.).
I have no clue what #DataRepository means. Never seen it before.
I hope this helps you.
These terms are usually associated with a dependency injection framework like guice and not with java in particular.
http://code.google.com/p/google-guice/wiki/Scopes describes the various scopes that are built into guice.
By default, Guice returns a new instance each time it supplies a value. This behaviour is configurable via scopes. Scopes allow you to reuse instances: for the lifetime of an application (#Singleton), a session (#SessionScoped), or a request (#RequestScoped). Guice includes a servlet extension that defines scopes for web apps. Custom scopes can be written for other types of applications.

Categories