I have some a java portlet application which calls a restful service. I have struck a problem where it looks like I am coming across a threadsafe issue. I have a servlet specifically used for Ajax calls. This servlet is called from myultiple locations at the same time.
It looks like my application is getting confused because the Ajax servlet is receiving multiple requests from different locations at the same time. I didn't think that this would be a problem.
Can someone help me understand the issue and secondly suggest a way to fix/improve? I think I will struggle to put a code snippet here because it will be too large to demonstrate the issue.
But basically the pattern is that I fire some 2 ajax requests from javascript to a servlet at the same time with different parameters. The handling of the servlet request is different based ont he different parameters passed in. But they both call the same java static methods to handle creating json objects. And it's those static methods that look like they are getting confused.
When I'm printing debug messages in the static methods the static methods show the debug info from the first call and then the static methods start showing debug info from the second call before the first is finished.
thanks for the help and sorry for no code snippet (probably too long)
All you need is to check if there are methods that using same non-threadsafe resources (i.e. HashMap in the field, or something). If there are, add locks or get rid of these fields (make them local).
Related
I have to automate certain operations of PUT/POST operation in my case, I have those endpoints already-in-place which will do their part.
My planning is to have another method which will drive this whole automation, consider this method as new POST endpoint which would gonna call each either POST and PUT endpoint from the same service which I already mentioned.
I will gonna call those existing PUT and POST based on input, if consider the input is new I will call existing POST and if given input exists in database I will going to call PUT.
Till I am good, But I have a question in my mind, Which is bugging me a lot that my new endpoint which is of POST is calling PUT as well as POST, I each method type has to do its type of operations only but here I am calling PUT as well as POST whereas my parent calling method type is POST.
I am not sure if I am working in right direction to achieve my use-case.
Please correct me in a different way.
Note - I am having Spring Boot application which would always need some endpoint to trigger any logic which I am talking about.
Update my question for better understanding.
I dont really know what you mean exactly. The HTTP methods are considered to do a specific task, but yet again its ok to use POST to update something - might be not best practice, but works. If you want to seperate the concerns (adding, updating), then just implement two different endpoints, one handling the creation the other one the update. The client (whether its a web-app or desktop app or whatever) has to handle this issue.
I have 2 comboboxes on a window that have their store loaded when the window is created. I have a single servlet that calls the same function for both comboboxes we are trying to load however I have found that this causes problems and the stores don't get loaded correctly. Any ideas?
EDIT: So the more appropriate question would be: How to handle multiple requests on the same servlet? Is that a multithreading issue? I'd really like to avoid having to deal with that since I'm not that experienced even though this one seems easy...
I still think there are problems if you call the same servlet from different XHR requests but the way to solve the loading problem is by calling the store.load functions in a cascading fashion inside each other's callback function:
store1.load({
callback: function() {
store2.load();
}
});
This way stuff doesn't get in the way of the ajax request. However I still don't know why this is happening, the server is supposed to take care of the multithreading of the servlets...
on my GAE app, I have a servlet that performs an XSLT transformation. I used to run it as frontent, but sometimes it took too much time to finish. So I'm now running this on the backend.
This is what I did:
1/ create a file 'backends.xml' defining a dynamic public backend named 'xslt'
2/ prepend 'xslt' to the domain when calling the servlet:
http://xslt.[appname].appspot.com/getCoordinates?[params]
This works!
The typical behaviour of the app is that a series of calls to this 'getCoordinates' servlet will be made. Each request will trigger the 'doGet' method of this 'getCoordinates' servlet, which does the initialization of the Saxon processor, xsltCompiler, xsltExecutable and xsltTransformer, but all of these objects could be reused across subsequent requests!
My question: how should I program to separate this initialization code into a handler for the backend initialization request to '_ah/start'?
If I just create another servlet 'startXslt' that answers the request to '_ah/start' and initialize all the generic objects within this servlet's 'doGet' method, how will I be able to use the objects from within the 'getCoordinates' servlet's 'doGet' method?
(I'm not very experienced with java servlet programming, so I reckon this may be more like a general question on java servlet programming, and not GAE-specific, or is it?)
Yes, it's general questions, and there is really a hundreds of ways of doing that. Btw, most projects are based on some framework, and it depends on it. If you're startd with plain raw servlets - i strongly recommend you to take a look at other options. For GAE there is Gaelyk. Or Spring MVC as most populart (is it?) general usage framework.
Btw, if you need an solution right now, I can recommend one of the following:
init in init() method (it will be called on app startup)
store it at class static field, and init in static {} block (called at class initialization, shared between instances)
make an singleton for this transformers (you can init it once, at first call)
Using a backend is a good idea, since you could control that only a single instance would be used and re-used when addressing the backend.
In this way, all servlets would be executed within the same JVM instance, and you could therefore have a shared object by using a Singleton pattern as suggested by splix on the other answer.
As I understand it, your question pertains on how you could hook on the backend initialization to initialize your own objects. If that is the case, you could implement a ServletContextListener and put your code on the contextInitialized(ServletContextEvent) method.
This method would be invoked once every time a new instance is created, be it at the front end or at the back end.
I'm writing a Java webservice with CXF. I have the following problem: A client calls a method from the webservice. The webservice has to do two things in parallel and starts two threads. One of the threads needs some additional information from the client. It is not possible to add this information when calling the webservice method, because it is dependent from the calculation done in the webservice. I cannot redesign the webservice becuase it is part of a course assignement and the assignements states that I have to do it this way. I want to pause the thread and notify it when the client delivers the additional information. Unfortunately it is not possible in Java to notify a particular thread. I can't find any other way to solve my problem.
Has anybody a suggestion?
I've edited my answer after thinking about this some more.
You have a fairly complex architecture and if your client requires information from the server in order to complete the request then I think you need to publish one or more 'helper' methods.
For example, you could publish (without all the Web Service annotation):
MyData validateMyData(MyData data);
boolean processMyData(MyData data);
The client would then call validateMyData() as many times as it liked, until it knew it had complete information. The server can modify (through calculation, database look-up, or whatever) the variables in MyData in order to help complete the information and pass it back to the client (for updating the UI, if there is one).
Once the information is complete the client can then call processMyData() to process the complete request.
This has the advantage that the server methods can be implemented without the need for background threads as they should be able to do their thing using the request-thread supplied by the server environment.
The only caveat to this is if MyData can get very large and you don't want to keep passing it back and forth between client and server. In that case you would need to come up with a smaller class that just contains the changes the server wants to make to MyData and exclude data that doesn't need correcting.
IMO it's pretty odd for a web service request to effectively be incomplete. Why can't the request pass all the information in one go? I would try to redesign your service like that, and make it fail if you don't pass in all the information required to process the request.
EDIT: Okay, if you really have to do this, I wouldn't actually start a new thread when you receive the first request. I would store the information from the first request (whether in a database or just in memory if this is just a dummy one) and then when the second request comes in, launch the thread.
As far as I know, Servlet 3 spec introduces asynchronous processing feature. Among other things, this will mean that the same thread can and will be reused for processing another, concurrent, HTTP request(s). This isn't revolutionary, at least for people who worked with NIO before.
Anyway, this leads to another important thing: no ThreadLocal variables as a temporary storage for the request data. Because if the same thread suddenly becomes the carrier thread to a different HTTP request, request-local data will be exposed to another request.
All of that is my pure speculation based on reading articles, I haven't got time to play with any Servlet 3 implementations (Tomcat 7, GlassFish 3.0.X, etc.).
So, the questions:
Am I correct to assume that ThreadLocal will cease to be a convenient hack to keep the request data?
Has anybody played with any of Servlet 3 implementations and tried using ThreadLocals to prove the above?
Apart from storing data inside HTTP Session, are there any other similar easy-to-reach hacks you could possibly advise?
EDIT: don't get me wrong. I completely understand the dangers and ThreadLocal being a hack. In fact, I always advise against using it in similar context. However, believe it or not, thread context has been used far more frequently than you probably imagine. A good example would be Spring's OpenSessionInViewFilter which, according to its Javadoc:
This filter makes Hibernate Sessions
available via the current thread,
which will be autodetected by
transaction managers.
This isn't strictly ThreadLocal (haven't checked the source) but already sounds alarming. I can think of more similar scenarios, and the abundance of web frameworks makes this much more likely.
Briefly speaking, many people have built their sand castles on top of this hack, with or without awareness. Therefore Stephen's answer is understandable but not quite what I'm after. I would like to get a confirmation whether anyone has actually tried and was able to reproduce failing behaviour so this question could be used as a reference point to others trapped by the same problem.
Async processing shouldn't bother you unless you explcitly ask for it.
For example, request can't be made async if servlet or any of filters in request's filter chain is not marked with <async-supported>true</async-supported>. Therefore, you can still use regular practices for regular requests.
Of couse, if you actually need async processing, you need to use appropriate practices. Basically, when request is processed asynchronously, its processing is broken into parts. These parts don't share thread-local state, however, you can still use thread-local state inside each of that parts, though you have to manage the state manually between the parts.
(Caveat: I've not read the Servlet 3 spec in detail, so I cannot say for sure that the spec says what you think it does. I'm just assuming that it does ...)
Am I correct to assume that ThreadLocal will cease to be a convenient hack to keep the request data?
Using ThreadLocal was always a poor approach, because you always ran the risk that information would leak when a worker thread finished one request and started on another one. Storing stuff as attributes in the ServletRequest object was always a better idea.
Now you've simply got another reason to do it the "right" way.
Has anybody played with any of Servlet 3 implementations and tried using ThreadLocals to prove the above?
That's not the right approach. It only tells you about the particular behaviour of a particular implementation under the particular circumstances of your test. You cannot generalize.
The correct approach is to assume that it will sometimes happen if the spec says it can ... and design your webapp to take account of it.
(Fear not! Apparently, in this case, this does not happen by default. Your webapp has to explicitly enable the async processing feature. If your code is infested with thread locals, you would be advised not to do this ...)
Apart from storing data inside HTTP Session, are there any other similar easy-to-reach hacks you could possibly advise.
Nope. The only right answer is storing request-specific data in the ServletRequest or ServletResponse object. Even storing it in the HTTP Session can be wrong, since there can be multiple requests active at the same time for a given session.
NOTE: Hacks follow. Use with caution, or really just don't use.
So long as you continue to understand which thread your code is executing in, there's no reason you can't use a ThreadLocal safely.
try {
tl.set(value);
doStuffUsingThreadLocal();
} finally {
tl.remove();
}
It's not as if your call stack is switched out randomly. Heck, if there are ThreadLocal values you want to set deep in the call stack and then use further out, you can hack that too:
public class Nasty {
static ThreadLocal<Set<ThreadLocal<?>>> cleanMe =
new ThreadLocal<Set<ThreadLocal<?>>>() {
protected Set<ThreadLocal<?>> initialValue() {
return new HashSet<ThreadLocal<?>>();
}
};
static void register(ThreadLocal<?> toClean) {
cleanMe.get().add(toClean);
}
static void cleanup() {
for(ThreadLocal<?> tl : toClean)
tl.remove();
toClean.clear();
}
}
Then you register your ThreadLocals as you set them, and cleanup in a finally clause somewhere. This is all shameful wankery that you shouldn't probably do. I'm sorry I wrote it but it's too late :/
I'm still wondering why people use the rotten javax.servlet API to actually implement their servlets. What I do:
I have a base class HttpRequestHandler which has private fields for request, response and a handle() method that can throw Exception plus some utility methods to get/set parameters, attributes, etc. I rarely need more than 5-10% of the servlet API, so this isn't as much work as it sounds.
In the servlet handler, I create an instance of this class and then forget about the servlet API.
I can extend this handler class and add all the fields and data that I need for the job. No huge parameter lists, no thread local hacking, no worries about concurrency.
I have a utility class for unit tests that creates a HttpRequestHandler with mock implementations of request and response. This way, I don't need a servlet environment to test my code.
This solves all my problems because I can get the DB session and other things in the init() method or I can insert a factory between the servlet and the real handler to do more complex things.
You are psychic ! (+1 for that)
My aim is ... to get a proof this has stopped working in Servlet 3.0 container
Here is the proof that you were asking for.
Incidentally, it is using the exact same OEMIV filter that you mentioned in your question and, guess what, it breaks Async servlet processing !
Edit: Here is another proof.
One solution is to not use ThreadLocal but rather use a singleton that contains a static array of the objects you want to make global. This object would contain a "threadName" field that you set. You first set the current thread's name (in doGet, doPost) to some random unique value (like a UUID), then store it as part of the object that contains the data you want stored in the singleton. Then whenever some part of your code needs to access the data, it simply goes through the array and checks for the object with the threadName that is currently running and retrieve the object. You'll need to add some cleanup code to remove the object from the array when the http request completes.