Merge jdk8-b15
authorlana
Mon, 28 Nov 2011 15:15:50 -0800
changeset 48013c248d0e2c48
parent 4768 bdb2d63c176c
parent 4800 855675a4235b
child 4802 929597c6e777
child 4803 23acf34c80b0
child 4824 4b416a0180dc
child 4837 c5313d712ab0
Merge
test/java/io/FileDescriptor/FileChannelFDTest.java
test/java/io/etc/FileDescriptorSharing.java
     1.1 --- a/make/docs/Makefile	Fri Nov 18 16:57:01 2011 -0800
     1.2 +++ b/make/docs/Makefile	Mon Nov 28 15:15:50 2011 -0800
     1.3 @@ -71,7 +71,7 @@
     1.4  ifeq ($(ARCH_DATA_MODEL),64)
     1.5    MAX_VM_MEMORY = 1024
     1.6  else
     1.7 -  MAX_VM_MEMORY = 512
     1.8 +  MAX_VM_MEMORY = 612
     1.9  endif
    1.10  
    1.11  # List of all possible directories for javadoc to look for sources
     2.1 --- a/src/share/classes/java/io/FileInputStream.java	Fri Nov 18 16:57:01 2011 -0800
     2.2 +++ b/src/share/classes/java/io/FileInputStream.java	Mon Nov 28 15:15:50 2011 -0800
     2.3 @@ -124,7 +124,7 @@
     2.4              throw new NullPointerException();
     2.5          }
     2.6          fd = new FileDescriptor();
     2.7 -        fd.incrementAndGetUseCount();
     2.8 +        fd.attach(this);
     2.9          open(name);
    2.10      }
    2.11  
    2.12 @@ -164,10 +164,9 @@
    2.13  
    2.14          /*
    2.15           * FileDescriptor is being shared by streams.
    2.16 -         * Ensure that it's GC'ed only when all the streams/channels are done
    2.17 -         * using it.
    2.18 +         * Register this stream with FileDescriptor tracker.
    2.19           */
    2.20 -        fd.incrementAndGetUseCount();
    2.21 +        fd.attach(this);
    2.22      }
    2.23  
    2.24      /**
    2.25 @@ -294,27 +293,14 @@
    2.26              closed = true;
    2.27          }
    2.28          if (channel != null) {
    2.29 -            /*
    2.30 -             * Decrement the FD use count associated with the channel
    2.31 -             * The use count is incremented whenever a new channel
    2.32 -             * is obtained from this stream.
    2.33 -             */
    2.34 -           fd.decrementAndGetUseCount();
    2.35             channel.close();
    2.36          }
    2.37  
    2.38 -        /*
    2.39 -         * Decrement the FD use count associated with this stream
    2.40 -         */
    2.41 -        int useCount = fd.decrementAndGetUseCount();
    2.42 -
    2.43 -        /*
    2.44 -         * If FileDescriptor is still in use by another stream, we
    2.45 -         * will not close it.
    2.46 -         */
    2.47 -        if (useCount <= 0) {
    2.48 -            close0();
    2.49 -        }
    2.50 +        fd.closeAll(new Closeable() {
    2.51 +            public void close() throws IOException {
    2.52 +               close0();
    2.53 +           }
    2.54 +        });
    2.55      }
    2.56  
    2.57      /**
    2.58 @@ -328,7 +314,9 @@
    2.59       * @see        java.io.FileDescriptor
    2.60       */
    2.61      public final FileDescriptor getFD() throws IOException {
    2.62 -        if (fd != null) return fd;
    2.63 +        if (fd != null) {
    2.64 +            return fd;
    2.65 +        }
    2.66          throw new IOException();
    2.67      }
    2.68  
    2.69 @@ -352,13 +340,6 @@
    2.70          synchronized (this) {
    2.71              if (channel == null) {
    2.72                  channel = FileChannelImpl.open(fd, true, false, this);
    2.73 -
    2.74 -                /*
    2.75 -                 * Increment fd's use count. Invoking the channel's close()
    2.76 -                 * method will result in decrementing the use count set for
    2.77 -                 * the channel.
    2.78 -                 */
    2.79 -                fd.incrementAndGetUseCount();
    2.80              }
    2.81              return channel;
    2.82          }
    2.83 @@ -381,7 +362,12 @@
    2.84       */
    2.85      protected void finalize() throws IOException {
    2.86          if ((fd != null) &&  (fd != FileDescriptor.in)) {
    2.87 -                close();
    2.88 +            /* if fd is shared, the references in FileDescriptor
    2.89 +             * will ensure that finalizer is only called when
    2.90 +             * safe to do so. All references using the fd have
    2.91 +             * become unreachable. We can call close()
    2.92 +             */
    2.93 +            close();
    2.94          }
    2.95      }
    2.96  }
     3.1 --- a/src/share/classes/java/io/FileOutputStream.java	Fri Nov 18 16:57:01 2011 -0800
     3.2 +++ b/src/share/classes/java/io/FileOutputStream.java	Mon Nov 28 15:15:50 2011 -0800
     3.3 @@ -197,9 +197,9 @@
     3.4              throw new NullPointerException();
     3.5          }
     3.6          this.fd = new FileDescriptor();
     3.7 +        fd.attach(this);
     3.8          this.append = append;
     3.9  
    3.10 -        fd.incrementAndGetUseCount();
    3.11          open(name, append);
    3.12      }
    3.13  
    3.14 @@ -237,12 +237,7 @@
    3.15          this.fd = fdObj;
    3.16          this.append = false;
    3.17  
    3.18 -        /*
    3.19 -         * FileDescriptor is being shared by streams.
    3.20 -         * Ensure that it's GC'ed only when all the streams/channels are done
    3.21 -         * using it.
    3.22 -         */
    3.23 -        fd.incrementAndGetUseCount();
    3.24 +        fd.attach(this);
    3.25      }
    3.26  
    3.27      /**
    3.28 @@ -331,27 +326,14 @@
    3.29          }
    3.30  
    3.31          if (channel != null) {
    3.32 -            /*
    3.33 -             * Decrement FD use count associated with the channel
    3.34 -             * The use count is incremented whenever a new channel
    3.35 -             * is obtained from this stream.
    3.36 -             */
    3.37 -            fd.decrementAndGetUseCount();
    3.38              channel.close();
    3.39          }
    3.40  
    3.41 -        /*
    3.42 -         * Decrement FD use count associated with this stream
    3.43 -         */
    3.44 -        int useCount = fd.decrementAndGetUseCount();
    3.45 -
    3.46 -        /*
    3.47 -         * If FileDescriptor is still in use by another stream, we
    3.48 -         * will not close it.
    3.49 -         */
    3.50 -        if (useCount <= 0) {
    3.51 -            close0();
    3.52 -        }
    3.53 +        fd.closeAll(new Closeable() {
    3.54 +            public void close() throws IOException {
    3.55 +               close0();
    3.56 +           }
    3.57 +        });
    3.58      }
    3.59  
    3.60      /**
    3.61 @@ -365,7 +347,9 @@
    3.62       * @see        java.io.FileDescriptor
    3.63       */
    3.64       public final FileDescriptor getFD()  throws IOException {
    3.65 -        if (fd != null) return fd;
    3.66 +        if (fd != null) {
    3.67 +            return fd;
    3.68 +        }
    3.69          throw new IOException();
    3.70       }
    3.71  
    3.72 @@ -390,13 +374,6 @@
    3.73          synchronized (this) {
    3.74              if (channel == null) {
    3.75                  channel = FileChannelImpl.open(fd, false, true, append, this);
    3.76 -
    3.77 -                /*
    3.78 -                 * Increment fd's use count. Invoking the channel's close()
    3.79 -                 * method will result in decrementing the use count set for
    3.80 -                 * the channel.
    3.81 -                 */
    3.82 -                fd.incrementAndGetUseCount();
    3.83              }
    3.84              return channel;
    3.85          }
    3.86 @@ -415,7 +392,12 @@
    3.87              if (fd == FileDescriptor.out || fd == FileDescriptor.err) {
    3.88                  flush();
    3.89              } else {
    3.90 -                    close();
    3.91 +                /* if fd is shared, the references in FileDescriptor
    3.92 +                 * will ensure that finalizer is only called when
    3.93 +                 * safe to do so. All references using the fd have
    3.94 +                 * become unreachable. We can call close()
    3.95 +                 */
    3.96 +                close();
    3.97              }
    3.98          }
    3.99      }
     4.1 --- a/src/share/classes/java/io/RandomAccessFile.java	Fri Nov 18 16:57:01 2011 -0800
     4.2 +++ b/src/share/classes/java/io/RandomAccessFile.java	Mon Nov 28 15:15:50 2011 -0800
     4.3 @@ -229,7 +229,7 @@
     4.4              throw new NullPointerException();
     4.5          }
     4.6          fd = new FileDescriptor();
     4.7 -        fd.incrementAndGetUseCount();
     4.8 +        fd.attach(this);
     4.9          open(name, imode);
    4.10      }
    4.11  
    4.12 @@ -242,7 +242,9 @@
    4.13       * @see        java.io.FileDescriptor
    4.14       */
    4.15      public final FileDescriptor getFD() throws IOException {
    4.16 -        if (fd != null) return fd;
    4.17 +        if (fd != null) {
    4.18 +            return fd;
    4.19 +        }
    4.20          throw new IOException();
    4.21      }
    4.22  
    4.23 @@ -268,17 +270,6 @@
    4.24          synchronized (this) {
    4.25              if (channel == null) {
    4.26                  channel = FileChannelImpl.open(fd, true, rw, this);
    4.27 -
    4.28 -                /*
    4.29 -                 * FileDescriptor could be shared by FileInputStream or
    4.30 -                 * FileOutputStream.
    4.31 -                 * Ensure that FD is GC'ed only when all the streams/channels
    4.32 -                 * are done using it.
    4.33 -                 * Increment fd's use count. Invoking the channel's close()
    4.34 -                 * method will result in decrementing the use count set for
    4.35 -                 * the channel.
    4.36 -                 */
    4.37 -                fd.incrementAndGetUseCount();
    4.38              }
    4.39              return channel;
    4.40          }
    4.41 @@ -577,28 +568,14 @@
    4.42              closed = true;
    4.43          }
    4.44          if (channel != null) {
    4.45 -            /*
    4.46 -             * Decrement FD use count associated with the channel. The FD use
    4.47 -             * count is incremented whenever a new channel is obtained from
    4.48 -             * this stream.
    4.49 -             */
    4.50 -            fd.decrementAndGetUseCount();
    4.51              channel.close();
    4.52          }
    4.53  
    4.54 -        /*
    4.55 -         * Decrement FD use count associated with this stream.
    4.56 -         * The count got incremented by FileDescriptor during its construction.
    4.57 -         */
    4.58 -        int useCount = fd.decrementAndGetUseCount();
    4.59 -
    4.60 -        /*
    4.61 -         * If FileDescriptor is still in use by another stream, we
    4.62 -         * will not close it.
    4.63 -         */
    4.64 -        if (useCount <= 0) {
    4.65 -            close0();
    4.66 -        }
    4.67 +        fd.closeAll(new Closeable() {
    4.68 +            public void close() throws IOException {
    4.69 +               close0();
    4.70 +           }
    4.71 +        });
    4.72      }
    4.73  
    4.74      //
     5.1 --- a/src/share/classes/java/io/Writer.java	Fri Nov 18 16:57:01 2011 -0800
     5.2 +++ b/src/share/classes/java/io/Writer.java	Mon Nov 28 15:15:50 2011 -0800
     5.3 @@ -57,7 +57,7 @@
     5.4      /**
     5.5       * Size of writeBuffer, must be >= 1
     5.6       */
     5.7 -    private final int writeBufferSize = 1024;
     5.8 +    private static final int WRITE_BUFFER_SIZE = 1024;
     5.9  
    5.10      /**
    5.11       * The object used to synchronize operations on this stream.  For
    5.12 @@ -107,7 +107,7 @@
    5.13      public void write(int c) throws IOException {
    5.14          synchronized (lock) {
    5.15              if (writeBuffer == null){
    5.16 -                writeBuffer = new char[writeBufferSize];
    5.17 +                writeBuffer = new char[WRITE_BUFFER_SIZE];
    5.18              }
    5.19              writeBuffer[0] = (char) c;
    5.20              write(writeBuffer, 0, 1);
    5.21 @@ -180,9 +180,9 @@
    5.22      public void write(String str, int off, int len) throws IOException {
    5.23          synchronized (lock) {
    5.24              char cbuf[];
    5.25 -            if (len <= writeBufferSize) {
    5.26 +            if (len <= WRITE_BUFFER_SIZE) {
    5.27                  if (writeBuffer == null) {
    5.28 -                    writeBuffer = new char[writeBufferSize];
    5.29 +                    writeBuffer = new char[WRITE_BUFFER_SIZE];
    5.30                  }
    5.31                  cbuf = writeBuffer;
    5.32              } else {    // Don't permanently allocate very large buffers.
     6.1 --- a/src/share/classes/java/lang/AssertionError.java	Fri Nov 18 16:57:01 2011 -0800
     6.2 +++ b/src/share/classes/java/lang/AssertionError.java	Mon Nov 28 15:15:50 2011 -0800
     6.3 @@ -71,7 +71,7 @@
     6.4       * @see   Throwable#getCause()
     6.5       */
     6.6      public AssertionError(Object detailMessage) {
     6.7 -        this("" +  detailMessage);
     6.8 +        this(String.valueOf(detailMessage));
     6.9          if (detailMessage instanceof Throwable)
    6.10              initCause((Throwable) detailMessage);
    6.11      }
    6.12 @@ -85,7 +85,7 @@
    6.13       * @param detailMessage value to be used in constructing detail message
    6.14       */
    6.15      public AssertionError(boolean detailMessage) {
    6.16 -        this("" +  detailMessage);
    6.17 +        this(String.valueOf(detailMessage));
    6.18      }
    6.19  
    6.20      /**
    6.21 @@ -97,7 +97,7 @@
    6.22       * @param detailMessage value to be used in constructing detail message
    6.23       */
    6.24      public AssertionError(char detailMessage) {
    6.25 -        this("" +  detailMessage);
    6.26 +        this(String.valueOf(detailMessage));
    6.27      }
    6.28  
    6.29      /**
    6.30 @@ -109,7 +109,7 @@
    6.31       * @param detailMessage value to be used in constructing detail message
    6.32       */
    6.33      public AssertionError(int detailMessage) {
    6.34 -        this("" +  detailMessage);
    6.35 +        this(String.valueOf(detailMessage));
    6.36      }
    6.37  
    6.38      /**
    6.39 @@ -121,7 +121,7 @@
    6.40       * @param detailMessage value to be used in constructing detail message
    6.41       */
    6.42      public AssertionError(long detailMessage) {
    6.43 -        this("" +  detailMessage);
    6.44 +        this(String.valueOf(detailMessage));
    6.45      }
    6.46  
    6.47      /**
    6.48 @@ -133,7 +133,7 @@
    6.49       * @param detailMessage value to be used in constructing detail message
    6.50       */
    6.51      public AssertionError(float detailMessage) {
    6.52 -        this("" +  detailMessage);
    6.53 +        this(String.valueOf(detailMessage));
    6.54      }
    6.55  
    6.56      /**
    6.57 @@ -145,7 +145,7 @@
    6.58       * @param detailMessage value to be used in constructing detail message
    6.59       */
    6.60      public AssertionError(double detailMessage) {
    6.61 -        this("" +  detailMessage);
    6.62 +        this(String.valueOf(detailMessage));
    6.63      }
    6.64  
    6.65      /**
     7.1 --- a/src/share/classes/java/lang/Class.java	Fri Nov 18 16:57:01 2011 -0800
     7.2 +++ b/src/share/classes/java/lang/Class.java	Mon Nov 28 15:15:50 2011 -0800
     7.3 @@ -3008,7 +3008,7 @@
     7.4  
     7.5      /**
     7.6       * Casts this {@code Class} object to represent a subclass of the class
     7.7 -     * represented by the specified class object.  Checks that that the cast
     7.8 +     * represented by the specified class object.  Checks that the cast
     7.9       * is valid, and throws a {@code ClassCastException} if it is not.  If
    7.10       * this method succeeds, it always returns a reference to this class object.
    7.11       *
     8.1 --- a/src/share/classes/java/lang/Double.java	Fri Nov 18 16:57:01 2011 -0800
     8.2 +++ b/src/share/classes/java/lang/Double.java	Mon Nov 28 15:15:50 2011 -0800
     8.3 @@ -607,8 +607,7 @@
     8.4       * @see       java.lang.Double#valueOf(java.lang.String)
     8.5       */
     8.6      public Double(String s) throws NumberFormatException {
     8.7 -        // REMIND: this is inefficient
     8.8 -        this(valueOf(s).doubleValue());
     8.9 +        value = parseDouble(s);
    8.10      }
    8.11  
    8.12      /**
     9.1 --- a/src/share/classes/java/lang/Float.java	Fri Nov 18 16:57:01 2011 -0800
     9.2 +++ b/src/share/classes/java/lang/Float.java	Mon Nov 28 15:15:50 2011 -0800
     9.3 @@ -529,8 +529,7 @@
     9.4       * @see        java.lang.Float#valueOf(java.lang.String)
     9.5       */
     9.6      public Float(String s) throws NumberFormatException {
     9.7 -        // REMIND: this is inefficient
     9.8 -        this(valueOf(s).floatValue());
     9.9 +        value = parseFloat(s);
    9.10      }
    9.11  
    9.12      /**
    10.1 --- a/src/share/classes/java/security/Policy.java	Fri Nov 18 16:57:01 2011 -0800
    10.2 +++ b/src/share/classes/java/security/Policy.java	Mon Nov 28 15:15:50 2011 -0800
    10.3 @@ -28,6 +28,7 @@
    10.4  
    10.5  import java.util.Enumeration;
    10.6  import java.util.WeakHashMap;
    10.7 +import java.util.concurrent.atomic.AtomicReference;
    10.8  import sun.security.jca.GetInstance;
    10.9  import sun.security.util.Debug;
   10.10  import sun.security.util.SecurityConstants;
   10.11 @@ -60,8 +61,8 @@
   10.12   * with a standard type.  The default policy type is "JavaPolicy".
   10.13   *
   10.14   * <p> Once a Policy instance has been installed (either by default, or by
   10.15 - * calling <code>setPolicy</code>),
   10.16 - * the Java runtime invokes its <code>implies</code> when it needs to
   10.17 + * calling <code>setPolicy</code>), the Java runtime invokes its
   10.18 + * <code>implies</code> method when it needs to
   10.19   * determine whether executing code (encapsulated in a ProtectionDomain)
   10.20   * can perform SecurityManager-protected operations.  How a Policy object
   10.21   * retrieves its policy data is up to the Policy implementation itself.
   10.22 @@ -94,18 +95,33 @@
   10.23      public static final PermissionCollection UNSUPPORTED_EMPTY_COLLECTION =
   10.24                          new UnsupportedEmptyCollection();
   10.25  
   10.26 -    /** the system-wide policy. */
   10.27 -    private static Policy policy; // package private for AccessControlContext
   10.28 +    // Information about the system-wide policy.
   10.29 +    private static class PolicyInfo {
   10.30 +        // the system-wide policy
   10.31 +        final Policy policy;
   10.32 +        // a flag indicating if the system-wide policy has been initialized
   10.33 +        final boolean initialized;
   10.34 +
   10.35 +        PolicyInfo(Policy policy, boolean initialized) {
   10.36 +            this.policy = policy;
   10.37 +            this.initialized = initialized;
   10.38 +        }
   10.39 +    }
   10.40 +
   10.41 +    // PolicyInfo is stored in an AtomicReference
   10.42 +    private static AtomicReference<PolicyInfo> policy =
   10.43 +        new AtomicReference<>(new PolicyInfo(null, false));
   10.44  
   10.45      private static final Debug debug = Debug.getInstance("policy");
   10.46  
   10.47      // Cache mapping ProtectionDomain.Key to PermissionCollection
   10.48      private WeakHashMap<ProtectionDomain.Key, PermissionCollection> pdMapping;
   10.49  
   10.50 -    /** package private for AccessControlContext */
   10.51 +    /** package private for AccessControlContext and ProtectionDomain */
   10.52      static boolean isSet()
   10.53      {
   10.54 -        return policy != null;
   10.55 +        PolicyInfo pi = policy.get();
   10.56 +        return pi.policy != null && pi.initialized == true;
   10.57      }
   10.58  
   10.59      private static void checkPermission(String type) {
   10.60 @@ -143,80 +159,92 @@
   10.61  
   10.62      /**
   10.63       * Returns the installed Policy object, skipping the security check.
   10.64 -     * Used by SecureClassLoader and getPolicy.
   10.65 +     * Used by ProtectionDomain and getPolicy.
   10.66       *
   10.67       * @return the installed Policy.
   10.68 -     *
   10.69       */
   10.70 -    static synchronized Policy getPolicyNoCheck()
   10.71 +    static Policy getPolicyNoCheck()
   10.72      {
   10.73 -        if (policy == null) {
   10.74 -            String policy_class = null;
   10.75 -            policy_class = AccessController.doPrivileged(
   10.76 -                new PrivilegedAction<String>() {
   10.77 -                    public String run() {
   10.78 -                        return Security.getProperty("policy.provider");
   10.79 -                    }
   10.80 -                });
   10.81 -            if (policy_class == null) {
   10.82 -                policy_class = "sun.security.provider.PolicyFile";
   10.83 -            }
   10.84 -
   10.85 -            try {
   10.86 -                policy = (Policy)
   10.87 -                    Class.forName(policy_class).newInstance();
   10.88 -            } catch (Exception e) {
   10.89 -                /*
   10.90 -                 * The policy_class seems to be an extension
   10.91 -                 * so we have to bootstrap loading it via a policy
   10.92 -                 * provider that is on the bootclasspath
   10.93 -                 * If it loads then shift gears to using the configured
   10.94 -                 * provider.
   10.95 -                 */
   10.96 -
   10.97 -                // install the bootstrap provider to avoid recursion
   10.98 -                policy = new sun.security.provider.PolicyFile();
   10.99 -
  10.100 -                final String pc = policy_class;
  10.101 -                Policy p = AccessController.doPrivileged(
  10.102 -                    new PrivilegedAction<Policy>() {
  10.103 -                        public Policy run() {
  10.104 -                            try {
  10.105 -                                ClassLoader cl =
  10.106 -                                        ClassLoader.getSystemClassLoader();
  10.107 -                                // we want the extension loader
  10.108 -                                ClassLoader extcl = null;
  10.109 -                                while (cl != null) {
  10.110 -                                    extcl = cl;
  10.111 -                                    cl = cl.getParent();
  10.112 -                                }
  10.113 -                                return (extcl != null ? (Policy)Class.forName(
  10.114 -                                        pc, true, extcl).newInstance() : null);
  10.115 -                            } catch (Exception e) {
  10.116 -                                if (debug != null) {
  10.117 -                                    debug.println("policy provider " +
  10.118 -                                                pc +
  10.119 -                                                " not available");
  10.120 -                                    e.printStackTrace();
  10.121 -                                }
  10.122 -                                return null;
  10.123 -                            }
  10.124 +        PolicyInfo pi = policy.get();
  10.125 +        // Use double-check idiom to avoid locking if system-wide policy is
  10.126 +        // already initialized
  10.127 +        if (pi.initialized == false || pi.policy == null) {
  10.128 +            synchronized (Policy.class) {
  10.129 +                PolicyInfo pinfo = policy.get();
  10.130 +                if (pinfo.policy == null) {
  10.131 +                    String policy_class = AccessController.doPrivileged(
  10.132 +                        new PrivilegedAction<String>() {
  10.133 +                        public String run() {
  10.134 +                            return Security.getProperty("policy.provider");
  10.135                          }
  10.136                      });
  10.137 -                /*
  10.138 -                 * if it loaded install it as the policy provider. Otherwise
  10.139 -                 * continue to use the system default implementation
  10.140 -                 */
  10.141 -                if (p != null) {
  10.142 -                    policy = p;
  10.143 -                } else {
  10.144 -                    if (debug != null) {
  10.145 -                        debug.println("using sun.security.provider.PolicyFile");
  10.146 +                    if (policy_class == null) {
  10.147 +                        policy_class = "sun.security.provider.PolicyFile";
  10.148                      }
  10.149 +
  10.150 +                    try {
  10.151 +                        pinfo = new PolicyInfo(
  10.152 +                            (Policy) Class.forName(policy_class).newInstance(),
  10.153 +                            true);
  10.154 +                    } catch (Exception e) {
  10.155 +                        /*
  10.156 +                         * The policy_class seems to be an extension
  10.157 +                         * so we have to bootstrap loading it via a policy
  10.158 +                         * provider that is on the bootclasspath.
  10.159 +                         * If it loads then shift gears to using the configured
  10.160 +                         * provider.
  10.161 +                         */
  10.162 +
  10.163 +                        // install the bootstrap provider to avoid recursion
  10.164 +                        Policy polFile = new sun.security.provider.PolicyFile();
  10.165 +                        pinfo = new PolicyInfo(polFile, false);
  10.166 +                        policy.set(pinfo);
  10.167 +
  10.168 +                        final String pc = policy_class;
  10.169 +                        Policy pol = AccessController.doPrivileged(
  10.170 +                            new PrivilegedAction<Policy>() {
  10.171 +                            public Policy run() {
  10.172 +                                try {
  10.173 +                                    ClassLoader cl =
  10.174 +                                            ClassLoader.getSystemClassLoader();
  10.175 +                                    // we want the extension loader
  10.176 +                                    ClassLoader extcl = null;
  10.177 +                                    while (cl != null) {
  10.178 +                                        extcl = cl;
  10.179 +                                        cl = cl.getParent();
  10.180 +                                    }
  10.181 +                                    return (extcl != null ? (Policy)Class.forName(
  10.182 +                                            pc, true, extcl).newInstance() : null);
  10.183 +                                } catch (Exception e) {
  10.184 +                                    if (debug != null) {
  10.185 +                                        debug.println("policy provider " +
  10.186 +                                                    pc +
  10.187 +                                                    " not available");
  10.188 +                                        e.printStackTrace();
  10.189 +                                    }
  10.190 +                                    return null;
  10.191 +                                }
  10.192 +                            }
  10.193 +                        });
  10.194 +                        /*
  10.195 +                         * if it loaded install it as the policy provider. Otherwise
  10.196 +                         * continue to use the system default implementation
  10.197 +                         */
  10.198 +                        if (pol != null) {
  10.199 +                            pinfo = new PolicyInfo(pol, true);
  10.200 +                        } else {
  10.201 +                            if (debug != null) {
  10.202 +                                debug.println("using sun.security.provider.PolicyFile");
  10.203 +                            }
  10.204 +                            pinfo = new PolicyInfo(polFile, true);
  10.205 +                        }
  10.206 +                    }
  10.207 +                    policy.set(pinfo);
  10.208                  }
  10.209 +                return pinfo.policy;
  10.210              }
  10.211          }
  10.212 -        return policy;
  10.213 +        return pi.policy;
  10.214      }
  10.215  
  10.216      /**
  10.217 @@ -245,7 +273,7 @@
  10.218              initPolicy(p);
  10.219          }
  10.220          synchronized (Policy.class) {
  10.221 -            Policy.policy = p;
  10.222 +            policy.set(new PolicyInfo(p, p != null));
  10.223          }
  10.224      }
  10.225  
  10.226 @@ -292,14 +320,14 @@
  10.227          PermissionCollection policyPerms = null;
  10.228          synchronized (p) {
  10.229              if (p.pdMapping == null) {
  10.230 -                p.pdMapping =
  10.231 -                    new WeakHashMap<ProtectionDomain.Key, PermissionCollection>();
  10.232 +                p.pdMapping = new WeakHashMap<>();
  10.233             }
  10.234          }
  10.235  
  10.236          if (policyDomain.getCodeSource() != null) {
  10.237 -            if (Policy.isSet()) {
  10.238 -                policyPerms = policy.getPermissions(policyDomain);
  10.239 +            Policy pol = policy.get().policy;
  10.240 +            if (pol != null) {
  10.241 +                policyPerms = pol.getPermissions(policyDomain);
  10.242              }
  10.243  
  10.244              if (policyPerms == null) { // assume it has all
  10.245 @@ -434,7 +462,7 @@
  10.246                                                          type,
  10.247                                                          params);
  10.248          } catch (NoSuchAlgorithmException nsae) {
  10.249 -            return handleException (nsae);
  10.250 +            return handleException(nsae);
  10.251          }
  10.252      }
  10.253  
  10.254 @@ -494,7 +522,7 @@
  10.255                                                          type,
  10.256                                                          params);
  10.257          } catch (NoSuchAlgorithmException nsae) {
  10.258 -            return handleException (nsae);
  10.259 +            return handleException(nsae);
  10.260          }
  10.261      }
  10.262  
  10.263 @@ -808,7 +836,7 @@
  10.264           *
  10.265           * @param permission the Permission object to compare.
  10.266           *
  10.267 -         * @return true if "permission" is implied by the  permissions in
  10.268 +         * @return true if "permission" is implied by the permissions in
  10.269           * the collection, false if not.
  10.270           */
  10.271          @Override public boolean implies(Permission permission) {
    11.1 --- a/src/share/classes/java/sql/PreparedStatement.java	Fri Nov 18 16:57:01 2011 -0800
    11.2 +++ b/src/share/classes/java/sql/PreparedStatement.java	Mon Nov 28 15:15:50 2011 -0800
    11.3 @@ -767,7 +767,7 @@
    11.4  
    11.5  
    11.6      /**
    11.7 -     * Sets the designated paramter to the given <code>String</code> object.
    11.8 +     * Sets the designated parameter to the given <code>String</code> object.
    11.9       * The driver converts this to a SQL <code>NCHAR</code> or
   11.10       * <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> value
   11.11       * (depending on the argument's
    12.1 --- a/src/share/classes/java/sql/Statement.java	Fri Nov 18 16:57:01 2011 -0800
    12.2 +++ b/src/share/classes/java/sql/Statement.java	Mon Nov 28 15:15:50 2011 -0800
    12.3 @@ -991,7 +991,7 @@
    12.4          /**
    12.5           * Requests that a <code>Statement</code> be pooled or not pooled.  The value
    12.6           * specified is a hint to the statement pool implementation indicating
    12.7 -         * whether the applicaiton wants the statement to be pooled.  It is up to
    12.8 +         * whether the application wants the statement to be pooled.  It is up to
    12.9           * the statement pool manager as to whether the hint is used.
   12.10           * <p>
   12.11           * The poolable value of a statement is applicable to both internal
    13.1 --- a/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java	Fri Nov 18 16:57:01 2011 -0800
    13.2 +++ b/src/share/classes/java/util/concurrent/LinkedBlockingDeque.java	Mon Nov 28 15:15:50 2011 -0800
    13.3 @@ -742,6 +742,8 @@
    13.4              throw new NullPointerException();
    13.5          if (c == this)
    13.6              throw new IllegalArgumentException();
    13.7 +        if (maxElements <= 0)
    13.8 +            return 0;
    13.9          final ReentrantLock lock = this.lock;
   13.10          lock.lock();
   13.11          try {
    14.1 --- a/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java	Fri Nov 18 16:57:01 2011 -0800
    14.2 +++ b/src/share/classes/java/util/concurrent/LinkedBlockingQueue.java	Mon Nov 28 15:15:50 2011 -0800
    14.3 @@ -332,7 +332,7 @@
    14.4          // Note: convention in all put/take/etc is to preset local var
    14.5          // holding count negative to indicate failure unless set.
    14.6          int c = -1;
    14.7 -        Node<E> node = new Node(e);
    14.8 +        Node<E> node = new Node<E>(e);
    14.9          final ReentrantLock putLock = this.putLock;
   14.10          final AtomicInteger count = this.count;
   14.11          putLock.lockInterruptibly();
   14.12 @@ -412,7 +412,7 @@
   14.13          if (count.get() == capacity)
   14.14              return false;
   14.15          int c = -1;
   14.16 -        Node<E> node = new Node(e);
   14.17 +        Node<E> node = new Node<E>(e);
   14.18          final ReentrantLock putLock = this.putLock;
   14.19          putLock.lock();
   14.20          try {
   14.21 @@ -728,6 +728,8 @@
   14.22              throw new NullPointerException();
   14.23          if (c == this)
   14.24              throw new IllegalArgumentException();
   14.25 +        if (maxElements <= 0)
   14.26 +            return 0;
   14.27          boolean signalNotFull = false;
   14.28          final ReentrantLock takeLock = this.takeLock;
   14.29          takeLock.lock();
    15.1 --- a/src/share/classes/java/util/jar/Attributes.java	Fri Nov 18 16:57:01 2011 -0800
    15.2 +++ b/src/share/classes/java/util/jar/Attributes.java	Mon Nov 28 15:15:50 2011 -0800
    15.3 @@ -629,7 +629,7 @@
    15.4          public static final Name IMPLEMENTATION_VENDOR_ID = new Name("Implementation-Vendor-Id");
    15.5  
    15.6         /**
    15.7 -         * <code>Name</code> object for <code>Implementation-Vendor-URL</code>
    15.8 +         * <code>Name</code> object for <code>Implementation-URL</code>
    15.9           * manifest attribute used for package versioning.
   15.10           * @see <a href="../../../../technotes/guides/versioning/spec/versioning2.html#wp90779">
   15.11           *      Java Product Versioning Specification</a>
    16.1 --- a/src/share/classes/sun/net/httpserver/ServerImpl.java	Fri Nov 18 16:57:01 2011 -0800
    16.2 +++ b/src/share/classes/sun/net/httpserver/ServerImpl.java	Mon Nov 28 15:15:50 2011 -0800
    16.3 @@ -402,10 +402,10 @@
    16.4                  } catch (IOException e) {
    16.5                      logger.log (Level.FINER, "Dispatcher (4)", e);
    16.6                  } catch (Exception e) {
    16.7 -                    e.printStackTrace();
    16.8                      logger.log (Level.FINER, "Dispatcher (7)", e);
    16.9                  }
   16.10              }
   16.11 +            try {selector.close(); } catch (Exception e) {}
   16.12          }
   16.13  
   16.14          private void handleException (SelectionKey key, Exception e) {
    17.1 --- a/src/share/classes/sun/rmi/registry/RegistryImpl.java	Fri Nov 18 16:57:01 2011 -0800
    17.2 +++ b/src/share/classes/sun/rmi/registry/RegistryImpl.java	Mon Nov 28 15:15:50 2011 -0800
    17.3 @@ -1,5 +1,5 @@
    17.4  /*
    17.5 - * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
    17.6 + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
    17.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    17.8   *
    17.9   * This code is free software; you can redistribute it and/or modify it
   17.10 @@ -29,6 +29,7 @@
   17.11  import java.util.Hashtable;
   17.12  import java.util.MissingResourceException;
   17.13  import java.util.ResourceBundle;
   17.14 +import java.io.FilePermission;
   17.15  import java.io.IOException;
   17.16  import java.net.*;
   17.17  import java.rmi.*;
   17.18 @@ -54,7 +55,6 @@
   17.19  import sun.rmi.transport.LiveRef;
   17.20  import sun.rmi.transport.ObjectTable;
   17.21  import sun.rmi.transport.Target;
   17.22 -import sun.security.action.GetPropertyAction;
   17.23  
   17.24  /**
   17.25   * A "registry" exists on every node that allows RMI connections to
   17.26 @@ -335,19 +335,6 @@
   17.27              URL[] urls = sun.misc.URLClassPath.pathToURLs(envcp);
   17.28              ClassLoader cl = new URLClassLoader(urls);
   17.29  
   17.30 -            String codebaseProperty = null;
   17.31 -            String prop = java.security.AccessController.doPrivileged(
   17.32 -                new GetPropertyAction("java.rmi.server.codebase"));
   17.33 -            if (prop != null && prop.trim().length() > 0) {
   17.34 -                codebaseProperty = prop;
   17.35 -            }
   17.36 -            URL[] codebaseURLs = null;
   17.37 -            if (codebaseProperty != null) {
   17.38 -                codebaseURLs = sun.misc.URLClassPath.pathToURLs(codebaseProperty);
   17.39 -            } else {
   17.40 -                codebaseURLs = new URL[0];
   17.41 -            }
   17.42 -
   17.43              /*
   17.44               * Fix bugid 4242317: Classes defined by this class loader should
   17.45               * be annotated with the value of the "java.rmi.server.codebase"
   17.46 @@ -365,7 +352,7 @@
   17.47                          public RegistryImpl run() throws RemoteException {
   17.48                              return new RegistryImpl(regPort);
   17.49                          }
   17.50 -                    }, getAccessControlContext(codebaseURLs));
   17.51 +                    }, getAccessControlContext());
   17.52              } catch (PrivilegedActionException ex) {
   17.53                  throw (RemoteException) ex.getException();
   17.54              }
   17.55 @@ -391,11 +378,11 @@
   17.56      }
   17.57  
   17.58      /**
   17.59 -     * Generates an AccessControlContext from several URLs.
   17.60 +     * Generates an AccessControlContext with minimal permissions.
   17.61       * The approach used here is taken from the similar method
   17.62       * getAccessControlContext() in the sun.applet.AppletPanel class.
   17.63       */
   17.64 -    private static AccessControlContext getAccessControlContext(URL[] urls) {
   17.65 +    private static AccessControlContext getAccessControlContext() {
   17.66          // begin with permissions granted to all code in current policy
   17.67          PermissionCollection perms = AccessController.doPrivileged(
   17.68              new java.security.PrivilegedAction<PermissionCollection>() {
   17.69 @@ -420,17 +407,15 @@
   17.70  
   17.71          perms.add(new RuntimePermission("accessClassInPackage.sun.*"));
   17.72  
   17.73 -        // add permissions required to load from codebase URL path
   17.74 -        LoaderHandler.addPermissionsForURLs(urls, perms, false);
   17.75 +        perms.add(new FilePermission("<<ALL FILES>>", "read"));
   17.76  
   17.77          /*
   17.78           * Create an AccessControlContext that consists of a single
   17.79           * protection domain with only the permissions calculated above.
   17.80           */
   17.81          ProtectionDomain pd = new ProtectionDomain(
   17.82 -            new CodeSource((urls.length > 0 ? urls[0] : null),
   17.83 -                (java.security.cert.Certificate[]) null),
   17.84 -            perms);
   17.85 +            new CodeSource(null,
   17.86 +                (java.security.cert.Certificate[]) null), perms);
   17.87          return new AccessControlContext(new ProtectionDomain[] { pd });
   17.88      }
   17.89  }
    18.1 --- a/src/share/classes/sun/rmi/server/LoaderHandler.java	Fri Nov 18 16:57:01 2011 -0800
    18.2 +++ b/src/share/classes/sun/rmi/server/LoaderHandler.java	Mon Nov 28 15:15:50 2011 -0800
    18.3 @@ -1,5 +1,5 @@
    18.4  /*
    18.5 - * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
    18.6 + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
    18.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    18.8   *
    18.9   * This code is free software; you can redistribute it and/or modify it
   18.10 @@ -1031,7 +1031,7 @@
   18.11       * loader.  A given permission is only added to the collection if
   18.12       * it is not already implied by the collection.
   18.13       */
   18.14 -    public static void addPermissionsForURLs(URL[] urls,
   18.15 +    private static void addPermissionsForURLs(URL[] urls,
   18.16                                               PermissionCollection perms,
   18.17                                               boolean forLoader)
   18.18      {
    19.1 --- a/src/share/classes/sun/security/krb5/internal/KerberosTime.java	Fri Nov 18 16:57:01 2011 -0800
    19.2 +++ b/src/share/classes/sun/security/krb5/internal/KerberosTime.java	Mon Nov 28 15:15:50 2011 -0800
    19.3 @@ -68,8 +68,8 @@
    19.4      private int  microSeconds; // the last three digits of the microsecond value
    19.5  
    19.6      // The time when this class is loaded. Used in setNow()
    19.7 -    private static final long initMilli = System.currentTimeMillis();
    19.8 -    private static final long initMicro = System.nanoTime() / 1000;
    19.9 +    private static long initMilli = System.currentTimeMillis();
   19.10 +    private static long initMicro = System.nanoTime() / 1000;
   19.11  
   19.12      private static long syncTime;
   19.13      private static boolean DEBUG = Krb5.DEBUG;
   19.14 @@ -212,9 +212,22 @@
   19.15      }
   19.16  
   19.17      public void setNow() {
   19.18 -        long microElapsed = System.nanoTime() / 1000 - initMicro;
   19.19 -        setTime(initMilli + microElapsed/1000);
   19.20 -        microSeconds = (int)(microElapsed % 1000);
   19.21 +        long newMilli = System.currentTimeMillis();
   19.22 +        long newMicro = System.nanoTime() / 1000;
   19.23 +        long microElapsed = newMicro - initMicro;
   19.24 +        long calcMilli = initMilli + microElapsed/1000;
   19.25 +        if (calcMilli - newMilli > 100 || newMilli - calcMilli > 100) {
   19.26 +            if (DEBUG) {
   19.27 +                System.out.println("System time adjusted");
   19.28 +            }
   19.29 +            initMilli = newMilli;
   19.30 +            initMicro = newMicro;
   19.31 +            setTime(newMilli);
   19.32 +            microSeconds = 0;
   19.33 +        } else {
   19.34 +            setTime(calcMilli);
   19.35 +            microSeconds = (int)(microElapsed % 1000);
   19.36 +        }
   19.37      }
   19.38  
   19.39      public int getMicroSeconds() {
    20.1 --- a/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java	Fri Nov 18 16:57:01 2011 -0800
    20.2 +++ b/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java	Mon Nov 28 15:15:50 2011 -0800
    20.3 @@ -375,7 +375,7 @@
    20.4          }
    20.5          AuthorizationDataEntry[] auDataEntry = readAuth();
    20.6          AuthorizationData auData = null;
    20.7 -        if (auData != null) {
    20.8 +        if (auDataEntry != null) {
    20.9              auData = new AuthorizationData(auDataEntry);
   20.10          }
   20.11          byte[] ticketData = readData();
    21.1 --- a/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java	Fri Nov 18 16:57:01 2011 -0800
    21.2 +++ b/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java	Mon Nov 28 15:15:50 2011 -0800
    21.3 @@ -209,10 +209,24 @@
    21.4      }
    21.5  
    21.6      public sun.security.krb5.Credentials setKrbCreds() {
    21.7 +        // Note: We will not pass authorizationData to s.s.k.Credentials. The
    21.8 +        // field in that class will be passed to Krb5Context as the return
    21.9 +        // value of ExtendedGSSContext.inquireSecContext(KRB5_GET_AUTHZ_DATA),
   21.10 +        // which is documented as the authData in the service ticket. That
   21.11 +        // is on the acceptor side.
   21.12 +        //
   21.13 +        // This class is for the initiator side. Also, authdata inside a ccache
   21.14 +        // is most likely to be the one in Authenticator in PA-TGS-REQ encoded
   21.15 +        // in TGS-REQ, therefore only stored with a service ticket. Currently
   21.16 +        // in Java, we only reads TGTs.
   21.17          return new sun.security.krb5.Credentials(ticket,
   21.18                  cname, sname, key, flags, authtime, starttime, endtime, renewTill, caddr);
   21.19      }
   21.20  
   21.21 +    public KerberosTime getStartTime() {
   21.22 +        return starttime;
   21.23 +    }
   21.24 +
   21.25      public KerberosTime getAuthTime() {
   21.26          return authtime;
   21.27      }
   21.28 @@ -221,6 +235,10 @@
   21.29          return endtime;
   21.30      }
   21.31  
   21.32 +    public KerberosTime getRenewTill() {
   21.33 +        return renewTill;
   21.34 +    }
   21.35 +
   21.36      public TicketFlags getTicketFlags() {
   21.37          return flags;
   21.38      }
   21.39 @@ -228,4 +246,8 @@
   21.40      public int getEType() {
   21.41          return key.getEType();
   21.42      }
   21.43 +
   21.44 +    public int getTktEType() {
   21.45 +        return ticket.encPart.getEType();
   21.46 +    }
   21.47  }
    22.1 --- a/src/share/classes/sun/security/ssl/SSLContextImpl.java	Fri Nov 18 16:57:01 2011 -0800
    22.2 +++ b/src/share/classes/sun/security/ssl/SSLContextImpl.java	Mon Nov 28 15:15:50 2011 -0800
    22.3 @@ -771,10 +771,15 @@
    22.4  final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
    22.5              implements X509TrustManager {
    22.6  
    22.7 +    // the delegated trust manager
    22.8      private final X509TrustManager tm;
    22.9  
   22.10 +    // Cache the trusted certificate to optimize the performance.
   22.11 +    private final Collection<X509Certificate> trustedCerts = new HashSet<>();
   22.12 +
   22.13      AbstractTrustManagerWrapper(X509TrustManager tm) {
   22.14          this.tm = tm;
   22.15 +        Collections.addAll(trustedCerts, tm.getAcceptedIssuers());
   22.16      }
   22.17  
   22.18      @Override
   22.19 @@ -863,20 +868,7 @@
   22.20                  constraints = new SSLAlgorithmConstraints(sslSocket, true);
   22.21              }
   22.22  
   22.23 -            AlgorithmChecker checker = new AlgorithmChecker(constraints);
   22.24 -            try {
   22.25 -                checker.init(false);
   22.26 -
   22.27 -                // a forward checker, need to check from trust to target
   22.28 -                for (int i = chain.length - 1; i >= 0; i--) {
   22.29 -                    Certificate cert = chain[i];
   22.30 -                    // We don't care about the unresolved critical extensions.
   22.31 -                    checker.check(cert, Collections.<String>emptySet());
   22.32 -                }
   22.33 -            } catch (CertPathValidatorException cpve) {
   22.34 -                throw new CertificateException(
   22.35 -                    "Certificates does not conform to algorithm constraints");
   22.36 -            }
   22.37 +            checkAlgorithmConstraints(chain, constraints);
   22.38          }
   22.39      }
   22.40  
   22.41 @@ -918,20 +910,33 @@
   22.42                  constraints = new SSLAlgorithmConstraints(engine, true);
   22.43              }
   22.44  
   22.45 -            AlgorithmChecker checker = new AlgorithmChecker(constraints);
   22.46 -            try {
   22.47 +            checkAlgorithmConstraints(chain, constraints);
   22.48 +        }
   22.49 +    }
   22.50 +
   22.51 +    private void checkAlgorithmConstraints(X509Certificate[] chain,
   22.52 +            AlgorithmConstraints constraints) throws CertificateException {
   22.53 +
   22.54 +        try {
   22.55 +            // Does the certificate chain end with a trusted certificate?
   22.56 +            int checkedLength = chain.length - 1;
   22.57 +            if (trustedCerts.contains(chain[checkedLength])) {
   22.58 +                    checkedLength--;
   22.59 +            }
   22.60 +
   22.61 +            // A forward checker, need to check from trust to target
   22.62 +            if (checkedLength >= 0) {
   22.63 +                AlgorithmChecker checker = new AlgorithmChecker(constraints);
   22.64                  checker.init(false);
   22.65 -
   22.66 -                // A forward checker, need to check from trust to target
   22.67 -                for (int i = chain.length - 1; i >= 0; i--) {
   22.68 +                for (int i = checkedLength; i >= 0; i--) {
   22.69                      Certificate cert = chain[i];
   22.70                      // We don't care about the unresolved critical extensions.
   22.71                      checker.check(cert, Collections.<String>emptySet());
   22.72                  }
   22.73 -            } catch (CertPathValidatorException cpve) {
   22.74 -                throw new CertificateException(
   22.75 -                    "Certificates does not conform to algorithm constraints");
   22.76              }
   22.77 +        } catch (CertPathValidatorException cpve) {
   22.78 +            throw new CertificateException(
   22.79 +                "Certificates does not conform to algorithm constraints");
   22.80          }
   22.81      }
   22.82  }
    23.1 --- a/src/share/classes/sun/security/ssl/SSLSocketImpl.java	Fri Nov 18 16:57:01 2011 -0800
    23.2 +++ b/src/share/classes/sun/security/ssl/SSLSocketImpl.java	Mon Nov 28 15:15:50 2011 -0800
    23.3 @@ -1485,7 +1485,8 @@
    23.4  
    23.5      private void closeSocket(boolean selfInitiated) throws IOException {
    23.6          if ((debug != null) && Debug.isOn("ssl")) {
    23.7 -            System.out.println(threadName() + ", called closeSocket(selfInitiated)");
    23.8 +            System.out.println(threadName() +
    23.9 +                ", called closeSocket(" + selfInitiated + ")");
   23.10          }
   23.11          if (self == this) {
   23.12              super.close();
    24.1 --- a/src/share/classes/sun/security/tools/CertAndKeyGen.java	Fri Nov 18 16:57:01 2011 -0800
    24.2 +++ b/src/share/classes/sun/security/tools/CertAndKeyGen.java	Mon Nov 28 15:15:50 2011 -0800
    24.3 @@ -33,18 +33,7 @@
    24.4  import java.util.Date;
    24.5  
    24.6  import sun.security.pkcs10.PKCS10;
    24.7 -import sun.security.x509.AlgorithmId;
    24.8 -import sun.security.x509.CertificateAlgorithmId;
    24.9 -import sun.security.x509.CertificateIssuerName;
   24.10 -import sun.security.x509.CertificateSerialNumber;
   24.11 -import sun.security.x509.CertificateSubjectName;
   24.12 -import sun.security.x509.CertificateValidity;
   24.13 -import sun.security.x509.CertificateVersion;
   24.14 -import sun.security.x509.CertificateX509Key;
   24.15 -import sun.security.x509.X500Name;
   24.16 -import sun.security.x509.X509CertImpl;
   24.17 -import sun.security.x509.X509CertInfo;
   24.18 -import sun.security.x509.X509Key;
   24.19 +import sun.security.x509.*;
   24.20  
   24.21  
   24.22  /**
   24.23 @@ -165,6 +154,13 @@
   24.24  
   24.25          publicKey = pair.getPublic();
   24.26          privateKey = pair.getPrivate();
   24.27 +
   24.28 +        // publicKey's format must be X.509 otherwise
   24.29 +        // the whole CertGen part of this class is broken.
   24.30 +        if (!"X.509".equalsIgnoreCase(publicKey.getFormat())) {
   24.31 +            throw new IllegalArgumentException("publicKey's is not X.509, but "
   24.32 +                    + publicKey.getFormat());
   24.33 +        }
   24.34      }
   24.35  
   24.36  
   24.37 @@ -186,6 +182,16 @@
   24.38          return (X509Key)publicKey;
   24.39      }
   24.40  
   24.41 +    /**
   24.42 +     * Always returns the public key of the generated key pair. Used
   24.43 +     * by KeyTool only.
   24.44 +     *
   24.45 +     * The publicKey is not necessarily to be an instance of
   24.46 +     * X509Key in some JCA/JCE providers, for example SunPKCS11.
   24.47 +     */
   24.48 +    public PublicKey getPublicKeyAnyway() {
   24.49 +        return publicKey;
   24.50 +    }
   24.51  
   24.52      /**
   24.53       * Returns the private key of the generated key pair.
   24.54 @@ -200,7 +206,6 @@
   24.55          return privateKey;
   24.56      }
   24.57  
   24.58 -
   24.59      /**
   24.60       * Returns a self-signed X.509v3 certificate for the public key.
   24.61       * The certificate is immediately valid. No extensions.
   24.62 @@ -225,6 +230,15 @@
   24.63      throws CertificateException, InvalidKeyException, SignatureException,
   24.64          NoSuchAlgorithmException, NoSuchProviderException
   24.65      {
   24.66 +        return getSelfCertificate(myname, firstDate, validity, null);
   24.67 +    }
   24.68 +
   24.69 +    // Like above, plus a CertificateExtensions argument, which can be null.
   24.70 +    public X509Certificate getSelfCertificate (X500Name myname, Date firstDate,
   24.71 +            long validity, CertificateExtensions ext)
   24.72 +    throws CertificateException, InvalidKeyException, SignatureException,
   24.73 +        NoSuchAlgorithmException, NoSuchProviderException
   24.74 +    {
   24.75          X509CertImpl    cert;
   24.76          Date            lastDate;
   24.77  
   24.78 @@ -248,6 +262,7 @@
   24.79              info.set(X509CertInfo.KEY, new CertificateX509Key(publicKey));
   24.80              info.set(X509CertInfo.VALIDITY, interval);
   24.81              info.set(X509CertInfo.ISSUER, new CertificateIssuerName(myname));
   24.82 +            if (ext != null) info.set(X509CertInfo.EXTENSIONS, ext);
   24.83  
   24.84              cert = new X509CertImpl(info);
   24.85              cert.sign(privateKey, this.sigAlg);
    25.1 --- a/src/share/classes/sun/security/tools/KeyTool.java	Fri Nov 18 16:57:01 2011 -0800
    25.2 +++ b/src/share/classes/sun/security/tools/KeyTool.java	Mon Nov 28 15:15:50 2011 -0800
    25.3 @@ -1518,9 +1518,16 @@
    25.4          keypair.generate(keysize);
    25.5          PrivateKey privKey = keypair.getPrivateKey();
    25.6  
    25.7 +        CertificateExtensions ext = createV3Extensions(
    25.8 +                null,
    25.9 +                null,
   25.10 +                v3ext,
   25.11 +                keypair.getPublicKeyAnyway(),
   25.12 +                null);
   25.13 +
   25.14          X509Certificate[] chain = new X509Certificate[1];
   25.15          chain[0] = keypair.getSelfCertificate(
   25.16 -                x500Name, getStartDate(startDate), validity*24L*60L*60L);
   25.17 +                x500Name, getStartDate(startDate), validity*24L*60L*60L, ext);
   25.18  
   25.19          if (verbose) {
   25.20              MessageFormat form = new MessageFormat(rb.getString
   25.21 @@ -1537,9 +1544,6 @@
   25.22              keyPass = promptForKeyPass(alias, null, storePass);
   25.23          }
   25.24          keyStore.setKeyEntry(alias, privKey, keyPass, chain);
   25.25 -
   25.26 -        // resign so that -ext are applied.
   25.27 -        doSelfCert(alias, null, sigAlgName);
   25.28      }
   25.29  
   25.30      /**
    26.1 --- a/src/share/native/sun/awt/medialib/mlib_types.h	Fri Nov 18 16:57:01 2011 -0800
    26.2 +++ b/src/share/native/sun/awt/medialib/mlib_types.h	Mon Nov 28 15:15:50 2011 -0800
    26.3 @@ -59,13 +59,8 @@
    26.4  
    26.5  #if defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__GNUC__)
    26.6  
    26.7 -#if defined(__linux__)
    26.8 -#include <stdint.h>                     /* for uintptr_t */
    26.9 -#include <malloc.h>                     /* for ptrdiff_t */
   26.10 -#else
   26.11 -#include <link.h>                       /* for uintptr_t */
   26.12 -#include <stddef.h>                     /* for ptrdiff_t */
   26.13 -#endif  /* __linux__ */
   26.14 +#include <stdint.h>
   26.15 +#include <stddef.h>
   26.16  
   26.17  #ifdef MLIB_OS64BIT
   26.18  
    27.1 --- a/src/solaris/classes/java/io/FileDescriptor.java	Fri Nov 18 16:57:01 2011 -0800
    27.2 +++ b/src/solaris/classes/java/io/FileDescriptor.java	Mon Nov 28 15:15:50 2011 -0800
    27.3 @@ -1,5 +1,5 @@
    27.4  /*
    27.5 - * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
    27.6 + * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
    27.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    27.8   *
    27.9   * This code is free software; you can redistribute it and/or modify it
   27.10 @@ -25,7 +25,8 @@
   27.11  
   27.12  package java.io;
   27.13  
   27.14 -import java.util.concurrent.atomic.AtomicInteger;
   27.15 +import java.util.ArrayList;
   27.16 +import java.util.List;
   27.17  
   27.18  /**
   27.19   * Instances of the file descriptor class serve as an opaque handle
   27.20 @@ -46,12 +47,9 @@
   27.21  
   27.22      private int fd;
   27.23  
   27.24 -    /**
   27.25 -     * A counter for tracking the FIS/FOS/RAF instances that
   27.26 -     * use this FileDescriptor. The FIS/FOS.finalize() will not release
   27.27 -     * the FileDescriptor if it is still under user by a stream.
   27.28 -     */
   27.29 -    private AtomicInteger useCount;
   27.30 +    private Closeable parent;
   27.31 +    private List<Closeable> otherParents;
   27.32 +    private boolean closed;
   27.33  
   27.34      /**
   27.35       * Constructs an (invalid) FileDescriptor
   27.36 @@ -59,12 +57,10 @@
   27.37       */
   27.38      public /**/ FileDescriptor() {
   27.39          fd = -1;
   27.40 -        useCount = new AtomicInteger();
   27.41      }
   27.42  
   27.43      private /* */ FileDescriptor(int fd) {
   27.44          this.fd = fd;
   27.45 -        useCount = new AtomicInteger();
   27.46      }
   27.47  
   27.48      /**
   27.49 @@ -164,13 +160,67 @@
   27.50          );
   27.51      }
   27.52  
   27.53 -    // package private methods used by FIS, FOS and RAF
   27.54 +    /*
   27.55 +     * Package private methods to track referents.
   27.56 +     * If multiple streams point to the same FileDescriptor, we cycle
   27.57 +     * through the list of all referents and call close()
   27.58 +     */
   27.59  
   27.60 -    int incrementAndGetUseCount() {
   27.61 -        return useCount.incrementAndGet();
   27.62 +    /**
   27.63 +     * Attach a Closeable to this FD for tracking.
   27.64 +     * parent reference is added to otherParents when
   27.65 +     * needed to make closeAll simpler.
   27.66 +     */
   27.67 +    synchronized void attach(Closeable c) {
   27.68 +        if (parent == null) {
   27.69 +            // first caller gets to do this
   27.70 +            parent = c;
   27.71 +        } else if (otherParents == null) {
   27.72 +            otherParents = new ArrayList<>();
   27.73 +            otherParents.add(parent);
   27.74 +            otherParents.add(c);
   27.75 +        } else {
   27.76 +            otherParents.add(c);
   27.77 +        }
   27.78      }
   27.79  
   27.80 -    int decrementAndGetUseCount() {
   27.81 -        return useCount.decrementAndGet();
   27.82 +    /**
   27.83 +     * Cycle through all Closeables sharing this FD and call
   27.84 +     * close() on each one.
   27.85 +     *
   27.86 +     * The caller closeable gets to call close0().
   27.87 +     */
   27.88 +    @SuppressWarnings("try")
   27.89 +    synchronized void closeAll(Closeable releaser) throws IOException {
   27.90 +        if (!closed) {
   27.91 +            closed = true;
   27.92 +            IOException ioe = null;
   27.93 +            try (Closeable c = releaser) {
   27.94 +                if (otherParents != null) {
   27.95 +                    for (Closeable referent : otherParents) {
   27.96 +                        try {
   27.97 +                            referent.close();
   27.98 +                        } catch(IOException x) {
   27.99 +                            if (ioe == null) {
  27.100 +                                ioe = x;
  27.101 +                            } else {
  27.102 +                                ioe.addSuppressed(x);
  27.103 +                            }
  27.104 +                        }
  27.105 +                    }
  27.106 +                }
  27.107 +            } catch(IOException ex) {
  27.108 +                /*
  27.109 +                 * If releaser close() throws IOException
  27.110 +                 * add other exceptions as suppressed.
  27.111 +                 */
  27.112 +                if (ioe != null)
  27.113 +                    ex.addSuppressed(ioe);
  27.114 +                ioe = ex;
  27.115 +            } finally {
  27.116 +                if (ioe != null)
  27.117 +                    throw ioe;
  27.118 +            }
  27.119 +        }
  27.120      }
  27.121  }
    28.1 --- a/src/solaris/native/java/net/Inet4AddressImpl.c	Fri Nov 18 16:57:01 2011 -0800
    28.2 +++ b/src/solaris/native/java/net/Inet4AddressImpl.c	Mon Nov 28 15:15:50 2011 -0800
    28.3 @@ -43,8 +43,9 @@
    28.4  #include "java_net_Inet4AddressImpl.h"
    28.5  
    28.6  /* the initial size of our hostent buffers */
    28.7 -#define HENT_BUF_SIZE 1024
    28.8 -#define BIG_HENT_BUF_SIZE 10240  /* a jumbo-sized one */
    28.9 +#ifndef NI_MAXHOST
   28.10 +#define NI_MAXHOST 1025
   28.11 +#endif
   28.12  
   28.13  /************************************************************************
   28.14   * Inet4AddressImpl
   28.15 @@ -57,60 +58,36 @@
   28.16   */
   28.17  JNIEXPORT jstring JNICALL
   28.18  Java_java_net_Inet4AddressImpl_getLocalHostName(JNIEnv *env, jobject this) {
   28.19 -    char hostname[MAXHOSTNAMELEN+1];
   28.20 +    char hostname[NI_MAXHOST+1];
   28.21  
   28.22      hostname[0] = '\0';
   28.23      if (JVM_GetHostName(hostname, sizeof(hostname))) {
   28.24          /* Something went wrong, maybe networking is not setup? */
   28.25          strcpy(hostname, "localhost");
   28.26      } else {
   28.27 -#ifdef __linux__
   28.28 -        /* On Linux gethostname() says "host.domain.sun.com".  On
   28.29 -         * Solaris gethostname() says "host", so extra work is needed.
   28.30 -         */
   28.31 -#else
   28.32 -        /* Solaris doesn't want to give us a fully qualified domain name.
   28.33 -         * We do a reverse lookup to try and get one.  This works
   28.34 -         * if DNS occurs before NIS in /etc/resolv.conf, but fails
   28.35 -         * if NIS comes first (it still gets only a partial name).
   28.36 -         * We use thread-safe system calls.
   28.37 -         */
   28.38 -#endif /* __linux__ */
   28.39 -        struct hostent res, res2, *hp;
   28.40 -        // these buffers must be pointer-aligned so they are declared
   28.41 -        // with pointer type
   28.42 -        char *buf[HENT_BUF_SIZE/(sizeof (char *))];
   28.43 -        char *buf2[HENT_BUF_SIZE/(sizeof (char *))];
   28.44 -        int h_error=0;
   28.45 +        struct addrinfo hints, *res;
   28.46 +        int error;
   28.47  
   28.48 -        // ensure null-terminated
   28.49 -        hostname[MAXHOSTNAMELEN] = '\0';
   28.50 +        hostname[NI_MAXHOST] = '\0';
   28.51 +        memset(&hints, 0, sizeof(hints));
   28.52 +        hints.ai_flags = AI_CANONNAME;
   28.53 +        hints.ai_family = AF_INET;
   28.54  
   28.55 -#ifdef __GLIBC__
   28.56 -        gethostbyname_r(hostname, &res, (char*)buf, sizeof(buf), &hp, &h_error);
   28.57 -#else
   28.58 -        hp = gethostbyname_r(hostname, &res, (char*)buf, sizeof(buf), &h_error);
   28.59 -#endif
   28.60 -        if (hp) {
   28.61 -#ifdef __GLIBC__
   28.62 -            gethostbyaddr_r(hp->h_addr, hp->h_length, AF_INET,
   28.63 -                            &res2, (char*)buf2, sizeof(buf2), &hp, &h_error);
   28.64 -#else
   28.65 -            hp = gethostbyaddr_r(hp->h_addr, hp->h_length, AF_INET,
   28.66 -                                 &res2, (char*)buf2, sizeof(buf2), &h_error);
   28.67 -#endif
   28.68 -            if (hp) {
   28.69 -                /*
   28.70 -                 * If gethostbyaddr_r() found a fully qualified host name,
   28.71 -                 * returns that name. Otherwise, returns the hostname
   28.72 -                 * found by gethostname().
   28.73 -                 */
   28.74 -                char *p = hp->h_name;
   28.75 -                if ((strlen(hp->h_name) > strlen(hostname))
   28.76 -                    && (strncmp(hostname, hp->h_name, strlen(hostname)) == 0)
   28.77 -                    && (*(p + strlen(hostname)) == '.'))
   28.78 -                    strcpy(hostname, hp->h_name);
   28.79 -            }
   28.80 +        error = getaddrinfo(hostname, NULL, &hints, &res);
   28.81 +
   28.82 +        if (error == 0) {/* host is known to name service */
   28.83 +            getnameinfo(res->ai_addr,
   28.84 +                        res->ai_addrlen,
   28.85 +                        hostname,
   28.86 +                        NI_MAXHOST,
   28.87 +                        NULL,
   28.88 +                        0,
   28.89 +                        NI_NAMEREQD);
   28.90 +
   28.91 +            /* if getnameinfo fails hostname is still the value
   28.92 +               from gethostname */
   28.93 +
   28.94 +            freeaddrinfo(res);
   28.95          }
   28.96      }
   28.97      return (*env)->NewStringUTF(env, hostname);
   28.98 @@ -140,14 +117,9 @@
   28.99                                                  jstring host) {
  28.100      const char *hostname;
  28.101      jobjectArray ret = 0;
  28.102 -    struct hostent res, *hp = 0;
  28.103 -    // this buffer must be pointer-aligned so is declared
  28.104 -    // with pointer type
  28.105 -    char *buf[HENT_BUF_SIZE/(sizeof (char *))];
  28.106 -
  28.107 -    /* temporary buffer, on the off chance we need to expand */
  28.108 -    char *tmp = NULL;
  28.109 -    int h_error=0;
  28.110 +    int retLen = 0;
  28.111 +    int error = 0;
  28.112 +    struct addrinfo hints, *res, *resNew = NULL;
  28.113  
  28.114      if (!initialized) {
  28.115        ni_iacls = (*env)->FindClass(env, "java/net/InetAddress");
  28.116 @@ -168,6 +140,11 @@
  28.117      hostname = JNU_GetStringPlatformChars(env, host, JNI_FALSE);
  28.118      CHECK_NULL_RETURN(hostname, NULL);
  28.119  
  28.120 +    /* Try once, with our static buffer. */
  28.121 +    memset(&hints, 0, sizeof(hints));
  28.122 +    hints.ai_flags = AI_CANONNAME;
  28.123 +    hints.ai_family = AF_INET;
  28.124 +
  28.125  #ifdef __solaris__
  28.126      /*
  28.127       * Workaround for Solaris bug 4160367 - if a hostname contains a
  28.128 @@ -181,69 +158,93 @@
  28.129      }
  28.130  #endif
  28.131  
  28.132 -    /* Try once, with our static buffer. */
  28.133 -#ifdef __GLIBC__
  28.134 -    gethostbyname_r(hostname, &res, (char*)buf, sizeof(buf), &hp, &h_error);
  28.135 -#else
  28.136 -    hp = gethostbyname_r(hostname, &res, (char*)buf, sizeof(buf), &h_error);
  28.137 -#endif
  28.138 +    error = getaddrinfo(hostname, NULL, &hints, &res);
  28.139  
  28.140 -    /* With the re-entrant system calls, it's possible that the buffer
  28.141 -     * we pass to it is not large enough to hold an exceptionally
  28.142 -     * large DNS entry.  This is signaled by errno->ERANGE.  We try once
  28.143 -     * more, with a very big size.
  28.144 -     */
  28.145 -    if (hp == NULL && errno == ERANGE) {
  28.146 -        if ((tmp = (char*)malloc(BIG_HENT_BUF_SIZE))) {
  28.147 -#ifdef __GLIBC__
  28.148 -            gethostbyname_r(hostname, &res, tmp, BIG_HENT_BUF_SIZE,
  28.149 -                            &hp, &h_error);
  28.150 -#else
  28.151 -            hp = gethostbyname_r(hostname, &res, tmp, BIG_HENT_BUF_SIZE,
  28.152 -                                 &h_error);
  28.153 -#endif
  28.154 -        }
  28.155 -    }
  28.156 -    if (hp != NULL) {
  28.157 -        struct in_addr **addrp = (struct in_addr **) hp->h_addr_list;
  28.158 +    if (error) {
  28.159 +        /* report error */
  28.160 +        ThrowUnknownHostExceptionWithGaiError(env, hostname, error);
  28.161 +        JNU_ReleaseStringPlatformChars(env, host, hostname);
  28.162 +        return NULL;
  28.163 +    } else {
  28.164          int i = 0;
  28.165 +        struct addrinfo *itr, *last = NULL, *iterator = res;
  28.166  
  28.167 -        while (*addrp != (struct in_addr *) 0) {
  28.168 -            i++;
  28.169 -            addrp++;
  28.170 +        while (iterator != NULL) {
  28.171 +            // remove the duplicate one
  28.172 +            int skip = 0;
  28.173 +            itr = resNew;
  28.174 +            while (itr != NULL) {
  28.175 +                struct sockaddr_in *addr1, *addr2;
  28.176 +                addr1 = (struct sockaddr_in *)iterator->ai_addr;
  28.177 +                addr2 = (struct sockaddr_in *)itr->ai_addr;
  28.178 +                if (addr1->sin_addr.s_addr ==
  28.179 +                    addr2->sin_addr.s_addr) {
  28.180 +                    skip = 1;
  28.181 +                    break;
  28.182 +                }
  28.183 +                itr = itr->ai_next;
  28.184 +            }
  28.185 +
  28.186 +            if (!skip) {
  28.187 +                struct addrinfo *next
  28.188 +                    = (struct addrinfo*) malloc(sizeof(struct addrinfo));
  28.189 +                if (!next) {
  28.190 +                    JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
  28.191 +                    ret = NULL;
  28.192 +                    goto cleanupAndReturn;
  28.193 +                }
  28.194 +                memcpy(next, iterator, sizeof(struct addrinfo));
  28.195 +                next->ai_next = NULL;
  28.196 +                if (resNew == NULL) {
  28.197 +                    resNew = next;
  28.198 +                } else {
  28.199 +                    last->ai_next = next;
  28.200 +                }
  28.201 +                last = next;
  28.202 +                i++;
  28.203 +            }
  28.204 +            iterator = iterator->ai_next;
  28.205          }
  28.206  
  28.207 -        ret = (*env)->NewObjectArray(env, i, ni_iacls, NULL);
  28.208 +        retLen = i;
  28.209 +        iterator = resNew;
  28.210 +
  28.211 +        ret = (*env)->NewObjectArray(env, retLen, ni_iacls, NULL);
  28.212 +
  28.213          if (IS_NULL(ret)) {
  28.214              /* we may have memory to free at the end of this */
  28.215              goto cleanupAndReturn;
  28.216          }
  28.217 -        addrp = (struct in_addr **) hp->h_addr_list;
  28.218 +
  28.219          i = 0;
  28.220 -        while (*addrp) {
  28.221 -          jobject iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID);
  28.222 -          if (IS_NULL(iaObj)) {
  28.223 -            ret = NULL;
  28.224 -            goto cleanupAndReturn;
  28.225 -          }
  28.226 -          (*env)->SetIntField(env, iaObj, ni_iaaddressID,
  28.227 -                              ntohl((*addrp)->s_addr));
  28.228 -          (*env)->SetObjectField(env, iaObj, ni_iahostID, host);
  28.229 -          (*env)->SetObjectArrayElement(env, ret, i, iaObj);
  28.230 -          addrp++;
  28.231 -          i++;
  28.232 +        while (iterator != NULL) {
  28.233 +            jobject iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID);
  28.234 +            if (IS_NULL(iaObj)) {
  28.235 +                ret = NULL;
  28.236 +                goto cleanupAndReturn;
  28.237 +            }
  28.238 +            (*env)->SetIntField(env, iaObj, ni_iaaddressID,
  28.239 +                                ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr));
  28.240 +            (*env)->SetObjectField(env, iaObj, ni_iahostID, host);
  28.241 +            (*env)->SetObjectArrayElement(env, ret, i++, iaObj);
  28.242 +            iterator = iterator->ai_next;
  28.243          }
  28.244 -    } else {
  28.245 -        JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
  28.246 -                        (char *)hostname);
  28.247 -        ret = NULL;
  28.248      }
  28.249  
  28.250 -cleanupAndReturn:
  28.251 -    JNU_ReleaseStringPlatformChars(env, host, hostname);
  28.252 -    if (tmp != NULL) {
  28.253 -        free(tmp);
  28.254 + cleanupAndReturn:
  28.255 +    {
  28.256 +        struct addrinfo *iterator, *tmp;
  28.257 +        iterator = resNew;
  28.258 +        while (iterator != NULL) {
  28.259 +            tmp = iterator;
  28.260 +            iterator = iterator->ai_next;
  28.261 +            free(tmp);
  28.262 +        }
  28.263 +        JNU_ReleaseStringPlatformChars(env, host, hostname);
  28.264      }
  28.265 +
  28.266 +    freeaddrinfo(res);
  28.267 +
  28.268      return ret;
  28.269  }
  28.270  
  28.271 @@ -256,63 +257,38 @@
  28.272  Java_java_net_Inet4AddressImpl_getHostByAddr(JNIEnv *env, jobject this,
  28.273                                              jbyteArray addrArray) {
  28.274      jstring ret = NULL;
  28.275 +
  28.276 +    char host[NI_MAXHOST+1];
  28.277 +    int error = 0;
  28.278 +    int len = 0;
  28.279 +    jbyte caddr[4];
  28.280 +
  28.281 +    struct sockaddr_in him4;
  28.282 +    struct sockaddr *sa;
  28.283 +
  28.284      jint addr;
  28.285 -    struct hostent hent, *hp = 0;
  28.286 -    // this buffer must be pointer-aligned so is declared
  28.287 -    // with pointer type
  28.288 -    char *buf[HENT_BUF_SIZE/(sizeof (char *))];
  28.289 -    int h_error = 0;
  28.290 -    char *tmp = NULL;
  28.291 -
  28.292 -    /*
  28.293 -     * We are careful here to use the reentrant version of
  28.294 -     * gethostbyname because at the Java level this routine is not
  28.295 -     * protected by any synchronization.
  28.296 -     *
  28.297 -     * Still keeping the reentrant platform dependent calls temporarily
  28.298 -     * We should probably conform to one interface later.
  28.299 -     *
  28.300 -     */
  28.301 -    jbyte caddr[4];
  28.302      (*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr);
  28.303      addr = ((caddr[0]<<24) & 0xff000000);
  28.304      addr |= ((caddr[1] <<16) & 0xff0000);
  28.305      addr |= ((caddr[2] <<8) & 0xff00);
  28.306      addr |= (caddr[3] & 0xff);
  28.307 -    addr = htonl(addr);
  28.308 -#ifdef __GLIBC__
  28.309 -    gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET, &hent,
  28.310 -                    (char*)buf, sizeof(buf), &hp, &h_error);
  28.311 -#else
  28.312 -    hp = gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET, &hent,
  28.313 -                         (char*)buf, sizeof(buf), &h_error);
  28.314 -#endif
  28.315 -    /* With the re-entrant system calls, it's possible that the buffer
  28.316 -     * we pass to it is not large enough to hold an exceptionally
  28.317 -     * large DNS entry.  This is signaled by errno->ERANGE.  We try once
  28.318 -     * more, with a very big size.
  28.319 -     */
  28.320 -    if (hp == NULL && errno == ERANGE) {
  28.321 -        if ((tmp = (char*)malloc(BIG_HENT_BUF_SIZE))) {
  28.322 -#ifdef __GLIBC__
  28.323 -            gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET,
  28.324 -                            &hent, tmp, BIG_HENT_BUF_SIZE, &hp, &h_error);
  28.325 -#else
  28.326 -            hp = gethostbyaddr_r((char *)&addr, sizeof(addr), AF_INET,
  28.327 -                                 &hent, tmp, BIG_HENT_BUF_SIZE, &h_error);
  28.328 -#endif
  28.329 -        } else {
  28.330 -            JNU_ThrowOutOfMemoryError(env, "getHostByAddr");
  28.331 -        }
  28.332 +    memset((void *) &him4, 0, sizeof(him4));
  28.333 +    him4.sin_addr.s_addr = (uint32_t) htonl(addr);
  28.334 +    him4.sin_family = AF_INET;
  28.335 +    sa = (struct sockaddr *) &him4;
  28.336 +    len = sizeof(him4);
  28.337 +
  28.338 +    error = getnameinfo(sa, len, host, NI_MAXHOST, NULL, 0,
  28.339 +                        NI_NAMEREQD);
  28.340 +
  28.341 +    if (!error) {
  28.342 +        ret = (*env)->NewStringUTF(env, host);
  28.343      }
  28.344 -    if (hp == NULL) {
  28.345 +
  28.346 +    if (ret == NULL) {
  28.347          JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException", NULL);
  28.348 -    } else {
  28.349 -        ret = (*env)->NewStringUTF(env, hp->h_name);
  28.350      }
  28.351 -    if (tmp) {
  28.352 -        free(tmp);
  28.353 -    }
  28.354 +
  28.355      return ret;
  28.356  }
  28.357  
    29.1 --- a/src/solaris/native/java/net/Inet6AddressImpl.c	Fri Nov 18 16:57:01 2011 -0800
    29.2 +++ b/src/solaris/native/java/net/Inet6AddressImpl.c	Mon Nov 28 15:15:50 2011 -0800
    29.3 @@ -82,31 +82,29 @@
    29.4           * We use thread-safe system calls.
    29.5           */
    29.6  #ifdef AF_INET6
    29.7 -        if (NET_addrtransAvailable()) {
    29.8 -            struct addrinfo  hints, *res;
    29.9 -            int error;
   29.10 +        struct addrinfo  hints, *res;
   29.11 +        int error;
   29.12  
   29.13 -            bzero(&hints, sizeof(hints));
   29.14 -            hints.ai_flags = AI_CANONNAME;
   29.15 -            hints.ai_family = AF_UNSPEC;
   29.16 +        memset(&hints, 0, sizeof(hints));
   29.17 +        hints.ai_flags = AI_CANONNAME;
   29.18 +        hints.ai_family = AF_UNSPEC;
   29.19  
   29.20 -            error = (*getaddrinfo_ptr)(hostname, NULL, &hints, &res);
   29.21 +        error = getaddrinfo(hostname, NULL, &hints, &res);
   29.22  
   29.23 -            if (error == 0) {
   29.24 -                /* host is known to name service */
   29.25 -                error = (*getnameinfo_ptr)(res->ai_addr,
   29.26 -                                           res->ai_addrlen,
   29.27 -                                           hostname,
   29.28 -                                           NI_MAXHOST,
   29.29 -                                           NULL,
   29.30 -                                           0,
   29.31 -                                           NI_NAMEREQD);
   29.32 +        if (error == 0) {
   29.33 +            /* host is known to name service */
   29.34 +            error = getnameinfo(res->ai_addr,
   29.35 +                                res->ai_addrlen,
   29.36 +                                hostname,
   29.37 +                                NI_MAXHOST,
   29.38 +                                NULL,
   29.39 +                                0,
   29.40 +                                NI_NAMEREQD);
   29.41  
   29.42 -                /* if getnameinfo fails hostname is still the value
   29.43 -                   from gethostname */
   29.44 +            /* if getnameinfo fails hostname is still the value
   29.45 +               from gethostname */
   29.46  
   29.47 -                (*freeaddrinfo_ptr)(res);
   29.48 -            }
   29.49 +            freeaddrinfo(res);
   29.50          }
   29.51  #endif /* AF_INET6 */
   29.52  #endif /* __linux__ */
   29.53 @@ -173,193 +171,191 @@
   29.54      CHECK_NULL_RETURN(hostname, NULL);
   29.55  
   29.56  #ifdef AF_INET6
   29.57 -    if (NET_addrtransAvailable()) {
   29.58 -        static jfieldID ia_preferIPv6AddressID;
   29.59 +    static jfieldID ia_preferIPv6AddressID;
   29.60 +    if (ia_preferIPv6AddressID == NULL) {
   29.61 +        jclass c = (*env)->FindClass(env,"java/net/InetAddress");
   29.62 +        if (c)  {
   29.63 +            ia_preferIPv6AddressID =
   29.64 +                (*env)->GetStaticFieldID(env, c, "preferIPv6Address", "Z");
   29.65 +        }
   29.66          if (ia_preferIPv6AddressID == NULL) {
   29.67 -            jclass c = (*env)->FindClass(env,"java/net/InetAddress");
   29.68 -            if (c)  {
   29.69 -                ia_preferIPv6AddressID =
   29.70 -                    (*env)->GetStaticFieldID(env, c, "preferIPv6Address", "Z");
   29.71 -            }
   29.72 -            if (ia_preferIPv6AddressID == NULL) {
   29.73 -                JNU_ReleaseStringPlatformChars(env, host, hostname);
   29.74 -                return NULL;
   29.75 -            }
   29.76 -        }
   29.77 -        /* get the address preference */
   29.78 -        preferIPv6Address
   29.79 -            = (*env)->GetStaticBooleanField(env, ia_class, ia_preferIPv6AddressID);
   29.80 -
   29.81 -        /* Try once, with our static buffer. */
   29.82 -        bzero(&hints, sizeof(hints));
   29.83 -        hints.ai_flags = AI_CANONNAME;
   29.84 -        hints.ai_family = AF_UNSPEC;
   29.85 -
   29.86 -#ifdef __solaris__
   29.87 -        /*
   29.88 -         * Workaround for Solaris bug 4160367 - if a hostname contains a
   29.89 -         * white space then 0.0.0.0 is returned
   29.90 -         */
   29.91 -        if (isspace((unsigned char)hostname[0])) {
   29.92 -            JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
   29.93 -                            hostname);
   29.94              JNU_ReleaseStringPlatformChars(env, host, hostname);
   29.95              return NULL;
   29.96          }
   29.97 +    }
   29.98 +    /* get the address preference */
   29.99 +    preferIPv6Address
  29.100 +        = (*env)->GetStaticBooleanField(env, ia_class, ia_preferIPv6AddressID);
  29.101 +
  29.102 +    /* Try once, with our static buffer. */
  29.103 +    memset(&hints, 0, sizeof(hints));
  29.104 +    hints.ai_flags = AI_CANONNAME;
  29.105 +    hints.ai_family = AF_UNSPEC;
  29.106 +
  29.107 +#ifdef __solaris__
  29.108 +    /*
  29.109 +     * Workaround for Solaris bug 4160367 - if a hostname contains a
  29.110 +     * white space then 0.0.0.0 is returned
  29.111 +     */
  29.112 +    if (isspace((unsigned char)hostname[0])) {
  29.113 +        JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
  29.114 +                        hostname);
  29.115 +        JNU_ReleaseStringPlatformChars(env, host, hostname);
  29.116 +        return NULL;
  29.117 +    }
  29.118  #endif
  29.119  
  29.120 -        error = (*getaddrinfo_ptr)(hostname, NULL, &hints, &res);
  29.121 +    error = getaddrinfo(hostname, NULL, &hints, &res);
  29.122  
  29.123 -        if (error) {
  29.124 -            /* report error */
  29.125 -            ThrowUnknownHostExceptionWithGaiError(env, hostname, error);
  29.126 -            JNU_ReleaseStringPlatformChars(env, host, hostname);
  29.127 -            return NULL;
  29.128 -        } else {
  29.129 -            int i = 0;
  29.130 -            int inetCount = 0, inet6Count = 0, inetIndex, inet6Index;
  29.131 -            struct addrinfo *itr, *last = NULL, *iterator = res;
  29.132 -            while (iterator != NULL) {
  29.133 -                int skip = 0;
  29.134 -                itr = resNew;
  29.135 -                while (itr != NULL) {
  29.136 -                    if (iterator->ai_family == itr->ai_family &&
  29.137 -                        iterator->ai_addrlen == itr->ai_addrlen) {
  29.138 -                        if (itr->ai_family == AF_INET) { /* AF_INET */
  29.139 -                            struct sockaddr_in *addr1, *addr2;
  29.140 -                            addr1 = (struct sockaddr_in *)iterator->ai_addr;
  29.141 -                            addr2 = (struct sockaddr_in *)itr->ai_addr;
  29.142 -                            if (addr1->sin_addr.s_addr ==
  29.143 -                                addr2->sin_addr.s_addr) {
  29.144 -                                skip = 1;
  29.145 -                                break;
  29.146 -                            }
  29.147 -                        } else {
  29.148 -                            int t;
  29.149 -                            struct sockaddr_in6 *addr1, *addr2;
  29.150 -                            addr1 = (struct sockaddr_in6 *)iterator->ai_addr;
  29.151 -                            addr2 = (struct sockaddr_in6 *)itr->ai_addr;
  29.152 +    if (error) {
  29.153 +        /* report error */
  29.154 +        ThrowUnknownHostExceptionWithGaiError(env, hostname, error);
  29.155 +        JNU_ReleaseStringPlatformChars(env, host, hostname);
  29.156 +        return NULL;
  29.157 +    } else {
  29.158 +        int i = 0;
  29.159 +        int inetCount = 0, inet6Count = 0, inetIndex, inet6Index;
  29.160 +        struct addrinfo *itr, *last = NULL, *iterator = res;
  29.161 +        while (iterator != NULL) {
  29.162 +            int skip = 0;
  29.163 +            itr = resNew;
  29.164 +            while (itr != NULL) {
  29.165 +                if (iterator->ai_family == itr->ai_family &&
  29.166 +                    iterator->ai_addrlen == itr->ai_addrlen) {
  29.167 +                    if (itr->ai_family == AF_INET) { /* AF_INET */
  29.168 +                        struct sockaddr_in *addr1, *addr2;
  29.169 +                        addr1 = (struct sockaddr_in *)iterator->ai_addr;
  29.170 +                        addr2 = (struct sockaddr_in *)itr->ai_addr;
  29.171 +                        if (addr1->sin_addr.s_addr ==
  29.172 +                            addr2->sin_addr.s_addr) {
  29.173 +                            skip = 1;
  29.174 +                            break;
  29.175 +                        }
  29.176 +                    } else {
  29.177 +                        int t;
  29.178 +                        struct sockaddr_in6 *addr1, *addr2;
  29.179 +                        addr1 = (struct sockaddr_in6 *)iterator->ai_addr;
  29.180 +                        addr2 = (struct sockaddr_in6 *)itr->ai_addr;
  29.181  
  29.182 -                            for (t = 0; t < 16; t++) {
  29.183 -                                if (addr1->sin6_addr.s6_addr[t] !=
  29.184 -                                    addr2->sin6_addr.s6_addr[t]) {
  29.185 -                                    break;
  29.186 -                                }
  29.187 -                            }
  29.188 -                            if (t < 16) {
  29.189 -                                itr = itr->ai_next;
  29.190 -                                continue;
  29.191 -                            } else {
  29.192 -                                skip = 1;
  29.193 +                        for (t = 0; t < 16; t++) {
  29.194 +                            if (addr1->sin6_addr.s6_addr[t] !=
  29.195 +                                addr2->sin6_addr.s6_addr[t]) {
  29.196                                  break;
  29.197                              }
  29.198                          }
  29.199 -                    } else if (iterator->ai_family != AF_INET &&
  29.200 -                               iterator->ai_family != AF_INET6) {
  29.201 -                        /* we can't handle other family types */
  29.202 -                        skip = 1;
  29.203 -                        break;
  29.204 +                        if (t < 16) {
  29.205 +                            itr = itr->ai_next;
  29.206 +                            continue;
  29.207 +                        } else {
  29.208 +                            skip = 1;
  29.209 +                            break;
  29.210 +                        }
  29.211                      }
  29.212 -                    itr = itr->ai_next;
  29.213 +                } else if (iterator->ai_family != AF_INET &&
  29.214 +                           iterator->ai_family != AF_INET6) {
  29.215 +                    /* we can't handle other family types */
  29.216 +                    skip = 1;
  29.217 +                    break;
  29.218                  }
  29.219 -
  29.220 -                if (!skip) {
  29.221 -                    struct addrinfo *next
  29.222 -                        = (struct addrinfo*) malloc(sizeof(struct addrinfo));
  29.223 -                    if (!next) {
  29.224 -                        JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
  29.225 -                        ret = NULL;
  29.226 -                        goto cleanupAndReturn;
  29.227 -                    }
  29.228 -                    memcpy(next, iterator, sizeof(struct addrinfo));
  29.229 -                    next->ai_next = NULL;
  29.230 -                    if (resNew == NULL) {
  29.231 -                        resNew = next;
  29.232 -                    } else {
  29.233 -                        last->ai_next = next;
  29.234 -                    }
  29.235 -                    last = next;
  29.236 -                    i++;
  29.237 -                    if (iterator->ai_family == AF_INET) {
  29.238 -                        inetCount ++;
  29.239 -                    } else if (iterator->ai_family == AF_INET6) {
  29.240 -                        inet6Count ++;
  29.241 -                    }
  29.242 -                }
  29.243 -                iterator = iterator->ai_next;
  29.244 -            }
  29.245 -            retLen = i;
  29.246 -            iterator = resNew;
  29.247 -
  29.248 -            ret = (*env)->NewObjectArray(env, retLen, ni_iacls, NULL);
  29.249 -
  29.250 -            if (IS_NULL(ret)) {
  29.251 -                /* we may have memory to free at the end of this */
  29.252 -                goto cleanupAndReturn;
  29.253 +                itr = itr->ai_next;
  29.254              }
  29.255  
  29.256 -            if (preferIPv6Address) {
  29.257 -                /* AF_INET addresses will be offset by inet6Count */
  29.258 -                inetIndex = inet6Count;
  29.259 -                inet6Index = 0;
  29.260 -            } else {
  29.261 -                /* AF_INET6 addresses will be offset by inetCount */
  29.262 -                inetIndex = 0;
  29.263 -                inet6Index = inetCount;
  29.264 +            if (!skip) {
  29.265 +                struct addrinfo *next
  29.266 +                    = (struct addrinfo*) malloc(sizeof(struct addrinfo));
  29.267 +                if (!next) {
  29.268 +                    JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
  29.269 +                    ret = NULL;
  29.270 +                    goto cleanupAndReturn;
  29.271 +                }
  29.272 +                memcpy(next, iterator, sizeof(struct addrinfo));
  29.273 +                next->ai_next = NULL;
  29.274 +                if (resNew == NULL) {
  29.275 +                    resNew = next;
  29.276 +                } else {
  29.277 +                    last->ai_next = next;
  29.278 +                }
  29.279 +                last = next;
  29.280 +                i++;
  29.281 +                if (iterator->ai_family == AF_INET) {
  29.282 +                    inetCount ++;
  29.283 +                } else if (iterator->ai_family == AF_INET6) {
  29.284 +                    inet6Count ++;
  29.285 +                }
  29.286              }
  29.287 +            iterator = iterator->ai_next;
  29.288 +        }
  29.289 +        retLen = i;
  29.290 +        iterator = resNew;
  29.291  
  29.292 -            while (iterator != NULL) {
  29.293 -              if (iterator->ai_family == AF_INET) {
  29.294 +        ret = (*env)->NewObjectArray(env, retLen, ni_iacls, NULL);
  29.295 +
  29.296 +        if (IS_NULL(ret)) {
  29.297 +            /* we may have memory to free at the end of this */
  29.298 +            goto cleanupAndReturn;
  29.299 +        }
  29.300 +
  29.301 +        if (preferIPv6Address) {
  29.302 +            /* AF_INET addresses will be offset by inet6Count */
  29.303 +            inetIndex = inet6Count;
  29.304 +            inet6Index = 0;
  29.305 +        } else {
  29.306 +            /* AF_INET6 addresses will be offset by inetCount */
  29.307 +            inetIndex = 0;
  29.308 +            inet6Index = inetCount;
  29.309 +        }
  29.310 +
  29.311 +        while (iterator != NULL) {
  29.312 +            if (iterator->ai_family == AF_INET) {
  29.313                  jobject iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID);
  29.314                  if (IS_NULL(iaObj)) {
  29.315 -                  ret = NULL;
  29.316 -                  goto cleanupAndReturn;
  29.317 +                    ret = NULL;
  29.318 +                    goto cleanupAndReturn;
  29.319                  }
  29.320                  (*env)->SetIntField(env, iaObj, ni_iaaddressID,
  29.321                                      ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr));
  29.322                  (*env)->SetObjectField(env, iaObj, ni_iahostID, host);
  29.323                  (*env)->SetObjectArrayElement(env, ret, inetIndex, iaObj);
  29.324                  inetIndex++;
  29.325 -              } else if (iterator->ai_family == AF_INET6) {
  29.326 +            } else if (iterator->ai_family == AF_INET6) {
  29.327                  jint scope = 0;
  29.328                  jbyteArray ipaddress;
  29.329  
  29.330                  jobject iaObj = (*env)->NewObject(env, ni_ia6cls, ni_ia6ctrID);
  29.331                  if (IS_NULL(iaObj)) {
  29.332 -                  ret = NULL;
  29.333 -                  goto cleanupAndReturn;
  29.334 +                    ret = NULL;
  29.335 +                    goto cleanupAndReturn;
  29.336                  }
  29.337                  ipaddress = (*env)->NewByteArray(env, 16);
  29.338                  if (IS_NULL(ipaddress)) {
  29.339 -                  ret = NULL;
  29.340 -                  goto cleanupAndReturn;
  29.341 +                    ret = NULL;
  29.342 +                    goto cleanupAndReturn;
  29.343                  }
  29.344                  (*env)->SetByteArrayRegion(env, ipaddress, 0, 16,
  29.345                                             (jbyte *)&(((struct sockaddr_in6*)iterator->ai_addr)->sin6_addr));
  29.346  #ifdef __linux__
  29.347                  if (!kernelIsV22()) {
  29.348 -                  scope = ((struct sockaddr_in6*)iterator->ai_addr)->sin6_scope_id;
  29.349 +                    scope = ((struct sockaddr_in6*)iterator->ai_addr)->sin6_scope_id;
  29.350                  }
  29.351  #else
  29.352                  scope = ((struct sockaddr_in6*)iterator->ai_addr)->sin6_scope_id;
  29.353  #endif
  29.354                  if (scope != 0) { /* zero is default value, no need to set */
  29.355 -                  (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope);
  29.356 -                  (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE);
  29.357 +                    (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope);
  29.358 +                    (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE);
  29.359                  }
  29.360                  (*env)->SetObjectField(env, iaObj, ni_ia6ipaddressID, ipaddress);
  29.361                  (*env)->SetObjectField(env, iaObj, ni_iahostID, host);
  29.362                  (*env)->SetObjectArrayElement(env, ret, inet6Index, iaObj);
  29.363                  inet6Index++;
  29.364 -              }
  29.365 -              iterator = iterator->ai_next;
  29.366              }
  29.367 +            iterator = iterator->ai_next;
  29.368          }
  29.369      }
  29.370  
  29.371 -cleanupAndReturn:
  29.372 + cleanupAndReturn:
  29.373      {
  29.374 -        struct addrinfo *iterator, *tmp;
  29.375 +      struct addrinfo *iterator, *tmp;
  29.376          iterator = resNew;
  29.377          while (iterator != NULL) {
  29.378              tmp = iterator;
  29.379 @@ -369,8 +365,7 @@
  29.380          JNU_ReleaseStringPlatformChars(env, host, hostname);
  29.381      }
  29.382  
  29.383 -    if (NET_addrtransAvailable())
  29.384 -        (*freeaddrinfo_ptr)(res);
  29.385 +    freeaddrinfo(res);
  29.386  #endif /* AF_INET6 */
  29.387  
  29.388      return ret;
  29.389 @@ -393,44 +388,42 @@
  29.390      int len = 0;
  29.391      jbyte caddr[16];
  29.392  
  29.393 -    if (NET_addrtransAvailable()) {
  29.394 -        struct sockaddr_in him4;
  29.395 -        struct sockaddr_in6 him6;
  29.396 -        struct sockaddr *sa;
  29.397 +    struct sockaddr_in him4;
  29.398 +    struct sockaddr_in6 him6;
  29.399 +    struct sockaddr *sa;
  29.400  
  29.401 +    /*
  29.402 +     * For IPv4 addresses construct a sockaddr_in structure.
  29.403 +     */
  29.404 +    if ((*env)->GetArrayLength(env, addrArray) == 4) {
  29.405 +        jint addr;
  29.406 +        (*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr);
  29.407 +        addr = ((caddr[0]<<24) & 0xff000000);
  29.408 +        addr |= ((caddr[1] <<16) & 0xff0000);
  29.409 +        addr |= ((caddr[2] <<8) & 0xff00);
  29.410 +        addr |= (caddr[3] & 0xff);
  29.411 +        memset((void *) &him4, 0, sizeof(him4));
  29.412 +        him4.sin_addr.s_addr = (uint32_t) htonl(addr);
  29.413 +        him4.sin_family = AF_INET;
  29.414 +        sa = (struct sockaddr *) &him4;
  29.415 +        len = sizeof(him4);
  29.416 +    } else {
  29.417          /*
  29.418 -         * For IPv4 addresses construct a sockaddr_in structure.
  29.419 +         * For IPv6 address construct a sockaddr_in6 structure.
  29.420           */
  29.421 -        if ((*env)->GetArrayLength(env, addrArray) == 4) {
  29.422 -            jint addr;
  29.423 -            (*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr);
  29.424 -            addr = ((caddr[0]<<24) & 0xff000000);
  29.425 -            addr |= ((caddr[1] <<16) & 0xff0000);
  29.426 -            addr |= ((caddr[2] <<8) & 0xff00);
  29.427 -            addr |= (caddr[3] & 0xff);
  29.428 -            memset((void *) &him4, 0, sizeof(him4));
  29.429 -            him4.sin_addr.s_addr = (uint32_t) htonl(addr);
  29.430 -            him4.sin_family = AF_INET;
  29.431 -            sa = (struct sockaddr *) &him4;
  29.432 -            len = sizeof(him4);
  29.433 -        } else {
  29.434 -            /*
  29.435 -             * For IPv6 address construct a sockaddr_in6 structure.
  29.436 -             */
  29.437 -            (*env)->GetByteArrayRegion(env, addrArray, 0, 16, caddr);
  29.438 -            memset((void *) &him6, 0, sizeof(him6));
  29.439 -            memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr) );
  29.440 -            him6.sin6_family = AF_INET6;
  29.441 -            sa = (struct sockaddr *) &him6 ;
  29.442 -            len = sizeof(him6) ;
  29.443 -        }
  29.444 +        (*env)->GetByteArrayRegion(env, addrArray, 0, 16, caddr);
  29.445 +        memset((void *) &him6, 0, sizeof(him6));
  29.446 +        memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr) );
  29.447 +        him6.sin6_family = AF_INET6;
  29.448 +        sa = (struct sockaddr *) &him6 ;
  29.449 +        len = sizeof(him6) ;
  29.450 +    }
  29.451  
  29.452 -        error = (*getnameinfo_ptr)(sa, len, host, NI_MAXHOST, NULL, 0,
  29.453 -                                   NI_NAMEREQD);
  29.454 +    error = getnameinfo(sa, len, host, NI_MAXHOST, NULL, 0,
  29.455 +                        NI_NAMEREQD);
  29.456  
  29.457 -        if (!error) {
  29.458 -            ret = (*env)->NewStringUTF(env, host);
  29.459 -        }
  29.460 +    if (!error) {
  29.461 +        ret = (*env)->NewStringUTF(env, host);
  29.462      }
  29.463  #endif /* AF_INET6 */
  29.464  
    30.1 --- a/src/solaris/native/java/net/net_util_md.c	Fri Nov 18 16:57:01 2011 -0800
    30.2 +++ b/src/solaris/native/java/net/net_util_md.c	Mon Nov 28 15:15:50 2011 -0800
    30.3 @@ -377,37 +377,12 @@
    30.4       *  we should also check if the APIs are available.
    30.5       */
    30.6      ipv6_fn = JVM_FindLibraryEntry(RTLD_DEFAULT, "inet_pton");
    30.7 +    close(fd);
    30.8      if (ipv6_fn == NULL ) {
    30.9 -        close(fd);
   30.10          return JNI_FALSE;
   30.11 +    } else {
   30.12 +        return JNI_TRUE;
   30.13      }
   30.14 -
   30.15 -    /*
   30.16 -     * We've got the library, let's get the pointers to some
   30.17 -     * IPV6 specific functions. We have to do that because, at least
   30.18 -     * on Solaris we may build on a system without IPV6 networking
   30.19 -     * libraries, therefore we can't have a hard link to these
   30.20 -     * functions.
   30.21 -     */
   30.22 -    getaddrinfo_ptr = (getaddrinfo_f)
   30.23 -        JVM_FindLibraryEntry(RTLD_DEFAULT, "getaddrinfo");
   30.24 -
   30.25 -    freeaddrinfo_ptr = (freeaddrinfo_f)
   30.26 -        JVM_FindLibraryEntry(RTLD_DEFAULT, "freeaddrinfo");
   30.27 -
   30.28 -    gai_strerror_ptr = (gai_strerror_f)
   30.29 -        JVM_FindLibraryEntry(RTLD_DEFAULT, "gai_strerror");
   30.30 -
   30.31 -    getnameinfo_ptr = (getnameinfo_f)
   30.32 -        JVM_FindLibraryEntry(RTLD_DEFAULT, "getnameinfo");
   30.33 -
   30.34 -    if (freeaddrinfo_ptr == NULL || getnameinfo_ptr == NULL) {
   30.35 -        /* We need all 3 of them */
   30.36 -        getaddrinfo_ptr = NULL;
   30.37 -    }
   30.38 -
   30.39 -    close(fd);
   30.40 -    return JNI_TRUE;
   30.41  #endif /* AF_INET6 */
   30.42  }
   30.43  
   30.44 @@ -920,10 +895,6 @@
   30.45      return 1;
   30.46  }
   30.47  
   30.48 -jboolean NET_addrtransAvailable() {
   30.49 -    return (jboolean)(getaddrinfo_ptr != NULL);
   30.50 -}
   30.51 -
   30.52  /*
   30.53   * Map the Java level socket option to the platform specific
   30.54   * level and option name.
    31.1 --- a/src/solaris/native/java/net/net_util_md.h	Fri Nov 18 16:57:01 2011 -0800
    31.2 +++ b/src/solaris/native/java/net/net_util_md.h	Mon Nov 28 15:15:50 2011 -0800
    31.3 @@ -102,10 +102,6 @@
    31.4                                             const char* hostname,
    31.5                                             int gai_error);
    31.6  
    31.7 -/* do we have address translation support */
    31.8 -
    31.9 -extern jboolean NET_addrtransAvailable();
   31.10 -
   31.11  #define NET_WAIT_READ   0x01
   31.12  #define NET_WAIT_WRITE  0x02
   31.13  #define NET_WAIT_CONNECT        0x04
    32.1 --- a/src/windows/classes/java/io/FileDescriptor.java	Fri Nov 18 16:57:01 2011 -0800
    32.2 +++ b/src/windows/classes/java/io/FileDescriptor.java	Mon Nov 28 15:15:50 2011 -0800
    32.3 @@ -1,5 +1,5 @@
    32.4  /*
    32.5 - * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
    32.6 + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
    32.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    32.8   *
    32.9   * This code is free software; you can redistribute it and/or modify it
   32.10 @@ -25,7 +25,8 @@
   32.11  
   32.12  package java.io;
   32.13  
   32.14 -import java.util.concurrent.atomic.AtomicInteger;
   32.15 +import java.util.ArrayList;
   32.16 +import java.util.List;
   32.17  
   32.18  /**
   32.19   * Instances of the file descriptor class serve as an opaque handle
   32.20 @@ -45,13 +46,9 @@
   32.21  
   32.22      private long handle;
   32.23  
   32.24 -    /**
   32.25 -     * A use counter for tracking the FIS/FOS/RAF instances that
   32.26 -     * use this FileDescriptor. The FIS/FOS.finalize() will not release
   32.27 -     * the FileDescriptor if it is still under use by any stream.
   32.28 -     */
   32.29 -    private AtomicInteger useCount;
   32.30 -
   32.31 +    private Closeable parent;
   32.32 +    private List<Closeable> otherParents;
   32.33 +    private boolean closed;
   32.34  
   32.35      /**
   32.36       * Constructs an (invalid) FileDescriptor
   32.37 @@ -60,7 +57,6 @@
   32.38      public /**/ FileDescriptor() {
   32.39          fd = -1;
   32.40          handle = -1;
   32.41 -        useCount = new AtomicInteger();
   32.42      }
   32.43  
   32.44      static {
   32.45 @@ -168,13 +164,67 @@
   32.46          return desc;
   32.47      }
   32.48  
   32.49 -    // package private methods used by FIS, FOS and RAF.
   32.50 +    /*
   32.51 +     * Package private methods to track referents.
   32.52 +     * If multiple streams point to the same FileDescriptor, we cycle
   32.53 +     * through the list of all referents and call close()
   32.54 +     */
   32.55  
   32.56 -    int incrementAndGetUseCount() {
   32.57 -        return useCount.incrementAndGet();
   32.58 +    /**
   32.59 +     * Attach a Closeable to this FD for tracking.
   32.60 +     * parent reference is added to otherParents when
   32.61 +     * needed to make closeAll simpler.
   32.62 +     */
   32.63 +    synchronized void attach(Closeable c) {
   32.64 +        if (parent == null) {
   32.65 +            // first caller gets to do this
   32.66 +            parent = c;
   32.67 +        } else if (otherParents == null) {
   32.68 +            otherParents = new ArrayList<>();
   32.69 +            otherParents.add(parent);
   32.70 +            otherParents.add(c);
   32.71 +        } else {
   32.72 +            otherParents.add(c);
   32.73 +        }
   32.74      }
   32.75  
   32.76 -    int decrementAndGetUseCount() {
   32.77 -        return useCount.decrementAndGet();
   32.78 +    /**
   32.79 +     * Cycle through all Closeables sharing this FD and call
   32.80 +     * close() on each one.
   32.81 +     *
   32.82 +     * The caller closeable gets to call close0().
   32.83 +     */
   32.84 +    @SuppressWarnings("try")
   32.85 +    synchronized void closeAll(Closeable releaser) throws IOException {
   32.86 +        if (!closed) {
   32.87 +            closed = true;
   32.88 +            IOException ioe = null;
   32.89 +            try (Closeable c = releaser) {
   32.90 +                if (otherParents != null) {
   32.91 +                    for (Closeable referent : otherParents) {
   32.92 +                        try {
   32.93 +                            referent.close();
   32.94 +                        } catch(IOException x) {
   32.95 +                            if (ioe == null) {
   32.96 +                                ioe = x;
   32.97 +                            } else {
   32.98 +                                ioe.addSuppressed(x);
   32.99 +                            }
  32.100 +                        }
  32.101 +                    }
  32.102 +                }
  32.103 +            } catch(IOException ex) {
  32.104 +                /*
  32.105 +                 * If releaser close() throws IOException
  32.106 +                 * add other exceptions as suppressed.
  32.107 +                 */
  32.108 +                if (ioe != null)
  32.109 +                    ex.addSuppressed(ioe);
  32.110 +                ioe = ex;
  32.111 +            } finally {
  32.112 +                if (ioe != null)
  32.113 +                    throw ioe;
  32.114 +            }
  32.115 +        }
  32.116      }
  32.117  }
    33.1 --- a/src/windows/classes/java/net/PlainSocketImpl.java	Fri Nov 18 16:57:01 2011 -0800
    33.2 +++ b/src/windows/classes/java/net/PlainSocketImpl.java	Mon Nov 28 15:15:50 2011 -0800
    33.3 @@ -314,7 +314,7 @@
    33.4  
    33.5      void socketSetOption(int cmd, boolean on, Object value)
    33.6          throws SocketException {
    33.7 -        socketSetOption(cmd, on, value);
    33.8 +        impl.socketSetOption(cmd, on, value);
    33.9      }
   33.10  
   33.11      int socketGetOption(int opt, Object iaContainerObj) throws SocketException {
    34.1 --- a/src/windows/classes/sun/security/krb5/internal/tools/Klist.java	Fri Nov 18 16:57:01 2011 -0800
    34.2 +++ b/src/windows/classes/sun/security/krb5/internal/tools/Klist.java	Mon Nov 28 15:15:50 2011 -0800
    34.3 @@ -207,7 +207,7 @@
    34.4                  }
    34.5                  if (options[2] == 't') {
    34.6                      System.out.println("\t Time stamp: " +
    34.7 -                            reformat(entries[i].getTimeStamp().toDate().toString()));
    34.8 +                            format(entries[i].getTimeStamp()));
    34.9                  }
   34.10              }
   34.11          }
   34.12 @@ -234,30 +234,39 @@
   34.13              System.out.println("\nDefault principal: " +
   34.14                                 defaultPrincipal + ", " +
   34.15                                 creds.length + " entries found.\n");
   34.16 -        String starttime = null;
   34.17 -        String endtime = null;
   34.18 -        String servicePrincipal = null;
   34.19 -        String etype = null;
   34.20          if (creds != null) {
   34.21              for (int i = 0; i < creds.length; i++) {
   34.22                  try {
   34.23 -                    starttime =
   34.24 -                        reformat(creds[i].getAuthTime().toDate().toString());
   34.25 -                    endtime =
   34.26 -                        reformat(creds[i].getEndTime().toDate().toString());
   34.27 +                    String starttime;
   34.28 +                    String endtime;
   34.29 +                    String renewTill;
   34.30 +                    String servicePrincipal;
   34.31 +                    if (creds[i].getStartTime() != null) {
   34.32 +                        starttime = format(creds[i].getStartTime());
   34.33 +                    } else {
   34.34 +                        starttime = format(creds[i].getAuthTime());
   34.35 +                    }
   34.36 +                    endtime = format(creds[i].getEndTime());
   34.37                      servicePrincipal =
   34.38                          creds[i].getServicePrincipal().toString();
   34.39                      System.out.println("[" + (i + 1) + "] " +
   34.40                                         " Service Principal:  " +
   34.41                                         servicePrincipal);
   34.42 -                    System.out.println("     Valid starting:  " + starttime);
   34.43 -                    System.out.println("     Expires:         " + endtime);
   34.44 +                    System.out.println("     Valid starting:     " + starttime);
   34.45 +                    System.out.println("     Expires:            " + endtime);
   34.46 +                    if (creds[i].getRenewTill() != null) {
   34.47 +                        renewTill = format(creds[i].getRenewTill());
   34.48 +                        System.out.println(
   34.49 +                                "     Renew until:        " + renewTill);
   34.50 +                    }
   34.51                      if (options[0] == 'e') {
   34.52 -                        etype = EType.toString(creds[i].getEType());
   34.53 -                        System.out.println("     Encryption type: " + etype);
   34.54 +                        String eskey = EType.toString(creds[i].getEType());
   34.55 +                        String etkt = EType.toString(creds[i].getTktEType());
   34.56 +                        System.out.println("     EType (skey, tkt):  "
   34.57 +                                + eskey + ", " + etkt);
   34.58                      }
   34.59                      if (options[1] == 'f') {
   34.60 -                        System.out.println("     Flags:           " +
   34.61 +                        System.out.println("     Flags:              " +
   34.62                                             creds[i].getTicketFlags().toString());
   34.63                      }
   34.64                      if (options[2] == 'a') {
   34.65 @@ -312,13 +321,14 @@
   34.66       * and yyyy is the year.
   34.67       * @param date the string form of Date object.
   34.68       */
   34.69 -    String reformat(String date) {
   34.70 +    private String format(KerberosTime kt) {
   34.71 +        String date = kt.toDate().toString();
   34.72          return (date.substring(4, 7) + " " + date.substring(8, 10) +
   34.73                  ", " + date.substring(24)
   34.74 -                + " " + date.substring(11, 16));
   34.75 +                + " " + date.substring(11, 19));
   34.76      }
   34.77      /**
   34.78 -     * Printes out the help information.
   34.79 +     * Prints out the help information.
   34.80       */
   34.81      void printHelp() {
   34.82          System.out.println("\nUsage: klist " +
    35.1 --- a/src/windows/lib/tzmappings	Fri Nov 18 16:57:01 2011 -0800
    35.2 +++ b/src/windows/lib/tzmappings	Mon Nov 28 15:15:50 2011 -0800
    35.3 @@ -167,7 +167,7 @@
    35.4  Argentina Standard Time:900,900::America/Buenos_Aires:
    35.5  Azerbaijan Standard Time:901,901:AZ:Asia/Baku:
    35.6  Bangladesh Standard Time:902,902::Asia/Dhaka:
    35.7 -Central Brazilian Standard Time:903,903:BR:America/Manaus:
    35.8 +Central Brazilian Standard Time:903,903:BR:America/Cuiaba:
    35.9  Central Standard Time (Mexico):904,904::America/Mexico_City:
   35.10  Georgian Standard Time:905,905:GE:Asia/Tbilisi:
   35.11  Jordan Standard Time:906,906:JO:Asia/Amman:
   35.12 @@ -189,5 +189,7 @@
   35.13  Ulaanbaatar Standard Time:922,922::Asia/Ulaanbaatar:
   35.14  Venezuela Standard Time:923,923::America/Caracas:
   35.15  Magadan Standard Time:924,924::Asia/Magadan:
   35.16 -Western Brazilian Standard Time:925,925:BR:America/Rio_Branco:
   35.17 -Armenian Standard Time:926,926:AM:Asia/Yerevan:
   35.18 +Kaliningrad Standard Time:925,925:RU:Europe/Kaliningrad:
   35.19 +Turkey Standard Time:926,926::Asia/Istanbul:
   35.20 +Western Brazilian Standard Time:927,927:BR:America/Rio_Branco:
   35.21 +Armenian Standard Time:928,928:AM:Asia/Yerevan:
    36.1 --- a/test/java/io/FileDescriptor/FileChannelFDTest.java	Fri Nov 18 16:57:01 2011 -0800
    36.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.3 @@ -1,92 +0,0 @@
    36.4 -/*
    36.5 - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
    36.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    36.7 - *
    36.8 - * This code is free software; you can redistribute it and/or modify it
    36.9 - * under the terms of the GNU General Public License version 2 only, as
   36.10 - * published by the Free Software Foundation.
   36.11 - *
   36.12 - * This code is distributed in the hope that it will be useful, but WITHOUT
   36.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   36.14 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   36.15 - * version 2 for more details (a copy is included in the LICENSE file that
   36.16 - * accompanied this code).
   36.17 - *
   36.18 - * You should have received a copy of the GNU General Public License version
   36.19 - * 2 along with this work; if not, write to the Free Software Foundation,
   36.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   36.21 - *
   36.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   36.23 - * or visit www.oracle.com if you need additional information or have any
   36.24 - * questions.
   36.25 - */
   36.26 -
   36.27 -/**
   36.28 - *
   36.29 - * @test
   36.30 - * @bug 6322678
   36.31 - * @summary Test for making sure that fd is closed during
   36.32 - *          finalization of a stream, when an associated
   36.33 - *          file channel is not available
   36.34 - */
   36.35 -
   36.36 -import java.io.*;
   36.37 -import java.nio.*;
   36.38 -import java.nio.channels.*;
   36.39 -
   36.40 -public class FileChannelFDTest {
   36.41 -
   36.42 -    static byte data[] = new byte[] {48, 49, 50, 51, 52, 53, 54, 55, 56, 57,};
   36.43 -    static String inFileName = "fd-in-test.txt";
   36.44 -    static String outFileName = "fd-out-test.txt";
   36.45 -    static File inFile;
   36.46 -    static File outFile;
   36.47 -
   36.48 -    private static void writeToInFile() throws IOException {
   36.49 -        FileOutputStream out = new FileOutputStream(inFile);
   36.50 -        out.write(data);
   36.51 -        out.close();
   36.52 -    }
   36.53 -
   36.54 -    public static void main(String[] args)
   36.55 -                throws Exception {
   36.56 -
   36.57 -        inFile= new File(System.getProperty("test.dir", "."),
   36.58 -                        inFileName);
   36.59 -        inFile.createNewFile();
   36.60 -        inFile.deleteOnExit();
   36.61 -        writeToInFile();
   36.62 -
   36.63 -        outFile  = new File(System.getProperty("test.dir", "."),
   36.64 -                        outFileName);
   36.65 -        outFile.createNewFile();
   36.66 -        outFile.deleteOnExit();
   36.67 -
   36.68 -        doFileChannel();
   36.69 -    }
   36.70 -
   36.71 -     private static void doFileChannel() throws Exception {
   36.72 -
   36.73 -        FileInputStream fis = new FileInputStream(inFile);
   36.74 -        FileDescriptor fd = fis.getFD();
   36.75 -        FileChannel fc = fis.getChannel();
   36.76 -        System.out.println("Created fis:" + fis);
   36.77 -
   36.78 -        /**
   36.79 -         * Encourage the GC
   36.80 -         */
   36.81 -        fis = null;
   36.82 -        fc = null;
   36.83 -        System.gc();
   36.84 -        Thread.sleep(500);
   36.85 -
   36.86 -        if (fd.valid()) {
   36.87 -            throw new Exception("Finalizer either didn't run --" +
   36.88 -                "try increasing the Thread's sleep time after System.gc();" +
   36.89 -                "or the finalizer didn't close the file");
   36.90 -        }
   36.91 -
   36.92 -        System.out.println("File Closed successfully");
   36.93 -        System.out.println();
   36.94 -  }
   36.95 -}
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/test/java/io/FileDescriptor/Sharing.java	Mon Nov 28 15:15:50 2011 -0800
    37.3 @@ -0,0 +1,408 @@
    37.4 +/*
    37.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    37.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    37.7 + *
    37.8 + * This code is free software; you can redistribute it and/or modify it
    37.9 + * under the terms of the GNU General Public License version 2 only, as
   37.10 + * published by the Free Software Foundation.
   37.11 + *
   37.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   37.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   37.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   37.15 + * version 2 for more details (a copy is included in the LICENSE file that
   37.16 + * accompanied this code).
   37.17 + *
   37.18 + * You should have received a copy of the GNU General Public License version
   37.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   37.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   37.21 + *
   37.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   37.23 + * or visit www.oracle.com if you need additional information or have any
   37.24 + * questions.
   37.25 + */
   37.26 +
   37.27 +/*
   37.28 + * @test
   37.29 + * @bug 7105952 6322678 7082769
   37.30 + * @summary Improve finalisation for FileInputStream/FileOutputStream/RandomAccessFile
   37.31 + * @run main/othervm Sharing
   37.32 + */
   37.33 +
   37.34 +import java.io.*;
   37.35 +import java.nio.channels.FileChannel;
   37.36 +import java.nio.channels.FileLock;
   37.37 +import java.util.concurrent.CountDownLatch;
   37.38 +
   37.39 +public class Sharing {
   37.40 +
   37.41 +    final static int numFiles = 10;
   37.42 +    volatile static boolean fail;
   37.43 +
   37.44 +    public static void main(String[] args) throws Exception {
   37.45 +        TestFinalizer();
   37.46 +        TestMultipleFD();
   37.47 +        TestIsValid();
   37.48 +        MultiThreadedFD();
   37.49 +        TestCloseAll();
   37.50 +    }
   37.51 +
   37.52 +    /**
   37.53 +     * Finalizer shouldn't discard a file descriptor until all streams have
   37.54 +     * finished with it.
   37.55 +     */
   37.56 +    private static void TestFinalizer() throws Exception {
   37.57 +        FileDescriptor fd = null;
   37.58 +        File tempFile = new File("TestFinalizer1.txt");
   37.59 +        tempFile.deleteOnExit();
   37.60 +        try (Writer writer = new FileWriter(tempFile)) {
   37.61 +            for (int i=0; i<5; i++) {
   37.62 +                writer.write("test file content test file content");
   37.63 +            }
   37.64 +        }
   37.65 +
   37.66 +        FileInputStream fis1 = new FileInputStream(tempFile);
   37.67 +        fd = fis1.getFD();
   37.68 +        // Create a new FIS based on the existing FD (so the two FIS's share the same native fd)
   37.69 +        try (FileInputStream fis2 = new FileInputStream(fd)) {
   37.70 +            // allow fis1 to be gc'ed
   37.71 +            fis1 = null;
   37.72 +            int ret = 0;
   37.73 +            while(ret >= 0) {
   37.74 +                // encourage gc
   37.75 +                System.gc();
   37.76 +                // read from fis2 - when fis1 is gc'ed and finalizer is run, read will fail
   37.77 +                System.out.print(".");
   37.78 +                ret = fis2.read();
   37.79 +            }
   37.80 +        }
   37.81 +
   37.82 +        // variation of above. Use RandomAccessFile to obtain a filedescriptor
   37.83 +        File testFinalizerFile = new File("TestFinalizer");
   37.84 +        RandomAccessFile raf = new RandomAccessFile(testFinalizerFile, "rw");
   37.85 +        raf.writeBytes("test file content test file content");
   37.86 +        raf.seek(0L);
   37.87 +        fd = raf.getFD();
   37.88 +        try (FileInputStream fis3 = new FileInputStream(fd)) {
   37.89 +            // allow raf to be gc'ed
   37.90 +            raf = null;
   37.91 +            int ret = 0;
   37.92 +            while (ret >= 0) {
   37.93 +                // encourage gc
   37.94 +                System.gc();
   37.95 +                /*
   37.96 +                 * read from fis3 - when raf is gc'ed and finalizer is run,
   37.97 +                 * fd should still be valid.
   37.98 +                 */
   37.99 +                System.out.print(".");
  37.100 +                ret = fis3.read();
  37.101 +            }
  37.102 +        } finally {
  37.103 +            testFinalizerFile.delete();
  37.104 +        }
  37.105 +    }
  37.106 +
  37.107 +    /**
  37.108 +     * Exercise FileDispatcher close()/preClose()
  37.109 +     */
  37.110 +    private static void TestMultipleFD() throws Exception {
  37.111 +        RandomAccessFile raf = null;
  37.112 +        FileOutputStream fos = null;
  37.113 +        FileInputStream fis = null;
  37.114 +        FileChannel fc = null;
  37.115 +        FileLock fileLock = null;
  37.116 +
  37.117 +        File test1 = new File("test1");
  37.118 +        try {
  37.119 +            raf = new RandomAccessFile(test1, "rw");
  37.120 +            fos = new FileOutputStream(raf.getFD());
  37.121 +            fis = new FileInputStream(raf.getFD());
  37.122 +            fc = raf.getChannel();
  37.123 +            fileLock = fc.lock();
  37.124 +            raf.setLength(0L);
  37.125 +            fos.flush();
  37.126 +            fos.write("TEST".getBytes());
  37.127 +        } finally {
  37.128 +            if (fileLock != null) fileLock.release();
  37.129 +            if (fis != null) fis.close();
  37.130 +            if (fos != null) fos.close();
  37.131 +            if (raf != null) raf.close();
  37.132 +            test1.delete();
  37.133 +        }
  37.134 +
  37.135 +        /*
  37.136 +         * Close out in different order to ensure FD is not
  37.137 +         * closed out too early
  37.138 +         */
  37.139 +        File test2 = new File("test2");
  37.140 +        try {
  37.141 +            raf = new RandomAccessFile(test2, "rw");
  37.142 +            fos = new FileOutputStream(raf.getFD());
  37.143 +            fis = new FileInputStream(raf.getFD());
  37.144 +            fc = raf.getChannel();
  37.145 +            fileLock = fc.lock();
  37.146 +            raf.setLength(0L);
  37.147 +            fos.flush();
  37.148 +            fos.write("TEST".getBytes());
  37.149 +        } finally {
  37.150 +            if (fileLock != null) fileLock.release();
  37.151 +            if (raf != null) raf.close();
  37.152 +            if (fos != null) fos.close();
  37.153 +            if (fis != null) fis.close();
  37.154 +            test2.delete();
  37.155 +        }
  37.156 +
  37.157 +        // one more time, fos first this time
  37.158 +        File test3 = new File("test3");
  37.159 +        try {
  37.160 +            raf = new RandomAccessFile(test3, "rw");
  37.161 +            fos = new FileOutputStream(raf.getFD());
  37.162 +            fis = new FileInputStream(raf.getFD());
  37.163 +            fc = raf.getChannel();
  37.164 +            fileLock = fc.lock();
  37.165 +            raf.setLength(0L);
  37.166 +            fos.flush();
  37.167 +            fos.write("TEST".getBytes());
  37.168 +        } finally {
  37.169 +            if (fileLock != null) fileLock.release();
  37.170 +            if (fos != null) fos.close();
  37.171 +            if (raf != null) raf.close();
  37.172 +            if (fis != null) fis.close();
  37.173 +            test3.delete();
  37.174 +        }
  37.175 +    }
  37.176 +
  37.177 +    /**
  37.178 +     * Similar to TestMultipleFD() but this time we
  37.179 +     * just get and use FileDescriptor.valid() for testing.
  37.180 +     */
  37.181 +    private static void TestIsValid() throws Exception {
  37.182 +        FileDescriptor fd = null;
  37.183 +        RandomAccessFile raf = null;
  37.184 +        FileOutputStream fos = null;
  37.185 +        FileInputStream fis = null;
  37.186 +        FileChannel fc = null;
  37.187 +
  37.188 +        File test1 = new File("test1");
  37.189 +        try {
  37.190 +            raf = new RandomAccessFile(test1, "rw");
  37.191 +            fd = raf.getFD();
  37.192 +            fos = new FileOutputStream(fd);
  37.193 +            fis = new FileInputStream(fd);
  37.194 +        } finally {
  37.195 +            try {
  37.196 +                if (fis != null) fis.close();
  37.197 +                if (fd.valid()) {
  37.198 +                    throw new RuntimeException("[FIS close()] FileDescriptor shouldn't be valid");
  37.199 +                }
  37.200 +                if (fos != null) fos.close();
  37.201 +                if (raf != null) raf.close();
  37.202 +            } finally {
  37.203 +                test1.delete();
  37.204 +            }
  37.205 +        }
  37.206 +
  37.207 +        /*
  37.208 +         * Close out in different order to ensure FD is
  37.209 +         * closed correctly.
  37.210 +         */
  37.211 +        File test2 = new File("test2");
  37.212 +        try {
  37.213 +            raf = new RandomAccessFile(test2, "rw");
  37.214 +            fd = raf.getFD();
  37.215 +            fos = new FileOutputStream(fd);
  37.216 +            fis = new FileInputStream(fd);
  37.217 +        } finally {
  37.218 +            try {
  37.219 +                if (raf != null) raf.close();
  37.220 +                if (fd.valid()) {
  37.221 +                    throw new RuntimeException("[RAF close()] FileDescriptor shouldn't be valid");
  37.222 +                }
  37.223 +                if (fos != null) fos.close();
  37.224 +                if (fis != null) fis.close();
  37.225 +            } finally {
  37.226 +                test2.delete();
  37.227 +            }
  37.228 +        }
  37.229 +
  37.230 +        // one more time, fos first this time
  37.231 +        File test3 = new File("test3");
  37.232 +        try {
  37.233 +            raf = new RandomAccessFile(test3, "rw");
  37.234 +            fd = raf.getFD();
  37.235 +            fos = new FileOutputStream(fd);
  37.236 +            fis = new FileInputStream(fd);
  37.237 +        } finally {
  37.238 +            try {
  37.239 +                if (fos != null) fos.close();
  37.240 +                if (fd.valid()) {
  37.241 +                    throw new RuntimeException("[FOS close()] FileDescriptor shouldn't be valid");
  37.242 +                }
  37.243 +                if (raf != null) raf.close();
  37.244 +                if (fis != null) fis.close();
  37.245 +            } finally {
  37.246 +                test3.delete();
  37.247 +            }
  37.248 +        }
  37.249 +    }
  37.250 +
  37.251 +    /**
  37.252 +     * Test concurrent access to the same FileDescriptor
  37.253 +     */
  37.254 +    private static void MultiThreadedFD() throws Exception {
  37.255 +        RandomAccessFile raf = null;
  37.256 +        FileDescriptor fd = null;
  37.257 +        int numThreads = 2;
  37.258 +        CountDownLatch done = new CountDownLatch(numThreads);
  37.259 +        OpenClose[] fileOpenClose = new OpenClose[numThreads];
  37.260 +        File MultipleThreadedFD = new File("MultipleThreadedFD");
  37.261 +        try {
  37.262 +            raf = new RandomAccessFile(MultipleThreadedFD, "rw");
  37.263 +            fd = raf.getFD();
  37.264 +            for(int count=0;count<numThreads;count++) {
  37.265 +                fileOpenClose[count] = new OpenClose(fd, done);
  37.266 +                fileOpenClose[count].start();
  37.267 +            }
  37.268 +            done.await();
  37.269 +        } finally {
  37.270 +            try {
  37.271 +                if(raf != null) raf.close();
  37.272 +                // fd should now no longer be valid
  37.273 +                if(fd.valid()) {
  37.274 +                    throw new RuntimeException("FileDescriptor should not be valid");
  37.275 +                }
  37.276 +                // OpenClose thread tests failed
  37.277 +                if(fail) {
  37.278 +                    throw new RuntimeException("OpenClose thread tests failed.");
  37.279 +                }
  37.280 +            } finally {
  37.281 +                MultipleThreadedFD.delete();
  37.282 +            }
  37.283 +        }
  37.284 +    }
  37.285 +
  37.286 +    /**
  37.287 +     * Test closeAll handling in FileDescriptor
  37.288 +     */
  37.289 +    private static void TestCloseAll() throws Exception {
  37.290 +        File testFile = new File("test");
  37.291 +        testFile.deleteOnExit();
  37.292 +        RandomAccessFile raf = new RandomAccessFile(testFile, "rw");
  37.293 +        FileInputStream fis = new FileInputStream(raf.getFD());
  37.294 +        fis.close();
  37.295 +        if (raf.getFD().valid()) {
  37.296 +             throw new RuntimeException("FD should not be valid.");
  37.297 +        }
  37.298 +
  37.299 +        // Test the suppressed exception handling - FileInputStream
  37.300 +
  37.301 +        raf = new RandomAccessFile(testFile, "rw");
  37.302 +        fis = new FileInputStream(raf.getFD());
  37.303 +        BadFileInputStream bfis1 = new BadFileInputStream(raf.getFD());
  37.304 +        BadFileInputStream bfis2 = new BadFileInputStream(raf.getFD());
  37.305 +        BadFileInputStream bfis3 = new BadFileInputStream(raf.getFD());
  37.306 +        // extra test - set bfis3 to null
  37.307 +        bfis3 = null;
  37.308 +        try {
  37.309 +            fis.close();
  37.310 +        } catch (IOException ioe) {
  37.311 +            ioe.printStackTrace();
  37.312 +            if (ioe.getSuppressed().length != 2) {
  37.313 +                throw new RuntimeException("[FIS]Incorrect number of suppressed " +
  37.314 +                          "exceptions received : " + ioe.getSuppressed().length);
  37.315 +            }
  37.316 +        }
  37.317 +        if (raf.getFD().valid()) {
  37.318 +            // we should still have closed the FD
  37.319 +            // even with the exception.
  37.320 +            throw new RuntimeException("[FIS]TestCloseAll : FD still valid.");
  37.321 +        }
  37.322 +
  37.323 +        // Now test with FileOutputStream
  37.324 +
  37.325 +        raf = new RandomAccessFile(testFile, "rw");
  37.326 +        FileOutputStream fos = new FileOutputStream(raf.getFD());
  37.327 +        BadFileOutputStream bfos1 = new BadFileOutputStream(raf.getFD());
  37.328 +        BadFileOutputStream bfos2 = new BadFileOutputStream(raf.getFD());
  37.329 +        BadFileOutputStream bfos3 = new BadFileOutputStream(raf.getFD());
  37.330 +        // extra test - set bfos3 to null
  37.331 +        bfos3 = null;
  37.332 +        try {
  37.333 +            fos.close();
  37.334 +        } catch (IOException ioe) {
  37.335 +            ioe.printStackTrace();
  37.336 +            if (ioe.getSuppressed().length != 2) {
  37.337 +                throw new RuntimeException("[FOS]Incorrect number of suppressed " +
  37.338 +                          "exceptions received : " + ioe.getSuppressed().length);
  37.339 +            }
  37.340 +        }
  37.341 +        if (raf.getFD().valid()) {
  37.342 +            // we should still have closed the FD
  37.343 +            // even with the exception.
  37.344 +            throw new RuntimeException("[FOS]TestCloseAll : FD still valid.");
  37.345 +        }
  37.346 +    }
  37.347 +
  37.348 +    /**
  37.349 +     * A thread which will open and close a number of FileInputStreams and
  37.350 +     * FileOutputStreams referencing the same native file descriptor.
  37.351 +     */
  37.352 +    private static class OpenClose extends Thread {
  37.353 +        private FileDescriptor fd = null;
  37.354 +        private CountDownLatch done;
  37.355 +        FileInputStream[] fisArray = new FileInputStream[numFiles];
  37.356 +        FileOutputStream[] fosArray = new FileOutputStream[numFiles];
  37.357 +
  37.358 +        OpenClose(FileDescriptor filedescriptor, CountDownLatch done) {
  37.359 +            this.fd = filedescriptor;
  37.360 +            this.done = done;
  37.361 +        }
  37.362 +
  37.363 +        public void run() {
  37.364 +             try {
  37.365 +                 for(int i=0;i<numFiles;i++) {
  37.366 +                     fisArray[i] = new FileInputStream(fd);
  37.367 +                     fosArray[i] = new FileOutputStream(fd);
  37.368 +                 }
  37.369 +
  37.370 +                 // Now close out
  37.371 +                 for(int i=0;i<numFiles;i++) {
  37.372 +                     if(fisArray[i] != null) fisArray[i].close();
  37.373 +                     if(fosArray[i] != null) fosArray[i].close();
  37.374 +                 }
  37.375 +
  37.376 +             } catch(IOException ioe) {
  37.377 +                 System.out.println("OpenClose encountered IO issue :" + ioe);
  37.378 +                 fail = true;
  37.379 +             } finally {
  37.380 +                 if (fd.valid()) { // fd should not be valid after first close() call
  37.381 +                     System.out.println("OpenClose: FileDescriptor shouldn't be valid");
  37.382 +                     fail = true;
  37.383 +                 }
  37.384 +                 done.countDown();
  37.385 +             }
  37.386 +         }
  37.387 +    }
  37.388 +
  37.389 +    private static class BadFileInputStream extends FileInputStream {
  37.390 +
  37.391 +        BadFileInputStream(FileDescriptor fd) {
  37.392 +            super(fd);
  37.393 +        }
  37.394 +
  37.395 +        public void close() throws IOException {
  37.396 +            throw new IOException("Bad close operation");
  37.397 +        }
  37.398 +    }
  37.399 +
  37.400 +    private static class BadFileOutputStream extends FileOutputStream {
  37.401 +
  37.402 +        BadFileOutputStream(FileDescriptor fd) {
  37.403 +            super(fd);
  37.404 +        }
  37.405 +
  37.406 +        public void close() throws IOException {
  37.407 +            throw new IOException("Bad close operation");
  37.408 +        }
  37.409 +    }
  37.410 +
  37.411 +}
    38.1 --- a/test/java/io/etc/FileDescriptorSharing.java	Fri Nov 18 16:57:01 2011 -0800
    38.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.3 @@ -1,336 +0,0 @@
    38.4 -/*
    38.5 - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    38.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    38.7 - *
    38.8 - * This code is free software; you can redistribute it and/or modify it
    38.9 - * under the terms of the GNU General Public License version 2 only, as
   38.10 - * published by the Free Software Foundation.
   38.11 - *
   38.12 - * This code is distributed in the hope that it will be useful, but WITHOUT
   38.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   38.14 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   38.15 - * version 2 for more details (a copy is included in the LICENSE file that
   38.16 - * accompanied this code).
   38.17 - *
   38.18 - * You should have received a copy of the GNU General Public License version
   38.19 - * 2 along with this work; if not, write to the Free Software Foundation,
   38.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   38.21 - *
   38.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   38.23 - * or visit www.oracle.com if you need additional information or have any
   38.24 - * questions.
   38.25 - */
   38.26 -
   38.27 -/*
   38.28 - * @test
   38.29 - * @bug 6322678 7082769
   38.30 - * @summary FileInputStream/FileOutputStream/RandomAccessFile allow file descriptor
   38.31 - *          to be closed while still in use.
   38.32 - * @run main/othervm FileDescriptorSharing
   38.33 - */
   38.34 -
   38.35 -import java.io.*;
   38.36 -import java.nio.channels.FileChannel;
   38.37 -import java.nio.channels.FileLock;
   38.38 -import java.util.concurrent.CountDownLatch;
   38.39 -
   38.40 -public class FileDescriptorSharing {
   38.41 -
   38.42 -    final static int numFiles = 10;
   38.43 -    volatile static boolean fail;
   38.44 -
   38.45 -    public static void main(String[] args) throws Exception {
   38.46 -        TestFinalizer();
   38.47 -        TestMultipleFD();
   38.48 -        TestIsValid();
   38.49 -        MultiThreadedFD();
   38.50 -    }
   38.51 -
   38.52 -    /**
   38.53 -     * We shouldn't discard a file descriptor until all streams have
   38.54 -     * finished with it
   38.55 -     */
   38.56 -    private static void TestFinalizer() throws Exception {
   38.57 -        FileDescriptor fd = null;
   38.58 -        File tempFile = new File("TestFinalizer1.txt");
   38.59 -        tempFile.deleteOnExit();
   38.60 -        try (Writer writer = new FileWriter(tempFile)) {
   38.61 -            for (int i=0; i<5; i++) {
   38.62 -                writer.write("test file content test file content");
   38.63 -            }
   38.64 -        }
   38.65 -
   38.66 -        FileInputStream fis1 = new FileInputStream(tempFile);
   38.67 -        fd = fis1.getFD();
   38.68 -        // Create a new FIS based on the existing FD (so the two FIS's share the same native fd)
   38.69 -        try (FileInputStream fis2 = new FileInputStream(fd)) {
   38.70 -            // allow fis1 to be gc'ed
   38.71 -            fis1 = null;
   38.72 -            int ret = 0;
   38.73 -            while(ret >= 0) {
   38.74 -                // encourage gc
   38.75 -                System.gc();
   38.76 -                // read from fis2 - when fis1 is gc'ed and finalizer is run, read will fail
   38.77 -                System.out.print(".");
   38.78 -                ret = fis2.read();
   38.79 -            }
   38.80 -        }
   38.81 -
   38.82 -        // variation of above. Use RandomAccessFile to obtain a filedescriptor
   38.83 -        File testFinalizerFile = new File("TestFinalizer");
   38.84 -        RandomAccessFile raf = new RandomAccessFile(testFinalizerFile, "rw");
   38.85 -        raf.writeBytes("test file content test file content");
   38.86 -        raf.seek(0L);
   38.87 -        fd = raf.getFD();
   38.88 -        try (FileInputStream fis3 = new FileInputStream(fd)) {
   38.89 -            // allow raf to be gc'ed
   38.90 -            raf = null;
   38.91 -            int ret = 0;
   38.92 -            while (ret >= 0) {
   38.93 -                // encourage gc
   38.94 -                System.gc();
   38.95 -                /*
   38.96 -                 * read from fis3 - when raf is gc'ed and finalizer is run,
   38.97 -                 * fd should still be valid.
   38.98 -                 */
   38.99 -                System.out.print(".");
  38.100 -                ret = fis3.read();
  38.101 -            }
  38.102 -            if(!fd.valid()) {
  38.103 -                throw new RuntimeException("TestFinalizer() : FileDescriptor should be valid");
  38.104 -            }
  38.105 -        } finally {
  38.106 -            testFinalizerFile.delete();
  38.107 -        }
  38.108 -    }
  38.109 -
  38.110 -    /**
  38.111 -     * Exercise FileDispatcher close()/preClose()
  38.112 -     */
  38.113 -    private static void TestMultipleFD() throws Exception {
  38.114 -        RandomAccessFile raf = null;
  38.115 -        FileOutputStream fos = null;
  38.116 -        FileInputStream fis = null;
  38.117 -        FileChannel fc = null;
  38.118 -        FileLock fileLock = null;
  38.119 -
  38.120 -        File test1 = new File("test1");
  38.121 -        try {
  38.122 -            raf = new RandomAccessFile(test1, "rw");
  38.123 -            fos = new FileOutputStream(raf.getFD());
  38.124 -            fis = new FileInputStream(raf.getFD());
  38.125 -            fc = raf.getChannel();
  38.126 -            fileLock = fc.lock();
  38.127 -            raf.setLength(0L);
  38.128 -            fos.flush();
  38.129 -            fos.write("TEST".getBytes());
  38.130 -        } finally {
  38.131 -            if (fileLock != null) fileLock.release();
  38.132 -            if (fis != null) fis.close();
  38.133 -            if (fos != null) fos.close();
  38.134 -            if (raf != null) raf.close();
  38.135 -            test1.delete();
  38.136 -        }
  38.137 -
  38.138 -        /*
  38.139 -         * Close out in different order to ensure FD is not
  38.140 -         * closed out too early
  38.141 -         */
  38.142 -        File test2 = new File("test2");
  38.143 -        try {
  38.144 -            raf = new RandomAccessFile(test2, "rw");
  38.145 -            fos = new FileOutputStream(raf.getFD());
  38.146 -            fis = new FileInputStream(raf.getFD());
  38.147 -            fc = raf.getChannel();
  38.148 -            fileLock = fc.lock();
  38.149 -            raf.setLength(0L);
  38.150 -            fos.flush();
  38.151 -            fos.write("TEST".getBytes());
  38.152 -        } finally {
  38.153 -            if (fileLock != null) fileLock.release();
  38.154 -            if (raf != null) raf.close();
  38.155 -            if (fos != null) fos.close();
  38.156 -            if (fis != null) fis.close();
  38.157 -            test2.delete();
  38.158 -        }
  38.159 -
  38.160 -        // one more time, fos first this time
  38.161 -        File test3 = new File("test3");
  38.162 -        try {
  38.163 -            raf = new RandomAccessFile(test3, "rw");
  38.164 -            fos = new FileOutputStream(raf.getFD());
  38.165 -            fis = new FileInputStream(raf.getFD());
  38.166 -            fc = raf.getChannel();
  38.167 -            fileLock = fc.lock();
  38.168 -            raf.setLength(0L);
  38.169 -            fos.flush();
  38.170 -            fos.write("TEST".getBytes());
  38.171 -        } finally {
  38.172 -            if (fileLock != null) fileLock.release();
  38.173 -            if (fos != null) fos.close();
  38.174 -            if (raf != null) raf.close();
  38.175 -            if (fis != null) fis.close();
  38.176 -            test3.delete();
  38.177 -        }
  38.178 -    }
  38.179 -
  38.180 -    /**
  38.181 -     * Similar to TestMultipleFD() but this time we
  38.182 -     * just get and use FileDescriptor.valid() for testing.
  38.183 -     */
  38.184 -    private static void TestIsValid() throws Exception {
  38.185 -        FileDescriptor fd = null;
  38.186 -        RandomAccessFile raf = null;
  38.187 -        FileOutputStream fos = null;
  38.188 -        FileInputStream fis = null;
  38.189 -        FileChannel fc = null;
  38.190 -
  38.191 -        File test1 = new File("test1");
  38.192 -        try {
  38.193 -            raf = new RandomAccessFile(test1, "rw");
  38.194 -            fd = raf.getFD();
  38.195 -            fos = new FileOutputStream(fd);
  38.196 -            fis = new FileInputStream(fd);
  38.197 -        } finally {
  38.198 -            try {
  38.199 -                if (fis != null) fis.close();
  38.200 -                if (fos != null) fos.close();
  38.201 -                if (!fd.valid()) {
  38.202 -                    throw new RuntimeException("FileDescriptor should be valid");
  38.203 -                }
  38.204 -                if (raf != null) raf.close();
  38.205 -                if (fd.valid()) {
  38.206 -                    throw new RuntimeException("close() called and FileDescriptor still valid");
  38.207 -                }
  38.208 -            } finally {
  38.209 -                if (raf != null) raf.close();
  38.210 -                test1.delete();
  38.211 -            }
  38.212 -        }
  38.213 -
  38.214 -        /*
  38.215 -         * Close out in different order to ensure FD is not
  38.216 -         * closed out too early
  38.217 -         */
  38.218 -        File test2 = new File("test2");
  38.219 -        try {
  38.220 -            raf = new RandomAccessFile(test2, "rw");
  38.221 -            fd = raf.getFD();
  38.222 -            fos = new FileOutputStream(fd);
  38.223 -            fis = new FileInputStream(fd);
  38.224 -        } finally {
  38.225 -            try {
  38.226 -                if (raf != null) raf.close();
  38.227 -                if (fos != null) fos.close();
  38.228 -                if (!fd.valid()) {
  38.229 -                    throw new RuntimeException("FileDescriptor should be valid");
  38.230 -                }
  38.231 -                if (fis != null) fis.close();
  38.232 -                if (fd.valid()) {
  38.233 -                    throw new RuntimeException("close() called and FileDescriptor still valid");
  38.234 -                }
  38.235 -            } finally {
  38.236 -                test2.delete();
  38.237 -            }
  38.238 -        }
  38.239 -
  38.240 -        // one more time, fos first this time
  38.241 -        File test3 = new File("test3");
  38.242 -        try {
  38.243 -            raf = new RandomAccessFile(test3, "rw");
  38.244 -            fd = raf.getFD();
  38.245 -            fos = new FileOutputStream(fd);
  38.246 -            fis = new FileInputStream(fd);
  38.247 -        } finally {
  38.248 -            try {
  38.249 -                if (fos != null) fos.close();
  38.250 -                if (raf != null) raf.close();
  38.251 -                if (!fd.valid()) {
  38.252 -                    throw new RuntimeException("FileDescriptor should be valid");
  38.253 -                }
  38.254 -                if (fis != null) fis.close();
  38.255 -                if (fd.valid()) {
  38.256 -                    throw new RuntimeException("close() called and FileDescriptor still valid");
  38.257 -                }
  38.258 -            } finally {
  38.259 -                test3.delete();
  38.260 -            }
  38.261 -        }
  38.262 -    }
  38.263 -
  38.264 -    /**
  38.265 -     * Test concurrent access to the same fd.useCount field
  38.266 -     */
  38.267 -    private static void MultiThreadedFD() throws Exception {
  38.268 -        RandomAccessFile raf = null;
  38.269 -        FileDescriptor fd = null;
  38.270 -        int numThreads = 2;
  38.271 -        CountDownLatch done = new CountDownLatch(numThreads);
  38.272 -        OpenClose[] fileOpenClose = new OpenClose[numThreads];
  38.273 -        File MultipleThreadedFD = new File("MultipleThreadedFD");
  38.274 -        try {
  38.275 -            raf = new RandomAccessFile(MultipleThreadedFD, "rw");
  38.276 -            fd = raf.getFD();
  38.277 -            for(int count=0;count<numThreads;count++) {
  38.278 -                fileOpenClose[count] = new OpenClose(fd, done);
  38.279 -                fileOpenClose[count].start();
  38.280 -            }
  38.281 -            done.await();
  38.282 -        } finally {
  38.283 -            try {
  38.284 -                if(raf != null) raf.close();
  38.285 -                // fd should now no longer be valid
  38.286 -                if(fd.valid()) {
  38.287 -                    throw new RuntimeException("FileDescriptor should not be valid");
  38.288 -                }
  38.289 -                // OpenClose thread tests failed
  38.290 -                if(fail) {
  38.291 -                    throw new RuntimeException("OpenClose thread tests failed.");
  38.292 -                }
  38.293 -            } finally {
  38.294 -                MultipleThreadedFD.delete();
  38.295 -            }
  38.296 -        }
  38.297 -    }
  38.298 -
  38.299 -    /**
  38.300 -     * A thread which will open and close a number of FileInputStreams and
  38.301 -     * FileOutputStreams referencing the same native file descriptor.
  38.302 -     */
  38.303 -    private static class OpenClose extends Thread {
  38.304 -        private FileDescriptor fd = null;
  38.305 -        private CountDownLatch done;
  38.306 -        FileInputStream[] fisArray = new FileInputStream[numFiles];
  38.307 -        FileOutputStream[] fosArray = new FileOutputStream[numFiles];
  38.308 -
  38.309 -        OpenClose(FileDescriptor filedescriptor, CountDownLatch done) {
  38.310 -            this.fd = filedescriptor;
  38.311 -            this.done = done;
  38.312 -        }
  38.313 -
  38.314 -        public void run() {
  38.315 -             try {
  38.316 -                 for(int i=0;i<numFiles;i++) {
  38.317 -                     fisArray[i] = new FileInputStream(fd);
  38.318 -                     fosArray[i] = new FileOutputStream(fd);
  38.319 -                 }
  38.320 -
  38.321 -                 // Now close out
  38.322 -                 for(int i=0;i<numFiles;i++) {
  38.323 -                     if(fisArray[i] != null) fisArray[i].close();
  38.324 -                     if(fosArray[i] != null) fosArray[i].close();
  38.325 -                 }
  38.326 -
  38.327 -             } catch(IOException ioe) {
  38.328 -                 System.out.println("OpenClose encountered IO issue :" + ioe);
  38.329 -                 fail = true;
  38.330 -             } finally {
  38.331 -                 if (!fd.valid()) { // fd should still be valid given RAF reference
  38.332 -                     System.out.println("OpenClose: FileDescriptor should be valid");
  38.333 -                     fail = true;
  38.334 -                 }
  38.335 -                 done.countDown();
  38.336 -             }
  38.337 -         }
  38.338 -    }
  38.339 -}
    39.1 --- a/test/java/lang/Runtime/exec/StreamsSurviveDestroy.java	Fri Nov 18 16:57:01 2011 -0800
    39.2 +++ b/test/java/lang/Runtime/exec/StreamsSurviveDestroy.java	Mon Nov 28 15:15:50 2011 -0800
    39.3 @@ -28,6 +28,7 @@
    39.4   */
    39.5  
    39.6  import java.io.*;
    39.7 +import java.util.concurrent.*;
    39.8  
    39.9  
   39.10  public class StreamsSurviveDestroy {
   39.11 @@ -40,15 +41,17 @@
   39.12          boolean wantInterrupt;
   39.13          boolean acceptException;
   39.14          Exception exc = null;
   39.15 +        CountDownLatch latch;
   39.16  
   39.17          Copier(String name, InputStream in, OutputStream out,
   39.18 -               boolean ae, boolean wi)
   39.19 +               boolean ae, boolean wi, CountDownLatch l)
   39.20          {
   39.21              this.name = name;
   39.22              this.in = in;
   39.23              this.out = out;
   39.24              this.acceptException = ae;
   39.25              this.wantInterrupt = wi;
   39.26 +            this.latch = l;
   39.27              setName(name);
   39.28              start();
   39.29          }
   39.30 @@ -59,6 +62,7 @@
   39.31  
   39.32          public void run() {
   39.33              byte[] buf = new byte[4242];
   39.34 +            latch.countDown();
   39.35              for (;;) {
   39.36                  try {
   39.37                      int n = in.read(buf);
   39.38 @@ -95,13 +99,17 @@
   39.39      }
   39.40  
   39.41      static void test() throws Exception {
   39.42 +        CountDownLatch latch = new CountDownLatch(2);
   39.43 +
   39.44          System.err.println("test");
   39.45          Process p = Runtime.getRuntime().exec("/bin/cat");
   39.46          Copier cp1 = new Copier("out", p.getInputStream(), System.err,
   39.47 -                               false, false);
   39.48 +                                false, false, latch);
   39.49          Copier cp2 = new Copier("err", p.getErrorStream(), System.err,
   39.50 -                               false, false);
   39.51 -        Thread.sleep(100);
   39.52 +                                false, false, latch);
   39.53 +        latch.await();    // Wait till both Copiers about to read
   39.54 +        Thread.sleep(100);// Give both Copiers a chance to start read
   39.55 +
   39.56          p.destroy();
   39.57          System.err.println("  exit: " + p.waitFor());
   39.58          cp1.join();
   39.59 @@ -111,13 +119,17 @@
   39.60      }
   39.61  
   39.62      static void testCloseBeforeDestroy() throws Exception {
   39.63 +        CountDownLatch latch = new CountDownLatch(2);
   39.64 +
   39.65          System.err.println("testCloseBeforeDestroy");
   39.66          Process p = Runtime.getRuntime().exec("/bin/cat");
   39.67          Copier cp1 = new Copier("out", p.getInputStream(), System.err,
   39.68 -                                true, false);
   39.69 +                                true, false, latch);
   39.70          Copier cp2 = new Copier("err", p.getErrorStream(), System.err,
   39.71 -                                true, false);
   39.72 -        Thread.sleep(100);
   39.73 +                                true, false, latch);
   39.74 +        latch.await();    // Wait till both Copiers about to read
   39.75 +        Thread.sleep(100);// Give both Copiers a chance to start read
   39.76 +
   39.77          p.getInputStream().close();
   39.78          p.getErrorStream().close();
   39.79          p.destroy();
   39.80 @@ -129,13 +141,17 @@
   39.81      }
   39.82  
   39.83      static void testCloseAfterDestroy() throws Exception {
   39.84 +        CountDownLatch latch = new CountDownLatch(2);
   39.85          System.err.println("testCloseAfterDestroy");
   39.86          Process p = Runtime.getRuntime().exec("/bin/cat");
   39.87          Copier cp1 = new Copier("out", p.getInputStream(), System.err,
   39.88 -                                true, false);
   39.89 +                                true, false,latch);
   39.90          Copier cp2 = new Copier("err", p.getErrorStream(), System.err,
   39.91 -                                true, false);
   39.92 -        Thread.sleep(100);
   39.93 +                                true, false, latch);
   39.94 +
   39.95 +        latch.await();    // Wait till both Copiers about to read
   39.96 +        Thread.sleep(100);// Give both Copiers a chance to start read
   39.97 +
   39.98          p.destroy();
   39.99          p.getInputStream().close();
  39.100          p.getErrorStream().close();
  39.101 @@ -147,13 +163,16 @@
  39.102      }
  39.103  
  39.104      static void testInterrupt() throws Exception {
  39.105 +        CountDownLatch latch = new CountDownLatch(2);
  39.106          System.err.println("testInterrupt");
  39.107          Process p = Runtime.getRuntime().exec("/bin/cat");
  39.108          Copier cp1 = new Copier("out", p.getInputStream(), System.err,
  39.109 -                                false, true);
  39.110 +                                false, true, latch);
  39.111          Copier cp2 = new Copier("err", p.getErrorStream(), System.err,
  39.112 -                                false, true);
  39.113 -        Thread.sleep(100);
  39.114 +                                false, true, latch);
  39.115 +        latch.await();    // Wait till both Copiers about to read
  39.116 +        Thread.sleep(100);// Give both Copiers a chance to start read
  39.117 +
  39.118          cp1.interrupt();
  39.119          cp2.interrupt();
  39.120          Thread.sleep(100);
  39.121 @@ -176,7 +195,5 @@
  39.122          testCloseBeforeDestroy();
  39.123          testCloseAfterDestroy();
  39.124          testInterrupt();
  39.125 -
  39.126      }
  39.127 -
  39.128  }
    40.1 --- a/test/java/lang/ThreadGroup/NullThreadName.java	Fri Nov 18 16:57:01 2011 -0800
    40.2 +++ b/test/java/lang/ThreadGroup/NullThreadName.java	Mon Nov 28 15:15:50 2011 -0800
    40.3 @@ -24,7 +24,6 @@
    40.4  /*
    40.5   * @test
    40.6   * @bug 6576763
    40.7 - * @ignore until hotspot 6776144 bug is resolved
    40.8   * @summary (thread) Thread constructors throw undocumented NPE for null name
    40.9   */
   40.10  
   40.11 @@ -64,8 +63,8 @@
   40.12              try { Thread.sleep(2000); }
   40.13              catch (InterruptedException unused) {}
   40.14  
   40.15 -            /* do not wait forever */
   40.16 -            if (count++ > 5)
   40.17 +            /* do not wait forever - allow 120 seconds same as jtreg default timeout. */
   40.18 +            if (count++ > 60)
   40.19                  throw new AssertionError("GoodThread is still alive!");
   40.20          }
   40.21  
    41.1 --- a/test/java/lang/ThreadGroup/Stop.java	Fri Nov 18 16:57:01 2011 -0800
    41.2 +++ b/test/java/lang/ThreadGroup/Stop.java	Mon Nov 28 15:15:50 2011 -0800
    41.3 @@ -29,37 +29,58 @@
    41.4   */
    41.5  
    41.6  public class Stop implements Runnable {
    41.7 -    private static Thread first=null;
    41.8 -    private static Thread second=null;
    41.9 -    private static ThreadGroup group = new ThreadGroup("");
   41.10 +    private static boolean groupStopped = false ;
   41.11 +    private static final Object lock = new Object();
   41.12  
   41.13 -    Stop() {
   41.14 -        Thread thread = new Thread(group, this);
   41.15 -        if (first == null)
   41.16 -            first = thread;
   41.17 -        else
   41.18 -            second = thread;
   41.19 -
   41.20 -        thread.start();
   41.21 -    }
   41.22 +    private static final ThreadGroup group = new ThreadGroup("");
   41.23 +    private static final Thread first = new Thread(group, new Stop());
   41.24 +    private static final Thread second = new Thread(group, new Stop());
   41.25  
   41.26      public void run() {
   41.27          while (true) {
   41.28 +            // Give the other thread a chance to start
   41.29              try {
   41.30 -                Thread.sleep(1000); // Give other thread a chance to start
   41.31 -                if (Thread.currentThread() == first)
   41.32 -                    group.stop();
   41.33 -            } catch(InterruptedException e){
   41.34 +                Thread.sleep(1000);
   41.35 +            } catch (InterruptedException e) {
   41.36 +            }
   41.37 +
   41.38 +            // When the first thread runs, it will stop the group.
   41.39 +            if (Thread.currentThread() == first) {
   41.40 +                synchronized (lock) {
   41.41 +                    try {
   41.42 +                        group.stop();
   41.43 +                    } finally {
   41.44 +                        // Signal the main thread it is time to check
   41.45 +                        // that the stopped thread group was successful
   41.46 +                        groupStopped = true;
   41.47 +                        lock.notifyAll();
   41.48 +                    }
   41.49 +                }
   41.50              }
   41.51          }
   41.52      }
   41.53  
   41.54      public static void main(String[] args) throws Exception {
   41.55 -        for (int i=0; i<2; i++)
   41.56 -            new Stop();
   41.57 -        Thread.sleep(3000);
   41.58 +        // Launch two threads as part of the same thread group
   41.59 +        first.start();
   41.60 +        second.start();
   41.61 +
   41.62 +        // Wait for the thread group stop to be issued
   41.63 +        synchronized(lock){
   41.64 +            while (!groupStopped) {
   41.65 +                lock.wait();
   41.66 +                // Give the other thread a chance to stop
   41.67 +                Thread.sleep(1000);
   41.68 +            }
   41.69 +        }
   41.70 +
   41.71 +        // Check that the second thread is terminated when the
   41.72 +        // first thread terminates the thread group.
   41.73          boolean failed = second.isAlive();
   41.74 -        first.stop(); second.stop();
   41.75 +
   41.76 +        // Clean up any threads that may have not been terminated
   41.77 +        first.stop();
   41.78 +        second.stop();
   41.79          if (failed)
   41.80              throw new RuntimeException("Failure.");
   41.81      }
    42.1 --- a/test/java/lang/management/PlatformLoggingMXBean/LoggingMXBeanTest.java	Fri Nov 18 16:57:01 2011 -0800
    42.2 +++ b/test/java/lang/management/PlatformLoggingMXBean/LoggingMXBeanTest.java	Mon Nov 28 15:15:50 2011 -0800
    42.3 @@ -23,7 +23,7 @@
    42.4  
    42.5  /*
    42.6   * @test
    42.7 - * @bug 7024172
    42.8 + * @bug 7024172 7067691
    42.9   * @summary Test if proxy for PlatformLoggingMXBean is equivalent
   42.10   *          to proxy for LoggingMXBean
   42.11   *
   42.12 @@ -43,6 +43,13 @@
   42.13      static String LOGGER_NAME_2 = "com.sun.management.Logger.Logger2";
   42.14      static String UNKNOWN_LOGGER_NAME = "com.sun.management.Unknown";
   42.15  
   42.16 +    // These instance variables prevent premature logger garbage collection
   42.17 +    // See getLogger() weak reference warnings.
   42.18 +    Logger logger1;
   42.19 +    Logger logger2;
   42.20 +
   42.21 +    static LoggingMXBeanTest test;
   42.22 +
   42.23      public static void main(String[] argv) throws Exception {
   42.24          MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
   42.25          LoggingMXBean proxy =
   42.26 @@ -51,7 +58,7 @@
   42.27                  LoggingMXBean.class);
   42.28  
   42.29          // test LoggingMXBean proxy
   42.30 -        LoggingMXBeanTest p = new LoggingMXBeanTest(proxy);
   42.31 +        test = new LoggingMXBeanTest(proxy);
   42.32  
   42.33          // check if the attributes implemented by PlatformLoggingMXBean
   42.34          // and LoggingMXBean return the same value
   42.35 @@ -64,9 +71,9 @@
   42.36      // same verification as in java/util/logging/LoggingMXBeanTest2
   42.37      public LoggingMXBeanTest(LoggingMXBean mbean) throws Exception {
   42.38  
   42.39 -        Logger logger1 = Logger.getLogger( LOGGER_NAME_1 );
   42.40 +        logger1 = Logger.getLogger( LOGGER_NAME_1 );
   42.41          logger1.setLevel(Level.FINE);
   42.42 -        Logger logger2 = Logger.getLogger( LOGGER_NAME_2 );
   42.43 +        logger2 = Logger.getLogger( LOGGER_NAME_2 );
   42.44          logger2.setLevel(null);
   42.45  
   42.46          /*
   42.47 @@ -207,6 +214,7 @@
   42.48          // verify logger names
   42.49          List<String> loggers1 = mxbean1.getLoggerNames();
   42.50          List<String> loggers2 = mxbean2.getLoggerNames();
   42.51 +
   42.52          if (loggers1.size() != loggers2.size())
   42.53              throw new RuntimeException("LoggerNames: unmatched number of entries");
   42.54          List<String> loggers3 = new ArrayList<>(loggers1);
   42.55 @@ -219,7 +227,10 @@
   42.56              if (!mxbean1.getLoggerLevel(logger)
   42.57                      .equals(mxbean2.getLoggerLevel(logger)))
   42.58                  throw new RuntimeException(
   42.59 -                    "LoggerLevel: unmatched level for " + logger);
   42.60 +                    "LoggerLevel: unmatched level for " + logger
   42.61 +                    + ", " + mxbean1.getLoggerLevel(logger)
   42.62 +                    + ", " + mxbean2.getLoggerLevel(logger));
   42.63 +
   42.64              if (!mxbean1.getParentLoggerName(logger)
   42.65                      .equals(mxbean2.getParentLoggerName(logger)))
   42.66                  throw new RuntimeException(
    43.1 --- a/test/java/lang/management/PlatformLoggingMXBean/PlatformLoggingMXBeanTest.java	Fri Nov 18 16:57:01 2011 -0800
    43.2 +++ b/test/java/lang/management/PlatformLoggingMXBean/PlatformLoggingMXBeanTest.java	Mon Nov 28 15:15:50 2011 -0800
    43.3 @@ -23,7 +23,7 @@
    43.4  
    43.5  /*
    43.6   * @test
    43.7 - * @bug     6876135 7024172
    43.8 + * @bug     6876135 7024172 7067691
    43.9   *
   43.10   * @summary Test PlatformLoggingMXBean
   43.11   *          This test performs similar testing as
   43.12 @@ -41,11 +41,15 @@
   43.13  
   43.14  public class PlatformLoggingMXBeanTest
   43.15  {
   43.16 -
   43.17      ObjectName objectName = null;
   43.18      static String LOGGER_NAME_1 = "com.sun.management.Logger1";
   43.19      static String LOGGER_NAME_2 = "com.sun.management.Logger2";
   43.20  
   43.21 +    // Use Logger instance variables to prevent premature garbage collection
   43.22 +    // of weak references.
   43.23 +    Logger logger1;
   43.24 +    Logger logger2;
   43.25 +
   43.26      public PlatformLoggingMXBeanTest() throws Exception {
   43.27      }
   43.28  
   43.29 @@ -135,8 +139,8 @@
   43.30          System.out.println( "*********** Phase 3 ***********" );
   43.31          System.out.println( "*******************************" );
   43.32          System.out.println( " Create and test new Loggers" );
   43.33 -        Logger logger1 = Logger.getLogger( LOGGER_NAME_1 );
   43.34 -        Logger logger2 = Logger.getLogger( LOGGER_NAME_2 );
   43.35 +        logger1 = Logger.getLogger( LOGGER_NAME_1 );
   43.36 +        logger2 = Logger.getLogger( LOGGER_NAME_2 );
   43.37  
   43.38          // check that Level object are returned properly
   43.39          try {
   43.40 @@ -187,6 +191,7 @@
   43.41          System.out.println( " Set and Check the Logger Level" );
   43.42          log1 = false;
   43.43          log2 = false;
   43.44 +
   43.45          try {
   43.46              // Set the level of logger1 to ALL
   43.47              params = new Object[2];
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/test/java/rmi/registry/readTest/readTest.java	Mon Nov 28 15:15:50 2011 -0800
    44.3 @@ -0,0 +1,58 @@
    44.4 +/*
    44.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    44.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    44.7 + *
    44.8 + * This code is free software; you can redistribute it and/or modify it
    44.9 + * under the terms of the GNU General Public License version 2 only, as
   44.10 + * published by the Free Software Foundation.
   44.11 + *
   44.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   44.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   44.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   44.15 + * version 2 for more details (a copy is included in the LICENSE file that
   44.16 + * accompanied this code).
   44.17 + *
   44.18 + * You should have received a copy of the GNU General Public License version
   44.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   44.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   44.21 + *
   44.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   44.23 + * or visit www.oracle.com if you need additional information or have any
   44.24 + * questions.
   44.25 + */
   44.26 +
   44.27 +import java.rmi.registry.Registry;
   44.28 +import java.rmi.registry.LocateRegistry;
   44.29 +import java.rmi.RemoteException;
   44.30 +import java.rmi.server.UnicastRemoteObject;
   44.31 +
   44.32 +public class readTest {
   44.33 +
   44.34 +    public static void main(String args[]) throws Exception {
   44.35 +        int port = 7491;
   44.36 +        try {
   44.37 +            testPkg.Server obj = new testPkg.Server();
   44.38 +            testPkg.Hello stub = (testPkg.Hello) UnicastRemoteObject.exportObject(obj, 0);
   44.39 +            // Bind the remote object's stub in the registry
   44.40 +            Registry registry = LocateRegistry.getRegistry(port);
   44.41 +            registry.bind("Hello", stub);
   44.42 +
   44.43 +            System.err.println("Server ready");
   44.44 +
   44.45 +            // now, let's test client
   44.46 +            testPkg.Client client = new testPkg.Client(port);
   44.47 +            String testStubReturn = client.testStub();
   44.48 +            if(!testStubReturn.equals(obj.hello)) {
   44.49 +                throw new RuntimeException("Test Fails : unexpected string from stub call");
   44.50 +            } else {
   44.51 +                System.out.println("Test passed");
   44.52 +            }
   44.53 +            registry.unbind("Hello");
   44.54 +
   44.55 +        } catch (Exception e) {
   44.56 +            System.err.println("Server exception: " + e.toString());
   44.57 +            e.printStackTrace();
   44.58 +        }
   44.59 +
   44.60 +    }
   44.61 +}
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/test/java/rmi/registry/readTest/readTest.sh	Mon Nov 28 15:15:50 2011 -0800
    45.3 @@ -0,0 +1,95 @@
    45.4 +#
    45.5 +# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    45.6 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    45.7 +#
    45.8 +# This code is free software; you can redistribute it and/or modify it
    45.9 +# under the terms of the GNU General Public License version 2 only, as
   45.10 +# published by the Free Software Foundation.
   45.11 +#
   45.12 +# This code is distributed in the hope that it will be useful, but WITHOUT
   45.13 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   45.14 +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   45.15 +# version 2 for more details (a copy is included in the LICENSE file that
   45.16 +# accompanied this code).
   45.17 +#
   45.18 +# You should have received a copy of the GNU General Public License version
   45.19 +# 2 along with this work; if not, write to the Free Software Foundation,
   45.20 +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   45.21 +#
   45.22 +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   45.23 +# or visit www.oracle.com if you need additional information or have any
   45.24 +# questions.
   45.25 +#
   45.26 +
   45.27 +# @test
   45.28 +# @bug 7102369 7094468 7100592
   45.29 +# @summary remove java.rmi.server.codebase property parsing from registyimpl
   45.30 +# @run shell readTest.sh
   45.31 +
   45.32 +OS=`uname -s`
   45.33 +case "$OS" in
   45.34 +  SunOS | Linux )
   45.35 +    PS=":"
   45.36 +    FS="/"
   45.37 +    FILEURL="file:"
   45.38 +    ;;
   45.39 +  Windows* | CYGWIN* )
   45.40 +    PS=";"
   45.41 +    FS="\\"
   45.42 +    FILEURL="file:/"
   45.43 +    ;;
   45.44 +  * )
   45.45 +    echo "Unrecognized system!"
   45.46 +    exit 1;
   45.47 +    ;;
   45.48 +esac
   45.49 +
   45.50 +cp -r ${TESTSRC}${FS}* .
   45.51 +${TESTJAVA}${FS}bin${FS}javac testPkg${FS}*java
   45.52 +${TESTJAVA}${FS}bin${FS}javac readTest.java
   45.53 +
   45.54 +mkdir rmi_tmp
   45.55 +RMIREG_OUT=rmi.out
   45.56 +#start rmiregistry without any local classes on classpath
   45.57 +cd rmi_tmp
   45.58 +${TESTJAVA}${FS}bin${FS}rmiregistry 7491 > ..${FS}${RMIREG_OUT} 2>&1 &
   45.59 +RMIREG_PID=$!
   45.60 +# allow some time to start
   45.61 +sleep 3
   45.62 +cd ..
   45.63 +
   45.64 +# trailing / after code base is important for rmi codebase property.
   45.65 +${TESTJAVA}${FS}bin${FS}java -Djava.rmi.server.codebase=${FILEURL}`pwd`/ readTest > OUT.TXT 2>&1 &
   45.66 +TEST_PID=$!
   45.67 +#bulk of testcase - let it run for a while
   45.68 +sleep 5
   45.69 +
   45.70 +#we're done, kill processes first
   45.71 +kill -9 ${RMIREG_PID} ${TEST_PID}
   45.72 +sleep 3
   45.73 +
   45.74 +echo "Test output : "
   45.75 +
   45.76 +cat OUT.TXT
   45.77 +echo "=============="
   45.78 +echo "rmiregistry output  : "
   45.79 +cat ${RMIREG_OUT}
   45.80 +echo "=============="
   45.81 +
   45.82 +grep "Server ready" OUT.TXT
   45.83 +result1=$?
   45.84 +grep "Test passed" OUT.TXT
   45.85 +result2=$?
   45.86 +
   45.87 +if [ $result1 -eq 0  -a $result2 -eq 0 ]
   45.88 +then 
   45.89 +    echo "Passed"
   45.90 +    exitCode=0;
   45.91 +else
   45.92 +    echo "Failed"
   45.93 +    exitCode=1
   45.94 +fi
   45.95 +rm -rf OUT.TXT ${RMIREG_OUT} rmi_tmp
   45.96 +exit ${exitCode}    
   45.97 +
   45.98 +
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/test/java/rmi/registry/readTest/testPkg/Client.java	Mon Nov 28 15:15:50 2011 -0800
    46.3 @@ -0,0 +1,48 @@
    46.4 +/*
    46.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    46.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    46.7 + *
    46.8 + * This code is free software; you can redistribute it and/or modify it
    46.9 + * under the terms of the GNU General Public License version 2 only, as
   46.10 + * published by the Free Software Foundation.
   46.11 + *
   46.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   46.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   46.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   46.15 + * version 2 for more details (a copy is included in the LICENSE file that
   46.16 + * accompanied this code).
   46.17 + *
   46.18 + * You should have received a copy of the GNU General Public License version
   46.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   46.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   46.21 + *
   46.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   46.23 + * or visit www.oracle.com if you need additional information or have any
   46.24 + * questions.
   46.25 + */
   46.26 +
   46.27 +package testPkg;
   46.28 +
   46.29 +import java.rmi.registry.LocateRegistry;
   46.30 +import java.rmi.registry.Registry;
   46.31 +
   46.32 +public class Client {
   46.33 +    int port;
   46.34 +
   46.35 +    public Client(int p) {
   46.36 +        port = p;
   46.37 +    }
   46.38 +
   46.39 +    public String testStub() throws Exception {
   46.40 +        try {
   46.41 +            Registry registry = LocateRegistry.getRegistry(port);
   46.42 +            Hello stub = (Hello) registry.lookup("Hello");
   46.43 +            String response = stub.sayHello();
   46.44 +            return response;
   46.45 +            } catch (Exception e) {
   46.46 +                System.err.println("Client exception: " + e.toString());
   46.47 +                throw e;
   46.48 +            }
   46.49 +        }
   46.50 +    }
   46.51 +
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/test/java/rmi/registry/readTest/testPkg/Hello.java	Mon Nov 28 15:15:50 2011 -0800
    47.3 @@ -0,0 +1,31 @@
    47.4 +/*
    47.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    47.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    47.7 + *
    47.8 + * This code is free software; you can redistribute it and/or modify it
    47.9 + * under the terms of the GNU General Public License version 2 only, as
   47.10 + * published by the Free Software Foundation.
   47.11 + *
   47.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   47.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   47.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   47.15 + * version 2 for more details (a copy is included in the LICENSE file that
   47.16 + * accompanied this code).
   47.17 + *
   47.18 + * You should have received a copy of the GNU General Public License version
   47.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   47.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   47.21 + *
   47.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   47.23 + * or visit www.oracle.com if you need additional information or have any
   47.24 + * questions.
   47.25 + */
   47.26 +
   47.27 +package testPkg;
   47.28 +
   47.29 +import java.rmi.Remote;
   47.30 +import java.rmi.RemoteException;
   47.31 +
   47.32 +public interface Hello extends Remote {
   47.33 +    String sayHello() throws RemoteException;
   47.34 +}
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/test/java/rmi/registry/readTest/testPkg/Server.java	Mon Nov 28 15:15:50 2011 -0800
    48.3 @@ -0,0 +1,36 @@
    48.4 +/*
    48.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    48.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    48.7 + *
    48.8 + * This code is free software; you can redistribute it and/or modify it
    48.9 + * under the terms of the GNU General Public License version 2 only, as
   48.10 + * published by the Free Software Foundation.
   48.11 + *
   48.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   48.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   48.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   48.15 + * version 2 for more details (a copy is included in the LICENSE file that
   48.16 + * accompanied this code).
   48.17 + *
   48.18 + * You should have received a copy of the GNU General Public License version
   48.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   48.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   48.21 + *
   48.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   48.23 + * or visit www.oracle.com if you need additional information or have any
   48.24 + * questions.
   48.25 + */
   48.26 +
   48.27 +package testPkg;
   48.28 +
   48.29 +public class Server implements Hello {
   48.30 +
   48.31 +    public String hello = "Hello, world!";
   48.32 +
   48.33 +    public Server() {}
   48.34 +
   48.35 +    public String sayHello() {
   48.36 +        return hello;
   48.37 +    }
   48.38 +
   48.39 +}
    49.1 --- a/test/java/util/Timer/Args.java	Fri Nov 18 16:57:01 2011 -0800
    49.2 +++ b/test/java/util/Timer/Args.java	Mon Nov 28 15:15:50 2011 -0800
    49.3 @@ -92,19 +92,22 @@
    49.4                 new F(){void f(){ t.scheduleAtFixedRate(x, (Date)null, 42); }}
    49.5                 );
    49.6  
    49.7 -        final long start = System.currentTimeMillis();
    49.8 -        final Date past = new Date(start - 10500);
    49.9          final CountDownLatch y1 = new CountDownLatch(1);
   49.10          final CountDownLatch y2 = new CountDownLatch(1);
   49.11          final CountDownLatch y3 = new CountDownLatch(11);
   49.12 +        final long start = System.currentTimeMillis();
   49.13 +        final Date past = new Date(start - 10500);
   49.14 +
   49.15          schedule(           t, counter(y1), past);
   49.16          schedule(           t, counter(y2), past, 1000);
   49.17          scheduleAtFixedRate(t, counter(y3), past, 1000);
   49.18          y3.await();
   49.19          y1.await();
   49.20          y2.await();
   49.21 -        System.out.printf("elapsed=%d%n", System.currentTimeMillis() - start);
   49.22 -        check(System.currentTimeMillis() - start < 500);
   49.23 +
   49.24 +        final long elapsed = System.currentTimeMillis() - start;
   49.25 +        System.out.printf("elapsed=%d%n", elapsed);
   49.26 +        check(elapsed < 500);
   49.27  
   49.28          t.cancel();
   49.29  
    50.1 --- a/test/java/util/Timer/KillThread.java	Fri Nov 18 16:57:01 2011 -0800
    50.2 +++ b/test/java/util/Timer/KillThread.java	Mon Nov 28 15:15:50 2011 -0800
    50.3 @@ -31,21 +31,26 @@
    50.4  import java.util.*;
    50.5  
    50.6  public class KillThread {
    50.7 +    static volatile Thread tdThread;
    50.8      public static void main (String[] args) throws Exception  {
    50.9          Timer t = new Timer();
   50.10  
   50.11          // Start a mean event that kills the timer thread
   50.12          t.schedule(new TimerTask() {
   50.13              public void run() {
   50.14 +                tdThread = Thread.currentThread();
   50.15                  throw new ThreadDeath();
   50.16              }
   50.17          }, 0);
   50.18  
   50.19          // Wait for mean event to do the deed and thread to die.
   50.20          try {
   50.21 -            Thread.sleep(100);
   50.22 +            do {
   50.23 +                Thread.sleep(100);
   50.24 +            } while(tdThread == null);
   50.25          } catch(InterruptedException e) {
   50.26          }
   50.27 +        tdThread.join();
   50.28  
   50.29          // Try to start another event
   50.30          try {
    51.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.2 +++ b/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLContextImpl/MD2InTrustAnchor.java	Mon Nov 28 15:15:50 2011 -0800
    51.3 @@ -0,0 +1,423 @@
    51.4 +/*
    51.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    51.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    51.7 + *
    51.8 + * This code is free software; you can redistribute it and/or modify it
    51.9 + * under the terms of the GNU General Public License version 2 only, as
   51.10 + * published by the Free Software Foundation.  Oracle designates this
   51.11 + * particular file as subject to the "Classpath" exception as provided
   51.12 + * by Oracle in the LICENSE file that accompanied this code.
   51.13 + *
   51.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   51.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   51.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   51.17 + * version 2 for more details (a copy is included in the LICENSE file that
   51.18 + * accompanied this code).
   51.19 + *
   51.20 + * You should have received a copy of the GNU General Public License version
   51.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   51.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   51.23 + *
   51.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   51.25 + * or visit www.oracle.com if you need additional information or have any
   51.26 + * questions.
   51.27 + */
   51.28 +
   51.29 +/*
   51.30 + * @test
   51.31 + * @bug 7113275
   51.32 + * @summary compatibility issue with MD2 trust anchor and old X509TrustManager
   51.33 + *
   51.34 + *     SunJSSE does not support dynamic system properties, no way to re-use
   51.35 + *     system properties in samevm/agentvm mode.
   51.36 + * @run main/othervm MD2InTrustAnchor PKIX TLSv1.1
   51.37 + * @run main/othervm MD2InTrustAnchor SunX509 TLSv1.1
   51.38 + * @run main/othervm MD2InTrustAnchor PKIX TLSv1.2
   51.39 + * @run main/othervm MD2InTrustAnchor SunX509 TLSv1.2
   51.40 + */
   51.41 +
   51.42 +import java.net.*;
   51.43 +import java.util.*;
   51.44 +import java.io.*;
   51.45 +import javax.net.ssl.*;
   51.46 +import java.security.KeyStore;
   51.47 +import java.security.KeyFactory;
   51.48 +import java.security.cert.Certificate;
   51.49 +import java.security.cert.CertificateFactory;
   51.50 +import java.security.spec.*;
   51.51 +import java.security.interfaces.*;
   51.52 +import sun.misc.BASE64Decoder;
   51.53 +
   51.54 +
   51.55 +public class MD2InTrustAnchor {
   51.56 +
   51.57 +    /*
   51.58 +     * =============================================================
   51.59 +     * Set the various variables needed for the tests, then
   51.60 +     * specify what tests to run on each side.
   51.61 +     */
   51.62 +
   51.63 +    /*
   51.64 +     * Should we run the client or server in a separate thread?
   51.65 +     * Both sides can throw exceptions, but do you have a preference
   51.66 +     * as to which side should be the main thread.
   51.67 +     */
   51.68 +    static boolean separateServerThread = false;
   51.69 +
   51.70 +    /*
   51.71 +     * Certificates and key used in the test.
   51.72 +     */
   51.73 +
   51.74 +    // It's a trust anchor signed with MD2 hash function.
   51.75 +    static String trustedCertStr =
   51.76 +        "-----BEGIN CERTIFICATE-----\n" +
   51.77 +        "MIICkjCCAfugAwIBAgIBADANBgkqhkiG9w0BAQIFADA7MQswCQYDVQQGEwJVUzEN\n" +
   51.78 +        "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" +
   51.79 +        "MTExMTE4MTExNDA0WhcNMzIxMDI4MTExNDA0WjA7MQswCQYDVQQGEwJVUzENMAsG\n" +
   51.80 +        "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwgZ8wDQYJ\n" +
   51.81 +        "KoZIhvcNAQEBBQADgY0AMIGJAoGBAPGyB9tugUGgxtdeqe0qJEwf9x1Gy4BOi1yR\n" +
   51.82 +        "wzDZY4H5LquvIfQ2V3J9X1MQENVsFvkvp65ZcFcy+ObOucXUUPFcd/iw2DVb5QXA\n" +
   51.83 +        "ffyeVqWD56GPi8Qe37wrJO3L6fBhN9oxp/BbdRLgjU81zx8qLEyPODhPMxV4OkcA\n" +
   51.84 +        "SDwZTSxxAgMBAAGjgaUwgaIwHQYDVR0OBBYEFLOAtr/YrYj9H04EDLA0fd14jisF\n" +
   51.85 +        "MGMGA1UdIwRcMFqAFLOAtr/YrYj9H04EDLA0fd14jisFoT+kPTA7MQswCQYDVQQG\n" +
   51.86 +        "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" +
   51.87 +        "Y2WCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEC\n" +
   51.88 +        "BQADgYEAr8ExpXu/FTIRiMzPm0ubqwME4lniilwQUiEOD/4DbksNjEIcUyS2hIk1\n" +
   51.89 +        "qsmjJz3SHBnwhxl9dhJVwk2tZLkPGW86Zn0TPVRsttK4inTgCC9GFGeqQBdrU/uf\n" +
   51.90 +        "lipBzXWljrfbg4N/kK8m2LabtKUMMnGysM8rN0Fx2PYm5xxGvtM=\n" +
   51.91 +        "-----END CERTIFICATE-----";
   51.92 +
   51.93 +    // The certificate issued by above trust anchor, signed with MD5
   51.94 +    static String targetCertStr =
   51.95 +        "-----BEGIN CERTIFICATE-----\n" +
   51.96 +        "MIICeDCCAeGgAwIBAgIBAjANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" +
   51.97 +        "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" +
   51.98 +        "MTExMTE4MTExNDA2WhcNMzEwODA1MTExNDA2WjBPMQswCQYDVQQGEwJVUzENMAsG\n" +
   51.99 +        "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxEjAQBgNV\n" +
  51.100 +        "BAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwDnm96mw\n" +
  51.101 +        "fXCH4bgXk1US0VcJsQVxUtGMyncAveMuzBzNzOmKZPeqyYX1Fuh4q+cuza03WTJd\n" +
  51.102 +        "G9nOkNr364e3Rn1aaHjCMcBmFflObnGnhhufNmIGYogJ9dJPmhUVPEVAXrMG+Ces\n" +
  51.103 +        "NKy2E8woGnLMrqu6yiuTClbLBPK8fWzTXrECAwEAAaN4MHYwCwYDVR0PBAQDAgPo\n" +
  51.104 +        "MB0GA1UdDgQWBBSdRrpocLPJXyGfDmMWJrcEf29WGDAfBgNVHSMEGDAWgBSzgLa/\n" +
  51.105 +        "2K2I/R9OBAywNH3deI4rBTAnBgNVHSUEIDAeBggrBgEFBQcDAQYIKwYBBQUHAwIG\n" +
  51.106 +        "CCsGAQUFBwMDMA0GCSqGSIb3DQEBBAUAA4GBAKJ71ZiCUykkJrCLYUxlFlhvUcr9\n" +
  51.107 +        "sTcOc67QdroW5f412NI15SXWDiley/JOasIiuIFPjaJBjOKoHOvTjG/snVu9wEgq\n" +
  51.108 +        "YNR8dPsO+NM8r79C6jO+Jx5fYAC7os2XxS75h3NX0ElJcbwIXGBJ6xRrsFh/BGYH\n" +
  51.109 +        "yvudOlX4BkVR0l1K\n" +
  51.110 +        "-----END CERTIFICATE-----";
  51.111 +
  51.112 +    // Private key in the format of PKCS#8.
  51.113 +    static String targetPrivateKey =
  51.114 +        "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMA55vepsH1wh+G4\n" +
  51.115 +        "F5NVEtFXCbEFcVLRjMp3AL3jLswczczpimT3qsmF9RboeKvnLs2tN1kyXRvZzpDa\n" +
  51.116 +        "9+uHt0Z9Wmh4wjHAZhX5Tm5xp4YbnzZiBmKICfXST5oVFTxFQF6zBvgnrDSsthPM\n" +
  51.117 +        "KBpyzK6rusorkwpWywTyvH1s016xAgMBAAECgYEAn9bF3oRkdDoBU0i/mcww5I+K\n" +
  51.118 +        "SH9tFt+WQbiojjz9ac49trkvUfu7MO1Jui2+QbrvaSkyj+HYGFOJd1wMsPXeB7ck\n" +
  51.119 +        "5mOIYV4uZK8jfNMSQ8v0tFEeIPp5lKdw1XnrQfSe+abo2eL5Lwso437Y4s3w37+H\n" +
  51.120 +        "aY3d76hR5qly+Ys+Ww0CQQDjeOoX89d/xhRqGXKjCx8ImE/dPmsI8O27cwtKrDYJ\n" +
  51.121 +        "6t0v/xryVIdvOYcRBvKnqEogOH7T1kI+LnWKUTJ2ehJ7AkEA2FVloPVqCehXcc7e\n" +
  51.122 +        "z3TDpU9w1B0JXklcV5HddYsRqp9RukN/VK4szKE7F1yoarIUtfE9Lr9082Jwyp3M\n" +
  51.123 +        "L11xwwJBAKsZ+Hur3x0tUY29No2Nf/pnFyvEF57SGwA0uPmiL8Ol9lpz+UDudDEl\n" +
  51.124 +        "hIM6Rqv12kwCMuQE9i7vo1o3WU3k5KECQEqhg1L49yD935TqiiFFpe0Ur9btQXse\n" +
  51.125 +        "kdXAA4d2d5zGI7q/aGD9SYU6phkUJSHR16VA2RuUfzMrpb+wmm1IrmMCQFtLoKRT\n" +
  51.126 +        "A5kokFb+E3Gplu29tJvCUpfwgBFRS+wmkvtiaU/tiyDcVgDO+An5DwedxxdVzqiE\n" +
  51.127 +        "njWHoKY3axDQ8OU=\n";
  51.128 +
  51.129 +
  51.130 +    static char passphrase[] = "passphrase".toCharArray();
  51.131 +
  51.132 +    /*
  51.133 +     * Is the server ready to serve?
  51.134 +     */
  51.135 +    volatile static boolean serverReady = false;
  51.136 +
  51.137 +    /*
  51.138 +     * Turn on SSL debugging?
  51.139 +     */
  51.140 +    static boolean debug = false;
  51.141 +
  51.142 +    /*
  51.143 +     * Define the server side of the test.
  51.144 +     *
  51.145 +     * If the server prematurely exits, serverReady will be set to true
  51.146 +     * to avoid infinite hangs.
  51.147 +     */
  51.148 +    void doServerSide() throws Exception {
  51.149 +        SSLContext context = generateSSLContext(trustedCertStr, targetCertStr,
  51.150 +                                            targetPrivateKey);
  51.151 +        SSLServerSocketFactory sslssf = context.getServerSocketFactory();
  51.152 +        SSLServerSocket sslServerSocket =
  51.153 +            (SSLServerSocket)sslssf.createServerSocket(serverPort);
  51.154 +        sslServerSocket.setNeedClientAuth(true);
  51.155 +        serverPort = sslServerSocket.getLocalPort();
  51.156 +
  51.157 +        /*
  51.158 +         * Signal Client, we're ready for his connect.
  51.159 +         */
  51.160 +        serverReady = true;
  51.161 +
  51.162 +        SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept();
  51.163 +        InputStream sslIS = sslSocket.getInputStream();
  51.164 +        OutputStream sslOS = sslSocket.getOutputStream();
  51.165 +
  51.166 +        sslIS.read();
  51.167 +        sslOS.write('A');
  51.168 +        sslOS.flush();
  51.169 +
  51.170 +        sslSocket.close();
  51.171 +    }
  51.172 +
  51.173 +    /*
  51.174 +     * Define the client side of the test.
  51.175 +     *
  51.176 +     * If the server prematurely exits, serverReady will be set to true
  51.177 +     * to avoid infinite hangs.
  51.178 +     */
  51.179 +    void doClientSide() throws Exception {
  51.180 +
  51.181 +        /*
  51.182 +         * Wait for server to get started.
  51.183 +         */
  51.184 +        while (!serverReady) {
  51.185 +            Thread.sleep(50);
  51.186 +        }
  51.187 +
  51.188 +        SSLContext context = generateSSLContext(trustedCertStr, targetCertStr,
  51.189 +                                            targetPrivateKey);
  51.190 +        SSLSocketFactory sslsf = context.getSocketFactory();
  51.191 +
  51.192 +        SSLSocket sslSocket =
  51.193 +            (SSLSocket)sslsf.createSocket("localhost", serverPort);
  51.194 +
  51.195 +        // enable the specified TLS protocol
  51.196 +        sslSocket.setEnabledProtocols(new String[] {tlsProtocol});
  51.197 +
  51.198 +        InputStream sslIS = sslSocket.getInputStream();
  51.199 +        OutputStream sslOS = sslSocket.getOutputStream();
  51.200 +
  51.201 +        sslOS.write('B');
  51.202 +        sslOS.flush();
  51.203 +        sslIS.read();
  51.204 +
  51.205 +        sslSocket.close();
  51.206 +    }
  51.207 +
  51.208 +    /*
  51.209 +     * =============================================================
  51.210 +     * The remainder is just support stuff
  51.211 +     */
  51.212 +    private static String tmAlgorithm;        // trust manager
  51.213 +    private static String tlsProtocol;        // trust manager
  51.214 +
  51.215 +    private static void parseArguments(String[] args) {
  51.216 +        tmAlgorithm = args[0];
  51.217 +        tlsProtocol = args[1];
  51.218 +    }
  51.219 +
  51.220 +    private static SSLContext generateSSLContext(String trustedCertStr,
  51.221 +            String keyCertStr, String keySpecStr) throws Exception {
  51.222 +
  51.223 +        // generate certificate from cert string
  51.224 +        CertificateFactory cf = CertificateFactory.getInstance("X.509");
  51.225 +
  51.226 +        // create a key store
  51.227 +        KeyStore ks = KeyStore.getInstance("JKS");
  51.228 +        ks.load(null, null);
  51.229 +
  51.230 +        // import the trused cert
  51.231 +        Certificate trusedCert = null;
  51.232 +        ByteArrayInputStream is = null;
  51.233 +        if (trustedCertStr != null) {
  51.234 +            is = new ByteArrayInputStream(trustedCertStr.getBytes());
  51.235 +            trusedCert = cf.generateCertificate(is);
  51.236 +            is.close();
  51.237 +
  51.238 +            ks.setCertificateEntry("RSA Export Signer", trusedCert);
  51.239 +        }
  51.240 +
  51.241 +        if (keyCertStr != null) {
  51.242 +            // generate the private key.
  51.243 +            PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(
  51.244 +                                new BASE64Decoder().decodeBuffer(keySpecStr));
  51.245 +            KeyFactory kf = KeyFactory.getInstance("RSA");
  51.246 +            RSAPrivateKey priKey =
  51.247 +                    (RSAPrivateKey)kf.generatePrivate(priKeySpec);
  51.248 +
  51.249 +            // generate certificate chain
  51.250 +            is = new ByteArrayInputStream(keyCertStr.getBytes());
  51.251 +            Certificate keyCert = cf.generateCertificate(is);
  51.252 +            is.close();
  51.253 +
  51.254 +            // It's not allowed to send MD2 signed certificate to peer,
  51.255 +            // even it may be a trusted certificate. Then we will not
  51.256 +            // place the trusted certficate in the chain.
  51.257 +            Certificate[] chain = new Certificate[1];
  51.258 +            chain[0] = keyCert;
  51.259 +
  51.260 +            // import the key entry.
  51.261 +            ks.setKeyEntry("Whatever", priKey, passphrase, chain);
  51.262 +        }
  51.263 +
  51.264 +        // create SSL context
  51.265 +        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlgorithm);
  51.266 +        tmf.init(ks);
  51.267 +
  51.268 +        SSLContext ctx = SSLContext.getInstance(tlsProtocol);
  51.269 +        if (keyCertStr != null && !keyCertStr.isEmpty()) {
  51.270 +            KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");
  51.271 +            kmf.init(ks, passphrase);
  51.272 +
  51.273 +            ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
  51.274 +            ks = null;
  51.275 +        } else {
  51.276 +            ctx.init(null, tmf.getTrustManagers(), null);
  51.277 +        }
  51.278 +
  51.279 +        return ctx;
  51.280 +    }
  51.281 +
  51.282 +
  51.283 +    // use any free port by default
  51.284 +    volatile int serverPort = 0;
  51.285 +
  51.286 +    volatile Exception serverException = null;
  51.287 +    volatile Exception clientException = null;
  51.288 +
  51.289 +    public static void main(String[] args) throws Exception {
  51.290 +        if (debug)
  51.291 +            System.setProperty("javax.net.debug", "all");
  51.292 +
  51.293 +        /*
  51.294 +         * Get the customized arguments.
  51.295 +         */
  51.296 +        parseArguments(args);
  51.297 +
  51.298 +        /*
  51.299 +         * Start the tests.
  51.300 +         */
  51.301 +        new MD2InTrustAnchor();
  51.302 +    }
  51.303 +
  51.304 +    Thread clientThread = null;
  51.305 +    Thread serverThread = null;
  51.306 +
  51.307 +    /*
  51.308 +     * Primary constructor, used to drive remainder of the test.
  51.309 +     *
  51.310 +     * Fork off the other side, then do your work.
  51.311 +     */
  51.312 +    MD2InTrustAnchor() throws Exception {
  51.313 +        try {
  51.314 +            if (separateServerThread) {
  51.315 +                startServer(true);
  51.316 +                startClient(false);
  51.317 +            } else {
  51.318 +                startClient(true);
  51.319 +                startServer(false);
  51.320 +            }
  51.321 +        } catch (Exception e) {
  51.322 +            // swallow for now.  Show later
  51.323 +        }
  51.324 +
  51.325 +        /*
  51.326 +         * Wait for other side to close down.
  51.327 +         */
  51.328 +        if (separateServerThread) {
  51.329 +            serverThread.join();
  51.330 +        } else {
  51.331 +            clientThread.join();
  51.332 +        }
  51.333 +
  51.334 +        /*
  51.335 +         * When we get here, the test is pretty much over.
  51.336 +         * Which side threw the error?
  51.337 +         */
  51.338 +        Exception local;
  51.339 +        Exception remote;
  51.340 +        String whichRemote;
  51.341 +
  51.342 +        if (separateServerThread) {
  51.343 +            remote = serverException;
  51.344 +            local = clientException;
  51.345 +            whichRemote = "server";
  51.346 +        } else {
  51.347 +            remote = clientException;
  51.348 +            local = serverException;
  51.349 +            whichRemote = "client";
  51.350 +        }
  51.351 +
  51.352 +        /*
  51.353 +         * If both failed, return the curthread's exception, but also
  51.354 +         * print the remote side Exception
  51.355 +         */
  51.356 +        if ((local != null) && (remote != null)) {
  51.357 +            System.out.println(whichRemote + " also threw:");
  51.358 +            remote.printStackTrace();
  51.359 +            System.out.println();
  51.360 +            throw local;
  51.361 +        }
  51.362 +
  51.363 +        if (remote != null) {
  51.364 +            throw remote;
  51.365 +        }
  51.366 +
  51.367 +        if (local != null) {
  51.368 +            throw local;
  51.369 +        }
  51.370 +    }
  51.371 +
  51.372 +    void startServer(boolean newThread) throws Exception {
  51.373 +        if (newThread) {
  51.374 +            serverThread = new Thread() {
  51.375 +                public void run() {
  51.376 +                    try {
  51.377 +                        doServerSide();
  51.378 +                    } catch (Exception e) {
  51.379 +                        /*
  51.380 +                         * Our server thread just died.
  51.381 +                         *
  51.382 +                         * Release the client, if not active already...
  51.383 +                         */
  51.384 +                        System.err.println("Server died...");
  51.385 +                        serverReady = true;
  51.386 +                        serverException = e;
  51.387 +                    }
  51.388 +                }
  51.389 +            };
  51.390 +            serverThread.start();
  51.391 +        } else {
  51.392 +            try {
  51.393 +                doServerSide();
  51.394 +            } catch (Exception e) {
  51.395 +                serverException = e;
  51.396 +            } finally {
  51.397 +                serverReady = true;
  51.398 +            }
  51.399 +        }
  51.400 +    }
  51.401 +
  51.402 +    void startClient(boolean newThread) throws Exception {
  51.403 +        if (newThread) {
  51.404 +            clientThread = new Thread() {
  51.405 +                public void run() {
  51.406 +                    try {
  51.407 +                        doClientSide();
  51.408 +                    } catch (Exception e) {
  51.409 +                        /*
  51.410 +                         * Our client thread just died.
  51.411 +                         */
  51.412 +                        System.err.println("Client died...");
  51.413 +                        clientException = e;
  51.414 +                    }
  51.415 +                }
  51.416 +            };
  51.417 +            clientThread.start();
  51.418 +        } else {
  51.419 +            try {
  51.420 +                doClientSide();
  51.421 +            } catch (Exception e) {
  51.422 +                clientException = e;
  51.423 +            }
  51.424 +        }
  51.425 +    }
  51.426 +}
    52.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.2 +++ b/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLContextImpl/TrustTrustedCert.java	Mon Nov 28 15:15:50 2011 -0800
    52.3 @@ -0,0 +1,475 @@
    52.4 +/*
    52.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    52.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    52.7 + *
    52.8 + * This code is free software; you can redistribute it and/or modify it
    52.9 + * under the terms of the GNU General Public License version 2 only, as
   52.10 + * published by the Free Software Foundation.  Oracle designates this
   52.11 + * particular file as subject to the "Classpath" exception as provided
   52.12 + * by Oracle in the LICENSE file that accompanied this code.
   52.13 + *
   52.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   52.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   52.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   52.17 + * version 2 for more details (a copy is included in the LICENSE file that
   52.18 + * accompanied this code).
   52.19 + *
   52.20 + * You should have received a copy of the GNU General Public License version
   52.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   52.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   52.23 + *
   52.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   52.25 + * or visit www.oracle.com if you need additional information or have any
   52.26 + * questions.
   52.27 + */
   52.28 +
   52.29 +/*
   52.30 + * @test
   52.31 + * @bug 7113275
   52.32 + * @summary compatibility issue with MD2 trust anchor and old X509TrustManager
   52.33 + *
   52.34 + *     SunJSSE does not support dynamic system properties, no way to re-use
   52.35 + *     system properties in samevm/agentvm mode.
   52.36 + * @run main/othervm TrustTrustedCert PKIX TLSv1.1
   52.37 + * @run main/othervm TrustTrustedCert SunX509 TLSv1.1
   52.38 + * @run main/othervm TrustTrustedCert PKIX TLSv1.2
   52.39 + * @run main/othervm TrustTrustedCert SunX509 TLSv1.2
   52.40 + */
   52.41 +
   52.42 +import java.net.*;
   52.43 +import java.util.*;
   52.44 +import java.io.*;
   52.45 +import javax.net.ssl.*;
   52.46 +import java.security.*;
   52.47 +import java.security.cert.*;
   52.48 +import java.security.spec.*;
   52.49 +import java.security.interfaces.*;
   52.50 +import sun.misc.BASE64Decoder;
   52.51 +
   52.52 +
   52.53 +public class TrustTrustedCert {
   52.54 +
   52.55 +    /*
   52.56 +     * =============================================================
   52.57 +     * Set the various variables needed for the tests, then
   52.58 +     * specify what tests to run on each side.
   52.59 +     */
   52.60 +
   52.61 +    /*
   52.62 +     * Should we run the client or server in a separate thread?
   52.63 +     * Both sides can throw exceptions, but do you have a preference
   52.64 +     * as to which side should be the main thread.
   52.65 +     */
   52.66 +    static boolean separateServerThread = false;
   52.67 +
   52.68 +    /*
   52.69 +     * Certificates and key used in the test.
   52.70 +     */
   52.71 +
   52.72 +    // It's a trust anchor signed with MD2 hash function.
   52.73 +    static String trustedCertStr =
   52.74 +        "-----BEGIN CERTIFICATE-----\n" +
   52.75 +        "MIICkjCCAfugAwIBAgIBADANBgkqhkiG9w0BAQIFADA7MQswCQYDVQQGEwJVUzEN\n" +
   52.76 +        "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" +
   52.77 +        "MTExMTE4MTExNDA0WhcNMzIxMDI4MTExNDA0WjA7MQswCQYDVQQGEwJVUzENMAsG\n" +
   52.78 +        "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwgZ8wDQYJ\n" +
   52.79 +        "KoZIhvcNAQEBBQADgY0AMIGJAoGBAPGyB9tugUGgxtdeqe0qJEwf9x1Gy4BOi1yR\n" +
   52.80 +        "wzDZY4H5LquvIfQ2V3J9X1MQENVsFvkvp65ZcFcy+ObOucXUUPFcd/iw2DVb5QXA\n" +
   52.81 +        "ffyeVqWD56GPi8Qe37wrJO3L6fBhN9oxp/BbdRLgjU81zx8qLEyPODhPMxV4OkcA\n" +
   52.82 +        "SDwZTSxxAgMBAAGjgaUwgaIwHQYDVR0OBBYEFLOAtr/YrYj9H04EDLA0fd14jisF\n" +
   52.83 +        "MGMGA1UdIwRcMFqAFLOAtr/YrYj9H04EDLA0fd14jisFoT+kPTA7MQswCQYDVQQG\n" +
   52.84 +        "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" +
   52.85 +        "Y2WCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEC\n" +
   52.86 +        "BQADgYEAr8ExpXu/FTIRiMzPm0ubqwME4lniilwQUiEOD/4DbksNjEIcUyS2hIk1\n" +
   52.87 +        "qsmjJz3SHBnwhxl9dhJVwk2tZLkPGW86Zn0TPVRsttK4inTgCC9GFGeqQBdrU/uf\n" +
   52.88 +        "lipBzXWljrfbg4N/kK8m2LabtKUMMnGysM8rN0Fx2PYm5xxGvtM=\n" +
   52.89 +        "-----END CERTIFICATE-----";
   52.90 +
   52.91 +    // The certificate issued by above trust anchor, signed with MD5
   52.92 +    static String targetCertStr =
   52.93 +        "-----BEGIN CERTIFICATE-----\n" +
   52.94 +        "MIICeDCCAeGgAwIBAgIBAjANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" +
   52.95 +        "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" +
   52.96 +        "MTExMTE4MTExNDA2WhcNMzEwODA1MTExNDA2WjBPMQswCQYDVQQGEwJVUzENMAsG\n" +
   52.97 +        "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxEjAQBgNV\n" +
   52.98 +        "BAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwDnm96mw\n" +
   52.99 +        "fXCH4bgXk1US0VcJsQVxUtGMyncAveMuzBzNzOmKZPeqyYX1Fuh4q+cuza03WTJd\n" +
  52.100 +        "G9nOkNr364e3Rn1aaHjCMcBmFflObnGnhhufNmIGYogJ9dJPmhUVPEVAXrMG+Ces\n" +
  52.101 +        "NKy2E8woGnLMrqu6yiuTClbLBPK8fWzTXrECAwEAAaN4MHYwCwYDVR0PBAQDAgPo\n" +
  52.102 +        "MB0GA1UdDgQWBBSdRrpocLPJXyGfDmMWJrcEf29WGDAfBgNVHSMEGDAWgBSzgLa/\n" +
  52.103 +        "2K2I/R9OBAywNH3deI4rBTAnBgNVHSUEIDAeBggrBgEFBQcDAQYIKwYBBQUHAwIG\n" +
  52.104 +        "CCsGAQUFBwMDMA0GCSqGSIb3DQEBBAUAA4GBAKJ71ZiCUykkJrCLYUxlFlhvUcr9\n" +
  52.105 +        "sTcOc67QdroW5f412NI15SXWDiley/JOasIiuIFPjaJBjOKoHOvTjG/snVu9wEgq\n" +
  52.106 +        "YNR8dPsO+NM8r79C6jO+Jx5fYAC7os2XxS75h3NX0ElJcbwIXGBJ6xRrsFh/BGYH\n" +
  52.107 +        "yvudOlX4BkVR0l1K\n" +
  52.108 +        "-----END CERTIFICATE-----";
  52.109 +
  52.110 +    // Private key in the format of PKCS#8.
  52.111 +    static String targetPrivateKey =
  52.112 +        "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMA55vepsH1wh+G4\n" +
  52.113 +        "F5NVEtFXCbEFcVLRjMp3AL3jLswczczpimT3qsmF9RboeKvnLs2tN1kyXRvZzpDa\n" +
  52.114 +        "9+uHt0Z9Wmh4wjHAZhX5Tm5xp4YbnzZiBmKICfXST5oVFTxFQF6zBvgnrDSsthPM\n" +
  52.115 +        "KBpyzK6rusorkwpWywTyvH1s016xAgMBAAECgYEAn9bF3oRkdDoBU0i/mcww5I+K\n" +
  52.116 +        "SH9tFt+WQbiojjz9ac49trkvUfu7MO1Jui2+QbrvaSkyj+HYGFOJd1wMsPXeB7ck\n" +
  52.117 +        "5mOIYV4uZK8jfNMSQ8v0tFEeIPp5lKdw1XnrQfSe+abo2eL5Lwso437Y4s3w37+H\n" +
  52.118 +        "aY3d76hR5qly+Ys+Ww0CQQDjeOoX89d/xhRqGXKjCx8ImE/dPmsI8O27cwtKrDYJ\n" +
  52.119 +        "6t0v/xryVIdvOYcRBvKnqEogOH7T1kI+LnWKUTJ2ehJ7AkEA2FVloPVqCehXcc7e\n" +
  52.120 +        "z3TDpU9w1B0JXklcV5HddYsRqp9RukN/VK4szKE7F1yoarIUtfE9Lr9082Jwyp3M\n" +
  52.121 +        "L11xwwJBAKsZ+Hur3x0tUY29No2Nf/pnFyvEF57SGwA0uPmiL8Ol9lpz+UDudDEl\n" +
  52.122 +        "hIM6Rqv12kwCMuQE9i7vo1o3WU3k5KECQEqhg1L49yD935TqiiFFpe0Ur9btQXse\n" +
  52.123 +        "kdXAA4d2d5zGI7q/aGD9SYU6phkUJSHR16VA2RuUfzMrpb+wmm1IrmMCQFtLoKRT\n" +
  52.124 +        "A5kokFb+E3Gplu29tJvCUpfwgBFRS+wmkvtiaU/tiyDcVgDO+An5DwedxxdVzqiE\n" +
  52.125 +        "njWHoKY3axDQ8OU=\n";
  52.126 +
  52.127 +
  52.128 +    static char passphrase[] = "passphrase".toCharArray();
  52.129 +
  52.130 +    /*
  52.131 +     * Is the server ready to serve?
  52.132 +     */
  52.133 +    volatile static boolean serverReady = false;
  52.134 +
  52.135 +    /*
  52.136 +     * Turn on SSL debugging?
  52.137 +     */
  52.138 +    static boolean debug = false;
  52.139 +
  52.140 +    /*
  52.141 +     * Define the server side of the test.
  52.142 +     *
  52.143 +     * If the server prematurely exits, serverReady will be set to true
  52.144 +     * to avoid infinite hangs.
  52.145 +     */
  52.146 +    void doServerSide() throws Exception {
  52.147 +        SSLContext context = generateSSLContext();
  52.148 +        SSLServerSocketFactory sslssf = context.getServerSocketFactory();
  52.149 +        SSLServerSocket sslServerSocket =
  52.150 +            (SSLServerSocket)sslssf.createServerSocket(serverPort);
  52.151 +        sslServerSocket.setNeedClientAuth(true);
  52.152 +        serverPort = sslServerSocket.getLocalPort();
  52.153 +
  52.154 +        /*
  52.155 +         * Signal Client, we're ready for his connect.
  52.156 +         */
  52.157 +        serverReady = true;
  52.158 +
  52.159 +        SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept();
  52.160 +        InputStream sslIS = sslSocket.getInputStream();
  52.161 +        OutputStream sslOS = sslSocket.getOutputStream();
  52.162 +
  52.163 +        sslIS.read();
  52.164 +        sslOS.write('A');
  52.165 +        sslOS.flush();
  52.166 +
  52.167 +        sslSocket.close();
  52.168 +    }
  52.169 +
  52.170 +    /*
  52.171 +     * Define the client side of the test.
  52.172 +     *
  52.173 +     * If the server prematurely exits, serverReady will be set to true
  52.174 +     * to avoid infinite hangs.
  52.175 +     */
  52.176 +    void doClientSide() throws Exception {
  52.177 +
  52.178 +        /*
  52.179 +         * Wait for server to get started.
  52.180 +         */
  52.181 +        while (!serverReady) {
  52.182 +            Thread.sleep(50);
  52.183 +        }
  52.184 +
  52.185 +        SSLContext context = generateSSLContext();
  52.186 +        SSLSocketFactory sslsf = context.getSocketFactory();
  52.187 +
  52.188 +        SSLSocket sslSocket =
  52.189 +            (SSLSocket)sslsf.createSocket("localhost", serverPort);
  52.190 +
  52.191 +        // enable the specified TLS protocol
  52.192 +        sslSocket.setEnabledProtocols(new String[] {tlsProtocol});
  52.193 +
  52.194 +        InputStream sslIS = sslSocket.getInputStream();
  52.195 +        OutputStream sslOS = sslSocket.getOutputStream();
  52.196 +
  52.197 +        sslOS.write('B');
  52.198 +        sslOS.flush();
  52.199 +        sslIS.read();
  52.200 +
  52.201 +        sslSocket.close();
  52.202 +    }
  52.203 +
  52.204 +    /*
  52.205 +     * =============================================================
  52.206 +     * The remainder is just support stuff
  52.207 +     */
  52.208 +    private static String tmAlgorithm;        // trust manager
  52.209 +    private static String tlsProtocol;        // trust manager
  52.210 +
  52.211 +    private static void parseArguments(String[] args) {
  52.212 +        tmAlgorithm = args[0];
  52.213 +        tlsProtocol = args[1];
  52.214 +    }
  52.215 +
  52.216 +    private static SSLContext generateSSLContext() throws Exception {
  52.217 +
  52.218 +        // generate certificate from cert string
  52.219 +        CertificateFactory cf = CertificateFactory.getInstance("X.509");
  52.220 +
  52.221 +        // create a key store
  52.222 +        KeyStore ks = KeyStore.getInstance("JKS");
  52.223 +        ks.load(null, null);
  52.224 +
  52.225 +        // import the trused cert
  52.226 +        X509Certificate trusedCert = null;
  52.227 +        ByteArrayInputStream is =
  52.228 +                new ByteArrayInputStream(trustedCertStr.getBytes());
  52.229 +        trusedCert = (X509Certificate)cf.generateCertificate(is);
  52.230 +        is.close();
  52.231 +
  52.232 +        ks.setCertificateEntry("Trusted RSA Signer", trusedCert);
  52.233 +
  52.234 +        // generate the private key.
  52.235 +        PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(
  52.236 +                            new BASE64Decoder().decodeBuffer(targetPrivateKey));
  52.237 +        KeyFactory kf = KeyFactory.getInstance("RSA");
  52.238 +        RSAPrivateKey priKey =
  52.239 +                (RSAPrivateKey)kf.generatePrivate(priKeySpec);
  52.240 +
  52.241 +        // generate certificate chain
  52.242 +        is = new ByteArrayInputStream(targetCertStr.getBytes());
  52.243 +        X509Certificate keyCert = (X509Certificate)cf.generateCertificate(is);
  52.244 +        is.close();
  52.245 +
  52.246 +        X509Certificate[] chain = new X509Certificate[2];
  52.247 +        chain[0] = keyCert;
  52.248 +        chain[1] = trusedCert;
  52.249 +
  52.250 +        // import the key entry and the chain
  52.251 +        ks.setKeyEntry("TheKey", priKey, passphrase, chain);
  52.252 +
  52.253 +        // create SSL context
  52.254 +        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlgorithm);
  52.255 +        tmf.init(ks);
  52.256 +
  52.257 +        // create the customized KM and TM
  52.258 +        NoneExtendedX509TM myTM =
  52.259 +            new NoneExtendedX509TM(tmf.getTrustManagers()[0]);
  52.260 +        NoneExtendedX509KM myKM =
  52.261 +            new NoneExtendedX509KM("TheKey", chain, priKey);
  52.262 +
  52.263 +        SSLContext ctx = SSLContext.getInstance(tlsProtocol);
  52.264 +        // KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");
  52.265 +        // kmf.init(ks, passphrase);
  52.266 +        // ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
  52.267 +        ctx.init(new KeyManager[]{myKM}, new TrustManager[]{myTM}, null);
  52.268 +        ks = null;
  52.269 +
  52.270 +        return ctx;
  52.271 +    }
  52.272 +
  52.273 +    static class NoneExtendedX509TM implements X509TrustManager {
  52.274 +        X509TrustManager tm;
  52.275 +
  52.276 +        NoneExtendedX509TM(TrustManager tm) {
  52.277 +            this.tm = (X509TrustManager)tm;
  52.278 +        }
  52.279 +
  52.280 +        public void checkClientTrusted(X509Certificate chain[], String authType)
  52.281 +                throws CertificateException {
  52.282 +            tm.checkClientTrusted(chain, authType);
  52.283 +        }
  52.284 +
  52.285 +        public void checkServerTrusted(X509Certificate chain[], String authType)
  52.286 +                throws CertificateException {
  52.287 +            tm.checkServerTrusted(chain, authType);
  52.288 +        }
  52.289 +
  52.290 +        public X509Certificate[] getAcceptedIssuers() {
  52.291 +            return tm.getAcceptedIssuers();
  52.292 +        }
  52.293 +    }
  52.294 +
  52.295 +    static class NoneExtendedX509KM implements X509KeyManager {
  52.296 +        private String keyAlias;
  52.297 +        private X509Certificate[] chain;
  52.298 +        private PrivateKey privateKey;
  52.299 +
  52.300 +        NoneExtendedX509KM(String keyAlias, X509Certificate[] chain,
  52.301 +                PrivateKey privateKey) {
  52.302 +            this.keyAlias = keyAlias;
  52.303 +            this.chain = chain;
  52.304 +            this.privateKey = privateKey;
  52.305 +        }
  52.306 +
  52.307 +        public String[] getClientAliases(String keyType, Principal[] issuers) {
  52.308 +            return new String[] {keyAlias};
  52.309 +        }
  52.310 +
  52.311 +        public String chooseClientAlias(String[] keyType, Principal[] issuers,
  52.312 +                Socket socket) {
  52.313 +            return keyAlias;
  52.314 +        }
  52.315 +
  52.316 +        public String[] getServerAliases(String keyType, Principal[] issuers) {
  52.317 +            return new String[] {keyAlias};
  52.318 +        }
  52.319 +
  52.320 +        public String chooseServerAlias(String keyType, Principal[] issuers,
  52.321 +                Socket socket) {
  52.322 +            return keyAlias;
  52.323 +        }
  52.324 +
  52.325 +        public X509Certificate[] getCertificateChain(String alias) {
  52.326 +            return chain;
  52.327 +        }
  52.328 +
  52.329 +        public PrivateKey getPrivateKey(String alias) {
  52.330 +            return privateKey;
  52.331 +        }
  52.332 +    }
  52.333 +
  52.334 +
  52.335 +    // use any free port by default
  52.336 +    volatile int serverPort = 0;
  52.337 +
  52.338 +    volatile Exception serverException = null;
  52.339 +    volatile Exception clientException = null;
  52.340 +
  52.341 +    public static void main(String[] args) throws Exception {
  52.342 +        if (debug)
  52.343 +            System.setProperty("javax.net.debug", "all");
  52.344 +
  52.345 +        /*
  52.346 +         * Get the customized arguments.
  52.347 +         */
  52.348 +        parseArguments(args);
  52.349 +
  52.350 +        /*
  52.351 +         * Start the tests.
  52.352 +         */
  52.353 +        new TrustTrustedCert();
  52.354 +    }
  52.355 +
  52.356 +    Thread clientThread = null;
  52.357 +    Thread serverThread = null;
  52.358 +
  52.359 +    /*
  52.360 +     * Primary constructor, used to drive remainder of the test.
  52.361 +     *
  52.362 +     * Fork off the other side, then do your work.
  52.363 +     */
  52.364 +    TrustTrustedCert() throws Exception {
  52.365 +        try {
  52.366 +            if (separateServerThread) {
  52.367 +                startServer(true);
  52.368 +                startClient(false);
  52.369 +            } else {
  52.370 +                startClient(true);
  52.371 +                startServer(false);
  52.372 +            }
  52.373 +        } catch (Exception e) {
  52.374 +            // swallow for now.  Show later
  52.375 +        }
  52.376 +
  52.377 +        /*
  52.378 +         * Wait for other side to close down.
  52.379 +         */
  52.380 +        if (separateServerThread) {
  52.381 +            serverThread.join();
  52.382 +        } else {
  52.383 +            clientThread.join();
  52.384 +        }
  52.385 +
  52.386 +        /*
  52.387 +         * When we get here, the test is pretty much over.
  52.388 +         * Which side threw the error?
  52.389 +         */
  52.390 +        Exception local;
  52.391 +        Exception remote;
  52.392 +        String whichRemote;
  52.393 +
  52.394 +        if (separateServerThread) {
  52.395 +            remote = serverException;
  52.396 +            local = clientException;
  52.397 +            whichRemote = "server";
  52.398 +        } else {
  52.399 +            remote = clientException;
  52.400 +            local = serverException;
  52.401 +            whichRemote = "client";
  52.402 +        }
  52.403 +
  52.404 +        /*
  52.405 +         * If both failed, return the curthread's exception, but also
  52.406 +         * print the remote side Exception
  52.407 +         */
  52.408 +        if ((local != null) && (remote != null)) {
  52.409 +            System.out.println(whichRemote + " also threw:");
  52.410 +            remote.printStackTrace();
  52.411 +            System.out.println();
  52.412 +            throw local;
  52.413 +        }
  52.414 +
  52.415 +        if (remote != null) {
  52.416 +            throw remote;
  52.417 +        }
  52.418 +
  52.419 +        if (local != null) {
  52.420 +            throw local;
  52.421 +        }
  52.422 +    }
  52.423 +
  52.424 +    void startServer(boolean newThread) throws Exception {
  52.425 +        if (newThread) {
  52.426 +            serverThread = new Thread() {
  52.427 +                public void run() {
  52.428 +                    try {
  52.429 +                        doServerSide();
  52.430 +                    } catch (Exception e) {
  52.431 +                        /*
  52.432 +                         * Our server thread just died.
  52.433 +                         *
  52.434 +                         * Release the client, if not active already...
  52.435 +                         */
  52.436 +                        System.err.println("Server died...");
  52.437 +                        serverReady = true;
  52.438 +                        serverException = e;
  52.439 +                    }
  52.440 +                }
  52.441 +            };
  52.442 +            serverThread.start();
  52.443 +        } else {
  52.444 +            try {
  52.445 +                doServerSide();
  52.446 +            } catch (Exception e) {
  52.447 +                serverException = e;
  52.448 +            } finally {
  52.449 +                serverReady = true;
  52.450 +            }
  52.451 +        }
  52.452 +    }
  52.453 +
  52.454 +    void startClient(boolean newThread) throws Exception {
  52.455 +        if (newThread) {
  52.456 +            clientThread = new Thread() {
  52.457 +                public void run() {
  52.458 +                    try {
  52.459 +                        doClientSide();
  52.460 +                    } catch (Exception e) {
  52.461 +                        /*
  52.462 +                         * Our client thread just died.
  52.463 +                         */
  52.464 +                        System.err.println("Client died...");
  52.465 +                        clientException = e;
  52.466 +                    }
  52.467 +                }
  52.468 +            };
  52.469 +            clientThread.start();
  52.470 +        } else {
  52.471 +            try {
  52.472 +                doClientSide();
  52.473 +            } catch (Exception e) {
  52.474 +                clientException = e;
  52.475 +            }
  52.476 +        }
  52.477 +    }
  52.478 +}