I’ve spent the day in a frustrating battle with JGroups trying to get it to create all its internal threads as Daemons, rather than user threads. For those that don’t know, when only Daemon threads are left active, the JVM will shutdown, which is precisely the behavior I required.
Unfortunately, getting JGroups to do this isn’t as easy as it really should be. It appears from traffic on their issue tracker that they’ve gone back on forth on the idea of making all threads Daemon by default or not. Suffice to say at this point in time, they default to user threads.
To save anyone else some pain in trying to figure out what is going on, I’ve included the code necessary to get JGroups using Daemon threads. It took me a while to figure it out, but I got there in the end. Further, if it wasn’t for the open source nature of JGroups I would not have been able to figure this out (or perhaps it would have taken much longer). Being able to trawl through source code really is a wonderful thing.
Anyway, here is the code. Remember to set both the ThreadFactory *AND* the ThreadPool. When JGroups creates its internal components on creation of a channel, it creates both the default factory and pool. However, when you set the factory, it doesn’t also set the pool, so if you only change the factory then the pool still has a link to the initial, default factory. I will submit a patch for this as it seems logical that any change to the factory should trigger a change to the pool as well.
JChannel channel = new JChannel(...); // create a thread factory that will use daemons DefaultThreadFactory factory = new DefaultThreadFactory( Util.getGlobalThreadGroup(), "Incoming", true, true ); // set the thread factory on the transport channel.getProtocolStack().getTransport().setThreadFactory( factory ); // set the thread pools on the transport LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(); Executor pool = new ThreadPoolExecutor( 2, 10, 5000, TimeUnit.MILLISECONDS, queue, factory ); channel.getProtocolStack().getTransport().setDefaultThreadPool( pool );
UPDATE: I’ve just checked out the latest code from CVS and this problem appears to be fixed there. I’m running version 2.6.3.GA. So if you are having this problem and using that version or earlier, the above code should help you. If you are using a later version, well, you shouldn’t be having this problemTags: java, jgroups