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 +}