Using the SCTP API from OpenJDK with Sun's JDK6.

WARNING: The suggestion below and instructions of how to have the SCTP implementation run with Sun's JDK6 are unsupported. The implementation uses Sun proprietary APIs that may be removed or changed in the future (albeit unlikely at this point in the 1.6 lifecycle). Also, Sun's JDK6 is built with RHAS 2.1A and an old gcc. JDK7 is built with Fedora 9 and a more modern gcc. Everything should work (in theory) but there are bound to to be older Linux distributions where Sun's JDK6 works but libsctp will not work.

Outline of the procedure

  1. Take the java source code for the API and implementation from OpenJDK
  2. Make 2 minor edits to remove 1.7 specific APIs
  3. Compile with javac from Sun's JDK6
  4. Create a jar containing the built 1.6 version
  5. Copy the native library from OpenJDK to your "special" Sun JDK6 binary
  6. Run this "special" JDK6 java with the scpt6.jar appended to the bootclasspath

Example

  1. Take source from the latest tl jdk repository (once it includes the changes for 6915313, which has been integrated). In this example /repos/tl/sctpJDK6 is a cloned tl jdk repository.
        mkdir -p sctpOnly/jdk/src/solaris/classes/sun/nio/ch
        mkdir -p sctpOnly/jdk/src/share/classes/sun/nio/ch
        mkdir -p sctpOnly/jdk/src/share/classes/com/sun/nio/sctp
    
        pushd sctpOnly/jdk/src/solaris/classes/sun/nio/ch
        cp -r /repos/tl/sctpJDK6/src/solaris/classes/sun/nio/ch/Sctp* .
        popd
        pushd sctpOnly/jdk/src/share/classes/sun/nio/ch
        cp /repos/tl/sctpJDK6/src/share/classes/sun/nio/ch/Sctp* .
        popd
        pushd sctpOnly/jdk/src/share/classes/com/sun/nio/sctp
        cp /repos/tl/sctpJDK6/src/share/classes/com/sun/nio/sctp/* .
        popd
    Now you have the complete java source code.
  2. Two minor edits to the java source are necessary to remove 1.7 dependencies
    • SocketOption is a new interface in 1.7, SctpSocketOption extends this interface and is used to get/set SCTP specific socket options. The change here is to define the SocketOption interface methods directly in SctpSocketOption.
          vi sctpOnly/jdk/src/share/classes/com/sun/nio/sctp/SctpSocketOption.java
          diffs:
          27d26
          < import java.net.SocketOption;
          38c37,40
          < public interface SctpSocketOption<T> extends SocketOption<T> { }
          ---
          > public interface SctpSocketOption<T> {
          >     String name();
          >     Class<T> type();
          > }
                      
    • AlreadyBoundException is a new Exception in 1.7. Throwing IllegalStateException should be sufficient in most cases, unless special handling is required in the situation where an address is already bound. In which case the implementation can determine this from the exception message, "Already Bound".
          vi sctpOnly/jdk/src/solaris/classes/sun/nio/ch/SctpNet.java
          diffs:
          32d31
          < import java.nio.channels.AlreadyBoundException;
          57c56
          <         throw new AlreadyBoundException();
          ---
          >         throw new IllegalStateException("Already Bound");
                      
  3. Compile with javac from Sun's JDK6
        mkdir jdk6classes
        jdk6u17/bin/javac
            -d jdk6classes
            -sourcepath sctpOnly/jdk/src/share/classes:sctpOnly/jdk/src/solaris/classes
            sctpOnly/jdk/src/share/classes/com/sun/nio/sctp/*.java 
  4. Create a jar containing the built 1.6 version, sctp6.jar
        cd jdk6classes
        jar -cvf sctp6.jar com sun 
  5. Copy the native library from OpenJDK to your "special" Sun JDK6 binary. Subsitiute amd below for your platform architecture, e.g. sparc, i386.
        cp jdk7/jre/lib/amd64/libsctp.so jdk6/jre/lib/amd64/

    Until the changes for 6915313 are promoted, estimated for b80, you cannot directly take the libsctp.so from any JDK7. You should use the following libraries:

    Note: This a temporary solution until the next promotion of JDK7.

  6. Run this "special" JDK6 java with the scpt6.jar appended to the bootclasspath. You have two options here:
    • Patch the JDK6 with the sctp classes so that you can always access it without any extra command line arguments. You also need to add 'com/sun/nio' to the meta index (list of packages) in rt.jar
          cd jdk6classes
          jar -uvf JDK6/jre/lib/rt.jar com sun
      
          vi JDK6/jre/lib/meta-index
              ! rt.jar
              com/sun/java/util/jar/pack/
              java/
              org/ietf/
              com/sun/beans/
              com/sun/java/browser/
              com/sun/corba/
              com/sun/media/
              com/sun/awt/
              com/sun/management/
            + com/sun/nio/
              sun/
              com/sun/jmx/
              com/sun/demo/ 
      To compile your source you can either use the javac from JDK7 with -source 1.6 -target 1.6, or run the javac from your patched JDK6 with -XDignore.symbol.file=true. This flag is necessary because javac uses a symbol file to determine packages in the com/sun namespace and will not recognize the new sctp classes as they are not in this symbol file.
    • Keep your JDK6 install relatively clean by appending the sctp classes to the boot classpath.
          JDK6/bin/javac -Xbootclasspath/a:jdk6classes/sctp6.jar TestSCTP.java
          JDK6/bin/java -Xbootclasspath/a:jdk6classes/sctp6.jar TestSCTP
                      

Running a simple SCTP application

To ensure that you have a correctly compiled and configured your "special" JDK6 compile and run this simple example.

    public class TestSCTP
    {
        public static void main(String[] args) throws Exception {
            com.sun.nio.sctp.SctpChannel sc = com.sun.nio.sctp.SctpChannel.open();
        }
    }

If it compiles and runs without any errors, then congratulations you have been successfully. You can now start running your SCTP applications with JDK6.