[muscle] Re: Patch for supporting NIO in Java client

  • From: Lior Okman <lior.okman@xxxxxxxxxxxxxxxxxxxxxxxx>
  • To: muscle@xxxxxxxxxxxxx
  • Date: Sat, 28 Jan 2006 20:17:26 +0200

Hi Jeremy,

MessageTransceiver2 is exactly the same as MessageTransceiver, except
that it uses NIO instead of the old I/O. The issue is that nio and old
IO don't mix well, so I thought it would be better to separate the two
driving classes completely. It is possible to reuse some parts of the
identical code. I'll probably do it later on, when I have more time on
my hands.

Regarding the backwards compatability, I'm afraid that is a bit more
difficult in the source code level, since the issue is that NIO doesn't
exist in Java prior to version 1.4.0. In order for the source to be
completely backwards compatible at compile time, it would have to not
use NIO in any way. Using reflection to get around direct references
would cause the code to be extremly ugly, and you still would need to
add a disclaimer to remove any classes that actually use the NIO code
prior to compilation on older environments, since at some point the code
must assume that NIO is available.

However, since Java 1.4.0 is extremely old, and has been replaced by
1.4.1, 1.4.2, and the current version 1.5.0 (aka 5.0), I don't really
think that requiring Java 1.4.0 is really of any consequence. If it
really is an issue, I suppose it would be possible to provide the NIO
code as a patch, and anybody that doesn't need it can un-apply the patch.

In addition, it is possible to compile the Java client with a 1.4.0 or
higher version of the Java compiler, in such a way as to allow older
JVMs to use the generated class files. This would work, as long as the
NIO code is not used at runtime in an older JRE.

Your compile command would be something like this:

lior:~/java/muscle/java$ javac -version
javac 1.5.0_06
javac: no source files
Usage: javac <options> <source files>
where possible options include:
<snipped some options>
  -source <release>          Provide source compatibility with specified
  -target <release>          Generate class files for specific VM version
<snipped some more options>

lior:~/java/muscle/java$ mkdir bin
lior:~/java/muscle/java$ javac -d bin -source 1.3 -target 1.3  `find .
-name \*.java`

The class files generated here will be usable for jdk version 1.3 and
up, as long as you don't use unsupported things like NIO in the 1.3 runtime.


Jeremy Friesner wrote:

>Hi Lior,
>Thanks for the patch -- is there any way to re-code it so that the Java
>classes will still run on earlier versions of Java?  It would be nice if we
>could add support for the newer APIs without having to give up compatibility 
>older systems.  Perhaps using a bit of Class.forName() and some exception
>handling to fall back to the old code if the new code won't run?
>Also it's not clear to me what the purpose of the MessageTransceiver2 class
>is -- does it do something that the regular MessageTransceiver class doesn't 
>It seems like an awful lot of code duplication that would make code maintenance
>more difficult in the future.
>>Attached is a patch that adds support to the Java client for using
>>java.nio instead of old-style i/o.
>>It removes the need for the LEDataOutputStream and LEDataInputStream
>>classes that are currently used, and it uses java.nio.ByteBuffer
>>instead, as well as SocketChannel, instead of Socket classes, both of
>>which should be good for performance.
>>I haven't removed the old classes, just added support for nio in the
>>relevant classes, as well as an extra class
>>"com/lcs/muscle/client/MessageTransceiver2.java" that uses ServerSocket
>>instead of Socket by default.
>>I've also fixed a bug in the NativeZLibMessageIOGateway class, and since
>>the JCraft classes are now distributed along with the MUSCLE classes,
>>I've fixed the AbstractMessageIOGateway class to use the JZLib enabled
>>class directly, instead of with reflection.
>>I'm also attaching an updated build.xml file that expects to find the
>>JZLib classes instead of the JZlib jar.
>>NIO support means that the MUSCLE java client code will require at least
>>Java 1.4.0 to compile.

Other related posts: