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?
Related
I have a spring component that calls AWS to do some stuff. It acquires temporary session credentials lasting for <=1h to initialize the AWS service client at the start of my app. The AWS service client is set as an instance property of the bean. Then after this hour, I need to block all threads using this bean and refresh the temporary session credentials used by the service client.
Is there any recommended way to do this? Any hints/clues are appreciated
I think that it would be best (and easiest) for you to implement it as a sort of a proxy.
First, create a class for an object that will be refresh. Lets call it RefreshableProperty.
Then you need the proxy which will have following responsibilities:
It will be injected into any place that requires access to RefreshableProperty
It would have an instance of a field of type AtomicReference<RefreshableProperty>
It can have a method annotated with #Scheduled (with some cron expression) that would be invoked periodically
This method would connect to your configuration server and download new settings which would be put into a new instance of RefreshableProperty
At the end of such operation your code should swap the reference so that it points to a new object
If you need to have it being done exactly every hour then it will be a difficult task and I would strongly advise against it since it would be very tricky to synchronize this service client with your Spring Application.
"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.
I have a simple web app which propagates requests to another web app. My web app provides two very similar API's which query the same web app but for different types of information. For instance, my web app takes these two URL's
http://myservice.com:8080/otherservicecall1?userId=(userid)
http://myservice.com:8080/otherservicecall2?accountId=(accountid)
If I want to use the same service and data layer for my web app, what is the best way to differentiate between the two different parameters for these requests? For instance, I have a class in my data layer which handles 404's from the other service, with log messages such as
log.error("Could not find information on userId = " + userId);
But logs and exception messages like this are not generic enough to apply to both types of requests, meaning I have to pass in a parameter type variable which just holds the name of the parameter.
I guess what I'm ultimately asking is, is there a simple way to propagate the name of the parameter that I'm passing in through the controller through the service and data layer without passing it in through every function call? I have thought of making use of enumerations somehow but I can't see how they would help here.
For exceptions, We throw a generic ObjectNotFoundException that has a method that will return the id of an object we're looking for. If we need specialized exception messages we will extend our ObjectNotFoundException with something more specific and then update our Spring SimpleMappingExceptionResolver to handle the new, more specific, exception.
We make sure to keep the most general exception (ObjectNotFoundException) last in the exceptionMapping list.
For services, well, I wouldn't worry about if the parameter is called userid or accountid. The behavior for both those parameters should be the same. If you are worried about it, then your user interface layer is bleeding into your service and persistence layers; Which, is a bad thing.
If the stateful session bean is going to passivate, its state is written to harddisk and then the bean instance will be freed to serve other request (at least this is my understanding). When the same client is active again, bean instance will read the state from hard disk to regain the state. But how the bean instance knows that for which client which file it has to read to maintain the state?
I am very new to J2EE, so please pardon me if I am asking a very naive doubt. If I need to know any other topic to understand this, please point me in the right direction.
It's best to visualize a Stateful Session Bean (SfSB) as very close to an instance of a normal Java class. You look up (or inject) an instance of a SfSB, and the container will create one for you and return the instance. You then work with that instance like you would any other Java instance.
That means that you can store the instance in to a Session, serialize it to disk, etc.
The detail is that the instance you are working with is actually a proxy to the actual, underlying SfSB instance. It's not the actual SfSB itself.
When you make a call on your local proxy to the bean, it is the containers job to manifest that bean in to memory for you. The passivation and activation of the bean is done behind the scenes for you (though you can tap in to the process through the beans lifecycle).
Any information that the container needs to find the passivated SfSB is stored in the proxy that you're working with, but this is opaque to you. You needn't worry about it.
So, in a typical web based scenario, the life cycle would be that you get your bean instance, store it in a web session, and then simply use it like normal. If the container decides it needs to passivate your bean to make room or whatever, it will passivate it automatically for you. When your user returns, your app pulls the instance from the web session, and makes its calls. At that time, if the bean is passivated, the container will activate the bean for you, again automatically. This entire mechanism is dependent on the container, yet transparent to you. The important thing for you to recall is that you must hang on to SfSB that you get from the container, like you would any java object.
The final caveat is that if you allow a SfSB to be passivated for too long, the container will automatically delete it for you.
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.