I am exposing some operations in a class in my Spring Boot application through JMX. However, in jConsole, when I invoke the method, "Method invoked successfully" pops up. I know that's because the method returns nothing. But I want to show useful information when method invoked.
I am using #ManagedOperation which is provided by Spring, but it has no such property. I couldn't find anything on the documentation, either.
I can notify the executor by sending a notification, but I wonder if there's any way of directly alerting information.
This is how it normally alerts.
Let me give an example. I have multiple containers that are running and I have provided an operation to stop and start them. When, for example, start is invoked, I want it to alert that "Container X has started" or "Container X is already running". I can do this, by returning these responses as string from the method, but I don't think this should be the way to go. I wonder if a way to do this exists through the API itself.
Hope, I'm clear.
That's not possible and you cannot change the jConsole behavior.
To your example:
If you have multiple outcomes of the invoked method it makes perfectly sense to return this as the message.
But maybe you should consider to expose these as HTTP endpoints where you can return an appropriate HTTP status code instead of a string.
Related
I have a AWS SQS listener that, when it receives a message, invokes the proper method to handle it. The problem is that it also waits for that method to return, and if it takes longer than the visibility timeout, we get the message again. Take this for instance:
if (FULL_LOAD.equalsIgnoreCase(msg.getLoadType())) {
//Create the controller and process the message
log.info("Process valid Full Load message from "+msg.getDataSourceName());
productRefService.fullRefresh(ctx);
jobCompletion(msg, jobStart, start);
}
// continue processing
So right now, before the listener can continue, it must wait for productRefService.fullRefresh to complete, which can be up to 15 minutes. It seems to me there should be a way to invoke the service method and continue, but I'm not sure how that would look. Make productRefService async?? Use the Callable interface? I'm not interested in the return value - I just want the listener freed up.
Per your request:
Good question! If you're on Java 8 or higher, consider
CompletableFuture:
Asynchronous Programming in Java
Guide To
CompletableFuture
A Java "CompletableFuture" is analogous to Javascript "Promises" or C#
"async/await". It's return value gives the caller something to "wait
on" (if it needs to).
From Javascript, I am calling a REST method which is computationally intensive. Would it be possible to stop that REST call, if you are no longer interested in what it returns.
I understand, it is possible to abort a request in JS. But it won't stop the thread which gets triggered due to the REST call. This is how I am aborting the ajax call in JS.
Abort Ajax requests using jQuery
The REST interface is written in Java. And internally this thread may create multiple threads also.
I would like to stop a Java thread. But from the caller. From JS, where I have triggered it.
How to properly stop the Thread in Java?
As Chris mentioned in the comments above, REST calls should be quick, definitely not an hour long. If the server needs to do a lot of work which takes considerably amount of time, you should modify your design to async. Either provide a callback that the server will use once it's done (also called push approach), or pull every few minutes, by sending a new request to the server to see if it's done.
In order to implement it you'll need the server to return a unique-id for each request in order to be able to identify in the callback/check-call what's the status of that specific request.
The unique-id should be implemented on the server-side in order to avoid two clients send the same ID - overriding each other.
In the link that I posted above you can see an example of how to implement a "stop thread" mechanism which can be implemented on the server-side and called by the client whenever is needed.
You could send a unique identifier along with your request, and then make another request that instructs the server to abort the operation started for that ID.
So the title says it all, what happens when during asynchronous invocation of a method performed by Java EE Container, there is a call to another method that is also annotated with #Asynchronous. I would expect that there will be one more asynchronous invocation. However the specification does not say anything about this, so could this also be Application sever vendor specific?
Currently I am analyzing the performance of a Java EE application that runs in Websphere. And I clearly see within the method tree that the second asynchronous method will actually be synchronously called. This actually makes sense for me, because we are already in some kind of asynchronous context, so instead of submitting new task we can just execute it right away..
Any idea about this?
This works. The second call will just post a request to execute that method to some internal queue that the AS maintains.
BUT... be very careful with waiting on the results from any Future that the second method might return. If the second method is a void method it's always safe.
Here's my scenario:
some email sending bean gets called with a bunch of parameters needed for mail construction.
it creates MultiPartEmail and queues it for sending which is done by separate thread on the background, caller doesn't care if it was sent or not.
the delivering thread picks up queued email instance and does email.send() - so off it goes.
when delivery fails, the bean will try re-sending the mail every 5 minutes for three times and then give up.
Question:
I can't figure out how to handle #4. What I've got at hand is previously constructed MultiPartEmail instance which failed to be sent. Apparently doing email.send() again throws this:
java.lang.IllegalStateException: The MimeMessage is already built.
Is there a way to reset this illegal state so that message can be re-used. I don't really have means of creating new instance from scratch - the caller is long gone, and it will make the whole mechanism quite ugly without being able to use already built object. I think I'm missing something very simple here..
I see this is an old question, but I just hit the same problem and I found the solution.
When you create an instance of MultiPartEmail (or HtmlEmail), set its properties, and then invoke the send() method, the object will internally invoke the following methods:
buildMimeMessage()
sendMimeMessage()
It is ok to invoke sendMimeMessage() multiple times, such as a send-with-retry scenario. The problem is that buildMimeMessage() can only be invoked once. When you rely on the send() method of the base Email class, you get the exception found by the original poster.
The solution is to use the two methods I just mentioned when your Email object is a MultiPartEmail. You explicitly invoke buildMimeMessage() once, then invoke sendMimeMessage() one or more times.
Is there any way to check if an async ServletRequest is completed from an AsyncContext? I saw that spring has some kind of wrapper that supports this but googling around I couldn't find anything in the standard library. That is what I was hoping for.
I am using Tomcat 7.
Sounds like one of the two - you either need a listener that will be called upon a asynchronous request completion or you don't need to use an asynchronous call.
Your question is a bit too general.
Talking generally - asynchronous calls are used when the caller is not interested in immediate result of the call.
If the caller is interested to know the result of the call immediately then synchronous calls should be used.
If the caller is not interested to know the result immediately (for example it has secondary priority, like logging in some business applications), but some action should be performed upon the end of execution of asynchronous calls you should use some sort of a listener.
What you need for asynchronous call is some listener (of class javax.servlet.AsyncListener).
In the listener you will know for sure that the asynchronous call is over (onComplete method) and may perform some action to finalize/complement the asynchronous call.
Again, if you see that the caller of the request needs to know the result upon completion immediately, there probably is a mistake in your architecture. You should use a synchronous call - just wait until the call is done and you will have the result of it. Using an asynchronous call is wrong in this situation.
I saw how people use some sort of a loop to check from time to time the result of a asynchronous call, but it looks like in 99.99% of cases such approach is the result of some architectural mistake.
You can register AsyncListener which can implement onComplete() method.
The AsyncListener needs to be added to the AsyncContext.