Mercurial > hg > icedtea9-forest > jdk
changeset 5765:7cadd5bb6983
Merge
author | lana |
---|---|
date | Wed, 27 Jun 2012 12:54:48 -0700 |
parents | 6d37b95f0555 (current diff) b92353a01aa0 (diff) |
children | 85f72a4f5f68 |
files | |
diffstat | 93 files changed, 2686 insertions(+), 503 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Tue Jun 26 17:29:10 2012 +0400 +++ b/.hgtags Wed Jun 27 12:54:48 2012 -0700 @@ -165,3 +165,4 @@ 4eac56f073ea8179b1a35fcd2af9b48b0088be9f jdk8-b41 cf5c1f6fbc5ba14163fe0ef8eb8601b33f951372 jdk8-b42 b3246687c3695dff6f461bb407f9db88f7d072e7 jdk8-b43 +db471a7af03168e4441c245b1d9976f720a7cb77 jdk8-b44
--- a/make/com/sun/jmx/Makefile Tue Jun 26 17:29:10 2012 +0400 +++ b/make/com/sun/jmx/Makefile Wed Jun 27 12:54:48 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 @@ -100,6 +100,23 @@ # so that *_tie classes are generated in package without the prefix # org.omg.stub (6375696) # +# To ensure the latest stub generator files are picked up from corba repo +# when available, we need to run with latest rmic version available. rmic +# launch tool not built at this stage but we can invoke via rmi class. + +RMIC_JAVA = $(OUTPUTDIR)/bin/java +# need to treat 64bit solaris differently +ifeq ($(PLATFORM)-$(LIBARCH), solaris-amd64) +RMIC_JAVA = $(OUTPUTDIR)/bin/amd64/java +endif +ifeq ($(PLATFORM)-$(LIBARCH), solaris-sparcv9) +RMIC_JAVA = $(OUTPUTDIR)/bin/sparcv9/java +endif + +ifeq ($(CROSS_COMPILE_ARCH),) +RMIC = $(RMIC_JAVA) $(JAVA_TOOLS_FLAGS) -cp $(OUTPUTDIR)/classes sun.rmi.rmic.Main +endif + $(CLASSDESTDIR)/%_Stub.class: $(CLASSDESTDIR)/%.class $(prep-target) $(RMIC) -classpath "$(CLASSDESTDIR)" \
--- a/make/common/Defs-embedded.gmk Tue Jun 26 17:29:10 2012 +0400 +++ b/make/common/Defs-embedded.gmk Wed Jun 27 12:54:48 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/make/java/java/FILES_java.gmk Tue Jun 26 17:29:10 2012 +0400 +++ b/make/java/java/FILES_java.gmk Wed Jun 27 12:54:48 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/make/java/nio/mapfile-linux Tue Jun 26 17:29:10 2012 +0400 +++ b/make/java/nio/mapfile-linux Wed Jun 27 12:54:48 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/make/java/nio/mapfile-solaris Tue Jun 26 17:29:10 2012 +0400 +++ b/make/java/nio/mapfile-solaris Wed Jun 27 12:54:48 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/src/macosx/classes/apple/applescript/AppleScriptEngine.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/macosx/classes/apple/applescript/AppleScriptEngine.java Wed Jun 27 12:54:48 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -26,6 +26,7 @@ package apple.applescript; import java.io.*; +import java.nio.file.Files; import java.util.*; import java.util.Map.Entry; @@ -297,7 +298,7 @@ File tmpfile; FileWriter tmpwrite; try { - tmpfile = File.createTempFile("AppleScriptEngine.", ".scpt"); + tmpfile = Files.createTempFile("AppleScriptEngine.", ".scpt").toFile(); tmpwrite = new FileWriter(tmpfile); // read in our input and write directly to tmpfile
--- a/src/share/classes/com/sun/java/util/jar/pack/Driver.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/com/sun/java/util/jar/pack/Driver.java Wed Jun 27 12:54:48 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, 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 @@ -35,6 +35,7 @@ import java.io.OutputStream; import java.io.PrintStream; import java.text.MessageFormat; +import java.nio.file.Files; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -385,9 +386,7 @@ if ( base.getParentFile() == null && suffix.equals(".bak")) where = new File(".").getAbsoluteFile(); - - File f = File.createTempFile(prefix, suffix, where); - return f; + return Files.createTempFile(where.toPath(), prefix, suffix).toFile(); } static private
--- a/src/share/classes/com/sun/rowset/CachedRowSetImpl.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/com/sun/rowset/CachedRowSetImpl.java Wed Jun 27 12:54:48 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/src/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java Wed Jun 27 12:54:48 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/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java Wed Jun 27 12:54:48 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/src/share/classes/java/awt/Font.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/java/awt/Font.java Wed Jun 27 12:54:48 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 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 @@ -36,6 +36,7 @@ import java.awt.peer.FontPeer; import java.io.*; import java.lang.ref.SoftReference; +import java.nio.file.Files; import java.security.AccessController; import java.security.PrivilegedExceptionAction; import java.text.AttributedCharacterIterator.Attribute; @@ -831,7 +832,7 @@ File f = null; boolean hasPerm = false; try { - f = File.createTempFile("+~JT", ".tmp", null); + f = Files.createTempFile("+~JT", ".tmp").toFile(); f.delete(); f = null; hasPerm = true; @@ -881,7 +882,7 @@ final File tFile = AccessController.doPrivileged( new PrivilegedExceptionAction<File>() { public File run() throws IOException { - return File.createTempFile("+~JF", ".tmp", null); + return Files.createTempFile("+~JF", ".tmp").toFile(); } } );
--- a/src/share/classes/java/io/SerialCallbackContext.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/java/io/SerialCallbackContext.java Wed Jun 27 12:54:48 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/src/share/classes/java/lang/invoke/MethodHandles.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/java/lang/invoke/MethodHandles.java Wed Jun 27 12:54:48 2012 -0700 @@ -407,7 +407,7 @@ * an access$N method. */ Lookup() { - this(getCallerClassAtEntryPoint(), ALL_MODES); + this(getCallerClassAtEntryPoint(false), ALL_MODES); // make sure we haven't accidentally picked up a privileged class: checkUnprivilegedlookupClass(lookupClass); } @@ -461,8 +461,8 @@ && !VerifyAccess.isSamePackageMember(this.lookupClass, requestedLookupClass)) { newModes &= ~PRIVATE; } - if (newModes == PUBLIC - && !VerifyAccess.isClassAccessible(requestedLookupClass, this.lookupClass)) { + if ((newModes & PUBLIC) != 0 + && !VerifyAccess.isClassAccessible(requestedLookupClass, this.lookupClass, allowedModes)) { // The requested class it not accessible from the lookup class. // No permissions. newModes = 0; @@ -540,13 +540,17 @@ } } - // call this from an entry point method in Lookup with extraFrames=0. - private static Class<?> getCallerClassAtEntryPoint() { + /* Obtain the external caller class, when called from Lookup.<init> or a first-level subroutine. */ + private static Class<?> getCallerClassAtEntryPoint(boolean inSubroutine) { final int CALLER_DEPTH = 4; + // Stack for the constructor entry point (inSubroutine=false): // 0: Reflection.getCC, 1: getCallerClassAtEntryPoint, // 2: Lookup.<init>, 3: MethodHandles.*, 4: caller + // The stack is slightly different for a subroutine of a Lookup.find* method: + // 2: Lookup.*, 3: Lookup.find*.*, 4: caller // Note: This should be the only use of getCallerClass in this file. - assert(Reflection.getCallerClass(CALLER_DEPTH-1) == MethodHandles.class); + assert(Reflection.getCallerClass(CALLER_DEPTH-2) == Lookup.class); + assert(Reflection.getCallerClass(CALLER_DEPTH-1) == (inSubroutine ? Lookup.class : MethodHandles.class)); return Reflection.getCallerClass(CALLER_DEPTH); } @@ -1087,7 +1091,7 @@ void checkSymbolicClass(Class<?> refc) throws IllegalAccessException { Class<?> caller = lookupClassOrNull(); - if (caller != null && !VerifyAccess.isClassAccessible(refc, caller)) + if (caller != null && !VerifyAccess.isClassAccessible(refc, caller, allowedModes)) throw new MemberName(refc).makeAccessException("symbolic reference class is not public", this); } @@ -1102,7 +1106,13 @@ // Step 1: smgr.checkMemberAccess(refc, Member.PUBLIC); // Step 2: - if (!VerifyAccess.classLoaderIsAncestor(lookupClass, refc)) + Class<?> callerClass = ((allowedModes & PRIVATE) != 0 + ? lookupClass // for strong access modes, no extra check + // next line does stack walk magic; do not refactor: + : getCallerClassAtEntryPoint(true)); + if (!VerifyAccess.classLoaderIsAncestor(lookupClass, refc) || + (callerClass != lookupClass && + !VerifyAccess.classLoaderIsAncestor(callerClass, refc))) smgr.checkPackageAccess(VerifyAccess.getPackageName(refc)); // Step 3: if (m.isPublic()) return; @@ -1153,9 +1163,10 @@ int requestedModes = fixmods(mods); // adjust 0 => PACKAGE if ((requestedModes & allowedModes) != 0 && VerifyAccess.isMemberAccessible(refc, m.getDeclaringClass(), - mods, lookupClass())) + mods, lookupClass(), allowedModes)) return; if (((requestedModes & ~allowedModes) & PROTECTED) != 0 + && (allowedModes & PACKAGE) != 0 && VerifyAccess.isSamePackage(m.getDeclaringClass(), lookupClass())) // Protected members can also be checked as if they were package-private. return; @@ -1170,9 +1181,9 @@ (defc == refc || Modifier.isPublic(refc.getModifiers()))); if (!classOK && (allowedModes & PACKAGE) != 0) { - classOK = (VerifyAccess.isClassAccessible(defc, lookupClass()) && + classOK = (VerifyAccess.isClassAccessible(defc, lookupClass(), ALL_MODES) && (defc == refc || - VerifyAccess.isClassAccessible(refc, lookupClass()))); + VerifyAccess.isClassAccessible(refc, lookupClass(), ALL_MODES))); } if (!classOK) return "class is not public";
--- a/src/share/classes/java/util/HashMap.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/java/util/HashMap.java Wed Jun 27 12:54:48 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/src/share/classes/java/util/Hashtable.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/java/util/Hashtable.java Wed Jun 27 12:54:48 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/src/share/classes/java/util/ResourceBundle.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/java/util/ResourceBundle.java Wed Jun 27 12:54:48 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/src/share/classes/java/util/WeakHashMap.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/java/util/WeakHashMap.java Wed Jun 27 12:54:48 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/src/share/classes/java/util/concurrent/ConcurrentHashMap.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/java/util/concurrent/ConcurrentHashMap.java Wed Jun 27 12:54:48 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/src/share/classes/java/util/spi/ResourceBundleControlProvider.java Wed Jun 27 12:54:48 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/src/share/classes/javax/imageio/stream/FileCacheImageInputStream.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/javax/imageio/stream/FileCacheImageInputStream.java Wed Jun 27 12:54:48 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -29,6 +29,7 @@ import java.io.InputStream; import java.io.IOException; import java.io.RandomAccessFile; +import java.nio.file.Files; import com.sun.imageio.stream.StreamCloser; import com.sun.imageio.stream.StreamFinalizer; import sun.java2d.Disposer; @@ -97,8 +98,11 @@ throw new IllegalArgumentException("Not a directory!"); } this.stream = stream; - this.cacheFile = - File.createTempFile("imageio", ".tmp", cacheDir); + if (cacheDir == null) + this.cacheFile = Files.createTempFile("imageio", ".tmp").toFile(); + else + this.cacheFile = Files.createTempFile(cacheDir.toPath(), "imageio", ".tmp") + .toFile(); this.cache = new RandomAccessFile(cacheFile, "rw"); this.closeAction = StreamCloser.createCloseAction(this);
--- a/src/share/classes/javax/imageio/stream/FileCacheImageOutputStream.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/javax/imageio/stream/FileCacheImageOutputStream.java Wed Jun 27 12:54:48 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -29,6 +29,7 @@ import java.io.IOException; import java.io.OutputStream; import java.io.RandomAccessFile; +import java.nio.file.Files; import com.sun.imageio.stream.StreamCloser; /** @@ -83,8 +84,11 @@ throw new IllegalArgumentException("Not a directory!"); } this.stream = stream; - this.cacheFile = - File.createTempFile("imageio", ".tmp", cacheDir); + if (cacheDir == null) + this.cacheFile = Files.createTempFile("imageio", ".tmp").toFile(); + else + this.cacheFile = Files.createTempFile(cacheDir.toPath(), "imageio", ".tmp") + .toFile(); this.cache = new RandomAccessFile(cacheFile, "rw"); this.closeAction = StreamCloser.createCloseAction(this);
--- a/src/share/classes/javax/management/loading/MLet.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/javax/management/loading/MLet.java Wed Jun 27 12:54:48 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -44,6 +44,7 @@ import java.net.MalformedURLException; import java.net.URL; import java.net.URLStreamHandlerFactory; +import java.nio.file.Files; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; @@ -1160,8 +1161,9 @@ try { File directory = new File(libraryDirectory); directory.mkdirs(); - File file = File.createTempFile(libname + ".", null, - directory); + File file = Files.createTempFile(directory.toPath(), + libname + ".", null) + .toFile(); file.deleteOnExit(); FileOutputStream fileOutput = new FileOutputStream(file); try {
--- a/src/share/classes/javax/swing/plaf/synth/SynthButtonUI.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/javax/swing/plaf/synth/SynthButtonUI.java Wed Jun 27 12:54:48 2012 -0700 @@ -152,8 +152,8 @@ if (!c.isEnabled()) { state = DISABLED; } - if (SynthLookAndFeel.selectedUI == this) { - return SynthLookAndFeel.selectedUIState | SynthConstants.ENABLED; + if (SynthLookAndFeel.getSelectedUI() == this) { + return SynthLookAndFeel.getSelectedUIState() | SynthConstants.ENABLED; } AbstractButton button = (AbstractButton) c; ButtonModel model = button.getModel();
--- a/src/share/classes/javax/swing/plaf/synth/SynthLabelUI.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/javax/swing/plaf/synth/SynthLabelUI.java Wed Jun 27 12:54:48 2012 -0700 @@ -97,9 +97,9 @@ private int getComponentState(JComponent c) { int state = SynthLookAndFeel.getComponentState(c); - if (SynthLookAndFeel.selectedUI == this && + if (SynthLookAndFeel.getSelectedUI() == this && state == SynthConstants.ENABLED) { - state = SynthLookAndFeel.selectedUIState | SynthConstants.ENABLED; + state = SynthLookAndFeel.getSelectedUIState() | SynthConstants.ENABLED; } return state; }
--- a/src/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/javax/swing/plaf/synth/SynthLookAndFeel.java Wed Jun 27 12:54:48 2012 -0700 @@ -77,27 +77,25 @@ new StringBuffer("com.sun.java.swing.plaf.gtk.StyleCache"); /** + * AppContext key to get selectedUI. + */ + private static final Object SELECTED_UI_KEY = new StringBuilder("selectedUI"); + + /** + * AppContext key to get selectedUIState. + */ + private static final Object SELECTED_UI_STATE_KEY = new StringBuilder("selectedUIState"); + + /** * The last SynthStyleFactory that was asked for from AppContext * <code>lastContext</code>. */ private static SynthStyleFactory lastFactory; /** - * If this is true it indicates there is more than one AppContext active - * and that we need to make sure in getStyleCache the requesting - * AppContext matches that of <code>lastContext</code> before returning - * it. - */ - private static boolean multipleApps; - /** * AppContext lastLAF came from. */ private static AppContext lastContext; - // Refer to setSelectedUI - static ComponentUI selectedUI; - // Refer to setSelectedUI - static int selectedUIState; - /** * SynthStyleFactory for the this SynthLookAndFeel. */ @@ -111,6 +109,10 @@ private Handler _handler; + static ComponentUI getSelectedUI() { + return (ComponentUI) AppContext.getAppContext().get(SELECTED_UI_KEY); + } + /** * Used by the renderers. For the most part the renderers are implemented * as Labels, which is problematic in so far as they are never selected. @@ -122,8 +124,8 @@ static void setSelectedUI(ComponentUI uix, boolean selected, boolean focused, boolean enabled, boolean rollover) { - selectedUI = uix; - selectedUIState = 0; + int selectedUIState = 0; + if (selected) { selectedUIState = SynthConstants.SELECTED; if (focused) { @@ -140,19 +142,32 @@ else { if (enabled) { selectedUIState |= SynthConstants.ENABLED; - selectedUIState = SynthConstants.FOCUSED; + if (focused) { + selectedUIState |= SynthConstants.FOCUSED; + } } else { selectedUIState |= SynthConstants.DISABLED; } } + + AppContext context = AppContext.getAppContext(); + + context.put(SELECTED_UI_KEY, uix); + context.put(SELECTED_UI_STATE_KEY, Integer.valueOf(selectedUIState)); + } + + static int getSelectedUIState() { + Integer result = (Integer) AppContext.getAppContext().get(SELECTED_UI_STATE_KEY); + + return result == null ? 0 : result.intValue(); } /** * Clears out the selected UI that was last set in setSelectedUI. */ static void resetSelectedUI() { - selectedUI = null; + AppContext.getAppContext().remove(SELECTED_UI_KEY); } @@ -167,10 +182,6 @@ // for a particular AppContext. synchronized(SynthLookAndFeel.class) { AppContext context = AppContext.getAppContext(); - if (!multipleApps && context != lastContext && - lastContext != null) { - multipleApps = true; - } lastFactory = cache; lastContext = context; context.put(STYLE_FACTORY_KEY, cache); @@ -184,17 +195,13 @@ */ public static SynthStyleFactory getStyleFactory() { synchronized(SynthLookAndFeel.class) { - if (!multipleApps) { - return lastFactory; - } AppContext context = AppContext.getAppContext(); if (lastContext == context) { return lastFactory; } lastContext = context; - lastFactory = (SynthStyleFactory)AppContext.getAppContext().get - (STYLE_FACTORY_KEY); + lastFactory = (SynthStyleFactory) context.get(STYLE_FACTORY_KEY); return lastFactory; } }
--- a/src/share/classes/sun/font/SunLayoutEngine.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/sun/font/SunLayoutEngine.java Wed Jun 27 12:54:48 2012 -0700 @@ -33,7 +33,7 @@ import sun.font.GlyphLayout.*; import java.awt.geom.Point2D; import java.lang.ref.SoftReference; -import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; import java.util.Locale; /* @@ -129,9 +129,9 @@ // !!! don't need this unless we have more than one sun layout engine... public LayoutEngine getEngine(LayoutEngineKey key) { - HashMap cache = (HashMap)cacheref.get(); + ConcurrentHashMap cache = (ConcurrentHashMap)cacheref.get(); if (cache == null) { - cache = new HashMap(); + cache = new ConcurrentHashMap(); cacheref = new SoftReference(cache); }
--- a/src/share/classes/sun/invoke/util/VerifyAccess.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/sun/invoke/util/VerifyAccess.java Wed Jun 27 12:54:48 2012 -0700 @@ -37,6 +37,8 @@ private VerifyAccess() { } // cannot instantiate private static final int PACKAGE_ONLY = 0; + private static final int PACKAGE_ALLOWED = java.lang.invoke.MethodHandles.Lookup.PACKAGE; + private static final int PROTECTED_OR_PACKAGE_ALLOWED = (PACKAGE_ALLOWED|PROTECTED); private static final int ALL_ACCESS_MODES = (PUBLIC|PRIVATE|PROTECTED|PACKAGE_ONLY); private static final boolean ALLOW_NESTMATE_ACCESS = false; @@ -82,14 +84,19 @@ public static boolean isMemberAccessible(Class<?> refc, // symbolic ref class Class<?> defc, // actual def class int mods, // actual member mods - Class<?> lookupClass) { + Class<?> lookupClass, + int allowedModes) { + if (allowedModes == 0) return false; + assert((allowedModes & PUBLIC) != 0 && + (allowedModes & ~(ALL_ACCESS_MODES|PACKAGE_ALLOWED)) == 0); // Usually refc and defc are the same, but if they differ, verify them both. if (refc != defc) { - if (!isClassAccessible(refc, lookupClass)) { + if (!isClassAccessible(refc, lookupClass, allowedModes)) { // Note that defc is verified in the switch below. return false; } - if ((mods & (ALL_ACCESS_MODES|STATIC)) == (PROTECTED|STATIC)) { + if ((mods & (ALL_ACCESS_MODES|STATIC)) == (PROTECTED|STATIC) && + (allowedModes & PROTECTED_OR_PACKAGE_ALLOWED) != 0) { // Apply the special rules for refc here. if (!isRelatedClass(refc, lookupClass)) return isSamePackage(defc, lookupClass); @@ -98,19 +105,28 @@ // a superclass of the lookup class. } } - if (defc == lookupClass) + if (defc == lookupClass && + (allowedModes & PRIVATE) != 0) return true; // easy check; all self-access is OK switch (mods & ALL_ACCESS_MODES) { case PUBLIC: if (refc != defc) return true; // already checked above - return isClassAccessible(refc, lookupClass); + return isClassAccessible(refc, lookupClass, allowedModes); case PROTECTED: - return isSamePackage(defc, lookupClass) || isPublicSuperClass(defc, lookupClass); - case PACKAGE_ONLY: - return isSamePackage(defc, lookupClass); + if ((allowedModes & PROTECTED_OR_PACKAGE_ALLOWED) != 0 && + isSamePackage(defc, lookupClass)) + return true; + if ((allowedModes & PROTECTED) != 0 && + isPublicSuperClass(defc, lookupClass)) + return true; + return false; + case PACKAGE_ONLY: // That is, zero. Unmarked member is package-only access. + return ((allowedModes & PACKAGE_ALLOWED) != 0 && + isSamePackage(defc, lookupClass)); case PRIVATE: // Loosened rules for privates follows access rules for inner classes. return (ALLOW_NESTMATE_ACCESS && + (allowedModes & PRIVATE) != 0 && isSamePackageMember(defc, lookupClass)); default: throw new IllegalArgumentException("bad modifiers: "+Modifier.toString(mods)); @@ -138,11 +154,16 @@ * @param refc the symbolic reference class to which access is being checked (C) * @param lookupClass the class performing the lookup (D) */ - public static boolean isClassAccessible(Class<?> refc, Class<?> lookupClass) { + public static boolean isClassAccessible(Class<?> refc, Class<?> lookupClass, + int allowedModes) { + if (allowedModes == 0) return false; + assert((allowedModes & PUBLIC) != 0 && + (allowedModes & ~(ALL_ACCESS_MODES|PACKAGE_ALLOWED)) == 0); int mods = refc.getModifiers(); if (isPublic(mods)) return true; - if (isSamePackage(lookupClass, refc)) + if ((allowedModes & PACKAGE_ALLOWED) != 0 && + isSamePackage(lookupClass, refc)) return true; return false; } @@ -157,7 +178,7 @@ assert(!class1.isArray() && !class2.isArray()); if (class1 == class2) return true; - if (!loadersAreRelated(class1.getClassLoader(), class2.getClassLoader(), false)) + if (class1.getClassLoader() != class2.getClassLoader()) return false; String name1 = class1.getName(), name2 = class2.getName(); int dot = name1.lastIndexOf('.');
--- a/src/share/classes/sun/misc/JarIndex.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/sun/misc/JarIndex.java Wed Jun 27 12:54:48 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/src/share/classes/sun/nio/ch/IOUtil.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/sun/nio/ch/IOUtil.java Wed Jun 27 12:54:48 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/src/share/classes/sun/nio/ch/Util.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/sun/nio/ch/Util.java Wed Jun 27 12:54:48 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/src/share/classes/sun/print/PSPrinterJob.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/sun/print/PSPrinterJob.java Wed Jun 27 12:54:48 2012 -0700 @@ -97,6 +97,7 @@ import java.nio.charset.*; import java.nio.CharBuffer; import java.nio.ByteBuffer; +import java.nio.file.Files; //REMIND: Remove use of this class when IPPPrintService is moved to share directory. import java.lang.reflect.Method; @@ -659,7 +660,7 @@ * is not removed for some reason, request that it is * removed when the VM exits. */ - spoolFile = File.createTempFile("javaprint", ".ps", null); + spoolFile = Files.createTempFile("javaprint", ".ps").toFile(); spoolFile.deleteOnExit(); result = new FileOutputStream(spoolFile);
--- a/src/share/classes/sun/print/ServiceDialog.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/sun/print/ServiceDialog.java Wed Jun 27 12:54:48 2012 -0700 @@ -429,6 +429,7 @@ ValidatingFileChooser jfc = new ValidatingFileChooser(); jfc.setApproveButtonText(getMsg("button.ok")); jfc.setDialogTitle(getMsg("dialog.printtofile")); + jfc.setDialogType(JFileChooser.SAVE_DIALOG); jfc.setSelectedFile(fileDest); int returnVal = jfc.showDialog(this, null);
--- a/src/share/classes/sun/rmi/server/Activation.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/sun/rmi/server/Activation.java Wed Jun 27 12:54:48 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -43,6 +43,7 @@ import java.net.Socket; import java.net.SocketAddress; import java.net.SocketException; +import java.nio.file.Files; import java.nio.channels.Channel; import java.nio.channels.ServerSocketChannel; import java.rmi.AccessException; @@ -1940,7 +1941,7 @@ new PrivilegedExceptionAction<Void>() { public Void run() throws IOException { File file = - File.createTempFile("rmid-err", null, null); + Files.createTempFile("rmid-err", null).toFile(); PrintStream errStream = new PrintStream(new FileOutputStream(file)); System.setErr(errStream);
--- a/src/share/classes/sun/security/provider/certpath/BasicChecker.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/sun/security/provider/certpath/BasicChecker.java Wed Jun 27 12:54:48 2012 -0700 @@ -90,6 +90,7 @@ this.date = date; this.sigProvider = sigProvider; this.sigOnly = sigOnly; + this.prevPubKey = trustedPubKey; } /**
--- a/src/share/classes/sun/security/ssl/SSLEngineImpl.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/sun/security/ssl/SSLEngineImpl.java Wed Jun 27 12:54:48 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/src/share/classes/sun/security/x509/CRLExtensions.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/sun/security/x509/CRLExtensions.java Wed Jun 27 12:54:48 2012 -0700 @@ -32,8 +32,10 @@ import java.security.cert.CRLException; import java.security.cert.CertificateException; import java.util.Collection; +import java.util.Collections; import java.util.Enumeration; -import java.util.Hashtable; +import java.util.Map; +import java.util.TreeMap; import sun.security.util.*; @@ -61,7 +63,8 @@ */ public class CRLExtensions { - private Hashtable<String,Extension> map = new Hashtable<String,Extension>(); + private Map<String,Extension> map = Collections.synchronizedMap( + new TreeMap<String,Extension>()); private boolean unsupportedCritExt = false; /** @@ -214,7 +217,7 @@ * @return an enumeration of the extensions in this CRL. */ public Enumeration<Extension> getElements() { - return map.elements(); + return Collections.enumeration(map.values()); } /**
--- a/src/share/classes/sun/security/x509/CertificateExtensions.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/sun/security/x509/CertificateExtensions.java Wed Jun 27 12:54:48 2012 -0700 @@ -57,7 +57,8 @@ private static final Debug debug = Debug.getInstance("x509"); - private Hashtable<String,Extension> map = new Hashtable<String,Extension>(); + private Map<String,Extension> map = Collections.synchronizedMap( + new TreeMap<String,Extension>()); private boolean unsupportedCritExt = false; private Map<String,Extension> unparseableExtensions; @@ -118,7 +119,7 @@ if (ext.isCritical() == false) { // ignore errors parsing non-critical extensions if (unparseableExtensions == null) { - unparseableExtensions = new HashMap<String,Extension>(); + unparseableExtensions = new TreeMap<String,Extension>(); } unparseableExtensions.put(ext.getExtensionId().toString(), new UnparseableExtension(ext, e)); @@ -219,6 +220,12 @@ return (obj); } + // Similar to get(String), but throw no exception, might return null. + // Used in X509CertImpl::getExtension(OID). + Extension getExtension(String name) { + return map.get(name); + } + /** * Delete the attribute value. * @param name the extension name used in the lookup. @@ -246,7 +253,7 @@ * attribute. */ public Enumeration<Extension> getElements() { - return map.elements(); + return Collections.enumeration(map.values()); } /**
--- a/src/share/classes/sun/security/x509/X509CRLEntryImpl.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/sun/security/x509/X509CRLEntryImpl.java Wed Jun 27 12:54:48 2012 -0700 @@ -30,14 +30,7 @@ import java.security.cert.CRLReason; import java.security.cert.X509CRLEntry; import java.math.BigInteger; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.HashSet; +import java.util.*; import javax.security.auth.x500.X500Principal; @@ -74,7 +67,8 @@ * @author Hemma Prafullchandra */ -public class X509CRLEntryImpl extends X509CRLEntry { +public class X509CRLEntryImpl extends X509CRLEntry + implements Comparable<X509CRLEntryImpl> { private SerialNumber serialNumber = null; private Date revocationDate = null; @@ -195,9 +189,14 @@ * @exception CRLException if an encoding error occurs. */ public byte[] getEncoded() throws CRLException { + return getEncoded0().clone(); + } + + // Called internally to avoid clone + private byte[] getEncoded0() throws CRLException { if (revokedCert == null) this.encode(new DerOutputStream()); - return revokedCert.clone(); + return revokedCert; } @Override @@ -351,7 +350,7 @@ if (extensions == null) { return null; } - Set<String> extSet = new HashSet<String>(); + Set<String> extSet = new TreeSet<>(); for (Extension ex : extensions.getAllExtensions()) { if (ex.isCritical()) { extSet.add(ex.getExtensionId().toString()); @@ -372,7 +371,7 @@ if (extensions == null) { return null; } - Set<String> extSet = new HashSet<String>(); + Set<String> extSet = new TreeSet<>(); for (Extension ex : extensions.getAllExtensions()) { if (!ex.isCritical()) { extSet.add(ex.getExtensionId().toString()); @@ -500,16 +499,39 @@ getExtension(PKIXExtensions.CertificateIssuer_Id); } + /** + * Returns all extensions for this entry in a map + * @return the extension map, can be empty, but not null + */ public Map<String, java.security.cert.Extension> getExtensions() { if (extensions == null) { return Collections.emptyMap(); } Collection<Extension> exts = extensions.getAllExtensions(); - HashMap<String, java.security.cert.Extension> map = - new HashMap<String, java.security.cert.Extension>(exts.size()); + Map<String, java.security.cert.Extension> map = new TreeMap<>(); for (Extension ext : exts) { map.put(ext.getId(), ext); } return map; } + + @Override + public int compareTo(X509CRLEntryImpl that) { + int compSerial = getSerialNumber().compareTo(that.getSerialNumber()); + if (compSerial != 0) { + return compSerial; + } + try { + byte[] thisEncoded = this.getEncoded0(); + byte[] thatEncoded = that.getEncoded0(); + for (int i=0; i<thisEncoded.length && i<thatEncoded.length; i++) { + int a = thisEncoded[i] & 0xff; + int b = thatEncoded[i] & 0xff; + if (a != b) return a-b; + } + return thisEncoded.length -thatEncoded.length; + } catch (CRLException ce) { + return -1; + } + } }
--- a/src/share/classes/sun/security/x509/X509CRLImpl.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/sun/security/x509/X509CRLImpl.java Wed Jun 27 12:54:48 2012 -0700 @@ -52,7 +52,7 @@ /** * <p> - * An implmentation for X509 CRL (Certificate Revocation List). + * An implementation for X509 CRL (Certificate Revocation List). * <p> * The X.509 v2 CRL format is described below in ASN.1: * <pre> @@ -103,7 +103,8 @@ private X500Principal issuerPrincipal = null; private Date thisUpdate = null; private Date nextUpdate = null; - private Map<X509IssuerSerial,X509CRLEntry> revokedCerts = new LinkedHashMap<X509IssuerSerial,X509CRLEntry>(); + private Map<X509IssuerSerial,X509CRLEntry> revokedMap = new TreeMap<>(); + private List<X509CRLEntry> revokedList = new LinkedList<>(); private CRLExtensions extensions = null; private final static boolean isExplicit = true; private static final long YR_2050 = 2524636800000L; @@ -222,7 +223,8 @@ badCert.setCertificateIssuer(crlIssuer, badCertIssuer); X509IssuerSerial issuerSerial = new X509IssuerSerial (badCertIssuer, badCert.getSerialNumber()); - this.revokedCerts.put(issuerSerial, badCert); + this.revokedMap.put(issuerSerial, badCert); + this.revokedList.add(badCert); if (badCert.hasExtensions()) { this.version = 1; } @@ -304,8 +306,8 @@ tmp.putGeneralizedTime(nextUpdate); } - if (!revokedCerts.isEmpty()) { - for (X509CRLEntry entry : revokedCerts.values()) { + if (!revokedList.isEmpty()) { + for (X509CRLEntry entry : revokedList) { ((X509CRLEntryImpl)entry).encode(rCerts); } tmp.write(DerValue.tag_Sequence, rCerts); @@ -489,14 +491,14 @@ sb.append("\nThis Update: " + thisUpdate.toString() + "\n"); if (nextUpdate != null) sb.append("Next Update: " + nextUpdate.toString() + "\n"); - if (revokedCerts.isEmpty()) + if (revokedList.isEmpty()) sb.append("\nNO certificates have been revoked\n"); else { - sb.append("\nRevoked Certificates: " + revokedCerts.size()); + sb.append("\nRevoked Certificates: " + revokedList.size()); int i = 1; - for (Iterator<X509CRLEntry> iter = revokedCerts.values().iterator(); - iter.hasNext(); i++) - sb.append("\n[" + i + "] " + iter.next().toString()); + for (X509CRLEntry entry: revokedList) { + sb.append("\n[" + i++ + "] " + entry.toString()); + } } if (extensions != null) { Collection<Extension> allExts = extensions.getAllExtensions(); @@ -542,12 +544,12 @@ * false otherwise. */ public boolean isRevoked(Certificate cert) { - if (revokedCerts.isEmpty() || (!(cert instanceof X509Certificate))) { + if (revokedMap.isEmpty() || (!(cert instanceof X509Certificate))) { return false; } X509Certificate xcert = (X509Certificate) cert; X509IssuerSerial issuerSerial = new X509IssuerSerial(xcert); - return revokedCerts.containsKey(issuerSerial); + return revokedMap.containsKey(issuerSerial); } /** @@ -637,24 +639,24 @@ * @see X509CRLEntry */ public X509CRLEntry getRevokedCertificate(BigInteger serialNumber) { - if (revokedCerts.isEmpty()) { + if (revokedMap.isEmpty()) { return null; } // assume this is a direct CRL entry (cert and CRL issuer are the same) X509IssuerSerial issuerSerial = new X509IssuerSerial (getIssuerX500Principal(), serialNumber); - return revokedCerts.get(issuerSerial); + return revokedMap.get(issuerSerial); } /** * Gets the CRL entry for the given certificate. */ public X509CRLEntry getRevokedCertificate(X509Certificate cert) { - if (revokedCerts.isEmpty()) { + if (revokedMap.isEmpty()) { return null; } X509IssuerSerial issuerSerial = new X509IssuerSerial(cert); - return revokedCerts.get(issuerSerial); + return revokedMap.get(issuerSerial); } /** @@ -666,10 +668,10 @@ * @see X509CRLEntry */ public Set<X509CRLEntry> getRevokedCertificates() { - if (revokedCerts.isEmpty()) { + if (revokedList.isEmpty()) { return null; } else { - return new HashSet<X509CRLEntry>(revokedCerts.values()); + return new TreeSet<X509CRLEntry>(revokedList); } } @@ -905,7 +907,7 @@ if (extensions == null) { return null; } - Set<String> extSet = new HashSet<String>(); + Set<String> extSet = new TreeSet<>(); for (Extension ex : extensions.getAllExtensions()) { if (ex.isCritical()) { extSet.add(ex.getExtensionId().toString()); @@ -926,7 +928,7 @@ if (extensions == null) { return null; } - Set<String> extSet = new HashSet<String>(); + Set<String> extSet = new TreeSet<>(); for (Extension ex : extensions.getAllExtensions()) { if (!ex.isCritical()) { extSet.add(ex.getExtensionId().toString()); @@ -1103,7 +1105,8 @@ entry.setCertificateIssuer(crlIssuer, badCertIssuer); X509IssuerSerial issuerSerial = new X509IssuerSerial (badCertIssuer, entry.getSerialNumber()); - revokedCerts.put(issuerSerial, entry); + revokedMap.put(issuerSerial, entry); + revokedList.add(entry); } } @@ -1207,7 +1210,8 @@ /** * Immutable X.509 Certificate Issuer DN and serial number pair */ - private final static class X509IssuerSerial { + private final static class X509IssuerSerial + implements Comparable<X509IssuerSerial> { final X500Principal issuer; final BigInteger serial; volatile int hashcode = 0; @@ -1286,5 +1290,13 @@ } return hashcode; } + + @Override + public int compareTo(X509IssuerSerial another) { + int cissuer = issuer.toString() + .compareTo(another.issuer.toString()); + if (cissuer != 0) return cissuer; + return this.serial.compareTo(another.serial); + } } }
--- a/src/share/classes/sun/security/x509/X509CertImpl.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/sun/security/x509/X509CertImpl.java Wed Jun 27 12:54:48 2012 -0700 @@ -1202,7 +1202,7 @@ if (exts == null) { return null; } - Set<String> extSet = new HashSet<String>(); + Set<String> extSet = new TreeSet<>(); for (Extension ex : exts.getAllExtensions()) { if (ex.isCritical()) { extSet.add(ex.getExtensionId().toString()); @@ -1232,7 +1232,7 @@ if (exts == null) { return null; } - Set<String> extSet = new HashSet<String>(); + Set<String> extSet = new TreeSet<>(); for (Extension ex : exts.getAllExtensions()) { if (!ex.isCritical()) { extSet.add(ex.getExtensionId().toString()); @@ -1266,10 +1266,14 @@ if (extensions == null) { return null; } else { - for (Extension ex : extensions.getAllExtensions()) { - if (ex.getExtensionId().equals((Object)oid)) { + Extension ex = extensions.getExtension(oid.toString()); + if (ex != null) { + return ex; + } + for (Extension ex2: extensions.getAllExtensions()) { + if (ex2.getExtensionId().equals((Object)oid)) { //XXXX May want to consider cloning this - return ex; + return ex2; } } /* no such extension in this certificate */ @@ -1465,10 +1469,10 @@ if (names.isEmpty()) { return Collections.<List<?>>emptySet(); } - Set<List<?>> newNames = new HashSet<List<?>>(); + List<List<?>> newNames = new ArrayList<>(); for (GeneralName gname : names.names()) { GeneralNameInterface name = gname.getName(); - List<Object> nameEntry = new ArrayList<Object>(2); + List<Object> nameEntry = new ArrayList<>(2); nameEntry.add(Integer.valueOf(name.getType())); switch (name.getType()) { case GeneralNameInterface.NAME_RFC822: @@ -1526,12 +1530,12 @@ } } if (mustClone) { - Set<List<?>> namesCopy = new HashSet<List<?>>(); + List<List<?>> namesCopy = new ArrayList<>(); for (List<?> nameEntry : altNames) { Object nameObject = nameEntry.get(1); if (nameObject instanceof byte[]) { List<Object> nameEntryCopy = - new ArrayList<Object>(nameEntry); + new ArrayList<>(nameEntry); nameEntryCopy.set(1, ((byte[])nameObject).clone()); namesCopy.add(Collections.unmodifiableList(nameEntryCopy)); } else {
--- a/src/share/classes/sun/tools/jar/Main.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/sun/tools/jar/Main.java Wed Jun 27 12:54:48 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 @@ -137,7 +137,7 @@ File dir = file.getParentFile(); if (dir == null) dir = new File("."); - return File.createTempFile("jartmp", null, dir); + return Files.createTempFile(dir.toPath(), "jartmp", null).toFile(); } private boolean ok;
--- a/src/share/classes/sun/tools/native2ascii/Main.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/classes/sun/tools/native2ascii/Main.java Wed Jun 27 12:54:48 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 @@ -71,6 +71,7 @@ import java.nio.charset.CharsetEncoder; import java.nio.charset.Charset; import java.nio.charset.IllegalCharsetNameException; +import java.nio.file.Files; import java.io.UnsupportedEncodingException; import java.nio.charset.UnsupportedCharsetException; import sun.tools.native2ascii.A2NFilter; @@ -240,9 +241,7 @@ if (tempDir == null) tempDir = new File(System.getProperty("user.dir")); - tempFile = File.createTempFile("_N2A", - ".TMP", - tempDir); + tempFile = Files.createTempFile(tempDir.toPath(), "_N2A", ".TMP").toFile(); tempFile.deleteOnExit(); try { @@ -292,9 +291,7 @@ File tempDir = f.getParentFile(); if (tempDir == null) tempDir = new File(System.getProperty("user.dir")); - tempFile = File.createTempFile("_N2A", - ".TMP", - tempDir); + tempFile = Files.createTempFile(tempDir.toPath(), "_N2A", ".TMP").toFile(); tempFile.deleteOnExit(); try {
--- a/src/share/demo/jvmti/hprof/hprof_table.c Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/demo/jvmti/hprof/hprof_table.c Wed Jun 27 12:54:48 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/src/share/lib/security/java.security Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/lib/security/java.security Wed Jun 27 12:54:48 2012 -0700 @@ -132,10 +132,10 @@ # corresponding RuntimePermission ("defineClassInPackage."+package) has # been granted. # -# by default, no packages are restricted for definition, and none of -# the class loaders supplied with the JDK call checkPackageDefinition. +# by default, none of the class loaders supplied with the JDK call +# checkPackageDefinition. # -#package.definition= +package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils. # # Determines whether this properties file can be appended to
--- a/src/share/lib/security/java.security-macosx Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/lib/security/java.security-macosx Wed Jun 27 12:54:48 2012 -0700 @@ -133,10 +133,10 @@ # corresponding RuntimePermission ("defineClassInPackage."+package) has # been granted. # -# by default, no packages are restricted for definition, and none of -# the class loaders supplied with the JDK call checkPackageDefinition. +# by default, none of the class loaders supplied with the JDK call +# checkPackageDefinition. # -#package.definition= +package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,apple.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils. # # Determines whether this properties file can be appended to
--- a/src/share/lib/security/java.security-solaris Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/lib/security/java.security-solaris Wed Jun 27 12:54:48 2012 -0700 @@ -134,10 +134,10 @@ # corresponding RuntimePermission ("defineClassInPackage."+package) has # been granted. # -# by default, no packages are restricted for definition, and none of -# the class loaders supplied with the JDK call checkPackageDefinition. +# by default, none of the class loaders supplied with the JDK call +# checkPackageDefinition. # -#package.definition= +package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils. # # Determines whether this properties file can be appended to
--- a/src/share/lib/security/java.security-windows Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/lib/security/java.security-windows Wed Jun 27 12:54:48 2012 -0700 @@ -133,10 +133,10 @@ # corresponding RuntimePermission ("defineClassInPackage."+package) has # been granted. # -# by default, no packages are restricted for definition, and none of -# the class loaders supplied with the JDK call checkPackageDefinition. +# by default, none of the class loaders supplied with the JDK call +# checkPackageDefinition. # -#package.definition= +package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils. # # Determines whether this properties file can be appended to
--- a/src/share/native/java/net/net_util.c Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/native/java/net/net_util.c Wed Jun 27 12:54:48 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -68,6 +68,8 @@ */ IPv6_available = IPv6_supported() & (!preferIPv4Stack); initLocalAddrTable (); + parseExclusiveBindProperty(env); + return JNI_VERSION_1_2; }
--- a/src/share/native/java/net/net_util.h Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/native/java/net/net_util.h Wed Jun 27 12:54:48 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -120,6 +120,7 @@ NET_SockaddrToInetAddress(JNIEnv *env, struct sockaddr *him, int *port); void initLocalAddrTable (); +void parseExclusiveBindProperty(JNIEnv *env); void NET_SetTrafficClass(struct sockaddr *him, int trafficClass);
--- a/src/share/native/sun/awt/image/jpeg/jpegdecoder.c Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/native/sun/awt/image/jpeg/jpegdecoder.c Wed Jun 27 12:54:48 2012 -0700 @@ -337,7 +337,7 @@ /* Save the data currently in the buffer */ offset = src->pub.bytes_in_buffer; if (src->pub.next_input_byte > src->inbuf) { - memcpy(src->inbuf, src->pub.next_input_byte, offset); + memmove(src->inbuf, src->pub.next_input_byte, offset); } RELEASE_ARRAYS(env, src); buflen = (*env)->GetArrayLength(env, src->hInputBuffer) - offset;
--- a/src/share/native/sun/font/layout/LookupProcessor.cpp Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/native/sun/font/layout/LookupProcessor.cpp Wed Jun 27 12:54:48 2012 -0700 @@ -95,6 +95,10 @@ if (selectMask != 0) { const LookupTable *lookupTable = lookupListTable->getLookupTable(lookup); + + if (!lookupTable) + continue; + le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags); glyphIterator.reset(lookupFlags, selectMask); @@ -136,6 +140,9 @@ for (le_uint16 lookup = 0; lookup < lookupCount; lookup += 1) { le_uint16 lookupListIndex = SWAPW(featureTable->lookupListIndexArray[lookup]); + if (lookupListIndex >= lookupSelectCount) + continue; + lookupSelectArray[lookupListIndex] |= featureMask; lookupOrderArray[store++] = lookupListIndex; } @@ -147,7 +154,7 @@ Offset scriptListOffset, Offset featureListOffset, Offset lookupListOffset, LETag scriptTag, LETag languageTag, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool orderFeatures, LEErrorCode& success) - : lookupListTable(NULL), featureListTable(NULL), lookupSelectArray(NULL), + : lookupListTable(NULL), featureListTable(NULL), lookupSelectArray(NULL), lookupSelectCount(0), lookupOrderArray(NULL), lookupOrderCount(0) { const ScriptListTable *scriptListTable = NULL; @@ -195,6 +202,8 @@ lookupSelectArray[i] = 0; } + lookupSelectCount = lookupListCount; + le_int32 count, order = 0; le_int32 featureReferences = 0; const FeatureTable *featureTable = NULL; @@ -211,6 +220,10 @@ le_uint16 featureIndex = SWAPW(langSysTable->featureIndexArray[feature]); featureTable = featureListTable->getFeatureTable(featureIndex, &featureTag); + + if (!featureTable) + continue; + featureReferences += SWAPW(featureTable->lookupCount); }
--- a/src/share/native/sun/font/layout/LookupProcessor.h Tue Jun 26 17:29:10 2012 +0400 +++ b/src/share/native/sun/font/layout/LookupProcessor.h Wed Jun 27 12:54:48 2012 -0700 @@ -90,6 +90,7 @@ const FeatureListTable *featureListTable; FeatureMask *lookupSelectArray; + le_uint32 lookupSelectCount; le_uint16 *lookupOrderArray; le_uint32 lookupOrderCount;
--- a/src/solaris/classes/sun/font/FcFontConfiguration.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/solaris/classes/sun/font/FcFontConfiguration.java Wed Jun 27 12:54:48 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -33,6 +33,7 @@ import java.net.InetAddress; import java.net.UnknownHostException; import java.nio.charset.Charset; +import java.nio.file.Files; import java.util.HashMap; import java.util.HashSet; import java.util.Properties; @@ -387,7 +388,7 @@ File fcInfoFile = getFcInfoFile(); File dir = fcInfoFile.getParentFile(); dir.mkdirs(); - File tempFile = File.createTempFile("fcinfo", null, dir); + File tempFile = Files.createTempFile(dir.toPath(), "fcinfo", null).toFile(); FileOutputStream fos = new FileOutputStream(tempFile); props.store(fos, "JDK Font Configuration Generated File: *Do Not Edit*");
--- a/src/solaris/classes/sun/print/CUPSPrinter.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/solaris/classes/sun/print/CUPSPrinter.java Wed Jun 27 12:54:48 2012 -0700 @@ -278,14 +278,26 @@ is); is.close(); - if (responseMap.length > 0) { + if (responseMap != null && responseMap.length > 0) { defaultMap = responseMap[0]; } if (defaultMap == null) { os.close(); urlConnection.disconnect(); - return null; + + /* CUPS on OS X, as initially configured, considers the + * default printer to be the last one used that's + * presently available. So if no default was + * reported, exec lpstat -d which has all the Apple + * special behaviour for this built in. + */ + if (UnixPrintServiceLookup.isMac()) { + return UnixPrintServiceLookup. + getDefaultPrinterNameSysV(); + } else { + return null; + } } AttributeClass attribClass = (AttributeClass)
--- a/src/solaris/classes/sun/print/UnixPrintJob.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/solaris/classes/sun/print/UnixPrintJob.java Wed Jun 27 12:54:48 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -42,6 +42,7 @@ import java.io.Reader; import java.io.StringWriter; import java.io.UnsupportedEncodingException; +import java.nio.file.Files; import java.util.Vector; import javax.print.CancelablePrintJob; @@ -938,7 +939,7 @@ * is not removed for some reason, request that it is * removed when the VM exits. */ - spoolFile = File.createTempFile("javaprint", ".ps", null); + spoolFile = Files.createTempFile("javaprint", ".ps").toFile(); spoolFile.deleteOnExit(); } result = new FileOutputStream(spoolFile);
--- a/src/solaris/classes/sun/print/UnixPrintServiceLookup.java Tue Jun 26 17:29:10 2012 +0400 +++ b/src/solaris/classes/sun/print/UnixPrintServiceLookup.java Wed Jun 27 12:54:48 2012 -0700 @@ -51,6 +51,7 @@ import java.io.File; import java.io.FileReader; import java.net.URL; +import java.nio.file.Files; /* * Remind: This class uses solaris commands. We also need a linux @@ -114,6 +115,10 @@ new sun.security.action.GetPropertyAction("os.name")); } + static boolean isMac() { + return osname.startsWith("Mac"); + } + static boolean isSysV() { return osname.equals("SunOS"); } @@ -212,7 +217,7 @@ } } } else { - if (isSysV()) { + if (isMac() || isSysV()) { printers = getAllPrinterNamesSysV(); } else { //BSD printers = getAllPrinterNamesBSD(); @@ -361,7 +366,7 @@ if (name == null || name.equals("") || !checkPrinterName(name)) { return null; } - if (isSysV()) { + if (isMac() || isSysV()) { printer = getNamedPrinterNameSysV(name); } else { printer = getNamedPrinterNameBSD(name); @@ -523,7 +528,7 @@ if (CUPSPrinter.isCupsRunning()) { defaultPrinter = CUPSPrinter.getDefaultPrinter(); } else { - if (isSysV()) { + if (isMac() || isSysV()) { defaultPrinter = getDefaultPrinterNameSysV(); } else { defaultPrinter = getDefaultPrinterNameBSD(); @@ -644,7 +649,7 @@ return names; } - private String getDefaultPrinterNameSysV() { + static String getDefaultPrinterNameSysV() { String defaultPrinter = "lp"; String command = "/usr/bin/lpstat -d"; @@ -714,7 +719,7 @@ Process proc; BufferedReader bufferedReader = null; - File f = File.createTempFile("prn","xc"); + File f = Files.createTempFile("prn","xc").toFile(); cmd[2] = cmd[2]+">"+f.getAbsolutePath(); proc = Runtime.getRuntime().exec(cmd);
--- a/src/solaris/demo/jvmti/hprof/hprof_md.c Tue Jun 26 17:29:10 2012 +0400 +++ b/src/solaris/demo/jvmti/hprof/hprof_md.c Wed Jun 27 12:54:48 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/src/solaris/native/java/net/net_util_md.c Tue Jun 26 17:29:10 2012 +0400 +++ b/src/solaris/native/java/net/net_util_md.c Wed Jun 27 12:54:48 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -76,7 +76,7 @@ getnameinfo_f getnameinfo_ptr = NULL; /* - * EXCLBIND socket options only on Solaris 8 & 9. + * EXCLBIND socket options only on Solaris */ #if defined(__solaris__) && !defined(TCP_EXCLBIND) #define TCP_EXCLBIND 0x21 @@ -131,6 +131,7 @@ static int init_tcp_max_buf, init_udp_max_buf; static int tcp_max_buf; static int udp_max_buf; +static int useExclBind = 0; /* * Get the specified parameter from the specified driver. The value @@ -765,6 +766,26 @@ #endif +void parseExclusiveBindProperty(JNIEnv *env) { +#ifdef __solaris__ + jstring s, flagSet; + jclass iCls; + jmethodID mid; + + s = (*env)->NewStringUTF(env, "sun.net.useExclusiveBind"); + CHECK_NULL(s); + iCls = (*env)->FindClass(env, "java/lang/System"); + CHECK_NULL(iCls); + mid = (*env)->GetStaticMethodID(env, iCls, "getProperty", + "(Ljava/lang/String;)Ljava/lang/String;"); + CHECK_NULL(mid); + flagSet = (*env)->CallStaticObjectMethod(env, iCls, mid, s); + if (flagSet != NULL) { + useExclBind = 1; + } +#endif +} + /* In the case of an IPv4 Inetaddress this method will return an * IPv4 mapped address where IPv6 is available and v4MappedAddress is TRUE. * Otherwise it will return a sockaddr_in structure for an IPv4 InetAddress. @@ -1478,8 +1499,8 @@ * Linux allows a socket to bind to 127.0.0.255 which must be * caught. * - * On Solaris 8/9 with IPv6 enabled we must use an exclusive - * bind to guaranteed a unique port number across the IPv4 and + * On Solaris with IPv6 enabled we must use an exclusive + * bind to guarantee a unique port number across the IPv4 and * IPv6 port spaces. * */ @@ -1509,10 +1530,10 @@ #if defined(__solaris__) && defined(AF_INET6) /* - * Solaris 8/9 have seperate IPv4 and IPv6 port spaces so we + * Solaris has separate IPv4 and IPv6 port spaces so we * use an exclusive bind when SO_REUSEADDR is not used to * give the illusion of a unified port space. - * This also avoid problems with IPv6 sockets connecting + * This also avoids problems with IPv6 sockets connecting * to IPv4 mapped addresses whereby the socket conversion * results in a late bind that fails because the * corresponding IPv4 port is in use. @@ -1521,11 +1542,12 @@ int arg, len; len = sizeof(arg); - if (getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&arg, - &len) == 0) { - if (arg == 0) { + if (useExclBind || getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, + (char *)&arg, &len) == 0) { + if (useExclBind || arg == 0) { /* - * SO_REUSEADDR is disabled so enable TCP_EXCLBIND or + * SO_REUSEADDR is disabled or sun.net.useExclusiveBind + * property is true so enable TCP_EXCLBIND or * UDP_EXCLBIND */ len = sizeof(arg);
--- a/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c Tue Jun 26 17:29:10 2012 +0400 +++ b/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c Wed Jun 27 12:54:48 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/src/solaris/native/sun/nio/ch/IOUtil.c Tue Jun 26 17:29:10 2012 +0400 +++ b/src/solaris/native/sun/nio/ch/IOUtil.c Wed Jun 27 12:54:48 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/src/windows/native/java/net/net_util_md.c Tue Jun 26 17:29:10 2012 +0400 +++ b/src/windows/native/java/net/net_util_md.c Wed Jun 27 12:54:48 2012 -0700 @@ -126,6 +126,7 @@ } void initLocalAddrTable () {} +void parseExclusiveBindProperty (JNIEnv *env) {} /* * Since winsock doesn't have the equivalent of strerror(errno)
--- a/src/windows/native/sun/net/www/protocol/http/ntlm/NTLMAuthSequence.c Tue Jun 26 17:29:10 2012 +0400 +++ b/src/windows/native/sun/net/www/protocol/http/ntlm/NTLMAuthSequence.c Wed Jun 27 12:54:48 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/src/windows/native/sun/nio/ch/IOUtil.c Tue Jun 26 17:29:10 2012 +0400 +++ b/src/windows/native/sun/nio/ch/IOUtil.c Wed Jun 27 12:54:48 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/src/windows/native/sun/nio/ch/SocketDispatcher.c Tue Jun 26 17:29:10 2012 +0400 +++ b/src/windows/native/sun/nio/ch/SocketDispatcher.c Wed Jun 27 12:54:48 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/src/windows/native/sun/nio/ch/nio_util.h Tue Jun 26 17:29:10 2012 +0400 +++ b/src/windows/native/sun/nio/ch/nio_util.h Wed Jun 27 12:54:48 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/test/ProblemList.txt Tue Jun 26 17:29:10 2012 +0400 +++ b/test/ProblemList.txt Wed Jun 27 12:54:48 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/invoke/AccessControlTest.java Wed Jun 27 12:54:48 2012 -0700 @@ -0,0 +1,495 @@ +/* + * 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. + */ + +/* @test + * @summary test access checking by java.lang.invoke.MethodHandles.Lookup + * @library ../../../.. + * @build test.java.lang.invoke.AccessControlTest + * @build test.java.lang.invoke.AccessControlTest_subpkg.Acquaintance_remote + * @run junit/othervm test.java.lang.invoke.AccessControlTest + */ + +package test.java.lang.invoke; + +import java.lang.invoke.*; +import java.lang.reflect.*; +import java.util.*; +import org.junit.*; + +import static java.lang.invoke.MethodHandles.*; +import static java.lang.invoke.MethodHandles.Lookup.*; +import static java.lang.invoke.MethodType.*; +import static org.junit.Assert.*; +import test.java.lang.invoke.AccessControlTest_subpkg.Acquaintance_remote; + + +/** + * Test many combinations of Lookup access and cross-class lookupStatic. + * @author jrose + */ +public class AccessControlTest { + static final Class<?> THIS_CLASS = AccessControlTest.class; + // How much output? + static int verbosity = 0; + static { + String vstr = System.getProperty(THIS_CLASS.getSimpleName()+".verbosity"); + if (vstr == null) + vstr = System.getProperty(THIS_CLASS.getName()+".verbosity"); + if (vstr != null) verbosity = Integer.parseInt(vstr); + } + + private class LookupCase implements Comparable<LookupCase> { + final Lookup lookup; + final Class<?> lookupClass; + final int lookupModes; + public LookupCase(Lookup lookup) { + this.lookup = lookup; + this.lookupClass = lookup.lookupClass(); + this.lookupModes = lookup.lookupModes(); + assert(lookupString().equals(lookup.toString())); + numberOf(lookupClass().getClassLoader()); // assign CL# + } + public LookupCase(Class<?> lookupClass, int lookupModes) { + this.lookup = null; + this.lookupClass = lookupClass; + this.lookupModes = lookupModes; + numberOf(lookupClass().getClassLoader()); // assign CL# + } + + public final Class<?> lookupClass() { return lookupClass; } + public final int lookupModes() { return lookupModes; } + + public Lookup lookup() { lookup.getClass(); return lookup; } + + @Override + public int compareTo(LookupCase that) { + Class<?> c1 = this.lookupClass(); + Class<?> c2 = that.lookupClass(); + if (c1 != c2) { + int cmp = c1.getName().compareTo(c2.getName()); + if (cmp != 0) return cmp; + cmp = numberOf(c1.getClassLoader()) - numberOf(c2.getClassLoader()); + assert(cmp != 0); + return cmp; + } + return -(this.lookupModes() - that.lookupModes()); + } + + @Override + public boolean equals(Object that) { + return (that instanceof LookupCase && equals((LookupCase)that)); + } + public boolean equals(LookupCase that) { + return (this.lookupClass() == that.lookupClass() && + this.lookupModes() == that.lookupModes()); + } + + @Override + public int hashCode() { + return lookupClass().hashCode() + (lookupModes() * 31); + } + + /** Simulate all assertions in the spec. for Lookup.toString. */ + private String lookupString() { + String name = lookupClass.getName(); + String suffix = ""; + if (lookupModes == 0) + suffix = "/noaccess"; + else if (lookupModes == PUBLIC) + suffix = "/public"; + else if (lookupModes == (PUBLIC|PACKAGE)) + suffix = "/package"; + else if (lookupModes == (PUBLIC|PACKAGE|PRIVATE)) + suffix = "/private"; + else if (lookupModes == (PUBLIC|PACKAGE|PRIVATE|PROTECTED)) + suffix = ""; + else + suffix = "/#"+Integer.toHexString(lookupModes); + return name+suffix; + } + + /** Simulate all assertions from the spec. for Lookup.in: + * <hr/> + * Creates a lookup on the specified new lookup class. + * [A1] The resulting object will report the specified + * class as its own {@link #lookupClass lookupClass}. + * <p> + * [A2] However, the resulting {@code Lookup} object is guaranteed + * to have no more access capabilities than the original. + * In particular, access capabilities can be lost as follows:<ul> + * <li>[A3] If the new lookup class differs from the old one, + * protected members will not be accessible by virtue of inheritance. + * (Protected members may continue to be accessible because of package sharing.) + * <li>[A4] If the new lookup class is in a different package + * than the old one, protected and default (package) members will not be accessible. + * <li>[A5] If the new lookup class is not within the same package member + * as the old one, private members will not be accessible. + * <li>[A6] If the new lookup class is not accessible to the old lookup class, + * using the original access modes, + * then no members, not even public members, will be accessible. + * [A7] (In all other cases, public members will continue to be accessible.) + * </ul> + * Other than the above cases, the new lookup will have the same + * access capabilities as the original. [A8] + * <hr/> + */ + public LookupCase in(Class<?> c2) { + Class<?> c1 = lookupClass(); + int m1 = lookupModes(); + int changed = 0; + boolean samePackage = (c1.getClassLoader() == c2.getClassLoader() && + packagePrefix(c1).equals(packagePrefix(c2))); + boolean sameTopLevel = (topLevelClass(c1) == topLevelClass(c2)); + boolean sameClass = (c1 == c2); + assert(samePackage || !sameTopLevel); + assert(sameTopLevel || !sameClass); + boolean accessible = sameClass; // [A6] + if ((m1 & PACKAGE) != 0) accessible |= samePackage; + if ((m1 & PUBLIC ) != 0) accessible |= (c2.getModifiers() & PUBLIC) != 0; + if (!accessible) { + // Different package and no access to c2; lose all access. + changed |= (PUBLIC|PACKAGE|PRIVATE|PROTECTED); // [A6] + } + if (!samePackage) { + // Different package; lose PACKAGE and lower access. + changed |= (PACKAGE|PRIVATE|PROTECTED); // [A4] + } + if (!sameTopLevel) { + // Different top-level class. Lose PRIVATE and lower access. + changed |= (PRIVATE|PROTECTED); // [A5] + } + if (!sameClass) { + changed |= (PROTECTED); // [A3] + } else { + assert(changed == 0); // [A8] (no deprivation if same class) + } + if (accessible) assert((changed & PUBLIC) == 0); // [A7] + int m2 = m1 & ~changed; + LookupCase l2 = new LookupCase(c2, m2); + assert(l2.lookupClass() == c2); // [A1] + assert((m1 | m2) == m1); // [A2] (no elevation of access) + return l2; + } + + @Override + public String toString() { + String s = lookupClass().getSimpleName(); + String lstr = lookupString(); + int sl = lstr.indexOf('/'); + if (sl >= 0) s += lstr.substring(sl); + ClassLoader cld = lookupClass().getClassLoader(); + if (cld != THIS_LOADER) s += "/loader#"+numberOf(cld); + return s; + } + + /** Predict the success or failure of accessing this method. */ + public boolean willAccess(Method m) { + Class<?> c1 = lookupClass(); + Class<?> c2 = m.getDeclaringClass(); + LookupCase lc = this.in(c2); + int m1 = lc.lookupModes(); + int m2 = fixMods(m.getModifiers()); + // privacy is strictly enforced on lookups + if (c1 != c2) m1 &= ~PRIVATE; + // protected access is sometimes allowed + if ((m2 & PROTECTED) != 0) { + int prev = m2; + m2 |= PACKAGE; // it acts like a package method also + if ((lookupModes() & PROTECTED) != 0 && + c2.isAssignableFrom(c1)) + m2 |= PUBLIC; // from a subclass, it acts like a public method also + } + if (verbosity >= 2) + System.out.println(this+" willAccess "+lc+" m1="+m1+" m2="+m2+" => "+((m2 & m1) != 0)); + return (m2 & m1) != 0; + } + } + + private static Class<?> topLevelClass(Class<?> cls) { + Class<?> c = cls; + for (Class<?> ec; (ec = c.getEnclosingClass()) != null; ) + c = ec; + assert(c.getEnclosingClass() == null); + assert(c == cls || cls.getEnclosingClass() != null); + return c; + } + + private static String packagePrefix(Class<?> c) { + while (c.isArray()) c = c.getComponentType(); + String s = c.getName(); + assert(s.indexOf('/') < 0); + return s.substring(0, s.lastIndexOf('.')+1); + } + + + private final TreeSet<LookupCase> CASES = new TreeSet<>(); + private final TreeMap<LookupCase,TreeSet<LookupCase>> CASE_EDGES = new TreeMap<>(); + private final ArrayList<ClassLoader> LOADERS = new ArrayList<>(); + private final ClassLoader THIS_LOADER = this.getClass().getClassLoader(); + { if (THIS_LOADER != null) LOADERS.add(THIS_LOADER); } // #1 + + private LookupCase lookupCase(String name) { + for (LookupCase lc : CASES) { + if (lc.toString().equals(name)) + return lc; + } + throw new AssertionError(name); + } + + private int numberOf(ClassLoader cl) { + if (cl == null) return 0; + int i = LOADERS.indexOf(cl); + if (i < 0) { + i = LOADERS.size(); + LOADERS.add(cl); + } + return i+1; + } + + private void addLookupEdge(LookupCase l1, Class<?> c2, LookupCase l2) { + TreeSet<LookupCase> edges = CASE_EDGES.get(l2); + if (edges == null) CASE_EDGES.put(l2, edges = new TreeSet<>()); + if (edges.add(l1)) { + Class<?> c1 = l1.lookupClass(); + assert(l2.lookupClass() == c2); // [A1] + int m1 = l1.lookupModes(); + int m2 = l2.lookupModes(); + assert((m1 | m2) == m1); // [A2] (no elevation of access) + LookupCase expect = l1.in(c2); + if (!expect.equals(l2)) + System.out.println("*** expect "+l1+" => "+expect+" but got "+l2); + assertEquals(expect, l2); + } + } + + private void makeCases(Lookup[] originalLookups) { + // make initial set of lookup test cases + CASES.clear(); LOADERS.clear(); CASE_EDGES.clear(); + ArrayList<Class<?>> classes = new ArrayList<>(); + for (Lookup l : originalLookups) { + CASES.add(new LookupCase(l)); + classes.remove(l.lookupClass()); // no dups please + classes.add(l.lookupClass()); + } + System.out.println("loaders = "+LOADERS); + int rounds = 0; + for (int lastCount = -1; lastCount != CASES.size(); ) { + lastCount = CASES.size(); // if CASES grow in the loop we go round again + for (LookupCase lc1 : CASES.toArray(new LookupCase[0])) { + for (Class<?> c2 : classes) { + LookupCase lc2 = new LookupCase(lc1.lookup().in(c2)); + addLookupEdge(lc1, c2, lc2); + CASES.add(lc2); + } + } + rounds++; + } + System.out.println("filled in "+CASES.size()+" cases from "+originalLookups.length+" original cases in "+rounds+" rounds"); + if (false) { + System.out.println("CASES: {"); + for (LookupCase lc : CASES) { + System.out.println(lc); + Set<LookupCase> edges = CASE_EDGES.get(lc); + if (edges != null) + for (LookupCase prev : edges) { + System.out.println("\t"+prev); + } + } + System.out.println("}"); + } + } + + @Test public void test() { + makeCases(lookups()); + if (verbosity > 0) { + verbosity += 9; + Method pro_in_self = targetMethod(THIS_CLASS, PROTECTED, methodType(void.class)); + testOneAccess(lookupCase("AccessControlTest/public"), pro_in_self, "find"); + testOneAccess(lookupCase("Remote_subclass/public"), pro_in_self, "find"); + testOneAccess(lookupCase("Remote_subclass"), pro_in_self, "find"); + verbosity -= 9; + } + Set<Class<?>> targetClassesDone = new HashSet<>(); + for (LookupCase targetCase : CASES) { + Class<?> targetClass = targetCase.lookupClass(); + if (!targetClassesDone.add(targetClass)) continue; // already saw this one + String targetPlace = placeName(targetClass); + if (targetPlace == null) continue; // Object, String, not a target + for (int targetAccess : ACCESS_CASES) { + MethodType methodType = methodType(void.class); + Method method = targetMethod(targetClass, targetAccess, methodType); + // Try to access target method from various contexts. + for (LookupCase sourceCase : CASES) { + testOneAccess(sourceCase, method, "find"); + testOneAccess(sourceCase, method, "unreflect"); + } + } + } + System.out.println("tested "+testCount+" access scenarios; "+testCountFails+" accesses were denied"); + } + + private int testCount, testCountFails; + + private void testOneAccess(LookupCase sourceCase, Method method, String kind) { + Class<?> targetClass = method.getDeclaringClass(); + String methodName = method.getName(); + MethodType methodType = methodType(method.getReturnType(), method.getParameterTypes()); + boolean willAccess = sourceCase.willAccess(method); + boolean didAccess = false; + ReflectiveOperationException accessError = null; + try { + switch (kind) { + case "find": + if ((method.getModifiers() & Modifier.STATIC) != 0) + sourceCase.lookup().findStatic(targetClass, methodName, methodType); + else + sourceCase.lookup().findVirtual(targetClass, methodName, methodType); + break; + case "unreflect": + sourceCase.lookup().unreflect(method); + break; + default: + throw new AssertionError(kind); + } + didAccess = true; + } catch (ReflectiveOperationException ex) { + accessError = ex; + } + if (willAccess != didAccess) { + System.out.println(sourceCase+" => "+targetClass.getSimpleName()+"."+methodName+methodType); + System.out.println("fail on "+method+" ex="+accessError); + assertEquals(willAccess, didAccess); + } + testCount++; + if (!didAccess) testCountFails++; + } + + static Method targetMethod(Class<?> targetClass, int targetAccess, MethodType methodType) { + String methodName = accessName(targetAccess)+placeName(targetClass); + if (verbosity >= 2) + System.out.println(targetClass.getSimpleName()+"."+methodName+methodType); + try { + Method method = targetClass.getDeclaredMethod(methodName, methodType.parameterArray()); + assertEquals(method.getReturnType(), methodType.returnType()); + int haveMods = method.getModifiers(); + assert(Modifier.isStatic(haveMods)); + assert(targetAccess == fixMods(haveMods)); + return method; + } catch (NoSuchMethodException ex) { + throw new AssertionError(methodName, ex); + } + } + + static String placeName(Class<?> cls) { + // return "self", "sibling", "nestmate", etc. + if (cls == AccessControlTest.class) return "self"; + String cln = cls.getSimpleName(); + int under = cln.lastIndexOf('_'); + if (under < 0) return null; + return cln.substring(under+1); + } + static String accessName(int acc) { + switch (acc) { + case PUBLIC: return "pub_in_"; + case PROTECTED: return "pro_in_"; + case PACKAGE: return "pkg_in_"; + case PRIVATE: return "pri_in_"; + } + assert(false); + return "?"; + } + private static final int[] ACCESS_CASES = { + PUBLIC, PACKAGE, PRIVATE, PROTECTED + }; + /** Return one of the ACCESS_CASES. */ + static int fixMods(int mods) { + mods &= (PUBLIC|PRIVATE|PROTECTED); + switch (mods) { + case PUBLIC: case PRIVATE: case PROTECTED: return mods; + case 0: return PACKAGE; + } + throw new AssertionError(mods); + } + + static Lookup[] lookups() { + ArrayList<Lookup> tem = new ArrayList<>(); + Collections.addAll(tem, + AccessControlTest.lookup_in_self(), + Inner_nestmate.lookup_in_nestmate(), + AccessControlTest_sibling.lookup_in_sibling()); + if (true) { + Collections.addAll(tem,Acquaintance_remote.lookups()); + } else { + try { + Class<?> remc = Class.forName("test.java.lang.invoke.AccessControlTest_subpkg.Acquaintance_remote"); + Lookup[] remls = (Lookup[]) remc.getMethod("lookups").invoke(null); + Collections.addAll(tem, remls); + } catch (ReflectiveOperationException ex) { + throw new LinkageError("reflection failed", ex); + } + } + tem.add(publicLookup()); + tem.add(publicLookup().in(String.class)); + tem.add(publicLookup().in(List.class)); + return tem.toArray(new Lookup[0]); + } + + static Lookup lookup_in_self() { + return MethodHandles.lookup(); + } + static public void pub_in_self() { } + static protected void pro_in_self() { } + static /*package*/ void pkg_in_self() { } + static private void pri_in_self() { } + + static class Inner_nestmate { + static Lookup lookup_in_nestmate() { + return MethodHandles.lookup(); + } + static public void pub_in_nestmate() { } + static protected void pro_in_nestmate() { } + static /*package*/ void pkg_in_nestmate() { } + static private void pri_in_nestmate() { } + } +} +class AccessControlTest_sibling { + static Lookup lookup_in_sibling() { + return MethodHandles.lookup(); + } + static public void pub_in_sibling() { } + static protected void pro_in_sibling() { } + static /*package*/ void pkg_in_sibling() { } + static private void pri_in_sibling() { } +} + +// This guy tests access from outside the package: +/* +package test.java.lang.invoke.AccessControlTest_subpkg; +public class Acquaintance_remote { + public static Lookup[] lookups() { ... + } + ... +} +*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/invoke/AccessControlTest_subpkg/Acquaintance_remote.java Wed Jun 27 12:54:48 2012 -0700 @@ -0,0 +1,42 @@ +package test.java.lang.invoke.AccessControlTest_subpkg; +import test.java.lang.invoke.AccessControlTest; +import java.lang.invoke.*; +import static java.lang.invoke.MethodHandles.*; + +// This guy tests access from outside the package test.java.lang.invoke: +public class Acquaintance_remote { + public static Lookup[] lookups() { + return new Lookup[] { + Acquaintance_remote.lookup_in_remote(), + Remote_subclass.lookup_in_subclass(), + Remote_hidden.lookup_in_hidden() + }; + } + + public static Lookup lookup_in_remote() { + return MethodHandles.lookup(); + } + static public void pub_in_remote() { } + static protected void pro_in_remote() { } + static /*package*/ void pkg_in_remote() { } + static private void pri_in_remote() { } + + static public class Remote_subclass extends AccessControlTest { + static Lookup lookup_in_subclass() { + return MethodHandles.lookup(); + } + static public void pub_in_subclass() { } + static protected void pro_in_subclass() { } + static /*package*/ void pkg_in_subclass() { } + static private void pri_in_subclass() { } + } + static /*package*/ class Remote_hidden { + static Lookup lookup_in_hidden() { + return MethodHandles.lookup(); + } + static public void pub_in_hidden() { } + static protected void pro_in_hidden() { } + static /*package*/ void pkg_in_hidden() { } + static private void pri_in_hidden() { } + } +}
--- a/test/java/net/Socket/setReuseAddress/Basic.java Tue Jun 26 17:29:10 2012 +0400 +++ b/test/java/net/Socket/setReuseAddress/Basic.java Wed Jun 27 12:54:48 2012 -0700 @@ -26,6 +26,8 @@ * @bug 4476378 * @summary Check the specific behaviour of the setReuseAddress(boolean) * method. + * @run main Basic + * @run main/othervm -Dsun.net.useExclusiveBind Basic */ import java.net.*; @@ -170,7 +172,12 @@ s2.bind( new InetSocketAddress(s1.getLocalPort()) ); passed(); } catch (BindException e) { - failed(); + if (System.getProperty("sun.net.useExclusiveBind") != null) { + // exclusive bind enabled - expected result + passed(); + } else { + failed(); + } } s2.close();
--- a/test/java/net/Socket/setReuseAddress/Restart.java Tue Jun 26 17:29:10 2012 +0400 +++ b/test/java/net/Socket/setReuseAddress/Restart.java Wed Jun 27 12:54:48 2012 -0700 @@ -26,6 +26,8 @@ * @bug 4476378 * @summary Check that SO_REUSEADDR allows a server to restart * after a crash. + * @run main Restart + * @run main/othervm -Dsun.net.useExclusiveBind Restart */ import java.net.*; @@ -57,6 +59,12 @@ // close the client socket s1.close(); + } catch (BindException be) { + if (System.getProperty("sun.net.useExclusiveBind") != null) { + // exclusive bind, expected exception + } else { + throw be; + } } finally { if (ss != null) ss.close(); if (s1 != null) s1.close();
--- a/test/java/nio/channels/AsyncCloseAndInterrupt.java Tue Jun 26 17:29:10 2012 +0400 +++ b/test/java/nio/channels/AsyncCloseAndInterrupt.java Wed Jun 27 12:54:48 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/test/java/nio/channels/SocketChannel/AdaptSocket.java Tue Jun 26 17:29:10 2012 +0400 +++ b/test/java/nio/channels/SocketChannel/AdaptSocket.java Wed Jun 27 12:54:48 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/test/java/nio/channels/SocketChannel/CloseDuringWrite.java Wed Jun 27 12:54:48 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/test/java/nio/channels/SocketChannel/ShortWrite.java Wed Jun 27 12:54:48 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/test/java/nio/channels/TestUtil.java Tue Jun 26 17:29:10 2012 +0400 +++ b/test/java/nio/channels/TestUtil.java Wed Jun 27 12:54:48 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/test/java/security/cert/CertPathBuilder/zeroLengthPath/ZeroLengthPath.java Wed Jun 27 12:54:48 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/test/java/util/Map/Collisions.java Tue Jun 26 17:29:10 2012 +0400 +++ b/test/java/util/Map/Collisions.java Wed Jun 27 12:54:48 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/test/java/util/spi/ResourceBundleControlProvider/UserDefaultControlTest.java Wed Jun 27 12:54:48 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/test/java/util/spi/ResourceBundleControlProvider/UserDefaultControlTest.sh Wed Jun 27 12:54:48 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/test/java/util/spi/ResourceBundleControlProvider/providersrc/Makefile Wed Jun 27 12:54:48 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/test/java/util/spi/ResourceBundleControlProvider/providersrc/UserControlProvider.java Wed Jun 27 12:54:48 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/test/java/util/spi/ResourceBundleControlProvider/providersrc/UserXMLControl.java Wed Jun 27 12:54:48 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/test/java/util/spi/ResourceBundleControlProvider/providersrc/XmlRB.xml Wed Jun 27 12:54:48 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/test/java/util/spi/ResourceBundleControlProvider/providersrc/XmlRB_ja.xml Wed Jun 27 12:54:48 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">Xï¼ï¼¬</entry> +</properties>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/util/spi/ResourceBundleControlProvider/providersrc/java.util.spi.ResourceBundleControlProvider Wed Jun 27 12:54:48 2012 -0700 @@ -0,0 +1,1 @@ +com.foo.UserControlProvider
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/swing/plaf/synth/7143614/bug7143614.java Wed Jun 27 12:54:48 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 + * @bug 7143614 + * @summary Issues with Synth Look&Feel + * @author Pavel Porvatov + */ + +import sun.awt.SunToolkit; + +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.basic.BasicButtonUI; +import javax.swing.plaf.synth.SynthConstants; +import javax.swing.plaf.synth.SynthLookAndFeel; +import java.lang.reflect.Method; + +public class bug7143614 { + private static Method setSelectedUIMethod; + + private static ComponentUI componentUI = new BasicButtonUI(); + + public static void main(String[] args) throws Exception { + setSelectedUIMethod = SynthLookAndFeel.class.getDeclaredMethod("setSelectedUI", ComponentUI.class, + boolean.class, boolean.class, boolean.class, boolean.class); + setSelectedUIMethod.setAccessible(true); + + setSelectedUIMethod.invoke(null, componentUI, true, true, true, true); + + validate(); + + Thread thread = new ThreadInAnotherAppContext(); + + thread.start(); + thread.join(); + + validate(); + + System.out.println("Test bug7143614 passed."); + } + + private static void validate() throws Exception { + Method getSelectedUIMethod = SynthLookAndFeel.class.getDeclaredMethod("getSelectedUI"); + + getSelectedUIMethod.setAccessible(true); + + Method getSelectedUIStateMethod = SynthLookAndFeel.class.getDeclaredMethod("getSelectedUIState"); + + getSelectedUIStateMethod.setAccessible(true); + + if (getSelectedUIMethod.invoke(null) != componentUI) { + throw new RuntimeException("getSelectedUI returns invalid value"); + } + if (((Integer) getSelectedUIStateMethod.invoke(null)).intValue() != + (SynthConstants.SELECTED | SynthConstants.FOCUSED)) { + throw new RuntimeException("getSelectedUIState returns invalid value"); + } + + } + + private static class ThreadInAnotherAppContext extends Thread { + public ThreadInAnotherAppContext() { + super(new ThreadGroup("7143614"), "ThreadInAnotherAppContext"); + } + + public void run() { + SunToolkit.createNewAppContext(); + + try { + setSelectedUIMethod.invoke(null, null, false, false, false, false); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/misc/JarIndex/JarIndexMergeForClassLoaderTest.java Wed Jun 27 12:54:48 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/test/sun/misc/JarIndex/JarIndexMergeTest.java Wed Jun 27 12:54:48 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/test/sun/security/krb5/auto/TcpTimeout.java Tue Jun 26 17:29:10 2012 +0400 +++ b/test/sun/security/krb5/auto/TcpTimeout.java Wed Jun 27 12:54:48 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(); } } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/x509/X509CRLImpl/OrderAndDup.java Wed Jun 27 12:54:48 2012 -0700 @@ -0,0 +1,99 @@ +/* + * 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 7143872 + * @summary Improve certificate extension processing + */ +import java.io.ByteArrayInputStream; +import java.math.BigInteger; +import java.security.KeyPairGenerator; +import java.security.cert.CertificateFactory; +import java.security.cert.X509CRLEntry; +import java.util.Date; +import sun.security.util.DerInputStream; +import sun.security.util.DerValue; +import sun.security.x509.*; + +public class OrderAndDup { + public static void main(String[] args) throws Exception { + + // Generate 20 serial numbers with dup and a special order + int count = 20; + BigInteger[] serials = new BigInteger[count]; + for (int i=0; i<count; i++) { + serials[i] = BigInteger.valueOf(i*7%10); + } + + // Generates a CRL + X509CRLEntry[] badCerts = new X509CRLEntry[count]; + for (int i=0; i<count; i++) { + badCerts[i] = new X509CRLEntryImpl(serials[i], + new Date(System.currentTimeMillis()+i*1000)); + } + X500Name owner = new X500Name("CN=CA"); + X509CRLImpl crl = new X509CRLImpl(owner, new Date(), new Date(), badCerts); + KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); + crl.sign(kpg.genKeyPair().getPrivate(), "SHA1withRSA"); + byte[] data = crl.getEncodedInternal(); + + // Check the encoding + checkData(crl, data, serials); + + // Load a CRL from raw data + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + X509CRLImpl crl2 = (X509CRLImpl)cf.generateCRL(new ByteArrayInputStream(data)); + + // Check the encoding again + data = crl2.getEncodedInternal(); + checkData(crl2, data, serials); + } + + // Check the raw data's ASN.1 structure to see if the revoked certs + // have the same number and correct order as inserted + static void checkData(X509CRLImpl c, byte[] data, BigInteger[] expected) + throws Exception { + if (c.getRevokedCertificates().size() != expected.length) { + throw new Exception("Wrong count in CRL object, now " + + c.getRevokedCertificates().size()); + } + DerValue d1 = new DerValue(data); + // revokedCertificates at 5th place of TBSCertList + DerValue[] d2 = new DerInputStream( + d1.data.getSequence(0)[4].toByteArray()) + .getSequence(0); + if (d2.length != expected.length) { + throw new Exception("Wrong count in raw data, now " + d2.length); + } + for (int i=0; i<d2.length; i++) { + // Serial is first in revokedCertificates entry + BigInteger bi = d2[i].data.getBigInteger(); + if (!bi.equals(expected[i])) { + throw new Exception("Entry at #" + i + " is " + bi + + ", should be " + expected[i]); + } + } + } +} +