Merge
authorlana
Mon, 25 Jun 2012 21:38:37 -0700
changeset 13034 dad69f88fe36
parent 13010 20759a13274c (current diff)
parent 13033 365efcc2d50c (diff)
child 13048 82534e9c5cc7
Merge
--- a/jdk/make/common/Defs-embedded.gmk	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/make/common/Defs-embedded.gmk	Mon Jun 25 21:38:37 2012 -0700
@@ -42,7 +42,7 @@
 OTHER_CPPFLAGS += -DJAVASE_EMBEDDED
 
 # Product naming
-PRODUCT_SUFFIX = SE Runtime Environment for Embedded
+PRODUCT_SUFFIX = SE Embedded Runtime Environment
 RUNTIME_NAME = $(PRODUCT_NAME) $(PRODUCT_SUFFIX)
 
 # Reduced JRE locations
--- a/jdk/make/java/java/FILES_java.gmk	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/make/java/java/FILES_java.gmk	Mon Jun 25 21:38:37 2012 -0700
@@ -372,6 +372,7 @@
     java/util/spi/CurrencyNameProvider.java \
     java/util/spi/LocaleNameProvider.java \
     java/util/spi/LocaleServiceProvider.java \
+    java/util/spi/ResourceBundleControlProvider.java \
     java/util/spi/TimeZoneNameProvider.java \
     java/io/Closeable.java \
     java/io/Flushable.java \
--- a/jdk/make/java/nio/mapfile-linux	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/make/java/nio/mapfile-linux	Mon Jun 25 21:38:37 2012 -0700
@@ -88,6 +88,7 @@
                 Java_sun_nio_ch_IOUtil_fdVal;
 		Java_sun_nio_ch_IOUtil_fdLimit;
                 Java_sun_nio_ch_IOUtil_initIDs;
+		Java_sun_nio_ch_IOUtil_iovMax;
                 Java_sun_nio_ch_IOUtil_makePipe;
                 Java_sun_nio_ch_IOUtil_randomBytes;
                 Java_sun_nio_ch_IOUtil_setfdVal;
--- a/jdk/make/java/nio/mapfile-solaris	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/make/java/nio/mapfile-solaris	Mon Jun 25 21:38:37 2012 -0700
@@ -76,6 +76,7 @@
 		Java_sun_nio_ch_IOUtil_fdLimit;
                 Java_sun_nio_ch_IOUtil_fdVal;
                 Java_sun_nio_ch_IOUtil_initIDs;
+		Java_sun_nio_ch_IOUtil_iovMax;
                 Java_sun_nio_ch_IOUtil_makePipe;
                 Java_sun_nio_ch_IOUtil_randomBytes;
                 Java_sun_nio_ch_IOUtil_setfdVal;
--- a/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java	Mon Jun 25 21:38:37 2012 -0700
@@ -659,7 +659,7 @@
                  * us work with drivers that do not support
                  * getObject with a map in fairly sensible way
                  */
-                if (map == null) {
+                if (map == null || map.isEmpty()) {
                     obj = data.getObject(i);
                 } else {
                     obj = data.getObject(i, map);
--- a/jdk/src/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/src/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java	Mon Jun 25 21:38:37 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -812,101 +812,119 @@
         }
     }
 
-    /**
-         * Inserts a row that has been inserted into the given
-         * <code>CachedRowSet</code> object into the data source from which
-         * the rowset is derived, returning <code>false</code> if the insertion
-         * was successful.
-         *
-         * @param crs the <code>CachedRowSet</code> object that has had a row inserted
-         *            and to whose underlying data source the row will be inserted
-         * @param pstmt the <code>PreparedStatement</code> object that will be used
-         *              to execute the insertion
-         * @return <code>false</code> to indicate that the insertion was successful;
-         *         <code>true</code> otherwise
-         * @throws SQLException if a database access error occurs
-         */
-    private boolean insertNewRow(CachedRowSet crs,
-        PreparedStatement pstmt, CachedRowSetImpl crsRes) throws SQLException {
-        int i = 0;
-        int icolCount = crs.getMetaData().getColumnCount();
+   /**
+    * Inserts a row that has been inserted into the given
+    * <code>CachedRowSet</code> object into the data source from which
+    * the rowset is derived, returning <code>false</code> if the insertion
+    * was successful.
+    *
+    * @param crs the <code>CachedRowSet</code> object that has had a row inserted
+    *            and to whose underlying data source the row will be inserted
+    * @param pstmt the <code>PreparedStatement</code> object that will be used
+    *              to execute the insertion
+    * @return <code>false</code> to indicate that the insertion was successful;
+    *         <code>true</code> otherwise
+    * @throws SQLException if a database access error occurs
+    */
+   private boolean insertNewRow(CachedRowSet crs,
+       PreparedStatement pstmt, CachedRowSetImpl crsRes) throws SQLException {
+
+       boolean returnVal = false;
 
-        boolean returnVal = false;
-        PreparedStatement pstmtSel = con.prepareStatement(selectCmd,
-                        ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
-        ResultSet rs, rs2 = null;
-        DatabaseMetaData dbmd = con.getMetaData();
-        rs = pstmtSel.executeQuery();
-        String table = crs.getTableName();
-        rs2 = dbmd.getPrimaryKeys(null, null, table);
-        String [] primaryKeys = new String[icolCount];
-        int k = 0;
-        while(rs2.next()) {
-            String pkcolname = rs2.getString("COLUMN_NAME");
-            primaryKeys[k] = pkcolname;
-            k++;
-        }
+       try (PreparedStatement pstmtSel = con.prepareStatement(selectCmd,
+                       ResultSet.TYPE_SCROLL_SENSITIVE,
+                       ResultSet.CONCUR_READ_ONLY);
+            ResultSet rs = pstmtSel.executeQuery();
+            ResultSet rs2 = con.getMetaData().getPrimaryKeys(null, null,
+                       crs.getTableName())
+       ) {
+
+           ResultSetMetaData rsmd = crs.getMetaData();
+           int icolCount = rsmd.getColumnCount();
+           String[] primaryKeys = new String[icolCount];
+           int k = 0;
+           while (rs2.next()) {
+               primaryKeys[k] = rs2.getString("COLUMN_NAME");
+               k++;
+           }
+
+           if (rs.next()) {
+               for (String pkName : primaryKeys) {
+                   if (!isPKNameValid(pkName, rsmd)) {
+
+                       /* We came here as one of the the primary keys
+                        * of the table is not present in the cached
+                        * rowset object, it should be an autoincrement column
+                        * and not included while creating CachedRowSet
+                        * Object, proceed to check for other primary keys
+                        */
+                       continue;
+                   }
 
-        if(rs.next()) {
-            for(int j=0;j<primaryKeys.length;j++) {
-                if(primaryKeys[j] != null) {
-                    if(crs.getObject(primaryKeys[j]) == null){
-                        break;
-                    }
-                    String crsPK = (crs.getObject(primaryKeys[j])).toString();
-                    String rsPK = (rs.getObject(primaryKeys[j])).toString();
-                    if(crsPK.equals(rsPK)) {
-                        returnVal = true;
-                        this.crsResolve.moveToInsertRow();
-                        for(i = 1; i <= icolCount; i++) {
-                            String colname = (rs.getMetaData()).getColumnName(i);
-                            if(colname.equals(primaryKeys[j]))
-                                this.crsResolve.updateObject(i,rsPK);
-                            else
-                                this.crsResolve.updateNull(i);
-                        }
-                        this.crsResolve.insertRow();
-                        this.crsResolve.moveToCurrentRow();
-                    }
-                }
-            }
-        }
-        if(returnVal)
-            return returnVal;
+                   Object crsPK = crs.getObject(pkName);
+                   if (crsPK == null) {
+                       /*
+                        * It is possible that the PK is null on some databases
+                        * and will be filled in at insert time (MySQL for example)
+                        */
+                       break;
+                   }
+
+                   String rsPK = rs.getObject(pkName).toString();
+                   if (crsPK.toString().equals(rsPK)) {
+                       returnVal = true;
+                       this.crsResolve.moveToInsertRow();
+                       for (int i = 1; i <= icolCount; i++) {
+                           String colname = (rs.getMetaData()).getColumnName(i);
+                           if (colname.equals(pkName))
+                               this.crsResolve.updateObject(i,rsPK);
+                           else
+                               this.crsResolve.updateNull(i);
+                       }
+                       this.crsResolve.insertRow();
+                       this.crsResolve.moveToCurrentRow();
+                   }
+               }
+           }
+
+           if (returnVal) {
+               return returnVal;
+           }
 
-        try {
-            for (i = 1; i <= icolCount; i++) {
-                Object obj = crs.getObject(i);
-                if (obj != null) {
-                    pstmt.setObject(i, obj);
-                } else {
-                    pstmt.setNull(i,crs.getMetaData().getColumnType(i));
-                }
-            }
+           try {
+               for (int i = 1; i <= icolCount; i++) {
+                   Object obj = crs.getObject(i);
+                   if (obj != null) {
+                       pstmt.setObject(i, obj);
+                   } else {
+                       pstmt.setNull(i,crs.getMetaData().getColumnType(i));
+                   }
+               }
 
-             i = pstmt.executeUpdate();
-             return false;
+               pstmt.executeUpdate();
+               return false;
 
-        } catch (SQLException ex) {
-            /**
-             * Cursor will come here if executeUpdate fails.
-             * There can be many reasons why the insertion failed,
-             * one can be violation of primary key.
-             * Hence we cannot exactly identify why the insertion failed
-             * Present the current row as a null row to the user.
-             **/
-            this.crsResolve.moveToInsertRow();
+           } catch (SQLException ex) {
+               /*
+                * Cursor will come here if executeUpdate fails.
+                * There can be many reasons why the insertion failed,
+                * one can be violation of primary key.
+                * Hence we cannot exactly identify why the insertion failed,
+                * present the current row as a null row to the caller.
+                */
+               this.crsResolve.moveToInsertRow();
 
-            for(i = 1; i <= icolCount; i++) {
-               this.crsResolve.updateNull(i);
-            }
+               for (int i = 1; i <= icolCount; i++) {
+                   this.crsResolve.updateNull(i);
+               }
 
-            this.crsResolve.insertRow();
-            this.crsResolve.moveToCurrentRow();
+               this.crsResolve.insertRow();
+               this.crsResolve.moveToCurrentRow();
 
-            return true;
-        }
-    }
+               return true;
+           }
+       }
+   }
 
 /**
  * Deletes the row in the underlying data source that corresponds to
@@ -1437,4 +1455,25 @@
     }
 
     static final long serialVersionUID =-8506030970299413976L;
+
+    /**
+     * Validate whether the Primary Key is known to the CachedRowSet.  If it is
+     * not, it is an auto-generated key
+     * @param pk - Primary Key to validate
+     * @param rsmd - ResultSetMetadata for the RowSet
+     * @return true if found, false otherwise (auto generated key)
+     */
+    private boolean isPKNameValid(String pk, ResultSetMetaData rsmd) throws SQLException {
+        boolean isValid = false;
+        int cols = rsmd.getColumnCount();
+        for(int i = 1; i<= cols; i++) {
+            String colName = rsmd.getColumnClassName(i);
+            if(colName.equalsIgnoreCase(pk)) {
+                isValid = true;
+                break;
+            }
+        }
+
+        return isValid;
+    }
 }
--- a/jdk/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java	Mon Jun 25 21:38:37 2012 -0700
@@ -764,6 +764,7 @@
                     rs.next();
                     rs.setOriginalRow();
                     applyUpdates();
+                    rs.deleteRow();
                 } catch (SQLException ex) {
                     throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errdel").toString() , ex.getMessage()));
                 }
--- a/jdk/src/share/classes/java/io/SerialCallbackContext.java	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/src/share/classes/java/io/SerialCallbackContext.java	Mon Jun 25 21:38:37 2012 -0700
@@ -1,54 +1,74 @@
-  /*
-   * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
-   * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
-   */
-
-  package java.io;
+/*
+ * Copyright (c) 2006, 2012, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
 
-  /**
-   * Context during upcalls from object stream to class-defined
-   * readObject/writeObject methods.
-   * Holds object currently being deserialized and descriptor for current class.
-   *
-   * This context keeps track of the thread it was constructed on, and allows
-   * only a single call of defaultReadObject, readFields, defaultWriteObject
-   * or writeFields which must be invoked on the same thread before the class's
-   * readObject/writeObject method has returned.
-   * If not set to the current thread, the getObj method throws NotActiveException.
-   */
-  final class SerialCallbackContext {
-      private final Object obj;
-      private final ObjectStreamClass desc;
-      /**
-       * Thread this context is in use by.
-       * As this only works in one thread, we do not need to worry about thread-safety.
-       */
-      private Thread thread;
+package java.io;
 
-      public SerialCallbackContext(Object obj, ObjectStreamClass desc) {
-          this.obj = obj;
-          this.desc = desc;
-          this.thread = Thread.currentThread();
-      }
-
-      public Object getObj() throws NotActiveException {
-          checkAndSetUsed();
-          return obj;
-      }
+/**
+ * Context during upcalls from object stream to class-defined
+ * readObject/writeObject methods.
+ * Holds object currently being deserialized and descriptor for current class.
+ *
+ * This context keeps track of the thread it was constructed on, and allows
+ * only a single call of defaultReadObject, readFields, defaultWriteObject
+ * or writeFields which must be invoked on the same thread before the class's
+ * readObject/writeObject method has returned.
+ * If not set to the current thread, the getObj method throws NotActiveException.
+ */
+final class SerialCallbackContext {
+    private final Object obj;
+    private final ObjectStreamClass desc;
+    /**
+     * Thread this context is in use by.
+     * As this only works in one thread, we do not need to worry about thread-safety.
+     */
+    private Thread thread;
 
-      public ObjectStreamClass getDesc() {
-          return desc;
-      }
+    public SerialCallbackContext(Object obj, ObjectStreamClass desc) {
+        this.obj = obj;
+        this.desc = desc;
+        this.thread = Thread.currentThread();
+    }
+
+    public Object getObj() throws NotActiveException {
+        checkAndSetUsed();
+        return obj;
+    }
 
-      private void checkAndSetUsed() throws NotActiveException {
-          if (thread != Thread.currentThread()) {
-               throw new NotActiveException(
-                "not in readObject invocation or fields already read");
-          }
-          thread = null;
-      }
+    public ObjectStreamClass getDesc() {
+        return desc;
+    }
 
-      public void setUsed() {
-          thread = null;
-      }
-  }
+    private void checkAndSetUsed() throws NotActiveException {
+        if (thread != Thread.currentThread()) {
+             throw new NotActiveException(
+              "not in readObject invocation or fields already read");
+        }
+        thread = null;
+    }
+
+    public void setUsed() {
+        thread = null;
+    }
+}
--- a/jdk/src/share/classes/java/util/HashMap.java	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/src/share/classes/java/util/HashMap.java	Mon Jun 25 21:38:37 2012 -0700
@@ -288,12 +288,11 @@
      * in lower bits.
      */
     final int hash(Object k) {
-        int h = hashSeed;
         if (k instanceof String) {
-            return ((String)k).hash32();
+            return ((String) k).hash32();
         }
 
-        h ^= k.hashCode();
+        int  h = hashSeed ^ k.hashCode();
 
         // This function ensures that hashCodes that differ only by
         // constant multiples at each bit position have a bounded
--- a/jdk/src/share/classes/java/util/Hashtable.java	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/src/share/classes/java/util/Hashtable.java	Mon Jun 25 21:38:37 2012 -0700
@@ -194,19 +194,17 @@
     transient final int hashSeed = sun.misc.Hashing.randomHashSeed(this);
 
     private int hash(Object k) {
-        int h = hashSeed;
-
         if (k instanceof String) {
             return ((String)k).hash32();
-        } else {
-            h ^= k.hashCode();
+        }
+
+        int h = hashSeed ^ k.hashCode();
 
-            // This function ensures that hashCodes that differ only by
-            // constant multiples at each bit position have a bounded
-            // number of collisions (approximately 8 at default load factor).
-            h ^= (h >>> 20) ^ (h >>> 12);
-            return h ^ (h >>> 7) ^ (h >>> 4);
-        }
+        // This function ensures that hashCodes that differ only by
+        // constant multiples at each bit position have a bounded
+        // number of collisions (approximately 8 at default load factor).
+        h ^= (h >>> 20) ^ (h >>> 12);
+        return h ^ (h >>> 7) ^ (h >>> 4);
     }
 
     /**
@@ -1015,7 +1013,7 @@
      */
     private static class Entry<K,V> implements Map.Entry<K,V> {
         final int hash;
-        K key;
+        final K key;
         V value;
         Entry<K,V> next;
 
--- a/jdk/src/share/classes/java/util/ResourceBundle.java	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/src/share/classes/java/util/ResourceBundle.java	Mon Jun 25 21:38:37 2012 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2012, 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
@@ -55,6 +55,7 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.jar.JarEntry;
+import java.util.spi.ResourceBundleControlProvider;
 
 import sun.util.locale.BaseLocale;
 import sun.util.locale.LocaleObjectCache;
@@ -192,6 +193,17 @@
  * {@link #getBundle(String, Locale, ClassLoader, Control) getBundle}
  * factory method for details.
  *
+ * <p><a name="modify_default_behavior">For the {@code getBundle} factory
+ * methods that take no {@link Control} instance, their <a
+ * href="#default_behavior"> default behavior</a> of resource bundle loading
+ * can be modified with <em>installed</em> {@link
+ * ResourceBundleControlProvider} implementations. Any installed providers are
+ * detected at the {@code ResourceBundle} class loading time. If any of the
+ * providers provides a {@link Control} for the given base name, that {@link
+ * Control} will be used instead of the default {@link Control}. If there is
+ * more than one service provider installed for supporting the same base name,
+ * the first one returned from {@link ServiceLoader} will be used.
+ *
  * <h4>Cache Management</h4>
  *
  * Resource bundle instances created by the <code>getBundle</code> factory
@@ -294,8 +306,7 @@
     /**
      * Queue for reference objects referring to class loaders or bundles.
      */
-    private static final ReferenceQueue<Object> referenceQueue =
-        new ReferenceQueue<>();
+    private static final ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
 
     /**
      * The parent bundle of this bundle.
@@ -330,6 +341,21 @@
      */
     private volatile Set<String> keySet;
 
+    private static final List<ResourceBundleControlProvider> providers;
+
+    static {
+        List<ResourceBundleControlProvider> list = null;
+        ServiceLoader<ResourceBundleControlProvider> serviceLoaders
+                = ServiceLoader.loadInstalled(ResourceBundleControlProvider.class);
+        for (ResourceBundleControlProvider provider : serviceLoaders) {
+            if (list == null) {
+                list = new ArrayList<>();
+            }
+            list.add(provider);
+        }
+        providers = list;
+    }
+
     /**
      * Sole constructor.  (For invocation by subclass constructors, typically
      * implicit.)
@@ -725,7 +751,7 @@
         return getBundleImpl(baseName, Locale.getDefault(),
                              /* must determine loader here, else we break stack invariant */
                              getLoader(),
-                             Control.INSTANCE);
+                             getDefaultControl(baseName));
     }
 
     /**
@@ -797,7 +823,7 @@
         return getBundleImpl(baseName, locale,
                              /* must determine loader here, else we break stack invariant */
                              getLoader(),
-                             Control.INSTANCE);
+                             getDefaultControl(baseName));
     }
 
     /**
@@ -849,9 +875,15 @@
      * Gets a resource bundle using the specified base name, locale, and class
      * loader.
      *
-     * <p><a name="default_behavior"/>This method behaves the same as calling
+     * <p>This method behaves the same as calling
      * {@link #getBundle(String, Locale, ClassLoader, Control)} passing a
-     * default instance of {@link Control}. The following describes this behavior.
+     * default instance of {@link Control} unless another {@link Control} is
+     * provided with the {@link ResourceBundleControlProvider} SPI. Refer to the
+     * description of <a href="#modify_default_behavior">modifying the default
+     * behavior</a>.
+     *
+     * <p><a name="default_behavior"/>The following describes the default
+     * behavior.
      *
      * <p><code>getBundle</code> uses the base name, the specified locale, and
      * the default locale (obtained from {@link java.util.Locale#getDefault()
@@ -1026,7 +1058,7 @@
         if (loader == null) {
             throw new NullPointerException();
         }
-        return getBundleImpl(baseName, locale, loader, Control.INSTANCE);
+        return getBundleImpl(baseName, locale, loader, getDefaultControl(baseName));
     }
 
     /**
@@ -1247,6 +1279,18 @@
         return getBundleImpl(baseName, targetLocale, loader, control);
     }
 
+    private static Control getDefaultControl(String baseName) {
+        if (providers != null) {
+            for (ResourceBundleControlProvider provider : providers) {
+                Control control = provider.getControl(baseName);
+                if (control != null) {
+                    return control;
+                }
+            }
+        }
+        return Control.INSTANCE;
+    }
+
     private static ResourceBundle getBundleImpl(String baseName, Locale locale,
                                                 ClassLoader loader, Control control) {
         if (locale == null || control == null) {
--- a/jdk/src/share/classes/java/util/WeakHashMap.java	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/src/share/classes/java/util/WeakHashMap.java	Mon Jun 25 21:38:37 2012 -0700
@@ -295,13 +295,11 @@
      * otherwise encounter collisions for hashCodes that do not differ
      * in lower bits.
      */
-    int hash(Object k) {
-        int h = hashSeed;
+    final int hash(Object k) {
         if (k instanceof String) {
             return ((String) k).hash32();
-        } else {
-            h ^= k.hashCode();
         }
+        int  h = hashSeed ^ k.hashCode();
 
         // This function ensures that hashCodes that differ only by
         // constant multiples at each bit position have a bounded
--- a/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java	Mon Jun 25 21:38:37 2012 -0700
@@ -269,13 +269,11 @@
      * differ in lower or upper bits.
      */
     private int hash(Object k) {
-       int h = hashSeed;
-
         if (k instanceof String) {
             return ((String) k).hash32();
         }
 
-        h ^= k.hashCode();
+        int h = hashSeed ^ k.hashCode();
 
         // Spread bits to regularize both segment and index locations,
         // using variant of single-word Wang/Jenkins hash.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/spi/ResourceBundleControlProvider.java	Mon Jun 25 21:38:37 2012 -0700
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2012, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package java.util.spi;
+
+import java.util.ResourceBundle;
+
+/**
+ * An interface for service providers that provide implementations of {@link
+ * java.util.ResourceBundle.Control}. The <a
+ * href="../ResourceBundle.html#default_behavior">default resource bundle loading
+ * behavior</a> of the {@code ResourceBundle.getBundle} factory methods that take
+ * no {@link java.util.ResourceBundle.Control} instance can be modified with {@code
+ * ResourceBundleControlProvider} implementations.
+ *
+ * <p>Provider implementations must be packaged using the <a
+ * href="../../../../technotes/guides/extensions/index.html">Java Extension
+ * Mechanism</a> as installed extensions. Refer to {@link java.util.ServiceLoader}
+ * for the extension packaging. Any installed {@code
+ * ResourceBundleControlProvider} implementations are loaded using {@link
+ * java.util.ServiceLoader} at the {@code ResourceBundle} class loading time.
+ *
+ * @author Masayoshi Okutsu
+ * @since 1.8
+ * @see ResourceBundle#getBundle(String, java.util.Locale, ClassLoader, ResourceBundle.Control)
+ *      ResourceBundle.getBundle
+ * @see java.util.ServiceLoader#loadInstalled(Class)
+ */
+public interface ResourceBundleControlProvider {
+    /**
+     * Returns a {@code ResourceBundle.Control} instance that is used
+     * to handle resource bundle loading for the given {@code
+     * baseName}. This method must return {@code null} if the given
+     * {@code baseName} isn't handled by this provider.
+     *
+     * @param baseName the base name of the resource bundle
+     * @return a {@code ResourceBundle.Control} instance,
+     *         or {@code null} if the given {@code baseName} is not
+     *         applicable to this provider.
+     * @throws NullPointerException if {@code baseName} is {@code null}
+     */
+    public ResourceBundle.Control getControl(String baseName);
+}
--- a/jdk/src/share/classes/sun/misc/JarIndex.java	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/src/share/classes/sun/misc/JarIndex.java	Mon Jun 25 21:38:37 2012 -0700
@@ -201,23 +201,20 @@
             packageName = fileName;
         }
 
-        // add the mapping to indexMap
-        addToList(packageName, jarName, indexMap);
-
-        // add the mapping to jarMap
-        addToList(jarName, packageName, jarMap);
+        addMapping(packageName, jarName);
     }
 
     /**
      * Same as add(String,String) except that it doesn't strip off from the
-     * last index of '/'. It just adds the filename.
+     * last index of '/'. It just adds the jarItem (filename or package)
+     * as it is received.
      */
-    private void addExplicit(String fileName, String jarName) {
+    private void addMapping(String jarItem, String jarName) {
         // add the mapping to indexMap
-        addToList(fileName, jarName, indexMap);
+        addToList(jarItem, jarName, indexMap);
 
         // add the mapping to jarMap
-        addToList(jarName, fileName, jarMap);
+        addToList(jarName, jarItem, jarMap);
      }
 
     /**
@@ -248,18 +245,14 @@
                     fileName.equals(JarFile.MANIFEST_NAME))
                     continue;
 
-                if (!metaInfFilenames) {
+                if (!metaInfFilenames || !fileName.startsWith("META-INF/")) {
                     add(fileName, currentJar);
-                } else {
-                    if (!fileName.startsWith("META-INF/")) {
-                        add(fileName, currentJar);
-                    } else if (!entry.isDirectory()) {
+                } else if (!entry.isDirectory()) {
                         // Add files under META-INF explicitly so that certain
                         // services, like ServiceLoader, etc, can be located
                         // with greater accuracy. Directories can be skipped
                         // since each file will be added explicitly.
-                        addExplicit(fileName, currentJar);
-                    }
+                        addMapping(fileName, currentJar);
                 }
             }
 
@@ -324,8 +317,7 @@
                 jars.add(currentJar);
             } else {
                 String name = line;
-                addToList(name, currentJar, indexMap);
-                addToList(currentJar, name, jarMap);
+                addMapping(name, currentJar);
             }
         }
 
@@ -354,7 +346,7 @@
                 if (path != null) {
                     jarName = path.concat(jarName);
                 }
-                toIndex.add(packageName, jarName);
+                toIndex.addMapping(packageName, jarName);
             }
         }
     }
--- a/jdk/src/share/classes/sun/nio/ch/IOUtil.java	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/IOUtil.java	Mon Jun 25 21:38:37 2012 -0700
@@ -36,6 +36,11 @@
 
 public class IOUtil {
 
+    /**
+     * Max number of iovec structures that readv/writev supports
+     */
+    static final int IOV_MAX;
+
     private IOUtil() { }                // No instantiation
 
     static int write(FileDescriptor fd, ByteBuffer src, long position,
@@ -111,7 +116,8 @@
 
             // Iterate over buffers to populate native iovec array.
             int count = offset + length;
-            for (int i=offset; i<count; i++) {
+            int i = offset;
+            while (i < count && iov_len < IOV_MAX) {
                 ByteBuffer buf = bufs[i];
                 int pos = buf.position();
                 int lim = buf.limit();
@@ -135,6 +141,7 @@
                     vec.putLen(iov_len, rem);
                     iov_len++;
                 }
+                i++;
             }
             if (iov_len == 0)
                 return 0L;
@@ -240,7 +247,8 @@
 
             // Iterate over buffers to populate native iovec array.
             int count = offset + length;
-            for (int i=offset; i<count; i++) {
+            int i = offset;
+            while (i < count && iov_len < IOV_MAX) {
                 ByteBuffer buf = bufs[i];
                 if (buf.isReadOnly())
                     throw new IllegalArgumentException("Read-only buffer");
@@ -264,6 +272,7 @@
                     vec.putLen(iov_len, rem);
                     iov_len++;
                 }
+                i++;
             }
             if (iov_len == 0)
                 return 0L;
@@ -336,11 +345,14 @@
 
     static native int fdLimit();
 
+    static native int iovMax();
+
     static native void initIDs();
 
     static {
         // Note that IOUtil.initIDs is called from within Util.load.
         Util.load();
+        IOV_MAX = iovMax();
     }
 
 }
--- a/jdk/src/share/classes/sun/nio/ch/Util.java	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/Util.java	Mon Jun 25 21:38:37 2012 -0700
@@ -45,7 +45,7 @@
     // -- Caches --
 
     // The number of temp buffers in our pool
-    private static final int TEMP_BUF_POOL_SIZE = 8;
+    private static final int TEMP_BUF_POOL_SIZE = IOUtil.IOV_MAX;
 
     // Per-thread cache of temporary direct buffers
     private static ThreadLocal<BufferCache> bufferCache =
--- a/jdk/src/share/classes/sun/security/provider/certpath/BasicChecker.java	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/src/share/classes/sun/security/provider/certpath/BasicChecker.java	Mon Jun 25 21:38:37 2012 -0700
@@ -90,6 +90,7 @@
         this.date = date;
         this.sigProvider = sigProvider;
         this.sigOnly = sigOnly;
+        this.prevPubKey = trustedPubKey;
     }
 
     /**
--- a/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java	Mon Jun 25 21:38:37 2012 -0700
@@ -1119,6 +1119,7 @@
                  * handle a few more records, so the sequence number
                  * of the last record cannot be wrapped.
                  */
+                hsStatus = getHSStatus(hsStatus);
                 if (connectionState < cs_ERROR && !isInboundDone() &&
                         (hsStatus == HandshakeStatus.NOT_HANDSHAKING)) {
                     if (checkSequenceNumber(readMAC,
@@ -1287,6 +1288,7 @@
          * handle a few more records, so the sequence number
          * of the last record cannot be wrapped.
          */
+        hsStatus = getHSStatus(hsStatus);
         if (connectionState < cs_ERROR && !isOutboundDone() &&
                 (hsStatus == HandshakeStatus.NOT_HANDSHAKING)) {
             if (checkSequenceNumber(writeMAC, eor.contentType())) {
--- a/jdk/src/share/demo/jvmti/hprof/hprof_table.c	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/src/share/demo/jvmti/hprof/hprof_table.c	Mon Jun 25 21:38:37 2012 -0700
@@ -120,7 +120,7 @@
     TableIndex     table_incr;          /* Suggested increment size. */
     TableIndex     hash_bucket_count;   /* Number of hash buckets. */
     int            elem_size;           /* Size of element. */
-    int            info_size;           /* Size of info structure. */
+    int            info_size;           /* Size of info structure (can be 0). */
     void          *freed_bv;            /* Freed element bit vector */
     int            freed_count;         /* Count of freed'd elements */
     TableIndex     freed_start;         /* First freed in table */
@@ -208,9 +208,6 @@
 {
     TableElement *element;
 
-    if ( ltable->info_size == 0 ) {
-        return NULL;
-    }
     element = (TableElement*)ELEMENT_PTR(ltable,index);
     return element->info;
 }
@@ -760,7 +757,11 @@
                 void *info;
 
                 get_key(ltable, index, &key_ptr, &key_len);
-                info = get_info(ltable, index);
+                if ( ltable->info_size == 0 ) {
+                    info = NULL;
+                } else {
+                    info = get_info(ltable, index);
+                }
                 (*func)(SANITY_ADD_HARE(index, ltable->hare), key_ptr, key_len, info, arg);
                 if ( is_freed_entry(ltable, index) ) {
                     fcount++;
--- a/jdk/src/solaris/demo/jvmti/hprof/hprof_md.c	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/src/solaris/demo/jvmti/hprof/hprof_md.c	Mon Jun 25 21:38:37 2012 -0700
@@ -119,9 +119,13 @@
 
     /* create a socket */
     fd = socket(AF_INET, SOCK_STREAM, 0);
+    if ( fd < 0 ) {
+        return -1;
+    }
 
     /* find remote host's addr from name */
     if ((hentry = gethostbyname(hostname)) == NULL) {
+        (void)close(fd);
         return -1;
     }
     (void)memset((char *)&s, 0, sizeof(s));
@@ -134,6 +138,7 @@
 
     /* now try connecting */
     if (-1 == connect(fd, (struct sockaddr*)&s, sizeof(s))) {
+        (void)close(fd);
         return 0;
     }
     return fd;
--- a/jdk/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c	Mon Jun 25 21:38:37 2012 -0700
@@ -94,9 +94,6 @@
 {
     jint fd = fdval(env, fdo);
     struct iovec *iov = (struct iovec *)jlong_to_ptr(address);
-    if (len > 16) {
-        len = 16;
-    }
     return convertLongReturnVal(env, readv(fd, iov, len), JNI_TRUE);
 }
 
@@ -126,9 +123,6 @@
 {
     jint fd = fdval(env, fdo);
     struct iovec *iov = (struct iovec *)jlong_to_ptr(address);
-    if (len > 16) {
-        len = 16;
-    }
     return convertLongReturnVal(env, writev(fd, iov, len), JNI_FALSE);
 }
 
--- a/jdk/src/solaris/native/sun/nio/ch/IOUtil.c	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/src/solaris/native/sun/nio/ch/IOUtil.c	Mon Jun 25 21:38:37 2012 -0700
@@ -136,6 +136,16 @@
     }
 }
 
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_IOUtil_iovMax(JNIEnv *env, jclass this)
+{
+    jlong iov_max = sysconf(_SC_IOV_MAX);
+    if (iov_max == -1)
+        iov_max = 16;
+    return (jint)iov_max;
+}
+
+
 /* Declared in nio_util.h for use elsewhere in NIO */
 
 jint
--- a/jdk/src/windows/native/sun/net/www/protocol/http/ntlm/NTLMAuthSequence.c	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/src/windows/native/sun/net/www/protocol/http/ntlm/NTLMAuthSequence.c	Mon Jun 25 21:38:37 2012 -0700
@@ -151,7 +151,7 @@
 
     VOID        *pInput = 0;
     DWORD            inputLen;
-    CHAR         buffOut[512];
+    CHAR         buffOut[1024];
     jboolean         isCopy;
     SECURITY_STATUS      ss;
     SecBufferDesc        OutBuffDesc;
@@ -178,7 +178,7 @@
     OutBuffDesc.cBuffers  = 1;
     OutBuffDesc.pBuffers  = &OutSecBuff;
 
-    OutSecBuff.cbBuffer   = 512;
+    OutSecBuff.cbBuffer   = 1024;
     OutSecBuff.BufferType = SECBUFFER_TOKEN;
     OutSecBuff.pvBuffer   = buffOut;
 
--- a/jdk/src/windows/native/sun/nio/ch/IOUtil.c	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/src/windows/native/sun/nio/ch/IOUtil.c	Mon Jun 25 21:38:37 2012 -0700
@@ -41,9 +41,6 @@
 /* field id for jint 'fd' in java.io.FileDescriptor used for socket fds */
 static jfieldID fd_fdID;
 
-/* false for 95/98/ME, true for NT/W2K */
-static jboolean onNT = JNI_FALSE;
-
 JNIEXPORT jboolean JNICALL
 Java_sun_security_provider_NativeSeedGenerator_nativeGenerateSeed
 (JNIEnv *env, jclass clazz, jbyteArray randArray);
@@ -55,13 +52,6 @@
 JNIEXPORT void JNICALL
 Java_sun_nio_ch_IOUtil_initIDs(JNIEnv *env, jclass clazz)
 {
-    OSVERSIONINFO ver;
-    ver.dwOSVersionInfoSize = sizeof(ver);
-    GetVersionEx(&ver);
-    if (ver.dwPlatformId == VER_PLATFORM_WIN32_NT) {
-        onNT = JNI_TRUE;
-    }
-
     clazz = (*env)->FindClass(env, "java/io/FileDescriptor");
     fd_fdID = (*env)->GetFieldID(env, clazz, "fd", "I");
     handle_fdID = (*env)->GetFieldID(env, clazz, "handle", "J");
@@ -80,6 +70,13 @@
                                                                     randArray);
 }
 
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_IOUtil_iovMax(JNIEnv *env, jclass this)
+{
+    return 16;
+}
+
+
 jint
 convertReturnVal(JNIEnv *env, jint n, jboolean reading)
 {
@@ -205,9 +202,3 @@
 {
     return (*env)->GetLongField(env, fdo, handle_fdID);
 }
-
-jboolean
-isNT()
-{
-    return onNT;
-}
--- a/jdk/src/windows/native/sun/nio/ch/SocketDispatcher.c	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/src/windows/native/sun/nio/ch/SocketDispatcher.c	Mon Jun 25 21:38:37 2012 -0700
@@ -97,10 +97,6 @@
         return IOS_THROWN;
     }
 
-    if ((isNT() == JNI_FALSE) && (len > 16)) {
-        len = 16;
-    }
-
     /* copy iovec into WSABUF */
     for(i=0; i<len; i++) {
         jint iov_len = iovp[i].iov_len;
@@ -141,41 +137,54 @@
 
 JNIEXPORT jint JNICALL
 Java_sun_nio_ch_SocketDispatcher_write0(JNIEnv *env, jclass clazz, jobject fdo,
-                                       jlong address, jint len)
+                                       jlong address, jint total)
 {
     /* set up */
     int i = 0;
     DWORD written = 0;
+    jint count = 0;
     jint fd = fdval(env, fdo);
     WSABUF buf;
 
-    /* limit size */
-    if (len > MAX_BUFFER_SIZE)
-        len = MAX_BUFFER_SIZE;
+    do {
+        /* limit size */
+        jint len = total - count;
+        if (len > MAX_BUFFER_SIZE)
+            len = MAX_BUFFER_SIZE;
 
-    /* copy iovec into WSABUF */
-    buf.buf = (char *)address;
-    buf.len = (u_long)len;
+        /* copy iovec into WSABUF */
+        buf.buf = (char *)address;
+        buf.len = (u_long)len;
+
+        /* write from the buffer */
+        i = WSASend((SOCKET)fd,     /* Socket */
+                    &buf,           /* pointers to the buffers */
+                    (DWORD)1,       /* number of buffers to process */
+                    &written,       /* receives number of bytes written */
+                    0,              /* no flags */
+                    0,              /* no overlapped sockets */
+                    0);             /* no completion routine */
 
-    /* read into the buffers */
-    i = WSASend((SOCKET)fd, /* Socket */
-            &buf,           /* pointers to the buffers */
-            (DWORD)1,       /* number of buffers to process */
-            &written,       /* receives number of bytes written */
-            0,              /* no flags */
-            0,              /* no overlapped sockets */
-            0);             /* no completion routine */
+        if (i == SOCKET_ERROR) {
+            if (count > 0) {
+                /* can't throw exception when some bytes have been written */
+                break;
+            } else {
+               int theErr = (jint)WSAGetLastError();
+               if (theErr == WSAEWOULDBLOCK) {
+                   return IOS_UNAVAILABLE;
+               }
+               JNU_ThrowIOExceptionWithLastError(env, "Write failed");
+               return IOS_THROWN;
+            }
+        }
 
-    if (i == SOCKET_ERROR) {
-        int theErr = (jint)WSAGetLastError();
-        if (theErr == WSAEWOULDBLOCK) {
-            return IOS_UNAVAILABLE;
-        }
-        JNU_ThrowIOExceptionWithLastError(env, "Write failed");
-        return IOS_THROWN;
-    }
+        count += written;
+        address += written;
 
-    return convertReturnVal(env, (jint)written, JNI_FALSE);
+    } while ((count < total) && (written == MAX_BUFFER_SIZE));
+
+    return count;
 }
 
 JNIEXPORT jlong JNICALL
@@ -195,10 +204,6 @@
         return IOS_THROWN;
     }
 
-    if ((isNT() == JNI_FALSE) && (len > 16)) {
-        len = 16;
-    }
-
     /* copy iovec into WSABUF */
     for(i=0; i<len; i++) {
         jint iov_len = iovp[i].iov_len;
--- a/jdk/src/windows/native/sun/nio/ch/nio_util.h	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/src/windows/native/sun/nio/ch/nio_util.h	Mon Jun 25 21:38:37 2012 -0700
@@ -35,7 +35,6 @@
 
 jint fdval(JNIEnv *env, jobject fdo);
 jlong handleval(JNIEnv *env, jobject fdo);
-jboolean isNT();
 jint convertReturnVal(JNIEnv *env, jint n, jboolean r);
 jlong convertLongReturnVal(JNIEnv *env, jlong n, jboolean r);
 jboolean purgeOutstandingICMP(JNIEnv *env, jclass clazz, jint fd);
--- a/jdk/test/ProblemList.txt	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/test/ProblemList.txt	Mon Jun 25 21:38:37 2012 -0700
@@ -287,6 +287,9 @@
 
 # jdk_security
 
+# 7177556
+com/sun/crypto/provider/KeyFactory/TestProviderLeak.java        generic-all
+
 # 7147060
 com/sun/org/apache/xml/internal/security/transforms/ClassLoaderTest.java	generic-all
 
--- a/jdk/test/java/nio/channels/AsyncCloseAndInterrupt.java	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/test/java/nio/channels/AsyncCloseAndInterrupt.java	Mon Jun 25 21:38:37 2012 -0700
@@ -644,9 +644,9 @@
         initPipes();
         initFile();
 
-        if (TestUtil.onME()) {
+        if (TestUtil.onWindows()) {
             log.println("WARNING: Cannot test FileChannel transfer operations"
-                        + " on Windows 95/98/ME");
+                        + " on Windows");
         } else {
             test(diskFileChannelFactory, TRANSFER_TO);
             test(diskFileChannelFactory, TRANSFER_FROM);
--- a/jdk/test/java/nio/channels/SocketChannel/AdaptSocket.java	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/test/java/nio/channels/SocketChannel/AdaptSocket.java	Mon Jun 25 21:38:37 2012 -0700
@@ -28,9 +28,7 @@
 
 import java.io.*;
 import java.net.*;
-import java.nio.*;
 import java.nio.channels.*;
-import java.nio.charset.*;
 
 
 public class AdaptSocket {
@@ -136,9 +134,8 @@
         out.println("timeout: " + so.getSoTimeout());
 
         testRead(so, shouldTimeout);
-        if (!TestUtil.onME())
-            for (int i = 0; i < 4; i++)
-                testRead(so, shouldTimeout);
+        for (int i = 0; i < 4; i++)
+            testRead(so, shouldTimeout);
 
         sc.close();
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/channels/SocketChannel/CloseDuringWrite.java	Mon Jun 25 21:38:37 2012 -0700
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2012, 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
+ * @summary Test asynchronous close during a blocking write
+ */
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.*;
+import java.net.*;
+import java.util.concurrent.*;
+import java.util.Random;
+
+public class CloseDuringWrite {
+
+    static final Random rand = new Random();
+
+    /**
+     * A task that closes a Closeable
+     */
+    static class Closer implements Callable<Void> {
+        final Closeable c;
+        Closer(Closeable c) {
+            this.c = c;
+        }
+        public Void call() throws IOException {
+            c.close();
+            return null;
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        ScheduledExecutorService pool = Executors.newSingleThreadScheduledExecutor();
+        try {
+            try (ServerSocketChannel ssc = ServerSocketChannel.open()) {
+                ssc.bind(new InetSocketAddress(0));
+                InetAddress lh = InetAddress.getLocalHost();
+                int port = ssc.socket().getLocalPort();
+                SocketAddress sa = new InetSocketAddress(lh, port);
+
+                ByteBuffer bb = ByteBuffer.allocate(2*1024*1024);
+
+                for (int i=0; i<20; i++) {
+                    try (SocketChannel source = SocketChannel.open(sa);
+                         SocketChannel sink = ssc.accept())
+                    {
+                        // schedule channel to be closed
+                        Closer c = new Closer(source);
+                        int when = 1000 + rand.nextInt(2000);
+                        Future<Void> result = pool.schedule(c, when, TimeUnit.MILLISECONDS);
+
+                        // the write should either succeed or else throw a
+                        // ClosedChannelException (more likely an
+                        // AsynchronousCloseException)
+                        try {
+                            for (;;) {
+                                int limit = rand.nextInt(bb.capacity());
+                                bb.position(0);
+                                bb.limit(limit);
+                                int n = source.write(bb);
+                                System.out.format("wrote %d, expected %d%n", n, limit);
+                            }
+                        } catch (ClosedChannelException expected) {
+                            System.out.println(expected + " (expected)");
+                        } finally {
+                            result.get();
+                        }
+                    }
+                }
+            }
+        } finally {
+            pool.shutdown();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/channels/SocketChannel/ShortWrite.java	Mon Jun 25 21:38:37 2012 -0700
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2012, 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 7176630
+ * @summary Check for short writes on SocketChannels configured in blocking mode
+ */
+
+import java.net.*;
+import java.nio.ByteBuffer;
+import java.nio.channels.*;
+import java.util.concurrent.*;
+import java.util.Random;
+import java.util.zip.CRC32;
+
+public class ShortWrite {
+
+    static final Random rand = new Random();
+
+    /**
+     * Returns a checksum on the remaining bytes in the given buffer.
+     */
+    static long computeChecksum(ByteBuffer bb) {
+        CRC32 crc32 = new CRC32();
+        crc32.update(bb);
+        return crc32.getValue();
+    }
+
+    /**
+     * A task that reads the expected number of bytes and returns the CRC32
+     * of those bytes.
+     */
+    static class Reader implements Callable<Long> {
+        final SocketChannel sc;
+        final ByteBuffer buf;
+
+        Reader(SocketChannel sc, int expectedSize) {
+            this.sc = sc;
+            this.buf = ByteBuffer.allocate(expectedSize);
+        }
+
+        public Long call() throws Exception {
+            while (buf.hasRemaining()) {
+                int n = sc.read(buf);
+                if (n == -1)
+                    throw new RuntimeException("Premature EOF encountered");
+            }
+            buf.flip();
+            return computeChecksum(buf);
+        }
+    }
+
+    /**
+     * Run test with a write of the given number of bytes.
+     */
+    static void test(ExecutorService pool,
+                     SocketChannel source,
+                     SocketChannel sink,
+                     int size)
+        throws Exception
+    {
+        System.out.println(size);
+
+        // random bytes in the buffer
+        ByteBuffer buf = ByteBuffer.allocate(size);
+        rand.nextBytes(buf.array());
+
+        // submit task to read the bytes
+        Future<Long> result = pool.submit(new Reader(sink, size));
+
+        // write the bytes
+        int n = source.write(buf);
+        if (n != size)
+            throw new RuntimeException("Short write detected");
+
+        // check the bytes that were received match
+        buf.rewind();
+        long expected = computeChecksum(buf);
+        long actual = result.get();
+        if (actual != expected)
+            throw new RuntimeException("Checksum did not match");
+    }
+
+
+    public static void main(String[] args) throws Exception {
+        ExecutorService pool = Executors.newSingleThreadExecutor();
+        try {
+            try (ServerSocketChannel ssc = ServerSocketChannel.open()) {
+                ssc.bind(new InetSocketAddress(0));
+                InetAddress lh = InetAddress.getLocalHost();
+                int port = ssc.socket().getLocalPort();
+                SocketAddress sa = new InetSocketAddress(lh, port);
+
+                try (SocketChannel source = SocketChannel.open(sa);
+                     SocketChannel sink = ssc.accept())
+                {
+                    // run tests on sizes around 128k as that is the problem
+                    // area on Windows.
+                    int BOUNDARY = 128 * 1024;
+                    for (int size=(BOUNDARY-2); size<=(BOUNDARY+2); size++) {
+                        test(pool, source, sink, size);
+                    }
+
+                    // run tests on random sizes
+                    for (int i=0; i<20; i++) {
+                        int size = rand.nextInt(1024*1024);
+                        test(pool, source, sink, size);
+                    }
+                }
+            }
+
+        } finally {
+            pool.shutdown();
+        }
+    }
+}
--- a/jdk/test/java/nio/channels/TestUtil.java	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/test/java/nio/channels/TestUtil.java	Mon Jun 25 21:38:37 2012 -0700
@@ -81,20 +81,6 @@
 
     private static String osName = System.getProperty("os.name");
 
-    // Examines os.name property to determine if running on 95/98/ME.
-    //
-    // Returns true if running on windows95/98/ME.
-    //
-    static boolean onME() {
-        if (osName.startsWith("Windows")) {
-            if (osName.indexOf("9") > 0)
-                return true;
-            if (osName.indexOf("M") > 0)
-                return true;
-        }
-        return false;
-    }
-
     static boolean onSolaris() {
         return osName.startsWith("SunOS");
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/cert/CertPathBuilder/zeroLengthPath/ZeroLengthPath.java	Mon Jun 25 21:38:37 2012 -0700
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2012, 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 4442566 7176326
+ * @summary check that we can build and validate a zero-length
+ *    certpath when a trust anchor cert satisfies the target constraints
+ */
+import java.io.ByteArrayInputStream;
+import java.security.cert.*;
+import java.util.Collections;
+
+public class ZeroLengthPath {
+
+    private static final String ANCHOR =
+        "-----BEGIN CERTIFICATE-----\n" +
+        "MIIBFzCBwgIBATANBgkqhkiG9w0BAQQFADAXMRUwEwYDVQQDEwxUcnVzdCBBbmNo\n" +
+        "b3IwHhcNMDIxMTA3MTE1NzAzWhcNMjIxMTA3MTE1NzAzWjAXMRUwEwYDVQQDEwxU\n" +
+        "cnVzdCBBbmNob3IwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA9uCj12hwDgC1n9go\n" +
+        "0ozQAVMM+DfX0vpKOemyGNp+ycSLfAq3pxBcUKbQhjSRL7YjPkEL8XC6pRLwyEoF\n" +
+        "osWweQIDAQABMA0GCSqGSIb3DQEBBAUAA0EAzZta5M1qbbozj7jWnNyTgB4HUpzv\n" +
+        "4eP0VYQb1pQY1/xEMczaRt+RuoIDnHCq5a1vOiwk6ZbdG6GlJKx9lj0oMQ==\n" +
+        "-----END CERTIFICATE-----";
+
+
+    public static void main(String[] args) throws Exception {
+
+        ByteArrayInputStream is = new ByteArrayInputStream(ANCHOR.getBytes());
+        CertificateFactory cf = CertificateFactory.getInstance("X.509");
+        X509Certificate cert = (X509Certificate)cf.generateCertificate(is);
+
+        X509CertSelector xcs = new X509CertSelector();
+        xcs.setSubject(cert.getSubjectX500Principal().getName());
+        PKIXBuilderParameters p = new PKIXBuilderParameters
+            (Collections.singleton(new TrustAnchor(cert, null)), xcs);
+        CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX");
+        CertPath cp = buildCertPath(cpb, p);
+        validateCertPath(cp, p);
+    }
+
+    private static CertPath buildCertPath(CertPathBuilder cpb,
+                                          PKIXBuilderParameters params)
+        throws Exception
+    {
+        CertPathBuilderResult res = cpb.build(params);
+        if (res.getCertPath().getCertificates().size() != 0) {
+            throw new Exception("built path is not zero-length");
+        }
+        return res.getCertPath();
+    }
+
+    private static void validateCertPath(CertPath cp, PKIXParameters params)
+        throws Exception
+    {
+        CertPathValidator cpv = CertPathValidator.getInstance("PKIX");
+        CertPathValidatorResult cpvr = cpv.validate(cp, params);
+    }
+}
--- a/jdk/test/java/util/Map/Collisions.java	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/test/java/util/Map/Collisions.java	Mon Jun 25 21:38:37 2012 -0700
@@ -68,7 +68,7 @@
             return Integer.toString(value);
         }
     }
-    private static final int ITEMS = 10000;
+    private static final int ITEMS = 5000;
     private static final Object KEYS[][];
 
     static {
@@ -133,8 +133,8 @@
 
     private static void realMain(String[] args) throws Throwable {
         for (Object[] keys_desc : KEYS) {
-            Map<Object, Boolean>[] MAPS = (Map<Object, Boolean>[]) new Map[]{
-//                        new Hashtable<>(),
+            Map<Object, Object>[] MAPS = (Map<Object, Object>[]) new Map[]{
+                        new Hashtable<>(),
                         new HashMap<>(),
                         new IdentityHashMap<>(),
                         new LinkedHashMap<>(),
@@ -144,51 +144,69 @@
                         new ConcurrentSkipListMap<>()
                     };
 
-            for (Map<Object, Boolean> map : MAPS) {
+            for (Map<Object, Object> map : MAPS) {
                 String desc = (String) keys_desc[0];
                 Object[] keys = (Object[]) keys_desc[1];
+                try {
                 testMap(map, desc, keys);
+                } catch(Exception all) {
+                    unexpected("Failed for " + map.getClass().getName() + " with " + desc, all);
+                }
             }
         }
     }
 
-    private static <T> void testMap(Map<T, Boolean> map, String keys_desc, T[] keys) {
-        System.err.println(map.getClass() + " : " + keys_desc);
+    private static <T> void testMap(Map<T, T> map, String keys_desc, T[] keys) {
+        System.out.println(map.getClass() + " : " + keys_desc);
+        System.out.flush();
         testInsertion(map, keys_desc, keys);
 
         if (keys[0] instanceof HashableInteger) {
-            testIntegerIteration((Map<HashableInteger, Boolean>) map, (HashableInteger[]) keys);
+            testIntegerIteration((Map<HashableInteger, HashableInteger>) map, (HashableInteger[]) keys);
         } else {
-            testStringIteration((Map<String, Boolean>) map, (String[]) keys);
+            testStringIteration((Map<String, String>) map, (String[]) keys);
         }
 
         testContainsKey(map, keys_desc, keys);
 
         testRemove(map, keys_desc, keys);
 
+        map.clear();
+        testInsertion(map, keys_desc, keys);
+        testKeysIteratorRemove(map, keys_desc, keys);
+
+        map.clear();
+        testInsertion(map, keys_desc, keys);
+        testValuesIteratorRemove(map, keys_desc, keys);
+
+        map.clear();
+        testInsertion(map, keys_desc, keys);
+        testEntriesIteratorRemove(map, keys_desc, keys);
+
         check(map.isEmpty());
     }
 
-    private static <T> void testInsertion(Map<T, Boolean> map, String keys_desc, T[] keys) {
+    private static <T> void testInsertion(Map<T, T> map, String keys_desc, T[] keys) {
         check("map empty", (map.size() == 0) && map.isEmpty());
 
         for (int i = 0; i < keys.length; i++) {
             check(String.format("insertion: map expected size m%d != i%d", map.size(), i),
                     map.size() == i);
-            check(String.format("insertion: put(%s[%d])", keys_desc, i), null == map.put(keys[i], true));
+            check(String.format("insertion: put(%s[%d])", keys_desc, i), null == map.put(keys[i], keys[i]));
             check(String.format("insertion: containsKey(%s[%d])", keys_desc, i), map.containsKey(keys[i]));
+            check(String.format("insertion: containsValue(%s[%d])", keys_desc, i), map.containsValue(keys[i]));
         }
 
         check(String.format("map expected size m%d != k%d", map.size(), keys.length),
                 map.size() == keys.length);
     }
 
-    private static void testIntegerIteration(Map<HashableInteger, Boolean> map, HashableInteger[] keys) {
+    private static void testIntegerIteration(Map<HashableInteger, HashableInteger> map, HashableInteger[] keys) {
         check(String.format("map expected size m%d != k%d", map.size(), keys.length),
                 map.size() == keys.length);
 
         BitSet all = new BitSet(keys.length);
-        for (Map.Entry<HashableInteger, Boolean> each : map.entrySet()) {
+        for (Map.Entry<HashableInteger, HashableInteger> each : map.entrySet()) {
             check("Iteration: key already seen", !all.get(each.getKey().value));
             all.set(each.getKey().value);
         }
@@ -205,7 +223,7 @@
         check("Iteration: some keys not visited", all.isEmpty());
 
         int count = 0;
-        for (Boolean each : map.values()) {
+        for (HashableInteger each : map.values()) {
             count++;
         }
 
@@ -213,12 +231,12 @@
                 map.size() == count);
     }
 
-    private static void testStringIteration(Map<String, Boolean> map, String[] keys) {
+    private static void testStringIteration(Map<String, String> map, String[] keys) {
         check(String.format("map expected size m%d != k%d", map.size(), keys.length),
                 map.size() == keys.length);
 
         BitSet all = new BitSet(keys.length);
-        for (Map.Entry<String, Boolean> each : map.entrySet()) {
+        for (Map.Entry<String, String> each : map.entrySet()) {
             String key = each.getKey();
             boolean longKey = key.length() > 5;
             int index = key.hashCode() + (longKey ? keys.length / 2 : 0);
@@ -240,7 +258,7 @@
         check("some keys not visited", all.isEmpty());
 
         int count = 0;
-        for (Boolean each : map.values()) {
+        for (String each : map.values()) {
             count++;
         }
 
@@ -248,14 +266,14 @@
                 map.size() == keys.length);
     }
 
-    private static <T> void testContainsKey(Map<T, Boolean> map, String keys_desc, T[] keys) {
+    private static <T> void testContainsKey(Map<T, T> map, String keys_desc, T[] keys) {
         for (int i = 0; i < keys.length; i++) {
             T each = keys[i];
             check("containsKey: " + keys_desc + "[" + i + "]" + each, map.containsKey(each));
         }
     }
 
-    private static <T> void testRemove(Map<T, Boolean> map, String keys_desc, T[] keys) {
+    private static <T> void testRemove(Map<T, T> map, String keys_desc, T[] keys) {
         check(String.format("remove: map expected size m%d != k%d", map.size(), keys.length),
                 map.size() == keys.length);
 
@@ -267,6 +285,56 @@
         check(String.format("remove: map empty. size=%d", map.size()),
                 (map.size() == 0) && map.isEmpty());
     }
+
+    private static <T> void testKeysIteratorRemove(Map<T, T> map, String keys_desc, T[] keys) {
+        check(String.format("remove: map expected size m%d != k%d", map.size(), keys.length),
+                map.size() == keys.length);
+
+        Iterator<T> each = map.keySet().iterator();
+        while (each.hasNext()) {
+            T t = each.next();
+            each.remove();
+            check("not removed: " + each, !map.containsKey(t) );
+        }
+
+        check(String.format("remove: map empty. size=%d", map.size()),
+                (map.size() == 0) && map.isEmpty());
+    }
+
+    private static <T> void testValuesIteratorRemove(Map<T, T> map, String keys_desc, T[] keys) {
+        check(String.format("remove: map expected size m%d != k%d", map.size(), keys.length),
+                map.size() == keys.length);
+
+        Iterator<T> each = map.values().iterator();
+        while (each.hasNext()) {
+            T t = each.next();
+            each.remove();
+            check("not removed: " + each, !map.containsValue(t) );
+        }
+
+        check(String.format("remove: map empty. size=%d", map.size()),
+                (map.size() == 0) && map.isEmpty());
+    }
+
+    private static <T> void testEntriesIteratorRemove(Map<T, T> map, String keys_desc, T[] keys) {
+        check(String.format("remove: map expected size m%d != k%d", map.size(), keys.length),
+                map.size() == keys.length);
+
+        Iterator<Map.Entry<T,T>> each = map.entrySet().iterator();
+        while (each.hasNext()) {
+            Map.Entry<T,T> t = each.next();
+            T key = t.getKey();
+            T value = t.getValue();
+            each.remove();
+            check("not removed: " + each, (map instanceof IdentityHashMap) || !map.entrySet().contains(t) );
+            check("not removed: " + each, !map.containsKey(key) );
+            check("not removed: " + each, !map.containsValue(value));
+        }
+
+        check(String.format("remove: map empty. size=%d", map.size()),
+                (map.size() == 0) && map.isEmpty());
+    }
+
     //--------------------- Infrastructure ---------------------------
     static volatile int passed = 0, failed = 0;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/spi/ResourceBundleControlProvider/UserDefaultControlTest.java	Mon Jun 25 21:38:37 2012 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2012, 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 6959653
+ * @summary Test ResourceBundle.Control provided using SPI.
+ * @build UserDefaultControlTest
+ * @run shell UserDefaultControlTest.sh
+ */
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+public class UserDefaultControlTest {
+    public static void main(String[] args) {
+        ResourceBundle rb = ResourceBundle.getBundle("com.foo.XmlRB", Locale.ROOT);
+        String type = rb.getString("type");
+        if (!type.equals("XML")) {
+            throw new RuntimeException("Root Locale: type: got " + type
+                                       + ", expected XML (ASCII)");
+        }
+
+        rb = ResourceBundle.getBundle("com.foo.XmlRB", Locale.JAPAN);
+        type = rb.getString("type");
+        // Expect fullwidth "XML"
+        if (!type.equals("\uff38\uff2d\uff2c")) {
+            throw new RuntimeException("Locale.JAPAN: type: got " + type
+                                       + ", expected \uff38\uff2d\uff2c (fullwidth XML)");
+        }
+
+        try {
+            rb = ResourceBundle.getBundle("com.bar.XmlRB", Locale.JAPAN);
+            throw new RuntimeException("com.bar.XmlRB test failed.");
+        } catch (MissingResourceException e) {
+            // OK
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/spi/ResourceBundleControlProvider/UserDefaultControlTest.sh	Mon Jun 25 21:38:37 2012 -0700
@@ -0,0 +1,24 @@
+# 
+# Copyright (c) 2012, 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.
+#
+
+${TESTJAVA}/bin/java -Djava.ext.dirs=${TESTSRC} -cp ${TESTCLASSES} UserDefaultControlTest
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/spi/ResourceBundleControlProvider/providersrc/Makefile	Mon Jun 25 21:38:37 2012 -0700
@@ -0,0 +1,63 @@
+#
+# Copyright (c) 2012, 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.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# 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.
+#
+
+#
+# Makefile for building a ResourceBundleControlProvider jar file for testing.
+#
+#    Usage: make JDK_HOME=... all install
+#
+
+DESTDIR = ..
+TMPDIR = tmp
+SERVICESDIR = $(TMPDIR)/META-INF/services
+TARGETJAR = rbcontrolprovider.jar
+BINDIR = $(JDK_HOME)/bin
+
+
+all: $(TARGETJAR)
+
+install: all
+	cp $(TARGETJAR) $(DESTDIR)
+
+SERVICES = java.util.spi.ResourceBundleControlProvider
+
+FILES_JAVA = UserControlProvider.java \
+             UserXMLControl.java
+
+RESOURCE_FILES = XmlRB.xml \
+                 XmlRB_ja.xml
+
+$(TARGETJAR): $(SERVICES) $(FILES_JAVA) $(RESOURCE_FILES)
+	rm -rf $(TMPDIR) $@
+	mkdir -p $(SERVICESDIR)
+	$(BINDIR)/javac -d $(TMPDIR) $(FILES_JAVA)
+	cp $(SERVICES) $(SERVICESDIR)
+	cp $(RESOURCE_FILES) $(TMPDIR)/com/foo
+	$(BINDIR)/jar  cvf $@ -C $(TMPDIR) .
+
+clean:
+	rm -rf $(TMPDIR) $(TARGETJAR)
+
+.PHONY: all install clean
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/spi/ResourceBundleControlProvider/providersrc/UserControlProvider.java	Mon Jun 25 21:38:37 2012 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package com.foo;
+
+import java.util.ResourceBundle;
+import java.util.spi.ResourceBundleControlProvider;
+
+public class UserControlProvider implements ResourceBundleControlProvider {
+    static final ResourceBundle.Control XMLCONTROL = new UserXMLControl();
+
+    public ResourceBundle.Control getControl(String baseName) {
+        System.out.println(getClass().getName()+".getControl called for " + baseName);
+
+        // Throws a NPE if baseName is null.
+        if (baseName.startsWith("com.foo.Xml")) {
+            System.out.println("\treturns " + XMLCONTROL);
+            return XMLCONTROL;
+        }
+        System.out.println("\treturns null");
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/spi/ResourceBundleControlProvider/providersrc/UserXMLControl.java	Mon Jun 25 21:38:37 2012 -0700
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+package com.foo;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import static java.util.ResourceBundle.Control.*;
+
+public class UserXMLControl extends ResourceBundle.Control {
+    @Override
+    public List<String> getFormats(String baseName) {
+        if (baseName == null) {
+            throw new NullPointerException();
+        }
+        return Arrays.asList("xml");
+    }
+
+    @Override
+    public ResourceBundle newBundle(String baseName, Locale locale,
+                                    String format,
+                                    ClassLoader loader,
+                                    boolean reload)
+        throws IllegalAccessException,
+               InstantiationException, IOException {
+        if (baseName == null || locale == null
+            || format == null || loader == null) {
+            throw new NullPointerException();
+        }
+        ResourceBundle bundle = null;
+        if (format.equals("xml")) {
+            String bundleName = toBundleName(baseName, locale);
+            String resourceName = toResourceName(bundleName, format);
+            URL url = loader.getResource(resourceName);
+            if (url != null) {
+                URLConnection connection = url.openConnection();
+                if (connection != null) {
+                    if (reload) {
+                        // disable caches if reloading
+                        connection.setUseCaches(false);
+                    }
+                    try (InputStream stream = connection.getInputStream()) {
+                        if (stream != null) {
+                            BufferedInputStream bis = new BufferedInputStream(stream);
+                            bundle = new XMLResourceBundle(bis);
+                        }
+                    }
+                }
+            }
+        }
+        return bundle;
+    }
+
+    private static class XMLResourceBundle extends ResourceBundle {
+        private Properties props;
+
+        XMLResourceBundle(InputStream stream) throws IOException {
+            props = new Properties();
+            props.loadFromXML(stream);
+        }
+
+        protected Object handleGetObject(String key) {
+            if (key == null) {
+                throw new NullPointerException();
+            }
+            return props.get(key);
+        }
+
+        public Enumeration<String> getKeys() {
+            // Not implemented
+            return null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/spi/ResourceBundleControlProvider/providersrc/XmlRB.xml	Mon Jun 25 21:38:37 2012 -0700
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2012, 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. Oracle designates this
+ particular file as subject to the Classpath exception as provided
+ by Oracle in the LICENSE file that accompanied this code.
+ 
+ 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.
+-->
+<!---->
+
+<!-- DTD for properties -->
+<!DOCTYPE properties [
+<!ELEMENT properties ( comment?, entry* ) >
+<!ATTLIST properties version CDATA #FIXED "1.0">
+<!ELEMENT comment (#PCDATA) >
+<!ELEMENT entry (#PCDATA) >
+<!ATTLIST entry key CDATA #REQUIRED>
+]>
+
+<properties>
+    <comment>Test data for UserDefaultControlTest.java</comment>
+    <entry key="type">XML</entry>
+</properties>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/spi/ResourceBundleControlProvider/providersrc/XmlRB_ja.xml	Mon Jun 25 21:38:37 2012 -0700
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2012, 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. Oracle designates this
+ particular file as subject to the Classpath exception as provided
+ by Oracle in the LICENSE file that accompanied this code.
+ 
+ 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.
+-->
+<!---->
+
+<!-- DTD for properties -->
+<!DOCTYPE properties [
+<!ELEMENT properties ( comment?, entry* ) >
+<!ATTLIST properties version CDATA #FIXED "1.0">
+<!ELEMENT comment (#PCDATA) >
+<!ELEMENT entry (#PCDATA) >
+<!ATTLIST entry key CDATA #REQUIRED>
+]>
+
+<properties>
+    <comment>Test data for UserDefaultControlTest.java</comment>
+    <entry key="type">XML</entry>
+</properties>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/spi/ResourceBundleControlProvider/providersrc/java.util.spi.ResourceBundleControlProvider	Mon Jun 25 21:38:37 2012 -0700
@@ -0,0 +1,1 @@
+com.foo.UserControlProvider
Binary file jdk/test/java/util/spi/ResourceBundleControlProvider/rbcontrolprovider.jar has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/JarIndexMergeForClassLoaderTest.java	Mon Jun 25 21:38:37 2012 -0700
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2012, 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     6901992
+ * @summary InvalidJarIndexException due to bug in sun.misc.JarIndex.merge()
+ *          Test URLClassLoader usage of the merge method when using indexes
+ * @author  Diego Belfer
+ */
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
+
+public class JarIndexMergeForClassLoaderTest {
+    static final String slash = File.separator;
+    static final String testClassesDir = System.getProperty("test.classes", ".");
+    static final String jar;
+    static final boolean debug = true;
+    static final File tmpFolder = new File(testClassesDir);
+
+    static {
+        String javaHome = System.getProperty("java.home");
+        if (javaHome.endsWith("jre")) {
+            int index = javaHome.lastIndexOf(slash);
+            if (index != -1)
+                javaHome = javaHome.substring(0, index);
+        }
+
+        jar = javaHome + slash + "bin" + slash + "jar";
+    }
+
+    public static void main(String[] args) throws Exception {
+        // Create the jars file
+        File jar1 = buildJar1();
+        File jar2 = buildJar2();
+        File jar3 = buildJar3();
+
+        // Index jar files in two levels: jar1 -> jar2 -> jar3
+        createIndex(jar2.getName(), jar3.getName());
+        createIndex(jar1.getName(), jar2.getName());
+
+        // Get root jar of the URLClassLoader
+        URL url = jar1.toURI().toURL();
+
+        URLClassLoader classLoader = new URLClassLoader(new URL[] { url });
+
+        assertResource(classLoader, "com/jar1/resource.file", "jar1");
+        assertResource(classLoader, "com/test/resource1.file", "resource1");
+        assertResource(classLoader, "com/jar2/resource.file", "jar2");
+        assertResource(classLoader, "com/test/resource2.file", "resource2");
+        assertResource(classLoader, "com/test/resource3.file", "resource3");
+
+        /*
+         * The following two asserts failed before the fix of the bug 6901992
+         */
+        // Check that an existing file is found using the merged index
+        assertResource(classLoader, "com/missing/jar3/resource.file", "jar3");
+        // Check that a non existent file in directory which does not contain
+        // any file is not found and it does not throw InvalidJarIndexException
+        assertResource(classLoader, "com/missing/nofile", null);
+    }
+
+    private static File buildJar3() throws FileNotFoundException, IOException {
+        JarBuilder jar3Builder = new JarBuilder(tmpFolder, "jar3.jar");
+        jar3Builder.addResourceFile("com/test/resource3.file", "resource3");
+        jar3Builder.addResourceFile("com/missing/jar3/resource.file", "jar3");
+        return jar3Builder.build();
+    }
+
+    private static File buildJar2() throws FileNotFoundException, IOException {
+        JarBuilder jar2Builder = new JarBuilder(tmpFolder, "jar2.jar");
+        jar2Builder.addResourceFile("com/jar2/resource.file", "jar2");
+        jar2Builder.addResourceFile("com/test/resource2.file", "resource2");
+        return jar2Builder.build();
+    }
+
+    private static File buildJar1() throws FileNotFoundException, IOException {
+        JarBuilder jar1Builder = new JarBuilder(tmpFolder, "jar1.jar");
+        jar1Builder.addResourceFile("com/jar1/resource.file", "jar1");
+        jar1Builder.addResourceFile("com/test/resource1.file", "resource1");
+        return jar1Builder.build();
+    }
+
+    /* create the index */
+    static void createIndex(String parentJar, String childJar) {
+        // ProcessBuilder is used so that the current directory can be set
+        // to the directory that directly contains the jars.
+        debug("Running jar to create the index for: " + parentJar + " and "
+                + childJar);
+        ProcessBuilder pb = new ProcessBuilder(jar, "-i", parentJar, childJar);
+
+        pb.directory(tmpFolder);
+        // pd.inheritIO();
+        try {
+            Process p = pb.start();
+            if (p.waitFor() != 0)
+                throw new RuntimeException("jar indexing failed");
+
+            if (debug && p != null) {
+                debugStream(p.getInputStream());
+                debugStream(p.getErrorStream());
+            }
+        } catch (InterruptedException | IOException x) {
+            throw new RuntimeException(x);
+        }
+    }
+
+    private static void debugStream(InputStream is) throws IOException {
+        try (BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
+            String line;
+            while ((line = reader.readLine()) != null) {
+                debug(line);
+            }
+        }
+    }
+
+    private static void assertResource(URLClassLoader classLoader, String file,
+            String expectedContent) throws IOException {
+        InputStream fileStream = classLoader.getResourceAsStream(file);
+
+        if (fileStream == null && expectedContent == null) {
+            return;
+        }
+        if (fileStream == null && expectedContent != null) {
+            throw new RuntimeException(
+                    buildMessage(file, expectedContent, null));
+        }
+        try {
+            String actualContent = readAsString(fileStream);
+
+            if (fileStream != null && expectedContent == null) {
+                throw new RuntimeException(buildMessage(file, null,
+                        actualContent));
+            }
+            if (!expectedContent.equals(actualContent)) {
+                throw new RuntimeException(buildMessage(file, expectedContent,
+                        actualContent));
+            }
+        } finally {
+            fileStream.close();
+        }
+    }
+
+    private static String buildMessage(String file, String expectedContent,
+            String actualContent) {
+        return "Expected: " + expectedContent + " for: " + file + " was: "
+                + actualContent;
+    }
+
+    private static String readAsString(InputStream fileStream)
+            throws IOException {
+        byte[] buffer = new byte[1024];
+        int count, len = 0;
+        while ((count = fileStream.read(buffer, len, buffer.length-len)) != -1)
+                len += count;
+        return new String(buffer, 0, len, "ASCII");
+    }
+
+    static void debug(Object message) {
+        if (debug)
+            System.out.println(message);
+    }
+
+    /*
+     * Helper class for building jar files
+     */
+    public static class JarBuilder {
+        private JarOutputStream os;
+        private File jarFile;
+
+        public JarBuilder(File tmpFolder, String jarName)
+            throws FileNotFoundException, IOException
+        {
+            this.jarFile = new File(tmpFolder, jarName);
+            this.os = new JarOutputStream(new FileOutputStream(jarFile));
+        }
+
+        public void addResourceFile(String pathFromRoot, String content)
+            throws IOException
+        {
+            JarEntry entry = new JarEntry(pathFromRoot);
+            os.putNextEntry(entry);
+            os.write(content.getBytes("ASCII"));
+            os.closeEntry();
+        }
+
+        public File build() throws IOException {
+            os.close();
+            return jarFile;
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/JarIndex/JarIndexMergeTest.java	Mon Jun 25 21:38:37 2012 -0700
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2012, 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 6901992
+ * @compile -XDignore.symbol.file JarIndexMergeTest.java
+ * @run main JarIndexMergeTest
+ * @summary InvalidJarIndexException due to bug in sun.misc.JarIndex.merge()
+ * @author  Diego Belfer
+ */
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
+// implementation specific API
+import sun.misc.JarIndex;
+
+public class JarIndexMergeTest {
+    static final String slash = File.separator;
+    static final String testClassesDir = System.getProperty("test.classes", ".");
+    static final File tmpFolder = new File(testClassesDir);
+
+    public static void main(String[] args) throws Exception {
+        File jar1 = buildJar1();
+        File jar2 = buildJar2();
+
+        JarIndex jarIndex1 = new JarIndex(new String[] { jar1.getAbsolutePath() });
+        JarIndex jarIndex2 = new JarIndex(new String[] { jar2.getAbsolutePath() });
+
+        jarIndex1.merge(jarIndex2, null);
+
+        assertFileResolved(jarIndex2, "com/test1/resource1.file",
+                           jar1.getAbsolutePath());
+        assertFileResolved(jarIndex2, "com/test2/resource2.file",
+                           jar2.getAbsolutePath());
+    }
+
+    static void assertFileResolved(JarIndex jarIndex2, String file,
+                                   String jarName) {
+        @SuppressWarnings("unchecked")
+        LinkedList<String> jarLists = (LinkedList<String>)jarIndex2.get(file);
+        if (jarLists == null || jarLists.size() == 0 ||
+            !jarName.equals(jarLists.get(0))) {
+            throw new RuntimeException(
+                "Unexpected result: the merged index must resolve file: "
+                + file);
+        }
+    }
+
+    private static File buildJar1() throws FileNotFoundException, IOException {
+        JarBuilder jar1Builder = new JarBuilder(tmpFolder, "jar1-merge.jar");
+        jar1Builder.addResourceFile("com/test1/resource1.file", "resource1");
+        return jar1Builder.build();
+    }
+
+    private static File buildJar2() throws FileNotFoundException, IOException {
+        JarBuilder jar2Builder = new JarBuilder(tmpFolder, "jar2-merge.jar");
+        jar2Builder.addResourceFile("com/test2/resource2.file", "resource2");
+        return jar2Builder.build();
+    }
+
+    /*
+     * Helper class for building jar files
+     */
+    public static class JarBuilder {
+        private JarOutputStream os;
+        private File jarFile;
+
+        public JarBuilder(File tmpFolder, String jarName)
+            throws FileNotFoundException, IOException
+        {
+            this.jarFile = new File(tmpFolder, jarName);
+            this.os = new JarOutputStream(new FileOutputStream(jarFile));
+        }
+
+        public void addResourceFile(String pathFromRoot, String content)
+            throws IOException
+        {
+            JarEntry entry = new JarEntry(pathFromRoot);
+            os.putNextEntry(entry);
+            os.write(content.getBytes("ASCII"));
+            os.closeEntry();
+        }
+
+        public File build() throws IOException {
+            os.close();
+            return jarFile;
+        }
+    }
+}
+
--- a/jdk/test/sun/security/krb5/auto/TcpTimeout.java	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/test/sun/security/krb5/auto/TcpTimeout.java	Mon Jun 25 21:38:37 2012 -0700
@@ -48,49 +48,60 @@
         k.addPrincipalRandKey("krbtgt/" + OneKDC.REALM);
 
         // Start two listener that does not communicate, simulate timeout
-        int p1 = new ServerSocket(0).getLocalPort();
-        int p2 = new ServerSocket(0).getLocalPort();
+        ServerSocket ss1 = null;
+        ServerSocket ss2 = null;
 
-        FileWriter fw = new FileWriter("alternative-krb5.conf");
+        try {
+            ss1 = new ServerSocket(0);
+            ss2 = new ServerSocket(0);
+            int p1 = ss1.getLocalPort();
+            int p2 = ss2.getLocalPort();
+
+            FileWriter fw = new FileWriter("alternative-krb5.conf");
 
-        fw.write("[libdefaults]\n" +
-                "udp_preference_limit = 1\n" +
-                "max_retries = 2\n" +
-                "default_realm = " + OneKDC.REALM + "\n" +
-                "kdc_timeout = 5000\n");
-        fw.write("[realms]\n" + OneKDC.REALM + " = {\n" +
-                "kdc = " + OneKDC.KDCHOST + ":" + p1 + "\n" +
-                "kdc = " + OneKDC.KDCHOST + ":" + p2 + "\n" +
-                "kdc = " + OneKDC.KDCHOST + ":" + p3 + "\n" +
-                "}\n");
+            fw.write("[libdefaults]\n" +
+                    "udp_preference_limit = 1\n" +
+                    "max_retries = 2\n" +
+                    "default_realm = " + OneKDC.REALM + "\n" +
+                    "kdc_timeout = 5000\n");
+            fw.write("[realms]\n" + OneKDC.REALM + " = {\n" +
+                    "kdc = " + OneKDC.KDCHOST + ":" + p1 + "\n" +
+                    "kdc = " + OneKDC.KDCHOST + ":" + p2 + "\n" +
+                    "kdc = " + OneKDC.KDCHOST + ":" + p3 + "\n" +
+                    "}\n");
 
-        fw.close();
-        System.setProperty("java.security.krb5.conf", "alternative-krb5.conf");
-        Config.refresh();
-
-        System.out.println("Ports opened on " + p1 + ", " + p2 + ", " + p3);
+            fw.close();
+            System.setProperty("java.security.krb5.conf",
+                    "alternative-krb5.conf");
+            Config.refresh();
 
-        // The correct behavior should be:
-        // 5 sec on p1, 5 sec on p1, fail
-        // 5 sec on p2, 5 sec on p2, fail
-        // p3 ok, p3 ok again for preauth.
-        int count = 6;
+            System.out.println("Ports opened on " + p1 + ", " + p2 + ", " + p3);
+
+            // The correct behavior should be:
+            // 5 sec on p1, 5 sec on p1, fail
+            // 5 sec on p2, 5 sec on p2, fail
+            // p3 ok, p3 ok again for preauth.
+            int count = 6;
+
+            ByteArrayOutputStream bo = new ByteArrayOutputStream();
+            PrintStream oldout = System.out;
+            System.setOut(new PrintStream(bo));
+            Context c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
+            System.setOut(oldout);
 
-        ByteArrayOutputStream bo = new ByteArrayOutputStream();
-        PrintStream oldout = System.out;
-        System.setOut(new PrintStream(bo));
-        Context c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
-        System.setOut(oldout);
-
-        String[] lines = new String(bo.toByteArray()).split("\n");
-        for (String line: lines) {
-            if (line.startsWith(">>> KDCCommunication")) {
-                System.out.println(line);
-                count--;
+            String[] lines = new String(bo.toByteArray()).split("\n");
+            for (String line: lines) {
+                if (line.startsWith(">>> KDCCommunication")) {
+                    System.out.println(line);
+                    count--;
+                }
             }
-        }
-        if (count != 0) {
-            throw new Exception("Retry count is " + count + " less");
+            if (count != 0) {
+                throw new Exception("Retry count is " + count + " less");
+            }
+        } finally {
+            if (ss1 != null) ss1.close();
+            if (ss2 != null) ss2.close();
         }
     }
 }
--- a/jdk/test/sun/tools/jinfo/Basic.sh	Mon Jun 25 21:36:32 2012 -0700
+++ b/jdk/test/sun/tools/jinfo/Basic.sh	Mon Jun 25 21:38:37 2012 -0700
@@ -43,7 +43,8 @@
 
 failed=0
 
-runSA=true
+# Skip SA options for now, see 7175133
+runSA=false
 
 if [ $isMacos = true ]; then
     runSA=false