How does async JMS work? I've below sample code:
public class JmsAdapter implements MessageListener, ExceptionListener
{
private ConnectionFactory connFactory = null;
private Connection conn = null;
private Session session = null;
public void receiveMessages()
{
try
{
this.session = this.conn.createSession(true, Session.SESSION_TRANSACTED);
this.conn.setExceptionListener(this);
Destination destination = this.session.createQueue("SOME_QUEUE_NAME");
this.consumer = this.session.createConsumer(destination);
this.consumer.setMessageListener(this);
this.conn.start();
}
catch (JMSException e)
{
//Handle JMS Exceptions Here
}
}
#Override
public void onMessage(Message message)
{
try
{
//Do Message Processing Here
//Message sucessfully processed... Go ahead and commit the transaction.
this.session.commit();
}
catch(SomeApplicationException e)
{
//Message processing failed.
//Do whatever you need to do here for the exception.
//NOTE: You may need to check the redelivery count of this message first
//and just commit it after it fails a predefined number of times (Make sure you
//store it somewhere if you don't want to lose it). This way you're process isn't
//handling the same failed message over and over again.
this.session.rollback()
}
}
}
But I'm new to Java & JMS. I'll probably consume messages in onMessage method. But I don't know how does it work exactly.
Do I need to add main method in JmsAdapter class? After adding main method, do I need to create a jar & then run the jar as "java -jar abc.jar"?
Any help is much appreciated.
UPDATE: What I want to know is that if I add main method, should I simply call receiveMessages() in main? And then after running, will the listener keep on running? And if there are messages, will it retrieve automatically in onMessage method?
Also, if the listener is continuously listening, doesn't it take CPU??? In case of threads, when we create a thread & put it in sleep, the CPU utilization is zero, how doe it work in case of listener?
Note: I've only Tomcat server & I'll not be using any jms server. I'm not sure if listener needs any specific jms server such as JBoss? But in any case, please assume that I'll not be having anything except tomcat.
Thanks!
You need to learn to walk before you start trying to run.
Read / do a tutorial on Java programming. This should explain (among other things) how to compile and run a Java program from the command line.
Read / do a tutorial on JMS.
Read the Oracle material on how to create an executable JAR file.
Figure out what it is you are trying to do ... and design your application.
Looking at what you've shown and told us:
You could add a main method to that class, but to make an executable JAR file, you've got to create your JAR file with a manifest entry that specifies the name of the class with the main method.
There's a lot more that you have to do before that code will work:
add code to (at least) log the exceptions that you are catching
add code to process the messages
add code to initialize the connection factory and connection objects
And like I said above, you probably need some kind of design ... so that you don't end up with everything in a "kitchen sink" class.
if I add main method, should I simply call receiveMessages() in main?
That is one approach. But like I said, you really need to design your application.
And then after running, will the listener keep on running?
It is not entirely clear. It should keep running as long as the main thread is alive, but it is not immediately obvious what happens when your main method returns. (It depends on whether the JMS threads are created as daemon threads, and that's not specified.)
And if there are messages, will it retrieve automatically in onMessage method?
It would appear that each message is retrieved (read from the socket) before your onMessage method is called.
Also, if the listener is continuously listening, doesn't it take CPU???
Not if it is implemented properly.
In case of threads, when we create a thread & put it in sleep, the CPU utilization is zero, how doe it work in case of listener?
At a certain level, a listener thread will make a system call that waits for data to arrive on a network socket. I don't know how it is exactly implemented, but this could be as simple as an read() call on the network socket's InoutStream. No CPU is used by a thread while it waits in a blocking system call.
This link looks like a pretty good place with examples using Oracle AQ. There's an examples section that tells you how to setup the examples and run them. Hopefully this can help.
Link to Oracle Advanced Queueing
Related
I am trying to diagnose a problem I am having using WSO2 identity management.
package org.wso2.carbon.identity.mgt;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* email sender this creates a new task in thread pool for each email sending request
*/
public class NotificationSender {
private static ExecutorService threadPool = Executors.newFixedThreadPool(5);
NotificationSendingModule module;
/**
* creates and submits a task to the thread pool
*
* #param module email sending module as task
*/
public void sendNotification(NotificationSendingModule module) {
threadPool.submit(module);
}
public NotificationSendingModule getModule() {
return module;
}
}
I am load testing the user creation process, and at the point where WSO2 sends a User credentials configuration mail it is sending multiple to the same email address even though they are unique.
I have never used Java but am familiar with C#, so have been able to read through the code without issue, and my questions is:
In the Java docs it mentions "If a thread terminates due to failure during execution and prior to shutdown, a new thread is created to take its place."
Does this mean that if the email send encounters an error then a new thread will begin the process again?
I'm thinking perhaps the send email is erroring so a new thread is created, but the logging with isn't tied into a result is performed anyway.
Also, is it ok to never call
threadPool.shutdown()
When a thread that is part of a thread pool throws an exception it is indeed replaced with a new fresh thread. However it will not retry the same operation. The replacement only occurs so the thread pool can continue do its work when more tasks needs to be executed.
Normally when a thread is terminated in such a fashion, a stack trace is logged, but it is possible the exception is swallowed somewhere. You could try adding a try-catch block around the sending code and logging any exception explicitly to analyze the problem further.
Not calling shutdown is fine.
I am load testing the user creation process, and at the point where WSO2 sends a User credentials configuration mail it is sending multiple to the same email address even though they are unique.
Well, when I hear a Java framework/app server doing identity management + thread pools + strange behavior, what immediatly comes to mind is that most frameworks use a thread per user model (that is : the user identity is tied to the thread. if you switch threads, the user authentication data is lost). Now I do not know if that is the case with SO2, but refer to the documentation. It is the "usual suspect" : thread local authentication mechanisms are everywhere.
In the Java docs it mentions "If a thread terminates due to failure during execution and prior to shutdown, a new thread is created to take its place."
Does this mean that if the email send encounters an error then a new thread will begin the process again?
No. It means that a new thread will be created to handle other unit of works as they are / have been submitted. But the failed unit of work will not be attempted again. As far as the thread pool is concerned, the task completed (with an exception), and it is done with it.
Also, is it ok to never call threadPool.shutdown()
It is not. You should either make your NotificationSender class have a close() or end() method of some sort. Or maybe tie it with some of WSO2 lifecycle callbacks (e.g. in a servlet context, you have listeners for lifecycle events, in a Spring container, you have other create/destroy callbacks, ... whatever works in your context). Failure to shut down a thread pool implies that some threads will hang around, and their resources never freed. Threads are coming pretty cheap nowadays, but they may still pile up and bit you in the long run. It may only be kind of ok if you are sure you only create one NotificationSender in your whole app, and that the lifecycle of this object is the same as your app. Then, essentially, shutting it down is the same as shutting the app down and so nothing bad really happens.
I have a question for you.
I have multiple Threads runnings of a class called ServerThread. When an specific event happens on ANY of those threads, I want to call a method of every other thread running in parallel.
public class ServerThread implements Runnable {
private TCPsocket clientSocket;
public ServerThread(Socket comSocket){
clientSocket = new TCPsocket(comSocket);
}
#Override
public void run(){
boolean waiting = true;
Message msg;
try{
while(waiting){
msg = clientSocket.getMessage();
shareMessage(msg);
}
}catch(Exception e){
ErrorLogger.toFile("EndConnection", e.toString());
}
}
public void shareMessage(Message msg){
clientSocket.sendMessage(msg);
}
}
I am talking about this specific line
shareMessage(msg);
which I would like to be called on every thread/instance
-- so that a message is sent to every client (in all tcp connections)
I've tried with synchronized but either I'm not using it well or that is not what I am looking for.
Another thing that might work is keeping a class with an static member which is a list of those tcpconnection objects and then do some loop in all every time.
Thanks for your help and time.
Edited with one possible solution
*Add an static array as a member of the class and add/remove objects of same class (or tcp sockets would also work)
private static ArrayList<ServerThread> handler;
...
handler.add(this);
...
handler.remove(this); //when client exists and thread stops
*Then create a method that iterates for each connection, and make it synchronized so that two threads won't interact at the same time. You may want to implement synchronized on your message sending methods as well.
public void shareMessage(Message msg){
//this.clientSocket.sendMessage(msg);
synchronized (handler){
for(ServerThread connection: handler){
try{
connection.clientSocket.sendMessage(msg);
} catch(Exception e){
connection.clientSocket.closeConnection();
}
}
}
}
First: synchronized is required to prevent race conditions when multiple threads want to call the same method and this method accesses/modifies shared data. So maybe (probably) you will need it somewhere but it does not provide you the functionality you require.
Second: You cannot command an other thread to call a method directly. It is not possible e.g. for ThreadA to call methodX in ThreadB.
I guess you have one thread per client. Probably each thread will block at clientSocket.getMessage() until the client sends a message. I don't know the implementation of TCPsocket but maybe it is possible to interrupt the thread. In this case you may need to catch a InterruptedException and ask some central data structure if the interrupt was caused because of a new shared message and to return the shared message.
Maybe it is also possible for TCPsocket.getMessage() to return, if no message was received for some time, in which case you would again have to ask a central data structure if there is a new shared message.
Maybe it is also possible to store all client connections in such a data structure and loop them every time, as you suggested. But keep in mind that the client might send a message at any time, maybe even at the exact same time when you try to send it the shared message received from another client. This might be no problem but this depends on your application. Also you have to consider that the message will also be shared with the client that sent it to your server in the first place…
Also take a look at java.util.concurrent and its subpackages, it is likely you find something useful there… ;-)
To summarize: There are many possibilities. Which one is the best depends on what you need. Please add some more detail to your question if you need more specific help.
After executing this line:
WifiManager man = ((WifiManager) ctx.getSystemService(Context.WIFI_SERVICE));
A thread labeled "WifiManager" will show up. In the Java source file for WifiService.java line 203:
HandlerThread wifiThread = new HandlerThread("WifiService");
wifiThread.start();
mWifiHandler = new WifiHandler(wifiThread.getLooper());
Problem is, every time our app is closed and reopened it creates a new thread, run it 5 times and you have 5 threads. Not sure if there is anyway to stop it?
EDIT
Changed to getApplicationContext to make sure the context it was accessing was consistent and all was well. I still get a thread labeled "WifiService," but I only get one thread over multiple runs.
I believe you are creating a new WifiManager in your started/stopped (Context) Activity.
A note from Context.getSystemService()
Note: System services obtained via this API may be closely associated with the Context in which they are obtained from. ...
Also from ContextImpl.java:1478 and :227
#Override
public Object getSystemService(String name) {
ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
return fetcher == null ? null : fetcher.getService(this);
}
...
service = cache.get(mContextCacheIndex);
if (service != null) {
return service;
}
...
It uses a map to cache system services, so I believe if you use the same context like Application, you wouldn't run into this problem. I am not sure if this is the right way of solving this problem however, if having threads laying around a bigger issue for you, it may worth while.
When you get the instance of a system service using Context.getSystemService(), you are not calling the constructor of the service. Instead, you are actually getting an instance of the service using IBinder so as to do a remote procedure call on it. So the constructor of WiFiService.java will not be called every time you get an instance of it. Where exactly are you seeing this thread pop up?
I hope your application is the only application which is accessing WifiManager. Please check at the same time with some dummy application which access WifiManager; in that case it should not create a new thread.
When creating a standalone server in Java (not using a container like tomcat/jetty), what are the various techniques to keep the service running and not ending?
I have seen where people use a ServerSocket (since you will be communicating with the service presumably), and they use ServerSocket.accept() which blocks until it receives a message. And this is usually done in a while loop:
while(...) {
serverSocket.accept();
}
(http://docs.oracle.com/javase/6/docs/api/java/net/ServerSocket.html#accept())
Is this the only way? If not, what other ways are there and any pros/cons with it?
Are there any libraries that help with building your own service, or its pretty much roll your own.
There are various libraries that help you roll your own Windows/Unix service in Java:
Apache Commons Daemon
Akuma
Java Service Wrapper
How you keep the application running depends on the actual needs of your application. If your application is a server, you would normally want to listen for incoming connections which usually involves some sort of blocking/polling. How you do that again depends on the type of server you want to build. Of the generic solutions there's the ServerSocket class and its method accept() that you already mentioned. Another possibility is to use java.nio and implement a reactor which provides a single-threaded server that can handle multiple connections at once (see http://gee.cs.oswego.edu/dl/cpjslides/nio.pdf for details), but may be a bit hard to grasp and debug.
What you probably want is a multi-threaded server.
Each time the server accepts a connection, the server creates a thread to handle sending/reciving to that client. If you do not use threads in your server, it will only be able to handle one connection at a time.
So, as you meantioned, the server loops infinitly and listens for incomming connections:
while(true){
serverSocket.accept();
ClientHandler c = new ClientHandler(serverSocket);
A instance of the class ClientHandler will be created each time a connection is accepted. This class implements Runnable, and loops for incomming messages using getInputStream and getOutputStream on that socket:
public class ClientHandler implements Runnable{
DataInputStream in;
DataOutputStream out;
//ClientHandler constructor
public ClientHandler(Socket s) throws IOException{
in= new DataInputStream(socket.getInputStream());
out=new DataOutputStream(socket.getOutputStream());
thread.start();
}
The run method:
public void run() {
while(true){
String temp="";
while ((temp = (String) in.readUTF()) != null){ // Read from the input stream each iteration. When temp is not null a message is recived
System.out.println(temp);
Please that the above code does not take into account different exceptions that might occur and is very basic. But it should give you a basic idea on how a server using Sockets can be implemented.
For a quick solution (in a testing environment only!) you can go for something often dubbed as "Enterprise Loop" (because it is too often found in production systems):
while (true)
try {
// do something
} catch (Throwable t) {
// maybe log
}
However, this is not good style in the production code.
(see [1] for a parody of that idiom)
To create a service, you want one of the libraries from this answer.
If you "just need multithreading", have a look into the Java concurrency framework. I stronly suggest reading Java Concurrency in Practice, as multi-threading is much more that just starting another thread and errors are hard to debug.
[1] http://blog.antiblau.de/2016/01/26/java-enterprise-loop/
I hava an app on JSF where I upload a file. Very basic. The question is, is there a way to launch (or keep executing) another java program when I reach the last page of my app? That is:
UploadFile.xhtml -> receiveFile.java -> Thanks.xhtml (user will close this the browser) -> another program make some processing on the recently uploaded file (even if user shutsdown the PC)
I thought using a daemon program that keeps checking if a new file arrived, but I want to know if there's a way to keep executing things even if the user closes the browser.
Thanks.
Certainly the best way to do this is to have a scheduler that will look for certain files every x time interval and do something with it within a thread.
Advice, make sure you shut down the scheduler on context unload. Here is an example on how to use a SchedulerService.
You would want to do something like in a context listener.
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
Runnable handler = new Runnable() {
public void run() {
// handle file
}
};
scheduler.scheduleAtFixedRate(handler, 10, 10, SECONDS);
Firstly, after receiving file from client, even when client had closed their browser, file is now on the server, and you can process it free (not depend on client now) :-D
As your question, you want to launch something right after page closed. How about using annotation #PreDestroy or #PostContructor with bean scope #ViewScoped in JSF?
(in my mind, you can do this right after receiving file uploaded from client)
A reliable way to implement this would be is to have some form of meta data saved in the database after the file upload is done.
And a separate listener like Quartz to read the meta data periodically and do the post processing.
The same metadata can contain more status flags for that meta data to avoid conflicts during file processing.
Again this would depend upon the complexity of your rrquirements.