changeset 3839:259011d14d48

Merge
author alanb
date Fri, 04 Mar 2011 09:33:05 +0000
parents 2fb9e2d4ef46 6e596210bf01
children c4bd93431a20 7b6ad3027f3d
files
diffstat 11 files changed, 286 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/jndi/ldap/Connection.java	Fri Mar 04 09:29:56 2011 +0000
+++ b/src/share/classes/com/sun/jndi/ldap/Connection.java	Fri Mar 04 09:33:05 2011 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -380,13 +380,19 @@
     }
 
     LdapRequest writeRequest(BerEncoder ber, int msgId) throws IOException {
-        return writeRequest(ber, msgId, false /* pauseAfterReceipt */);
+        return writeRequest(ber, msgId, false /* pauseAfterReceipt */, -1);
     }
 
-    LdapRequest writeRequest(BerEncoder ber, int msgId, boolean pauseAfterReceipt)
-        throws IOException {
+    LdapRequest writeRequest(BerEncoder ber, int msgId,
+        boolean pauseAfterReceipt) throws IOException {
+        return writeRequest(ber, msgId, pauseAfterReceipt, -1);
+    }
 
-        LdapRequest req = new LdapRequest(msgId, pauseAfterReceipt);
+    LdapRequest writeRequest(BerEncoder ber, int msgId,
+        boolean pauseAfterReceipt, int replyQueueCapacity) throws IOException {
+
+        LdapRequest req =
+            new LdapRequest(msgId, pauseAfterReceipt, replyQueueCapacity);
         addRequest(req);
 
         if (traceFile != null) {
--- a/src/share/classes/com/sun/jndi/ldap/LdapClient.java	Fri Mar 04 09:29:56 2011 +0000
+++ b/src/share/classes/com/sun/jndi/ldap/LdapClient.java	Fri Mar 04 09:33:05 2011 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -516,7 +516,8 @@
     LdapResult search(String dn, int scope, int deref, int sizeLimit,
                       int timeLimit, boolean attrsOnly, String attrs[],
                       String filter, int batchSize, Control[] reqCtls,
-                      Hashtable binaryAttrs, boolean waitFirstReply)
+                      Hashtable binaryAttrs, boolean waitFirstReply,
+                      int replyQueueCapacity)
         throws IOException, NamingException {
 
         ensureOpen();
@@ -543,7 +544,8 @@
                 if (isLdapv3) encodeControls(ber, reqCtls);
             ber.endSeq();
 
-         LdapRequest req = conn.writeRequest(ber, curMsgId);
+         LdapRequest req =
+                conn.writeRequest(ber, curMsgId, false, replyQueueCapacity);
 
          res.msgId = curMsgId;
          res.status = LdapClient.LDAP_SUCCESS; //optimistic
--- a/src/share/classes/com/sun/jndi/ldap/LdapCtx.java	Fri Mar 04 09:29:56 2011 +0000
+++ b/src/share/classes/com/sun/jndi/ldap/LdapCtx.java	Fri Mar 04 09:33:05 2011 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -191,6 +191,14 @@
     // Environment property for the domain name (derived from this context's DN)
     private static final String DOMAIN_NAME = "com.sun.jndi.ldap.domainname";
 
+    // Block until the first search reply is received
+    private static final String WAIT_FOR_REPLY =
+        "com.sun.jndi.ldap.search.waitForReply";
+
+    // Size of the queue of unprocessed search replies
+    private static final String REPLY_QUEUE_SIZE =
+        "com.sun.jndi.ldap.search.replyQueueSize";
+
     // ----------------- Fields that don't change -----------------------
     private static final NameParser parser = new LdapNameParser();
 
@@ -246,6 +254,8 @@
     private Hashtable binaryAttrs = null;    // attr values returned as byte[]
     private int connectTimeout = -1;         // no timeout value
     private int readTimeout = -1;            // no timeout value
+    private boolean waitForReply = true;     // wait for search response
+    private int replyQueueSize  = -1;        // unlimited queue size
     private boolean useSsl = false;          // true if SSL protocol is active
     private boolean useDefaultPortNumber = false; // no port number was supplied
 
@@ -1759,8 +1769,8 @@
                                          SearchControls cons,
                                          Continuation cont)
             throws NamingException {
-        return searchAux(name, filter, cloneSearchControls(cons), true, true,
-                         cont);
+        return searchAux(name, filter, cloneSearchControls(cons), true,
+                 waitForReply, cont);
     }
 
     protected NamingEnumeration c_search(Name name,
@@ -1928,7 +1938,7 @@
     }
 
     private LdapResult doSearch(Name name, String filter, SearchControls cons,
-        boolean relative, boolean waitFirstReply) throws NamingException {
+        boolean relative, boolean waitForReply) throws NamingException {
             ensureOpen();
             try {
                 int scope;
@@ -1984,7 +1994,8 @@
                         batchSize,
                         reqCtls,
                         binaryAttrs,
-                        waitFirstReply);
+                        waitForReply,
+                        replyQueueSize);
                 respCtls = answer.resControls; // retrieve response controls
                 return answer;
 
@@ -2170,6 +2181,10 @@
             connectTimeout = -1;
         } else if (propName.equals(READ_TIMEOUT)) {
             readTimeout = -1;
+        } else if (propName.equals(WAIT_FOR_REPLY)) {
+            waitForReply = true;
+        } else if (propName.equals(REPLY_QUEUE_SIZE)) {
+            replyQueueSize = -1;
 
 // The following properties affect the connection
 
@@ -2225,6 +2240,11 @@
                 setConnectTimeout((String)propVal);
             } else if (propName.equals(READ_TIMEOUT)) {
                 setReadTimeout((String)propVal);
+            } else if (propName.equals(WAIT_FOR_REPLY)) {
+                setWaitForReply((String)propVal);
+            } else if (propName.equals(REPLY_QUEUE_SIZE)) {
+                setReplyQueueSize((String)propVal);
+
 // The following properties affect the connection
 
             } else if (propName.equals(Context.SECURITY_PROTOCOL)) {
@@ -2312,6 +2332,13 @@
         // Set the read timeout
         setReadTimeout((String)envprops.get(READ_TIMEOUT));
 
+        // Set the flag that controls whether to block until the first reply
+        // is received
+        setWaitForReply((String)envprops.get(WAIT_FOR_REPLY));
+
+        // Set the size of the queue of unprocessed search replies
+        setReplyQueueSize((String)envprops.get(REPLY_QUEUE_SIZE));
+
         // When connection is created, it will use these and other
         // properties from the environment
     }
@@ -2442,6 +2469,34 @@
     }
 
     /**
+     * Sets the size of the queue of unprocessed search replies
+     */
+    private void setReplyQueueSize(String replyQueueSizeProp) {
+        if (replyQueueSizeProp != null) {
+           replyQueueSize = Integer.parseInt(replyQueueSizeProp);
+            // disallow an empty queue
+            if (replyQueueSize <= 0) {
+                replyQueueSize = -1;    // unlimited
+            }
+        } else {
+            replyQueueSize = -1;        // unlimited
+        }
+    }
+
+    /**
+     * Sets the flag that controls whether to block until the first search
+     * reply is received
+     */
+    private void setWaitForReply(String waitForReplyProp) {
+        if (waitForReplyProp != null &&
+            (waitForReplyProp.equalsIgnoreCase("false"))) {
+            waitForReply = false;
+        } else {
+            waitForReply = true;
+        }
+    }
+
+    /**
      * Sets the read timeout value
      */
     private void setReadTimeout(String readTimeoutProp) {
--- a/src/share/classes/com/sun/jndi/ldap/LdapRequest.java	Fri Mar 04 09:29:56 2011 +0000
+++ b/src/share/classes/com/sun/jndi/ldap/LdapRequest.java	Fri Mar 04 09:33:05 2011 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,8 @@
 package com.sun.jndi.ldap;
 
 import java.io.IOException;
-import java.util.Vector;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
 import javax.naming.CommunicationException;
 
 final class LdapRequest {
@@ -35,14 +36,26 @@
     int msgId;          // read-only
 
     private int gotten = 0;
-    private Vector replies = new Vector(3);
+    private BlockingQueue<BerDecoder> replies;
+    private int highWatermark = -1;
     private boolean cancelled = false;
     private boolean pauseAfterReceipt = false;
     private boolean completed = false;
 
     LdapRequest(int msgId, boolean pause) {
+        this(msgId, pause, -1);
+    }
+
+    LdapRequest(int msgId, boolean pause, int replyQueueCapacity) {
         this.msgId = msgId;
         this.pauseAfterReceipt = pause;
+        if (replyQueueCapacity == -1) {
+            this.replies = new LinkedBlockingQueue<BerDecoder>();
+        } else {
+            this.replies =
+                new LinkedBlockingQueue<BerDecoder>(replyQueueCapacity);
+            highWatermark = (replyQueueCapacity * 80) / 100; // 80% capacity
+        }
     }
 
     synchronized void cancel() {
@@ -57,7 +70,13 @@
         if (cancelled) {
             return false;
         }
-        replies.addElement(ber);
+
+        // Add a new reply to the queue of unprocessed replies.
+        try {
+            replies.put(ber);
+        } catch (InterruptedException e) {
+            // ignore
+        }
 
         // peek at the BER buffer to check if it is a SearchResultDone PDU
         try {
@@ -70,6 +89,14 @@
         ber.reset();
 
         notify(); // notify anyone waiting for reply
+        /*
+         * If a queue capacity has been set then trigger a pause when the
+         * queue has filled to 80% capacity. Later, when the queue has drained
+         * then the reader gets unpaused.
+         */
+        if (highWatermark != -1 && replies.size() >= highWatermark) {
+            return true; // trigger the pause
+        }
         return pauseAfterReceipt;
     }
 
@@ -79,14 +106,12 @@
                 " cancelled");
         }
 
-        if (gotten < replies.size()) {
-            BerDecoder answer = (BerDecoder)replies.elementAt(gotten);
-            replies.setElementAt(null, gotten); // remove reference
-            ++gotten; // skip to next
-            return answer;
-        } else {
-            return null;
-        }
+        /*
+         * Remove a reply if the queue is not empty.
+         * poll returns null if queue is empty.
+         */
+        BerDecoder reply = replies.poll();
+        return reply;
     }
 
     synchronized boolean hasSearchCompleted() {
--- a/src/share/classes/java/net/HttpURLConnection.java	Fri Mar 04 09:29:56 2011 +0000
+++ b/src/share/classes/java/net/HttpURLConnection.java	Fri Mar 04 09:33:05 2011 +0000
@@ -400,7 +400,8 @@
      * @exception ProtocolException if the method cannot be reset or if
      *              the requested method isn't valid for HTTP.
      * @exception SecurityException if a security manager is set and the
-     *              "allowHttpTrace" NetPermission is not granted.
+     *              method is "TRACE", but the "allowHttpTrace"
+     *              NetPermission is not granted.
      * @see #getRequestMethod()
      */
     public void setRequestMethod(String method) throws ProtocolException {
--- a/src/share/classes/java/net/NetPermission.java	Fri Mar 04 09:29:56 2011 +0000
+++ b/src/share/classes/java/net/NetPermission.java	Fri Mar 04 09:33:05 2011 +0000
@@ -73,6 +73,13 @@
  *   </tr>
  *
  * <tr>
+ *  <td>getNetworkInformation</td>
+ *  <td>The ability to retrieve all information about local network interfaces.</td>
+ *  <td>Malicious code can read information about network hardware such as
+ *  MAC addresses, which could be used to construct local IPv6 addresses.</td>
+ * </tr>
+ *
+ * <tr>
  *   <td>getProxySelector</td>
  *   <td>The ability to get the proxy selector used to make decisions
  *   on which proxies to use when making network connections.</td>
--- a/src/share/classes/java/net/URI.java	Fri Mar 04 09:29:56 2011 +0000
+++ b/src/share/classes/java/net/URI.java	Fri Mar 04 09:33:05 2011 +0000
@@ -991,7 +991,7 @@
      *   authority and path are taken from the given URI. </p></li>
      *
      *   <li><p> Otherwise the new URI's authority component is copied from
-     *   this URI, and its path is computed as follows: </p></li>
+     *   this URI, and its path is computed as follows: </p>
      *
      *   <ol type=a>
      *
@@ -1005,7 +1005,7 @@
      *     path and then normalizing the result as if by invoking the {@link
      *     #normalize() normalize} method. </p></li>
      *
-     *   </ol>
+     *   </ol></li>
      *
      * </ol>
      *
@@ -1511,7 +1511,7 @@
      *   fragments. </p></li>
      *
      *   <li><p> Two hierarchical URIs with identical schemes are ordered
-     *   according to the ordering of their authority components: </p></li>
+     *   according to the ordering of their authority components: </p>
      *
      *   <ul type=disc>
      *
@@ -1526,7 +1526,7 @@
      *     the URIs are ordered according to the ordering of their authority
      *     components. </p></li>
      *
-     *   </ul>
+     *   </ul></li>
      *
      *   <li><p> Finally, two hierarchical URIs with identical schemes and
      *   authority components are ordered according to the ordering of their
--- a/src/share/classes/java/net/package.html	Fri Mar 04 09:29:56 2011 +0000
+++ b/src/share/classes/java/net/package.html	Fri Mar 04 09:33:05 2011 +0000
@@ -31,18 +31,18 @@
 
 <p> The java.net package can be roughly divided in two sections:</p>
 <ul>
-    <li> <p><i>A Low Level API</i>, which deals with the following abstractions:</p></li>
+    <li> <p><i>A Low Level API</i>, which deals with the following abstractions:</p>
     <ul>
       <li><p><i>Addresses</i>, which are networking identifiers, like IP addresses.</p></li>
       <li><p><i>Sockets</i>, which are basic bidirectional data communication mechanisms.</p></li>
       <li><p><i>Interfaces</i>, which describe network interfaces. </p></li>
-    </ul>
-    <li> <p><i>A High Level API</i>, which deals with the following abstractions:</p></li>
+    </ul></li>
+    <li> <p><i>A High Level API</i>, which deals with the following abstractions:</p>
     <ul>
       <li><p><i>URIs</i>, which represent Universal Resource Identifiers.</p></li>
       <li><p><i>URLs</i>, which represent Universal Resource Locators.</p></li>
       <li><p><i>Connections</i>, which represents connections to the resource pointed to by <i>URLs</i>.</p></li>
-      </ul>
+      </ul></li>
 </ul>
 <h2>Addresses</h2>
 <p>Addresses are used throughout the java.net APIs as either host identifiers, or socket endpoint identifiers.</p>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/com/sun/jndi/ldap/NoWaitForReplyTest.java	Fri Mar 04 09:33:05 2011 +0000
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 6748156
+ * @summary add an new JNDI property to control the boolean flag WaitForReply
+ */
+
+import java.net.Socket;
+import java.net.ServerSocket;
+import java.io.*;
+import javax.naming.*;
+import javax.naming.directory.*;
+import java.util.Hashtable;
+
+public class NoWaitForReplyTest {
+
+    public static void main(String[] args) throws Exception {
+
+    boolean passed = false;
+
+    // Set up the environment for creating the initial context
+    Hashtable env = new Hashtable(11);
+        env.put(Context.PROVIDER_URL, "ldap://localhost:22001");
+    env.put(Context.INITIAL_CONTEXT_FACTORY,
+        "com.sun.jndi.ldap.LdapCtxFactory");
+
+    // Wait up to 10 seconds for a response from the LDAP server
+    env.put("com.sun.jndi.ldap.read.timeout", "10000");
+
+    // Don't wait until the first search reply is received
+    env.put("com.sun.jndi.ldap.search.waitForReply", "false");
+
+    // Send the LDAP search request without first authenticating (no bind)
+    env.put("java.naming.ldap.version", "3");
+
+    DummyServer ldapServer = new DummyServer();
+
+    try {
+
+        // start the LDAP server
+        ldapServer.start();
+
+        // Create initial context
+        System.out.println("Client: connecting to the server");
+        DirContext ctx = new InitialDirContext(env);
+
+        SearchControls scl = new SearchControls();
+        scl.setSearchScope(SearchControls.SUBTREE_SCOPE);
+        System.out.println("Client: performing search");
+        NamingEnumeration answer =
+        ctx.search("ou=People,o=JNDITutorial", "(objectClass=*)", scl);
+
+        // Server will never reply: either we waited in the call above until
+        // the timeout (fail) or we did not wait and reached here (pass).
+        passed = true;
+        System.out.println("Client: did not wait until first reply");
+
+        // Close the context when we're done
+        ctx.close();
+
+    } catch (NamingException e) {
+        // timeout (ignore)
+    }
+    ldapServer.interrupt();
+
+    if (!passed) {
+        throw new Exception(
+        "Test FAILED: should not have waited until first search reply");
+    }
+    System.out.println("Test PASSED");
+    }
+
+    static class DummyServer extends Thread {
+
+        static int serverPort = 22001;
+
+    DummyServer() {
+    }
+
+    public void run() {
+        try {
+        ServerSocket serverSock = new ServerSocket(serverPort);
+                Socket socket = serverSock.accept();
+                System.out.println("Server: accepted a connection");
+                BufferedInputStream bin =
+            new BufferedInputStream(socket.getInputStream());
+
+                while (true) {
+                    bin.read();
+                }
+        } catch (IOException e) {
+        // ignore
+        }
+    }
+}
+}
--- a/test/java/lang/ProcessBuilder/Basic.java	Fri Mar 04 09:29:56 2011 +0000
+++ b/test/java/lang/ProcessBuilder/Basic.java	Fri Mar 04 09:33:05 2011 +0000
@@ -26,7 +26,7 @@
  * @bug 4199068 4738465 4937983 4930681 4926230 4931433 4932663 4986689
  *      5026830 5023243 5070673 4052517 4811767 6192449 6397034 6413313
  *      6464154 6523983 6206031 4960438 6631352 6631966 6850957 6850958
- *      4947220
+ *      4947220 7018606
  * @summary Basic tests for Process and Environment Variable code
  * @run main/othervm/timeout=300 Basic
  * @author Martin Buchholz
@@ -47,6 +47,9 @@
 
 public class Basic {
 
+    /* used for Windows only */
+    static final String systemRoot = System.getenv("SystemRoot");
+
     private static String commandOutput(Reader r) throws Throwable {
         StringBuilder sb = new StringBuilder();
         int c;
@@ -1073,7 +1076,11 @@
         try {
             ProcessBuilder pb = new ProcessBuilder();
             pb.environment().clear();
-            equal(getenvInChild(pb), "");
+            String expected = Windows.is() ? "SystemRoot="+systemRoot+",": "";
+            if (Windows.is()) {
+                pb.environment().put("SystemRoot", systemRoot);
+            }
+            equal(getenvInChild(pb), expected);
         } catch (Throwable t) { unexpected(t); }
 
         //----------------------------------------------------------------
@@ -1561,13 +1568,21 @@
             List<String> childArgs = new ArrayList<String>(javaChildArgs);
             childArgs.add("System.getenv()");
             String[] cmdp = childArgs.toArray(new String[childArgs.size()]);
-            String[] envp = {"=ExitValue=3", "=C:=\\"};
+            String[] envp;
+            String[] envpWin = {"=ExitValue=3", "=C:=\\", "SystemRoot="+systemRoot};
+            String[] envpOth = {"=ExitValue=3", "=C:=\\"};
+            if (Windows.is()) {
+                envp = envpWin;
+            } else {
+                envp = envpOth;
+            }
             Process p = Runtime.getRuntime().exec(cmdp, envp);
-            String expected = Windows.is() ? "=C:=\\,=ExitValue=3," : "=C:=\\,";
+            String expected = Windows.is() ? "=C:=\\,SystemRoot="+systemRoot+",=ExitValue=3," : "=C:=\\,";
             equal(commandOutput(p), expected);
             if (Windows.is()) {
                 ProcessBuilder pb = new ProcessBuilder(childArgs);
                 pb.environment().clear();
+                pb.environment().put("SystemRoot", systemRoot);
                 pb.environment().put("=ExitValue", "3");
                 pb.environment().put("=C:", "\\");
                 equal(commandOutput(pb), expected);
@@ -1591,10 +1606,18 @@
             List<String> childArgs = new ArrayList<String>(javaChildArgs);
             childArgs.add("System.getenv()");
             String[] cmdp = childArgs.toArray(new String[childArgs.size()]);
-            String[] envp = {"LC_ALL=C\u0000\u0000", // Yuck!
+            String[] envpWin = {"SystemRoot="+systemRoot, "LC_ALL=C\u0000\u0000", // Yuck!
                              "FO\u0000=B\u0000R"};
+            String[] envpOth = {"LC_ALL=C\u0000\u0000", // Yuck!
+                             "FO\u0000=B\u0000R"};
+            String[] envp;
+            if (Windows.is()) {
+                envp = envpWin;
+            } else {
+                envp = envpOth;
+            }
             Process p = Runtime.getRuntime().exec(cmdp, envp);
-            check(commandOutput(p).equals("LC_ALL=C,"),
+            check(commandOutput(p).equals(Windows.is() ? "SystemRoot="+systemRoot+",LC_ALL=C," : "LC_ALL=C,"),
                   "Incorrect handling of envstrings containing NULs");
         } catch (Throwable t) { unexpected(t); }
 
@@ -2144,6 +2167,7 @@
     static void equal(Object x, Object y) {
         if (x == null ? y == null : x.equals(y)) pass();
         else fail(x + " not equal to " + y);}
+
     public static void main(String[] args) throws Throwable {
         try {realMain(args);} catch (Throwable t) {unexpected(t);}
         System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
--- a/test/java/lang/Thread/StartOOMTest.java	Fri Mar 04 09:29:56 2011 +0000
+++ b/test/java/lang/Thread/StartOOMTest.java	Fri Mar 04 09:33:05 2011 +0000
@@ -22,11 +22,14 @@
  */
 
 /*
- * @test
- * @bug 6379235
- * @ignore until 6721694 is fixed
- * @run main/othervm -server -Xmx32m -Xms32m -Xss256m StartOOMTest
- * @summary ThreadGroup accounting mistake possible with failure of Thread.start()
+ * This test is relatively useful for verifying 6379235, but
+ * is too resource intensive, especially on 64 bit systems,
+ * to be run automatically, see 6721694.
+ *
+ * When run it should be typically be run with the server vm
+ * and a relatively small java heap, and a large stack size
+ * ( to provoke the OOM quicker ).
+ *    java -server -Xmx32m -Xms32m -Xss256m StartOOMTest
  */
 
 import java.util.*;