powered by Jive Software

Smack multi-thread in "single threaded" execution JVM


I’m trying to run Smack in an Oracle Database environment i.e. “within” the Oracle Database. I realise this is not perhaps usual for Smack, but I’m trying to get our Oracle based application able to communicate into MUC rooms directly. This is using (and pssibly adding to) http://oracle-xmpp.sourceforge.net/

I have found a few issues in this, and thought it worth advising on one of these - as Smack API developers may want to consider.

Having looked at the code, I can see that Smack is multi-threaded. When I run within Oracle database I find I can successfully connect, and issue send message commands, but the messages only get delivered when I disconnect the session - they get buffered/queued.

Oracle Database JVM support is, according to oracle docs:

“…single-threaded at the execution level. In this model, JVM runs all Java threads associated with a database session on a single operating system thread. Once dispatched, a thread continues execution until it explicitly yields by calling Thread.yield(), blocks by calling Socket.read(),or is preempted by the execution engine. Once a thread yields, blocks or is preempted, JVM dispatches another thread”

I have managed to get (in a short test) messages to be sent correctly when the command is issued. This I did by adding a few “Thread.yield()” calls into XMPPConnection.sendPacket() and PacketWriter.writePacket() and PacketWriter.KeepAliveTask.run(). This works, but I confess I don’t know if this is a complete or correct change.

My suspicion is any use of sleep() in this environment may not be quite what is expected i.e. if a thread does yield() just before a sleep() - it will allow other threads to get in, but once it regains control, and dives straight into the sleep, it will hold onto control for the period of that sleep - thus denying others. It may be that performing a read() on a dummy socket with a timeout (say) may be a more “friendly” way of achieving this in this environment. I notice there are six places in Smack where Thread.sleep() is used.

I fully appreciate that Smack has been written for more “normal” Java environments, but thought this may be interest.