From ed15f54cfbc4535041f799d2b15770057fc7962c Mon Sep 17 00:00:00 2001 From: Yuka Kamiya Date: Wed, 21 Apr 2010 10:34:56 +0900 Subject: [PATCH 01/38] 6943963: NumericShaper with ARABIC doesn't shape digits correctly after calling another instance Reviewed-by: okutsu --- .../classes/java/awt/font/NumericShaper.java | 8 +- .../java/awt/font/NumericShaper/MTTest.java | 51 +++++---- .../awt/font/NumericShaper/ShapingTest.java | 107 +++++++++++------- 3 files changed, 100 insertions(+), 66 deletions(-) diff --git a/jdk/src/share/classes/java/awt/font/NumericShaper.java b/jdk/src/share/classes/java/awt/font/NumericShaper.java index 75f4dbad751..6aff9cba920 100644 --- a/jdk/src/share/classes/java/awt/font/NumericShaper.java +++ b/jdk/src/share/classes/java/awt/font/NumericShaper.java @@ -1163,8 +1163,14 @@ public final class NumericShaper implements java.io.Serializable { lastkey = newkey; ctxKey = newkey; - if (((mask & EASTERN_ARABIC) != 0) && (ctxKey == ARABIC_KEY || ctxKey == EASTERN_ARABIC_KEY)) { + if (((mask & EASTERN_ARABIC) != 0) && + (ctxKey == ARABIC_KEY || + ctxKey == EASTERN_ARABIC_KEY)) { ctxKey = EASTERN_ARABIC_KEY; + } else if (((mask & ARABIC) != 0) && + (ctxKey == ARABIC_KEY || + ctxKey == EASTERN_ARABIC_KEY)) { + ctxKey = ARABIC_KEY; } else if ((mask & (1<."); + System.err.println(" text = " + given); + System.err.println(" got = " + got); + System.err.println(" expected = " + expected); + } else { + System.out.println("OK with range(s) <" + ranges + ">."); + System.out.println(" text = " + given); + System.out.println(" got = " + got); + System.out.println(" expected = " + expected); } } From dea5e42c57f5b6607456ac0a23cacc34a9528cb4 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Wed, 21 Apr 2010 12:24:56 +0100 Subject: [PATCH 02/38] 6730476: invalid "unchecked generic array" warning Reifiable-ness of varargs element type should be checked after JLS3 15.12.2.8 Reviewed-by: jjg --- .../com/sun/tools/javac/comp/Attr.java | 10 ++--- .../com/sun/tools/javac/comp/Check.java | 13 +++++++ .../com/sun/tools/javac/comp/Infer.java | 6 ++- .../com/sun/tools/javac/comp/Resolve.java | 3 +- .../javac/varargs/6730476/T6730476a.java | 39 +++++++++++++++++++ .../javac/varargs/6730476/T6730476b.java | 36 +++++++++++++++++ 6 files changed, 99 insertions(+), 8 deletions(-) create mode 100644 langtools/test/tools/javac/varargs/6730476/T6730476a.java create mode 100644 langtools/test/tools/javac/varargs/6730476/T6730476b.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index 214a9723003..0d3df466c64 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -2621,12 +2621,10 @@ public class Attr extends JCTree.Visitor { } if (useVarargs) { JCTree tree = env.tree; - Type argtype = owntype.getParameterTypes().last(); - if (!types.isReifiable(argtype)) - chk.warnUnchecked(env.tree.pos(), - "unchecked.generic.array.creation", - argtype); - Type elemtype = types.elemtype(argtype); + if (owntype.getReturnType().tag != FORALL || warned) { + chk.checkVararg(env.tree.pos(), owntype.getParameterTypes()); + } + Type elemtype = types.elemtype(owntype.getParameterTypes().last()); switch (tree.getTag()) { case JCTree.APPLY: ((JCMethodInvocation) tree).varargsElement = elemtype; diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index 44cf6a6e717..de05270d818 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -677,6 +677,19 @@ public class Check { } } + /** + * Check that vararg method call is sound + * @param pos Position to be used for error reporting. + * @param argtypes Actual arguments supplied to vararg method. + */ + void checkVararg(DiagnosticPosition pos, List argtypes) { + Type argtype = argtypes.last(); + if (!types.isReifiable(argtype)) + warnUnchecked(pos, + "unchecked.generic.array.creation", + argtype); + } + /** Check that given modifiers are legal for given symbol and * return modifiers together with any implicit modififiers for that symbol. * Warning: we can't use flags() here since this method diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java index 840a97de5ce..2856f734cb1 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java @@ -287,7 +287,8 @@ public class Infer { /** Instantiate method type `mt' by finding instantiations of * `tvars' so that method can be applied to `argtypes'. */ - public Type instantiateMethod(List tvars, + public Type instantiateMethod(final Env env, + List tvars, MethodType mt, final List argtypes, final boolean allowBoxing, @@ -416,6 +417,9 @@ public class Infer { // check that inferred bounds conform to their bounds checkWithinBounds(all_tvars, types.subst(inferredTypes, tvars, inferred), warn); + if (useVarargs) { + chk.checkVararg(env.tree.pos(), formals); + } return super.inst(inferred, types); }}; return mt2; diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java index c7a23e782ea..43503f15bbf 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -345,7 +345,8 @@ public class Resolve { if (instNeeded) return - infer.instantiateMethod(tvars, + infer.instantiateMethod(env, + tvars, (MethodType)mt, argtypes, allowBoxing, diff --git a/langtools/test/tools/javac/varargs/6730476/T6730476a.java b/langtools/test/tools/javac/varargs/6730476/T6730476a.java new file mode 100644 index 00000000000..7f44b1b4362 --- /dev/null +++ b/langtools/test/tools/javac/varargs/6730476/T6730476a.java @@ -0,0 +1,39 @@ +/* + * Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6730476 + * + * @summary invalid "unchecked generic array" warning + * @author mcimadamore + * @compile T6730476a.java -Xlint -Werror + * + */ + +class T6730476a { + void f(int i, T ... x) {} + void g() { + f(1); + } +} diff --git a/langtools/test/tools/javac/varargs/6730476/T6730476b.java b/langtools/test/tools/javac/varargs/6730476/T6730476b.java new file mode 100644 index 00000000000..5e38ba9e547 --- /dev/null +++ b/langtools/test/tools/javac/varargs/6730476/T6730476b.java @@ -0,0 +1,36 @@ +/* + * Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6730476 + * + * @summary invalid "unchecked generic array" warning + * @author mcimadamore + * @compile T6730476b.java -Xlint -Werror + * + */ + +class T6730476b { + java.util.List ints = java.util.Arrays.asList(); +} From f05dd156c2cb16c6c78ccdced90a625f11119c46 Mon Sep 17 00:00:00 2001 From: Pavel Porvatov Date: Wed, 21 Apr 2010 18:12:21 +0400 Subject: [PATCH 03/38] 6945316: The Win32ShellFolderManager2.isFileSystemRoot can throw NPE Reviewed-by: alexp --- .../awt/shell/Win32ShellFolderManager2.java | 11 ++- .../JFileChooser/6945316/bug6945316.java | 74 +++++++++++++++++++ 2 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 jdk/test/javax/swing/JFileChooser/6945316/bug6945316.java diff --git a/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java b/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java index b7639fa77bb..1a53198349f 100644 --- a/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java +++ b/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java @@ -403,9 +403,14 @@ public class Win32ShellFolderManager2 extends ShellFolderManager { } } String path = dir.getPath(); - return (path.length() == 3 - && path.charAt(1) == ':' - && Arrays.asList(drives.listFiles()).contains(dir)); + + if (path.length() != 3 || path.charAt(1) != ':') { + return false; + } + + File[] files = drives.listFiles(); + + return files != null && Arrays.asList(files).contains(dir); } return false; } diff --git a/jdk/test/javax/swing/JFileChooser/6945316/bug6945316.java b/jdk/test/javax/swing/JFileChooser/6945316/bug6945316.java new file mode 100644 index 00000000000..cc495f7a6db --- /dev/null +++ b/jdk/test/javax/swing/JFileChooser/6945316/bug6945316.java @@ -0,0 +1,74 @@ +/* + * Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* @test + @bug 6945316 + @summary The Win32ShellFolderManager2.isFileSystemRoot can throw NPE + @author Pavel Porvatov + @run main bug6945316 +*/ + +import sun.awt.OSInfo; +import sun.awt.shell.ShellFolder; + +import java.awt.*; +import java.io.File; +import java.util.concurrent.CountDownLatch; + +public class bug6945316 { + public static void main(String[] args) throws Exception { + if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) { + System.out.println("The test is suitable only for Windows OS. Skipped."); + + return; + } + + // Init toolkit because it shouldn't be interrupted while initialization + Toolkit.getDefaultToolkit(); + + // Init the sun.awt.shell.Win32ShellFolderManager2.drives field + ShellFolder.get("fileChooserComboBoxFolders"); + + // To get NPE the path must obey the following rules: + // path.length() == 3 && path.charAt(1) == ':' + final File tempFile = new File("c:\\"); + + for (int i = 0; i < 10000; i++) { + final CountDownLatch countDownLatch = new CountDownLatch(1); + + final Thread thread = new Thread() { + public void run() { + countDownLatch.countDown(); + + ShellFolder.isFileSystemRoot(tempFile); + } + }; + + thread.start(); + + countDownLatch.await(); + + thread.interrupt(); + } + } +} From 7cc72590c763920d35e8646ec04d00795fd16d0b Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Thu, 22 Apr 2010 12:45:36 +0800 Subject: [PATCH 04/38] 6856069: PrincipalName.clone() does not invoke super.clone() Reviewed-by: chegar --- .../sun/security/krb5/PrincipalName.java | 27 ++++++------ .../sun/security/krb5/ServiceNameClone.java | 41 +++++++++++++++++++ 2 files changed, 55 insertions(+), 13 deletions(-) create mode 100644 jdk/test/sun/security/krb5/ServiceNameClone.java diff --git a/jdk/src/share/classes/sun/security/krb5/PrincipalName.java b/jdk/src/share/classes/sun/security/krb5/PrincipalName.java index 6705fd63e9a..91d5d8bb395 100644 --- a/jdk/src/share/classes/sun/security/krb5/PrincipalName.java +++ b/jdk/src/share/classes/sun/security/krb5/PrincipalName.java @@ -1,5 +1,5 @@ /* - * Portions Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved. + * Portions Copyright 2000-2010 Sun Microsystems, Inc. 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 @@ -101,7 +101,7 @@ public class PrincipalName private Realm nameRealm; // optional; a null realm means use default // Note: the nameRealm is not included in the default ASN.1 encoding - // salt for principal + // cached salt, might be changed by KDC info, not used in clone private String salt = null; protected PrincipalName() { @@ -123,18 +123,19 @@ public class PrincipalName } public Object clone() { - PrincipalName pName = new PrincipalName(); - pName.nameType = nameType; - if (nameStrings != null) { - pName.nameStrings = - new String[nameStrings.length]; - System.arraycopy(nameStrings,0,pName.nameStrings,0, - nameStrings.length); + try { + PrincipalName pName = (PrincipalName) super.clone(); + // Re-assign mutable fields + if (nameStrings != null) { + pName.nameStrings = nameStrings.clone(); + } + if (nameRealm != null) { + pName.nameRealm = (Realm)nameRealm.clone(); + } + return pName; + } catch (CloneNotSupportedException ex) { + throw new AssertionError("Should never happen"); } - if (nameRealm != null) { - pName.nameRealm = (Realm)nameRealm.clone(); - } - return pName; } /* diff --git a/jdk/test/sun/security/krb5/ServiceNameClone.java b/jdk/test/sun/security/krb5/ServiceNameClone.java new file mode 100644 index 00000000000..282712c032a --- /dev/null +++ b/jdk/test/sun/security/krb5/ServiceNameClone.java @@ -0,0 +1,41 @@ +/* + * Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +/* + * @test + * @bug 6856069 + * @summary PrincipalName.clone() does not invoke super.clone() + */ + +import sun.security.krb5.ServiceName; + +public class ServiceNameClone { + public static void main(String[] args) throws Exception { + ServiceName sn = new ServiceName("me@HERE"); + if (sn.clone().getClass() != ServiceName.class) { + throw new Exception("ServiceName's clone is not a ServiceName"); + } + if (!sn.clone().equals(sn)) { + throw new Exception("ServiceName's clone changed"); + } + } +} From ba20286ba3efca1520fd4beae28da4f8353f70f7 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Sat, 24 Apr 2010 17:09:18 +0100 Subject: [PATCH 05/38] 6939646: Remove obsolete com.sun.corba.se.internal.io package Reviewed-by: ohair --- corba/make/sun/corba/Makefile | 3 +- corba/make/sun/corba/core/Makefile | 101 -- corba/make/sun/corba/core/mapfile-vers | 80 -- .../corba/se/internal/io/IIOPInputStream.java | 66 -- .../se/internal/io/IIOPOutputStream.java | 51 -- .../corba/se/internal/io/LibraryManager.java | 41 - .../se/internal/io/ObjectStreamClass.java | 33 - .../com/sun/corba/se/internal/io/ioser.c | 862 ------------------ 8 files changed, 1 insertion(+), 1236 deletions(-) delete mode 100644 corba/make/sun/corba/core/Makefile delete mode 100644 corba/make/sun/corba/core/mapfile-vers delete mode 100644 corba/src/share/classes/com/sun/corba/se/internal/io/IIOPInputStream.java delete mode 100644 corba/src/share/classes/com/sun/corba/se/internal/io/IIOPOutputStream.java delete mode 100644 corba/src/share/classes/com/sun/corba/se/internal/io/LibraryManager.java delete mode 100644 corba/src/share/classes/com/sun/corba/se/internal/io/ObjectStreamClass.java delete mode 100644 corba/src/share/native/com/sun/corba/se/internal/io/ioser.c diff --git a/corba/make/sun/corba/Makefile b/corba/make/sun/corba/Makefile index 9b14f4edd35..931f31b0793 100644 --- a/corba/make/sun/corba/Makefile +++ b/corba/make/sun/corba/Makefile @@ -30,8 +30,7 @@ BUILDDIR = ../.. include $(BUILDDIR)/common/Defs.gmk -SUBDIRS = org core +SUBDIRS = org all build clean clobber:: $(SUBDIRS-loop) - $(RM) -r $(CLASSBINDIR)/com/sun/corba/se/internal/io diff --git a/corba/make/sun/corba/core/Makefile b/corba/make/sun/corba/core/Makefile deleted file mode 100644 index ce1b875c197..00000000000 --- a/corba/make/sun/corba/core/Makefile +++ /dev/null @@ -1,101 +0,0 @@ -# -# Copyright 1997-2005 Sun Microsystems, Inc. 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. Sun designates this -# particular file as subject to the "Classpath" exception as provided -# by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -# CA 95054 USA or visit www.sun.com if you need additional information or -# have any questions. -# - -# -# Makefile for building RMI/IIOP -# - -BUILDDIR = ../../.. -PACKAGE = com.sun.corba.se.internal.io -PRODUCT = sun -LIBRARY = ioser12 -include $(BUILDDIR)/common/Defs.gmk - -# -# Use mapfile -# -FILES_m = mapfile-vers -include $(BUILDDIR)/common/Mapfile-vers.gmk - -# -# Files to compile. -# -CORBA_JMK_DIRECTORY=$(TOPDIR)/make/com/sun/corba/minclude/ -include $(CORBA_JMK_DIRECTORY)javax_rmi.jmk -include $(CORBA_JMK_DIRECTORY)javax_rmi_CORBA.jmk -include $(CORBA_JMK_DIRECTORY)javax_transaction.jmk -include $(CORBA_JMK_DIRECTORY)javax_activity.jmk -include $(CORBA_JMK_DIRECTORY)ioser_io.jmk -include $(CORBA_JMK_DIRECTORY)sun_corba.jmk - -ifdef STANDALONE_CORBA_WS -# FIXUP: What is this all about? -OTHER_LDFLAGS=-L$(BOOTDIR)/jre/lib/$(ARCH) -L$(BOOTDIR)/jre/lib/$(LIBARCH)/native_threads -ljvm -OTHER_INCLUDES+=-ICClassHeaders -I$(BOOTDIR)/include -I$(BOOTDIR)/include/$(PLATFORM) -else -OTHER_LDLIBS=$(JVMLIB) -OTHER_INCLUDES+=-ICClassHeaders -I$(BOOTDIR)/include -I$(BOOTDIR)/include/$(PLATFORM) -endif - - -FILES_c = ioser.c - -FILES_java = \ - $(javax_rmi_java) \ - $(javax_rmi_CORBA_java) \ - $(javax_transaction_java) \ - $(javax_activity_java) \ - $(IOSER_IO_java) \ - $(sun_corba_java) - -# -# Generate header files for. -# -FILES_export = \ - com/sun/corba/se/internal/io/IIOPInputStream.java \ - com/sun/corba/se/internal/io/IIOPOutputStream.java \ - com/sun/corba/se/internal/io/ObjectStreamClass.java \ - com/sun/corba/se/internal/io/LibraryManager.java -# -# Resources -# -LOCALE_SET_DEFINITION = jre -RESOURCE_BUNDLES_PROPERTIES = \ - com/sun/corba/se/impl/orbutil/resources/sunorb.properties - -# -# Rules -# -include $(BUILDDIR)/common/Library.gmk - -# -# Extra clean rules because we build more than one package. -# -clean:: classheaders.clean objects.clean - $(RM) -r $(CLASSBINDIR)/javax/rmi - $(RM) -r $(CLASSBINDIR)/javax/transaction - $(RM) -r $(CLASSBINDIR)/javax/activity - $(RM) -r $(CLASSBINDIR)/com/sun/corba/se/impl - diff --git a/corba/make/sun/corba/core/mapfile-vers b/corba/make/sun/corba/core/mapfile-vers deleted file mode 100644 index 31f65a3fbb9..00000000000 --- a/corba/make/sun/corba/core/mapfile-vers +++ /dev/null @@ -1,80 +0,0 @@ -# -# Copyright 2005 Sun Microsystems, Inc. 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. Sun designates this -# particular file as subject to the "Classpath" exception as provided -# by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -# CA 95054 USA or visit www.sun.com if you need additional information or -# have any questions. -# - -# Define library interface. - -SUNWprivate_1.1 { - global: - Java_com_sun_corba_se_internal_io_IIOPInputStream_allocateNewObject; - Java_com_sun_corba_se_internal_io_IIOPInputStream_loadClass; - Java_com_sun_corba_se_internal_io_IIOPInputStream_readObject; - Java_com_sun_corba_se_internal_io_IIOPInputStream_setBooleanField; - Java_com_sun_corba_se_internal_io_IIOPInputStream_setBooleanFieldOpt; - Java_com_sun_corba_se_internal_io_IIOPInputStream_setByteField; - Java_com_sun_corba_se_internal_io_IIOPInputStream_setByteFieldOpt; - Java_com_sun_corba_se_internal_io_IIOPInputStream_setCharField; - Java_com_sun_corba_se_internal_io_IIOPInputStream_setCharFieldOpt; - Java_com_sun_corba_se_internal_io_IIOPInputStream_setDoubleField; - Java_com_sun_corba_se_internal_io_IIOPInputStream_setDoubleFieldOpt; - Java_com_sun_corba_se_internal_io_IIOPInputStream_setFloatField; - Java_com_sun_corba_se_internal_io_IIOPInputStream_setFloatFieldOpt; - Java_com_sun_corba_se_internal_io_IIOPInputStream_setIntField; - Java_com_sun_corba_se_internal_io_IIOPInputStream_setIntFieldOpt; - Java_com_sun_corba_se_internal_io_IIOPInputStream_setLongField; - Java_com_sun_corba_se_internal_io_IIOPInputStream_setLongFieldOpt; - Java_com_sun_corba_se_internal_io_IIOPInputStream_setObjectField; - Java_com_sun_corba_se_internal_io_IIOPInputStream_setObjectFieldOpt; - Java_com_sun_corba_se_internal_io_IIOPInputStream_setShortField; - Java_com_sun_corba_se_internal_io_IIOPInputStream_setShortFieldOpt; - Java_com_sun_corba_se_internal_io_IIOPInputStream_throwExceptionType; - Java_com_sun_corba_se_internal_io_IIOPOutputStream_getBooleanField; - Java_com_sun_corba_se_internal_io_IIOPOutputStream_getBooleanFieldOpt; - Java_com_sun_corba_se_internal_io_IIOPOutputStream_getByteField; - Java_com_sun_corba_se_internal_io_IIOPOutputStream_getByteFieldOpt; - Java_com_sun_corba_se_internal_io_IIOPOutputStream_getCharField; - Java_com_sun_corba_se_internal_io_IIOPOutputStream_getCharFieldOpt; - Java_com_sun_corba_se_internal_io_IIOPOutputStream_getDoubleField; - Java_com_sun_corba_se_internal_io_IIOPOutputStream_getDoubleFieldOpt; - Java_com_sun_corba_se_internal_io_IIOPOutputStream_getFloatField; - Java_com_sun_corba_se_internal_io_IIOPOutputStream_getFloatFieldOpt; - Java_com_sun_corba_se_internal_io_IIOPOutputStream_getIntField; - Java_com_sun_corba_se_internal_io_IIOPOutputStream_getIntFieldOpt; - Java_com_sun_corba_se_internal_io_IIOPOutputStream_getLongField; - Java_com_sun_corba_se_internal_io_IIOPOutputStream_getLongFieldOpt; - Java_com_sun_corba_se_internal_io_IIOPOutputStream_getObjectField; - Java_com_sun_corba_se_internal_io_IIOPOutputStream_getObjectFieldOpt; - Java_com_sun_corba_se_internal_io_IIOPOutputStream_getShortField; - Java_com_sun_corba_se_internal_io_IIOPOutputStream_getShortFieldOpt; - Java_com_sun_corba_se_internal_io_IIOPOutputStream_throwExceptionType; - Java_com_sun_corba_se_internal_io_IIOPOutputStream_writeObject; - Java_com_sun_corba_se_internal_io_LibraryManager_getMajorVersion; - Java_com_sun_corba_se_internal_io_LibraryManager_getMinorVersion; - Java_com_sun_corba_se_internal_io_LibraryManager_setEnableOverride; - Java_com_sun_corba_se_internal_io_ObjectStreamClass_hasStaticInitializer; - Java_com_sun_corba_se_internal_io_ObjectStreamField_getFieldIDNative; - Java_com_sun_corba_se_internal_util_JDKClassLoader_specialLoadClass; - local: - *; -}; diff --git a/corba/src/share/classes/com/sun/corba/se/internal/io/IIOPInputStream.java b/corba/src/share/classes/com/sun/corba/se/internal/io/IIOPInputStream.java deleted file mode 100644 index f211f1dd819..00000000000 --- a/corba/src/share/classes/com/sun/corba/se/internal/io/IIOPInputStream.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2003 Sun Microsystems, Inc. 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. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package com.sun.corba.se.internal.io; - -public class IIOPInputStream { - private static native Object allocateNewObject(Class aclass, - Class initclass) - throws InstantiationException, IllegalAccessException; - /* Create a pending exception. This is needed to get around - * the fact that the *Delegate methods do not explicitly - * declare that they throw exceptions. - * - * This native methods creates an exception of the given type with - * the given message string and posts it to the pending queue. - */ - private static native void throwExceptionType(Class c, String message); - - /* The following native methods of the form set*Field are used - * to set private, protected, and package private fields - * of an Object. - */ - private static native void setObjectField(Object o, Class c, String fieldName, String fieldSig, Object v); - private static native void setBooleanField(Object o, Class c, String fieldName, String fieldSig, boolean v); - private static native void setByteField(Object o, Class c, String fieldName, String fieldSig, byte v); - private static native void setCharField(Object o, Class c, String fieldName, String fieldSig, char v); - private static native void setShortField(Object o, Class c, String fieldName, String fieldSig, short v); - private static native void setIntField(Object o, Class c, String fieldName, String fieldSig, int v); - private static native void setLongField(Object o, Class c, String fieldName, String fieldSig, long v); - private static native void setFloatField(Object o, Class c, String fieldName, String fieldSig, float v); - private static native void setDoubleField(Object o, Class c, String fieldName, String fieldSig, double v); - private static native void readObject(Object obj, Class asClass, Object ois); - - private static native void setObjectFieldOpt(Object o, long fieldID, Object v); - private static native void setBooleanFieldOpt(Object o, long fieldID, boolean v); - private static native void setByteFieldOpt(Object o, long fieldID, byte v); - private static native void setCharFieldOpt(Object o, long fieldID, char v); - private static native void setShortFieldOpt(Object o, long fieldID, short v); - private static native void setIntFieldOpt(Object o, long fieldID, int v); - private static native void setLongFieldOpt(Object o, long fieldID, long v); - - private static native void setFloatFieldOpt(Object o, long fieldID, float v); - private static native void setDoubleFieldOpt(Object o, long fieldID, double v); -} diff --git a/corba/src/share/classes/com/sun/corba/se/internal/io/IIOPOutputStream.java b/corba/src/share/classes/com/sun/corba/se/internal/io/IIOPOutputStream.java deleted file mode 100644 index dcc7e41bf34..00000000000 --- a/corba/src/share/classes/com/sun/corba/se/internal/io/IIOPOutputStream.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2003 Sun Microsystems, Inc. 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. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package com.sun.corba.se.internal.io; - - -public class IIOPOutputStream { - - /* Create a pending exception. This is needed to get around - * the fact that the *Delegate methods do not explicitly - * declare that they throw exceptions. - * - * This native method creates an exception of the given type with - * the given message string and posts it to the pending queue. - */ - private static native void throwExceptionType(Class c, String message); - - private static native Object getObjectFieldOpt(Object o, long fieldID); - private static native boolean getBooleanFieldOpt(Object o, long fieldID); - private static native byte getByteFieldOpt(Object o, long fieldID); - private static native char getCharFieldOpt(Object o, long fieldID); - private static native short getShortFieldOpt(Object o, long fieldID); - private static native int getIntFieldOpt(Object o, long fieldID); - private static native long getLongFieldOpt(Object o, long fieldID); - private static native float getFloatFieldOpt(Object o, long fieldID); - private static native double getDoubleFieldOpt(Object o, long fieldID); - - private static native void writeObject(Object obj, Class asClass, Object oos) throws IllegalAccessException; -} diff --git a/corba/src/share/classes/com/sun/corba/se/internal/io/LibraryManager.java b/corba/src/share/classes/com/sun/corba/se/internal/io/LibraryManager.java deleted file mode 100644 index a4e0a3bf435..00000000000 --- a/corba/src/share/classes/com/sun/corba/se/internal/io/LibraryManager.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2003 Sun Microsystems, Inc. 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. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ -/* - * Licensed Materials - Property of IBM - * RMI-IIOP v1.0 - * Copyright IBM Corp. 1998 1999 All Rights Reserved - * - */ - -package com.sun.corba.se.internal.io; - -public class LibraryManager -{ - native private static int getMajorVersion(); - - native private static int getMinorVersion(); - - private static native boolean setEnableOverride(Class targetClass, Object instance); -} diff --git a/corba/src/share/classes/com/sun/corba/se/internal/io/ObjectStreamClass.java b/corba/src/share/classes/com/sun/corba/se/internal/io/ObjectStreamClass.java deleted file mode 100644 index e8e21d9ca5b..00000000000 --- a/corba/src/share/classes/com/sun/corba/se/internal/io/ObjectStreamClass.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2003 Sun Microsystems, Inc. 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. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -package com.sun.corba.se.internal.io; - -public class ObjectStreamClass { - - /* Find out if the class has a static class initializer */ - private static native boolean hasStaticInitializer(Class cl); - -} diff --git a/corba/src/share/native/com/sun/corba/se/internal/io/ioser.c b/corba/src/share/native/com/sun/corba/se/internal/io/ioser.c deleted file mode 100644 index 521e7c73c61..00000000000 --- a/corba/src/share/native/com/sun/corba/se/internal/io/ioser.c +++ /dev/null @@ -1,862 +0,0 @@ -/* - * Copyright 1998-2002 Sun Microsystems, Inc. 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. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - */ - -#include "jni.h" - -#include "com_sun_corba_se_internal_io_IIOPInputStream.h" -#include "com_sun_corba_se_internal_io_IIOPOutputStream.h" -#include "com_sun_corba_se_internal_io_ObjectStreamClass.h" -#include "com_sun_corba_se_internal_io_LibraryManager.h" - -#define MAJOR_VERSION 1 -#define MINOR_VERSION 11 /*sun.4296963 ibm.11861*/ - -static char *copyright[] = { - "Licensed Materials - Property of IBM and Sun", - "RMI-IIOP v1.0", - "Copyright IBM Corp. 1998 1999 All Rights Reserved", - "Copyright 1998-1999 Sun Microsystems, Inc. 901 San Antonio Road,", - "Palo Alto, CA 94303, U.S.A. All rights reserved." -}; - -/* - * Class: com_sun_corba_se_internal_io_LibraryManager - * Method: getMajorVersion - * Signature: ()I - */ -JNIEXPORT jint JNICALL Java_com_sun_corba_se_internal_io_LibraryManager_getMajorVersion - (JNIEnv *env, jclass this) -{ - return MAJOR_VERSION; -} - -/* - * Class: com_sun_corba_se_internal_io_LibraryManager - * Method: getMinorVersion - * Signature: ()I - */ -JNIEXPORT jint JNICALL Java_com_sun_corba_se_internal_io_LibraryManager_getMinorVersion - (JNIEnv *env, jclass this) -{ - return MINOR_VERSION; -} - -/* - * Class: com_sun_corba_se_internal_io_LibraryManager - * Method: setEnableOverride - * Signature: (Ljava/lang/Class;Ljava/lang/Object;)Z - */ -JNIEXPORT jboolean JNICALL Java_com_sun_corba_se_internal_io_LibraryManager_setEnableOverride - (JNIEnv *env, jclass this, jclass targetClass, jobject instance) -{ - jfieldID fieldID = (*env)->GetFieldID(env, targetClass, - "enableSubclassImplementation", - "Z"); - (*env)->SetBooleanField(env, instance, fieldID, JNI_TRUE); - - return (*env)->GetBooleanField(env, instance, fieldID); - -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPOutputStream - * Method: throwExceptionType - * Signature: (Ljava/lang/Class;Ljava/lang/String;)V - * - * Construct and throw the given exception using the given message. - */ -JNIEXPORT void JNICALL Java_com_sun_corba_se_internal_io_IIOPOutputStream_throwExceptionType - (JNIEnv *env, jobject obj, jclass c, jstring mssg) -{ - const char* strMsg = (*env)->GetStringUTFChars(env, mssg, 0L); - (*env)->ThrowNew(env, c, strMsg); - (*env)->ReleaseStringUTFChars(env, mssg, strMsg); - return; -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPInputStream - * Method: throwExceptionType - * Signature: (Ljava/lang/Class;Ljava/lang/String;)V - * - * Construct and throw the given exception using the given message. - */ -JNIEXPORT void JNICALL Java_com_sun_corba_se_internal_io_IIOPInputStream_throwExceptionType - (JNIEnv *env, jobject obj, jclass c, jstring mssg) -{ - const char* strMsg = (*env)->GetStringUTFChars(env, mssg, 0L); - (*env)->ThrowNew(env, c, strMsg); - (*env)->ReleaseStringUTFChars(env, mssg, strMsg); - return; - -} - -JNIEXPORT jobject JNICALL -Java_com_sun_corba_se_internal_io_IIOPInputStream_allocateNewObject (JNIEnv * env, - jclass this, - jclass aclass, - jclass initclass) -{ - jmethodID cid; - - /** - * Get the method ID of the default constructor of - * initclass, which is the first non-Serializable - * superclass. - */ - cid = (*env)->GetMethodID(env, initclass, "", "()V"); - - if (cid == NULL) { - /* exception thrown */ - return NULL; - } - - /** - * Allocates an object of type aclass and calls the - * initclass default constructor (found above) - */ - return (*env)->NewObject(env, aclass, cid); -} - - -/* DEPRECATED - This is no longer used. - * - * Find the first class loader up the stack and use its class to call - * FindClassFromClass to resolve the specified class - * name. The code is similar to that of java.lang.currentClassLoader - */ -JNIEXPORT jclass JNICALL -Java_com_sun_corba_se_internal_io_IIOPInputStream_loadClass (JNIEnv * env, - jobject this, - jclass curClass, - jstring currClassName) -{ - return 0L; -} - -#include "com_sun_corba_se_internal_io_ObjectStreamClass.h" - -/* - * Class: com_sun_corba_se_internal_io_ObjectStreamClass - * Method: hasStaticInitializer - * Signature: (Ljava/lang/Class;)Z - * - * If the method ()V is defined true is returned. - * Otherwise, false is returned. - */ -JNIEXPORT jboolean JNICALL -Java_com_sun_corba_se_internal_io_ObjectStreamClass_hasStaticInitializer(JNIEnv *env, jclass this, - jclass clazz) -{ - jclass superclazz = NULL; - jmethodID superclinit = NULL; - - jmethodID clinit = (*env)->GetStaticMethodID(env, clazz, - "", "()V"); - if (clinit == NULL || (*env)->ExceptionOccurred(env)) { - (*env)->ExceptionClear(env); - return 0; - } - - /* Ask the superclass the same question - * If the answer is the same then the constructor is from a superclass. - * If different, it's really defined on the subclass. - */ - superclazz = (*env)->GetSuperclass(env, clazz); - if ((*env)->ExceptionOccurred(env)) { - return 0; - } - - if (superclazz == NULL) - return 1; - - superclinit = (*env)->GetStaticMethodID(env, superclazz, - "", "()V"); - if ((*env)->ExceptionOccurred(env)) { - (*env)->ExceptionClear(env); - superclinit = NULL; - } - - return (superclinit != clinit); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPInputStream - * Method: readObject - * Signature: (Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Object;)V - */ -JNIEXPORT void JNICALL Java_com_sun_corba_se_internal_io_IIOPInputStream_readObject - (JNIEnv *env, jobject this, jobject obj, jclass cls, jobject ois) -{ - jthrowable exc; - jclass newExcCls; - jmethodID mid = (*env)->GetMethodID(env, cls, "readObject", "(Ljava/io/ObjectInputStream;)V"); - if (mid == 0) - return; - (*env)->CallNonvirtualVoidMethod(env, obj, cls, mid, ois); - - exc = (*env)->ExceptionOccurred(env); - if (exc) { - (*env)->ExceptionDescribe(env); - (*env)->ExceptionClear(env); - - newExcCls = (*env)->FindClass(env, "java/io/IOException"); - if (newExcCls == 0) /* Unable to find the new exception class, give up. */ - return; - (*env)->ThrowNew(env, newExcCls, "Serializable readObject method failed internally"); - return; - } - - return; -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPOutputStream - * Method: writeObject - * Signature: (Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Object;)V - */ -JNIEXPORT void JNICALL Java_com_sun_corba_se_internal_io_IIOPOutputStream_writeObject - (JNIEnv *env, jobject this, jobject obj, jclass cls, jobject oos) -{ - jthrowable exc; - jclass newExcCls; - jmethodID mid = (*env)->GetMethodID(env, cls, "writeObject", "(Ljava/io/ObjectOutputStream;)V"); - if (mid == 0) - return; - (*env)->CallNonvirtualVoidMethod(env, obj, cls, mid, oos); - - exc = (*env)->ExceptionOccurred(env); - if (exc) { - (*env)->ExceptionDescribe(env); - (*env)->ExceptionClear(env); - - newExcCls = (*env)->FindClass(env, "java/io/IOException"); - if (newExcCls == 0) /* Unable to find the new exception class, give up. */ - return; - (*env)->ThrowNew(env, newExcCls, "Serializable readObject method failed internally"); - return; - } - - return; - -} - - -/* - * Class: com_sun_corba_se_internal_io_IIOPOutputStream - * Method: getObjectField - * Signature: (Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object; - */ -JNIEXPORT jobject JNICALL Java_com_sun_corba_se_internal_io_IIOPOutputStream_getObjectField - (JNIEnv *env, jobject this, jobject obj, jclass clazz, jstring fieldName, jstring fieldSig) -{ - const char *strFieldName = (*env)->GetStringUTFChars(env, fieldName, 0L); - const char *strFieldSig = (*env)->GetStringUTFChars(env, fieldSig, 0L); - - jfieldID fieldID = (*env)->GetFieldID(env, clazz, strFieldName, strFieldSig); - - (*env)->ReleaseStringUTFChars(env, fieldName, strFieldName); - (*env)->ReleaseStringUTFChars(env, fieldSig, strFieldSig); - - return (*env)->GetObjectField(env, obj, fieldID); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPOutputStream - * Method: getBooleanField - * Signature: (Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;)Z - */ -JNIEXPORT jboolean JNICALL Java_com_sun_corba_se_internal_io_IIOPOutputStream_getBooleanField - (JNIEnv *env, jobject this, jobject obj, jclass clazz, jstring fieldName, jstring fieldSig) -{ - const char* strFieldName = (*env)->GetStringUTFChars(env, fieldName, 0L); - const char* strFieldSig = (*env)->GetStringUTFChars(env, fieldSig, 0L); - - jfieldID fieldID = (*env)->GetFieldID(env, clazz, strFieldName, strFieldSig); - - (*env)->ReleaseStringUTFChars(env, fieldName, strFieldName); - (*env)->ReleaseStringUTFChars(env, fieldSig, strFieldSig); - - return (*env)->GetBooleanField(env, obj, fieldID); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPOutputStream - * Method: getByteField - * Signature: (Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;)B - */ -JNIEXPORT jbyte JNICALL Java_com_sun_corba_se_internal_io_IIOPOutputStream_getByteField - (JNIEnv *env, jobject this, jobject obj, jclass clazz, jstring fieldName, jstring fieldSig) -{ - const char* strFieldName = (*env)->GetStringUTFChars(env, fieldName, 0L); - const char* strFieldSig = (*env)->GetStringUTFChars(env, fieldSig, 0L); - - jfieldID fieldID = (*env)->GetFieldID(env, clazz, strFieldName, strFieldSig); - - (*env)->ReleaseStringUTFChars(env, fieldName, strFieldName); - (*env)->ReleaseStringUTFChars(env, fieldSig, strFieldSig); - - return (*env)->GetByteField(env, obj, fieldID); - -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPOutputStream - * Method: getCharField - * Signature: (Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;)C - */ -JNIEXPORT jchar JNICALL Java_com_sun_corba_se_internal_io_IIOPOutputStream_getCharField - (JNIEnv *env, jobject this, jobject obj, jclass clazz, jstring fieldName, jstring fieldSig) -{ - const char* strFieldName = (*env)->GetStringUTFChars(env, fieldName, 0L); - const char* strFieldSig = (*env)->GetStringUTFChars(env, fieldSig, 0L); - - jfieldID fieldID = (*env)->GetFieldID(env, clazz, strFieldName, strFieldSig); - - (*env)->ReleaseStringUTFChars(env, fieldName, strFieldName); - (*env)->ReleaseStringUTFChars(env, fieldSig, strFieldSig); - - return (*env)->GetCharField(env, obj, fieldID); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPOutputStream - * Method: getShortField - * Signature: (Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;)S - */ -JNIEXPORT jshort JNICALL Java_com_sun_corba_se_internal_io_IIOPOutputStream_getShortField - (JNIEnv *env, jobject this, jobject obj, jclass clazz, jstring fieldName, jstring fieldSig) -{ - const char* strFieldName = (*env)->GetStringUTFChars(env, fieldName, 0L); - const char* strFieldSig = (*env)->GetStringUTFChars(env, fieldSig, 0L); - - jfieldID fieldID = (*env)->GetFieldID(env, clazz, strFieldName, strFieldSig); - - (*env)->ReleaseStringUTFChars(env, fieldName, strFieldName); - (*env)->ReleaseStringUTFChars(env, fieldSig, strFieldSig); - - return (*env)->GetShortField(env, obj, fieldID); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPOutputStream - * Method: getIntField - * Signature: (Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;)I - */ -JNIEXPORT jint JNICALL Java_com_sun_corba_se_internal_io_IIOPOutputStream_getIntField - (JNIEnv *env, jobject this, jobject obj, jclass clazz, jstring fieldName, jstring fieldSig) -{ - const char* strFieldName = (*env)->GetStringUTFChars(env, fieldName, 0L); - const char* strFieldSig = (*env)->GetStringUTFChars(env, fieldSig, 0L); - - jfieldID fieldID = (*env)->GetFieldID(env, clazz, strFieldName, strFieldSig); - - (*env)->ReleaseStringUTFChars(env, fieldName, strFieldName); - (*env)->ReleaseStringUTFChars(env, fieldSig, strFieldSig); - - return (*env)->GetIntField(env, obj, fieldID); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPOutputStream - * Method: getLongField - * Signature: (Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;)J - */ -JNIEXPORT jlong JNICALL Java_com_sun_corba_se_internal_io_IIOPOutputStream_getLongField - (JNIEnv *env, jobject this, jobject obj, jclass clazz, jstring fieldName, jstring fieldSig) -{ - const char* strFieldName = (*env)->GetStringUTFChars(env, fieldName, 0L); - const char* strFieldSig = (*env)->GetStringUTFChars(env, fieldSig, 0L); - - jfieldID fieldID = (*env)->GetFieldID(env, clazz, strFieldName, strFieldSig); - - (*env)->ReleaseStringUTFChars(env, fieldName, strFieldName); - (*env)->ReleaseStringUTFChars(env, fieldSig, strFieldSig); - - return (*env)->GetLongField(env, obj, fieldID); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPOutputStream - * Method: getFloatField - * Signature: (Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;)F - */ -JNIEXPORT jfloat JNICALL Java_com_sun_corba_se_internal_io_IIOPOutputStream_getFloatField - (JNIEnv *env, jobject this, jobject obj, jclass clazz, jstring fieldName, jstring fieldSig) -{ - const char* strFieldName = (*env)->GetStringUTFChars(env, fieldName, 0L); - const char* strFieldSig = (*env)->GetStringUTFChars(env, fieldSig, 0L); - - jfieldID fieldID = (*env)->GetFieldID(env, clazz, strFieldName, strFieldSig); - - (*env)->ReleaseStringUTFChars(env, fieldName, strFieldName); - (*env)->ReleaseStringUTFChars(env, fieldSig, strFieldSig); - - return (*env)->GetFloatField(env, obj, fieldID); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPOutputStream - * Method: getDoubleField - * Signature: (Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;)D - */ -JNIEXPORT jdouble JNICALL Java_com_sun_corba_se_internal_io_IIOPOutputStream_getDoubleField - (JNIEnv *env, jobject this, jobject obj, jclass clazz, jstring fieldName, jstring fieldSig) -{ - const char* strFieldName = (*env)->GetStringUTFChars(env, fieldName, 0L); - const char* strFieldSig = (*env)->GetStringUTFChars(env, fieldSig, 0L); - - jfieldID fieldID = (*env)->GetFieldID(env, clazz, strFieldName, strFieldSig); - - (*env)->ReleaseStringUTFChars(env, fieldName, strFieldName); - (*env)->ReleaseStringUTFChars(env, fieldSig, strFieldSig); - - return (*env)->GetDoubleField(env, obj, fieldID); -} - - - -/* - * Class: com_sun_corba_se_internal_io_IIOPInputStream - * Method: setObjectField - * Signature: (Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V - */ -JNIEXPORT void JNICALL Java_com_sun_corba_se_internal_io_IIOPInputStream_setObjectField - (JNIEnv *env, jobject this, jobject obj, jclass clazz, jstring fieldName, jstring fieldSig, jobject v) -{ - const char* strFieldName = (*env)->GetStringUTFChars(env, fieldName, 0L); - const char* strFieldSig = (*env)->GetStringUTFChars(env, fieldSig, 0L); - - jfieldID fieldID = (*env)->GetFieldID(env, clazz, strFieldName, strFieldSig); - - (*env)->ReleaseStringUTFChars(env, fieldName, strFieldName); - (*env)->ReleaseStringUTFChars(env, fieldSig, strFieldSig); - - (*env)->SetObjectField(env, obj, fieldID, v); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPInputStream - * Method: setBooleanField - * Signature: (Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Z)V - */ -JNIEXPORT void JNICALL Java_com_sun_corba_se_internal_io_IIOPInputStream_setBooleanField - (JNIEnv *env, jobject this, jobject obj, jclass clazz, jstring fieldName, jstring fieldSig, jboolean v) -{ - const char* strFieldName = (*env)->GetStringUTFChars(env, fieldName, 0L); - const char* strFieldSig = (*env)->GetStringUTFChars(env, fieldSig, 0L); - - jfieldID fieldID = (*env)->GetFieldID(env, clazz, strFieldName, strFieldSig); - - (*env)->ReleaseStringUTFChars(env, fieldName, strFieldName); - (*env)->ReleaseStringUTFChars(env, fieldSig, strFieldSig); - - (*env)->SetBooleanField(env, obj, fieldID, v); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPInputStream - * Method: setByteField - * Signature: (Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;B)V - */ -JNIEXPORT void JNICALL Java_com_sun_corba_se_internal_io_IIOPInputStream_setByteField - (JNIEnv *env, jobject this, jobject obj, jclass clazz, jstring fieldName, jstring fieldSig, jbyte v) -{ - const char* strFieldName = (*env)->GetStringUTFChars(env, fieldName, 0L); - const char* strFieldSig = (*env)->GetStringUTFChars(env, fieldSig, 0L); - - jfieldID fieldID = (*env)->GetFieldID(env, clazz, strFieldName, strFieldSig); - - (*env)->ReleaseStringUTFChars(env, fieldName, strFieldName); - (*env)->ReleaseStringUTFChars(env, fieldSig, strFieldSig); - - (*env)->SetByteField(env, obj, fieldID, v); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPInputStream - * Method: setCharField - * Signature: (Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;C)V - */ -JNIEXPORT void JNICALL Java_com_sun_corba_se_internal_io_IIOPInputStream_setCharField - (JNIEnv *env, jobject this, jobject obj, jclass clazz, jstring fieldName, jstring fieldSig, jchar v) -{ - const char* strFieldName = (*env)->GetStringUTFChars(env, fieldName, 0L); - const char* strFieldSig = (*env)->GetStringUTFChars(env, fieldSig, 0L); - - jfieldID fieldID = (*env)->GetFieldID(env, clazz, strFieldName, strFieldSig); - - (*env)->ReleaseStringUTFChars(env, fieldName, strFieldName); - (*env)->ReleaseStringUTFChars(env, fieldSig, strFieldSig); - - (*env)->SetCharField(env, obj, fieldID, v); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPInputStream - * Method: setShortField - * Signature: (Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;S)V - */ -JNIEXPORT void JNICALL Java_com_sun_corba_se_internal_io_IIOPInputStream_setShortField - (JNIEnv *env, jobject this, jobject obj, jclass clazz, jstring fieldName, jstring fieldSig, jshort v) -{ - const char* strFieldName = (*env)->GetStringUTFChars(env, fieldName, 0L); - const char* strFieldSig = (*env)->GetStringUTFChars(env, fieldSig, 0L); - - jfieldID fieldID = (*env)->GetFieldID(env, clazz, strFieldName, strFieldSig); - - (*env)->ReleaseStringUTFChars(env, fieldName, strFieldName); - (*env)->ReleaseStringUTFChars(env, fieldSig, strFieldSig); - - (*env)->SetShortField(env, obj, fieldID, v); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPInputStream - * Method: setIntField - * Signature: (Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;I)V - */ -JNIEXPORT void JNICALL Java_com_sun_corba_se_internal_io_IIOPInputStream_setIntField - (JNIEnv *env, jobject this, jobject obj, jclass clazz, jstring fieldName, jstring fieldSig, jint v) -{ - const char* strFieldName = (*env)->GetStringUTFChars(env, fieldName, 0L); - const char* strFieldSig = (*env)->GetStringUTFChars(env, fieldSig, 0L); - - jfieldID fieldID = (*env)->GetFieldID(env, clazz, strFieldName, strFieldSig); - - (*env)->ReleaseStringUTFChars(env, fieldName, strFieldName); - (*env)->ReleaseStringUTFChars(env, fieldSig, strFieldSig); - - (*env)->SetIntField(env, obj, fieldID, v); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPInputStream - * Method: setLongField - * Signature: (Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;J)V - */ -JNIEXPORT void JNICALL Java_com_sun_corba_se_internal_io_IIOPInputStream_setLongField - (JNIEnv *env, jobject this, jobject obj, jclass clazz, jstring fieldName, jstring fieldSig, jlong v) -{ - const char* strFieldName = (*env)->GetStringUTFChars(env, fieldName, 0L); - const char* strFieldSig = (*env)->GetStringUTFChars(env, fieldSig, 0L); - - jfieldID fieldID = (*env)->GetFieldID(env, clazz, strFieldName, strFieldSig); - - (*env)->ReleaseStringUTFChars(env, fieldName, strFieldName); - (*env)->ReleaseStringUTFChars(env, fieldSig, strFieldSig); - - (*env)->SetLongField(env, obj, fieldID, v); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPInputStream - * Method: setFloatField - * Signature: (Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;F)V - */ -JNIEXPORT void JNICALL Java_com_sun_corba_se_internal_io_IIOPInputStream_setFloatField - (JNIEnv *env, jobject this, jobject obj, jclass clazz, jstring fieldName, jstring fieldSig, jfloat v) -{ - const char* strFieldName = (*env)->GetStringUTFChars(env, fieldName, 0L); - const char* strFieldSig = (*env)->GetStringUTFChars(env, fieldSig, 0L); - - jfieldID fieldID = (*env)->GetFieldID(env, clazz, strFieldName, strFieldSig); - - (*env)->ReleaseStringUTFChars(env, fieldName, strFieldName); - (*env)->ReleaseStringUTFChars(env, fieldSig, strFieldSig); - - (*env)->SetFloatField(env, obj, fieldID, v); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPInputStream - * Method: setDoubleField - * Signature: (Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;D)V - */ -JNIEXPORT void JNICALL Java_com_sun_corba_se_internal_io_IIOPInputStream_setDoubleField - (JNIEnv *env, jobject this, jobject obj, jclass clazz, jstring fieldName, jstring fieldSig, jdouble v) -{ - const char* strFieldName = (*env)->GetStringUTFChars(env, fieldName, 0L); - const char* strFieldSig = (*env)->GetStringUTFChars(env, fieldSig, 0L); - - jfieldID fieldID = (*env)->GetFieldID(env, clazz, strFieldName, strFieldSig); - - (*env)->ReleaseStringUTFChars(env, fieldName, strFieldName); - (*env)->ReleaseStringUTFChars(env, fieldSig, strFieldSig); - - (*env)->SetDoubleField(env, obj, fieldID, v); -} - -/* - * Class: com_sun_corba_se_internal_util_JDKClassLoader - * Method: specialLoadClass - * Signature: (Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Class; - */ -JNIEXPORT jclass JNICALL Java_com_sun_corba_se_internal_util_JDKClassLoader_specialLoadClass - (JNIEnv *env, jclass this, jobject target, jclass cls, jstring clsName) -{ - jthrowable exc; - jclass streamTargetCls; - jmethodID mid; - jclass result; - streamTargetCls = (*env)->FindClass(env, "java/io/ObjectInputStream"); - mid = (*env)->GetMethodID(env, streamTargetCls, "loadClass0", "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Class;"); - if (mid == 0) - return 0L; - result = (jclass) (*env)->CallNonvirtualObjectMethod(env, target, streamTargetCls, mid, cls, clsName); - - exc = (*env)->ExceptionOccurred(env); - if (exc) { - return 0L; - } - - return result; -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPOutputStream - * Method: getObjectFieldOpt - * Signature: (Ljava/lang/Object;J)Ljava/lang/Object; - */ -JNIEXPORT jobject JNICALL Java_com_sun_corba_se_internal_io_IIOPOutputStream_getObjectFieldOpt - (JNIEnv *env, jobject this, jobject obj, jlong fieldID) -{ - return (*env)->GetObjectField(env, obj, (jfieldID)fieldID); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPOutputStream - * Method: getBooleanFieldOpt - * Signature: (Ljava/lang/Object;J)Z - */ -JNIEXPORT jboolean JNICALL Java_com_sun_corba_se_internal_io_IIOPOutputStream_getBooleanFieldOpt - (JNIEnv *env, jobject this, jobject obj, jlong fieldID) -{ - return (*env)->GetBooleanField(env, obj, (jfieldID)fieldID); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPOutputStream - * Method: getByteFieldOpt - * Signature: (Ljava/lang/Object;J)B - */ -JNIEXPORT jbyte JNICALL Java_com_sun_corba_se_internal_io_IIOPOutputStream_getByteFieldOpt - (JNIEnv *env, jobject this, jobject obj, jlong fieldID) -{ - return (*env)->GetByteField(env, obj, (jfieldID)fieldID); - -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPOutputStream - * Method: getCharFieldOpt - * Signature: (Ljava/lang/Object;J)C - */ -JNIEXPORT jchar JNICALL Java_com_sun_corba_se_internal_io_IIOPOutputStream_getCharFieldOpt - (JNIEnv *env, jobject this, jobject obj, jlong fieldID) -{ - return (*env)->GetCharField(env, obj, (jfieldID)fieldID); - -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPOutputStream - * Method: getShortFieldOpt - * Signature: (Ljava/lang/Object;J)S - */ -JNIEXPORT jshort JNICALL Java_com_sun_corba_se_internal_io_IIOPOutputStream_getShortFieldOpt - (JNIEnv *env, jobject this, jobject obj, jlong fieldID) -{ - return (*env)->GetShortField(env, obj, (jfieldID)fieldID); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPOutputStream - * Method: getIntFieldOpt - * Signature: (Ljava/lang/Object;J)I - */ -JNIEXPORT jint JNICALL Java_com_sun_corba_se_internal_io_IIOPOutputStream_getIntFieldOpt - (JNIEnv *env, jobject this, jobject obj, jlong fieldID) -{ - return (*env)->GetIntField(env, obj, (jfieldID)fieldID); - -} - - -/* - * Class: com_sun_corba_se_internal_io_IIOPOutputStream - * Method: getLongFieldOpt - * Signature: (Ljava/lang/Object;J)J - */ -JNIEXPORT jlong JNICALL Java_com_sun_corba_se_internal_io_IIOPOutputStream_getLongFieldOpt - (JNIEnv *env, jobject this, jobject obj, jlong fieldID) -{ - return (*env)->GetLongField(env, obj, (jfieldID)fieldID); - -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPOutputStream - * Method: getFloatFieldOpt - * Signature: (Ljava/lang/Object;J)F - */ -JNIEXPORT jfloat JNICALL Java_com_sun_corba_se_internal_io_IIOPOutputStream_getFloatFieldOpt - (JNIEnv *env, jobject this, jobject obj, jlong fieldID) -{ - return (*env)->GetFloatField(env, obj, (jfieldID)fieldID); - -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPOutputStream - * Method: getDoubleFieldOpt - * Signature: (Ljava/lang/Object;J)D - */ -JNIEXPORT jdouble JNICALL Java_com_sun_corba_se_internal_io_IIOPOutputStream_getDoubleFieldOpt - (JNIEnv *env, jobject this, jobject obj, jlong fieldID) -{ - return (*env)->GetDoubleField(env, obj, (jfieldID)fieldID); - -} - - - -/* - * Class: com_sun_corba_se_internal_io_IIOPInputStream - * Method: setObjectFieldOpt - * Signature: (Ljava/lang/Object;JLjava/lang/Object;)V - */ -JNIEXPORT void JNICALL Java_com_sun_corba_se_internal_io_IIOPInputStream_setObjectFieldOpt - (JNIEnv *env, jobject this, jobject obj, jlong fieldID, jobject v) -{ - (*env)->SetObjectField(env, obj, (jfieldID)fieldID, v); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPInputStream - * Method: setBooleanFieldOpt - * Signature: (Ljava/lang/Object;JZ)V - */ -JNIEXPORT void JNICALL Java_com_sun_corba_se_internal_io_IIOPInputStream_setBooleanFieldOpt - (JNIEnv *env, jobject this, jobject obj, jlong fieldID, jboolean v) -{ - (*env)->SetBooleanField(env, obj, (jfieldID)fieldID, v); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPInputStream - * Method: setByteFieldOpt - * Signature: (Ljava/lang/Object;JB)V - */ -JNIEXPORT void JNICALL Java_com_sun_corba_se_internal_io_IIOPInputStream_setByteFieldOpt - (JNIEnv *env, jobject this, jobject obj, jlong fieldID, jbyte v) -{ - (*env)->SetByteField(env, obj, (jfieldID)fieldID, v); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPInputStream - * Method: setCharFieldOpt - * Signature: (Ljava/lang/Object;JC)V - */ -JNIEXPORT void JNICALL Java_com_sun_corba_se_internal_io_IIOPInputStream_setCharFieldOpt - (JNIEnv *env, jobject this, jobject obj, jlong fieldID, jchar v) -{ - (*env)->SetCharField(env, obj, (jfieldID)fieldID, v); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPInputStream - * Method: setShortFieldOpt - * Signature: (Ljava/lang/Object;JS)V - */ -JNIEXPORT void JNICALL Java_com_sun_corba_se_internal_io_IIOPInputStream_setShortFieldOpt - (JNIEnv *env, jobject this, jobject obj, jlong fieldID, jshort v) -{ - (*env)->SetShortField(env, obj, (jfieldID)fieldID, v); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPInputStream - * Method: setIntFieldOpt - * Signature: (Ljava/lang/Object;JI)V - */ -JNIEXPORT void JNICALL Java_com_sun_corba_se_internal_io_IIOPInputStream_setIntFieldOpt - (JNIEnv *env, jobject this, jobject obj, jlong fieldID, jint v) -{ - (*env)->SetIntField(env, obj, (jfieldID)fieldID, v); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPInputStream - * Method: setLongFieldOpt - * Signature: (Ljava/lang/Object;JJ)V - */ -JNIEXPORT void JNICALL Java_com_sun_corba_se_internal_io_IIOPInputStream_setLongFieldOpt - (JNIEnv *env, jobject this, jobject obj, jlong fieldID, jlong v) -{ - (*env)->SetLongField(env, obj, (jfieldID)fieldID, v); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPInputStream - * Method: setFloatFieldOpt - * Signature: (Ljava/lang/Object;JF)V - */ -JNIEXPORT void JNICALL Java_com_sun_corba_se_internal_io_IIOPInputStream_setFloatFieldOpt - (JNIEnv *env, jobject this, jobject obj, jlong fieldID, jfloat v) -{ - (*env)->SetFloatField(env, obj, (jfieldID)fieldID, v); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPInputStream - * Method: setDoubleFieldOpt - * Signature: (Ljava/lang/Object;JD)V - */ -JNIEXPORT void JNICALL Java_com_sun_corba_se_internal_io_IIOPInputStream_setDoubleFieldOpt - (JNIEnv *env, jobject this, jobject obj, jlong fieldID, jdouble v) -{ - (*env)->SetDoubleField(env, obj, (jfieldID)fieldID, v); -} - -/* - * Class: com_sun_corba_se_internal_io_IIOPObjectStreamField - * Method: getFieldID - * Signature: (Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;)X - */ -JNIEXPORT jlong JNICALL Java_com_sun_corba_se_internal_io_ObjectStreamField_getFieldIDNative - (JNIEnv *env, jobject this, jclass clazz, jstring fieldName, jstring fieldSig) -{ - const char* strFieldName = (*env)->GetStringUTFChars(env, fieldName, 0L); - const char* strFieldSig = (*env)->GetStringUTFChars(env, fieldSig, 0L); - - jfieldID fieldID = (*env)->GetFieldID(env, clazz, strFieldName, strFieldSig); - - (*env)->ReleaseStringUTFChars(env, fieldName, strFieldName); - (*env)->ReleaseStringUTFChars(env, fieldSig, strFieldSig); - - return (jlong)fieldID; -} From 77a56e5d33e82d4128ac36861c3704223821f888 Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Tue, 27 Apr 2010 09:42:51 +0100 Subject: [PATCH 06/38] 6718504: IN6_IS_ADDR_ANY tests only 12 bytes of 16-byte address Reviewed-by: alanb --- jdk/src/windows/native/java/net/net_util_md.h | 3 +- .../DatagramSocket/LocalSocketAddress.java | 71 +++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 jdk/test/java/net/DatagramSocket/LocalSocketAddress.java diff --git a/jdk/src/windows/native/java/net/net_util_md.h b/jdk/src/windows/native/java/net/net_util_md.h index 23574f1725f..679fbfc08d4 100644 --- a/jdk/src/windows/native/java/net/net_util_md.h +++ b/jdk/src/windows/native/java/net/net_util_md.h @@ -222,7 +222,8 @@ LPFN_GETNAMEINFO getnameinfo_ptr; #define IN6_IS_ADDR_ANY(a) \ (((a)->s6_words[0] == 0) && ((a)->s6_words[1] == 0) && \ ((a)->s6_words[2] == 0) && ((a)->s6_words[3] == 0) && \ - ((a)->s6_words[4] == 0) && ((a)->s6_words[5] == 0)) + ((a)->s6_words[4] == 0) && ((a)->s6_words[5] == 0) && \ + ((a)->s6_words[6] == 0) && ((a)->s6_words[7] == 0)) #endif #ifndef IPV6_V6ONLY diff --git a/jdk/test/java/net/DatagramSocket/LocalSocketAddress.java b/jdk/test/java/net/DatagramSocket/LocalSocketAddress.java new file mode 100644 index 00000000000..bf20cf17283 --- /dev/null +++ b/jdk/test/java/net/DatagramSocket/LocalSocketAddress.java @@ -0,0 +1,71 @@ +/* + * Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* @test + * @bug 6718504 + * @summary IN6_IS_ADDR_ANY tests only 12 bytes of 16-byte address + */ + +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.Inet6Address; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.*; + +public class LocalSocketAddress { + public static void main(String[] args) throws SocketException { + InetAddress IPv6LoopbackAddr = null; + DatagramSocket soc = null; + + try { + List nics = Collections.list(NetworkInterface.getNetworkInterfaces()); + for (NetworkInterface nic : nics) { + if (!nic.isLoopback()) + continue; + + List addrs = Collections.list(nic.getInetAddresses()); + for (InetAddress addr : addrs) { + if (addr instanceof Inet6Address) { + IPv6LoopbackAddr = addr; + break; + } + } + } + + if (IPv6LoopbackAddr == null) { + System.out.println("IPv6 is not available, exiting test."); + return; + } + + soc = new DatagramSocket(0, IPv6LoopbackAddr); + + if (!IPv6LoopbackAddr.equals(soc.getLocalAddress())) { + throw new RuntimeException("Bound address is " + soc.getLocalAddress() + + ", but should be " + IPv6LoopbackAddr); + } + } finally { + if (soc != null) { soc.close(); } + } + } +} From d052130c49573b0212a3cf1250284a7e6e6f605c Mon Sep 17 00:00:00 2001 From: Artem Ananiev Date: Tue, 27 Apr 2010 18:08:26 +0400 Subject: [PATCH 07/38] 6880336: SwingWorker deadlocks due one thread in the swingworker-pool Reviewed-by: dcherepanov, alexp --- .../classes/javax/swing/SwingWorker.java | 11 +-- .../SwingWorker/6880336/NestedWorkers.java | 72 +++++++++++++++++++ 2 files changed, 78 insertions(+), 5 deletions(-) create mode 100644 jdk/test/javax/swing/SwingWorker/6880336/NestedWorkers.java diff --git a/jdk/src/share/classes/javax/swing/SwingWorker.java b/jdk/src/share/classes/javax/swing/SwingWorker.java index 263284acc4e..ebeeb639112 100644 --- a/jdk/src/share/classes/javax/swing/SwingWorker.java +++ b/jdk/src/share/classes/javax/swing/SwingWorker.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2010 Sun Microsystems, Inc. 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,9 +42,10 @@ import sun.awt.AppContext; import sun.swing.AccumulativeRunnable; /** - * An abstract class to perform lengthy GUI-interacting tasks in a - * dedicated thread. - * + * An abstract class to perform lengthy GUI-interaction tasks in a + * background thread. Several background threads can be used to execute such + * tasks. However, the exact strategy of choosing a thread for any particular + * {@code SwingWorker} is unspecified and should not be relied on. *

* When writing a multi-threaded application using Swing, there are * two constraints to keep in mind: @@ -772,7 +773,7 @@ public abstract class SwingWorker implements RunnableFuture { }; executorService = - new ThreadPoolExecutor(1, MAX_WORKER_THREADS, + new ThreadPoolExecutor(MAX_WORKER_THREADS, MAX_WORKER_THREADS, 10L, TimeUnit.MINUTES, new LinkedBlockingQueue(), threadFactory); diff --git a/jdk/test/javax/swing/SwingWorker/6880336/NestedWorkers.java b/jdk/test/javax/swing/SwingWorker/6880336/NestedWorkers.java new file mode 100644 index 00000000000..1df1dbd1834 --- /dev/null +++ b/jdk/test/javax/swing/SwingWorker/6880336/NestedWorkers.java @@ -0,0 +1,72 @@ +/* + * Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* @test + * @bug 6880336 + * @summary Test for nested SwingWorkers, i.e. when the second worker is +started from the first's doInBackground() method. A timeout when running +* this test is an indication of failure. + * @author Artem Ananiev + * @run main/timeout=32 NestedWorkers + */ + +import javax.swing.*; + +public class NestedWorkers extends SwingWorker { + + private final static int MAX_LEVEL = 2; + + private int level; + + public NestedWorkers(int level) { + super(); + this.level = level; + } + + @Override + public String doInBackground() throws Exception { + if (level < MAX_LEVEL) { + SwingWorker nested = new NestedWorkers(level + 1); + nested.execute(); + nested.get(); + } + System.out.println("doInBackground " + level + " is complete"); + return String.valueOf(level); + } + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + SwingWorker sw = new NestedWorkers(0); + sw.execute(); + try { + System.err.println(sw.get()); + } catch (Exception z) { + throw new RuntimeException(z); + } + } + }); + } + +} From c21ea1a6d8cc5202eab80efca1d036e40e631aec Mon Sep 17 00:00:00 2001 From: Costantino Cerbo Date: Wed, 28 Apr 2010 17:16:05 +0400 Subject: [PATCH 08/38] 6913179: The java.awt.FileDialog should use native GTK file chooser on linux distros Introduce a GTK-based alternative implementation of the FileDialogPeer on X11 Reviewed-by: anthony, peterz --- jdk/make/sun/xawt/FILES_c_unix.gmk | 3 +- jdk/make/sun/xawt/FILES_export_unix.gmk | 3 +- jdk/make/sun/xawt/mapfile-vers | 4 + .../solaris/classes/sun/awt/UNIXToolkit.java | 23 ++ .../sun/awt/X11/GtkFileDialogPeer.java | 134 +++++++++++ .../solaris/classes/sun/awt/X11/XToolkit.java | 4 +- .../solaris/native/sun/awt/awt_UNIXToolkit.c | 20 ++ .../solaris/native/sun/awt/gtk2_interface.c | 87 ++++++- .../solaris/native/sun/awt/gtk2_interface.h | 133 ++++++++++- .../sun/awt/sun_awt_X11_GtkFileDialogPeer.c | 225 ++++++++++++++++++ .../sun/awt/sun_awt_X11_GtkFileDialogPeer.h | 31 +++ .../solaris/native/sun/awt/swing_GTKEngine.c | 44 +++- .../solaris/native/sun/awt/swing_GTKStyle.c | 30 ++- 13 files changed, 725 insertions(+), 16 deletions(-) create mode 100644 jdk/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java create mode 100644 jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c create mode 100644 jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.h diff --git a/jdk/make/sun/xawt/FILES_c_unix.gmk b/jdk/make/sun/xawt/FILES_c_unix.gmk index 604955e1e6e..5edc187388e 100644 --- a/jdk/make/sun/xawt/FILES_c_unix.gmk +++ b/jdk/make/sun/xawt/FILES_c_unix.gmk @@ -79,4 +79,5 @@ FILES_c = \ gtk2_interface.c \ swing_GTKEngine.c \ swing_GTKStyle.c \ - rect.c + rect.c \ + sun_awt_X11_GtkFileDialogPeer.c diff --git a/jdk/make/sun/xawt/FILES_export_unix.gmk b/jdk/make/sun/xawt/FILES_export_unix.gmk index f09f83242a9..bade1544e0e 100644 --- a/jdk/make/sun/xawt/FILES_export_unix.gmk +++ b/jdk/make/sun/xawt/FILES_export_unix.gmk @@ -33,4 +33,5 @@ FILES_export = \ sun/awt/X11/XDesktopPeer.java \ sun/awt/X11/XToolkit.java \ sun/awt/X11/XComponentPeer.java \ - sun/awt/X11/XInputMethod.java + sun/awt/X11/XInputMethod.java \ + sun/awt/X11/GtkFileDialogPeer.java diff --git a/jdk/make/sun/xawt/mapfile-vers b/jdk/make/sun/xawt/mapfile-vers index 82fe94f63ec..aee09457fb1 100644 --- a/jdk/make/sun/xawt/mapfile-vers +++ b/jdk/make/sun/xawt/mapfile-vers @@ -172,6 +172,7 @@ SUNWprivate_1.1 { Java_sun_awt_UNIXToolkit_load_1stock_1icon; Java_sun_awt_UNIXToolkit_load_1gtk_1icon; Java_sun_awt_UNIXToolkit_nativeSync; + Java_sun_awt_UNIXToolkit_gtkCheckVersionImpl; Java_java_awt_AWTEvent_initIDs; Java_java_awt_event_InputEvent_initIDs; Java_java_awt_event_KeyEvent_initIDs; @@ -396,6 +397,9 @@ SUNWprivate_1.1 { Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetClassValue; Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetPangoFontName; + Java_sun_awt_X11_GtkFileDialogPeer_run; + Java_sun_awt_X11_GtkFileDialogPeer_quit; + Java_sun_print_CUPSPrinter_initIDs; Java_sun_print_CUPSPrinter_getCupsServer; Java_sun_print_CUPSPrinter_getCupsPort; diff --git a/jdk/src/solaris/classes/sun/awt/UNIXToolkit.java b/jdk/src/solaris/classes/sun/awt/UNIXToolkit.java index 23e39cabe49..c35e4859c80 100644 --- a/jdk/src/solaris/classes/sun/awt/UNIXToolkit.java +++ b/jdk/src/solaris/classes/sun/awt/UNIXToolkit.java @@ -314,4 +314,27 @@ public abstract class UNIXToolkit extends SunToolkit } return new RenderingHints(KEY_TEXT_ANTIALIASING, aaHint); } + + private native boolean gtkCheckVersionImpl(int major, int minor, + int micro); + + /** + * Returns {@code true} if the GTK+ library is compatible with the given + * version. + * + * @param major + * The required major version. + * @param minor + * The required minor version. + * @param micro + * The required micro version. + * @return {@code true} if the GTK+ library is compatible with the given + * version. + */ + public boolean checkGtkVersion(int major, int minor, int micro) { + if (loadGTK()) { + return gtkCheckVersionImpl(major, minor, micro); + } + return false; + } } diff --git a/jdk/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java b/jdk/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java new file mode 100644 index 00000000000..5860b396b61 --- /dev/null +++ b/jdk/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java @@ -0,0 +1,134 @@ +/* + * Copyright 2010 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +package sun.awt.X11; + +import java.awt.Dialog; +import java.awt.FileDialog; +import java.awt.peer.FileDialogPeer; +import java.io.File; +import java.io.FilenameFilter; +import javax.swing.SwingUtilities; +import javax.swing.SwingWorker; +import sun.awt.AWTAccessor; + +/** + * FileDialogPeer for the GtkFileChooser. + * + * @author Costantino Cerbo (c.cerbo@gmail.com) + */ +class GtkFileDialogPeer extends XDialogPeer implements FileDialogPeer { + + private FileDialog fd; + + public GtkFileDialogPeer(FileDialog fd) { + super((Dialog) fd); + this.fd = fd; + } + + private native void run(String title, int mode, String dir, String file, + FilenameFilter filter, boolean isMultipleMode); + + private native void quit(); + + /** + * Called exclusively by the native C code. + */ + private void setFileInternal(String directory, String[] filenames) { + AWTAccessor.FileDialogAccessor accessor = AWTAccessor + .getFileDialogAccessor(); + + if (filenames == null) { + accessor.setDirectory(fd, null); + accessor.setFile(fd, null); + accessor.setFiles(fd, null, null); + } else { + accessor.setDirectory(fd, directory); + accessor.setFile(fd, filenames[0]); + accessor.setFiles(fd, directory, filenames); + } + } + + /** + * Called exclusively by the native C code. + */ + private boolean filenameFilterCallback(String fullname) { + if (fd.getFilenameFilter() == null) { + // no filter, accept all. + return true; + } + + File filen = new File(fullname); + return fd.getFilenameFilter().accept(new File(filen.getParent()), + filen.getName()); + } + + @Override + public void setVisible(boolean b) { + XToolkit.awtLock(); + try { + if (b) { + Thread t = new Thread() { + public void run() { + GtkFileDialogPeer.this.run(fd.getTitle(), fd.getMode(), + fd.getDirectory(), fd.getFile(), fd + .getFilenameFilter(), fd + .isMultipleMode()); + fd.setVisible(false); + } + }; + t.start(); + } else { + quit(); + fd.setVisible(false); + } + } finally { + XToolkit.awtUnlock(); + } + } + + @Override + public void dispose() { + quit(); + super.dispose(); + } + + @Override + public void setDirectory(String dir) { + // We do not implement this method because we + // have delegated to FileDialog#setDirectory + } + + @Override + public void setFile(String file) { + // We do not implement this method because we + // have delegated to FileDialog#setFile + } + + @Override + public void setFilenameFilter(FilenameFilter filter) { + // We do not implement this method because we + // have delegated to FileDialog#setFilenameFilter + } +} diff --git a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java index 8676c6affb9..4ab6cd21960 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java @@ -1041,7 +1041,9 @@ public final class XToolkit extends UNIXToolkit implements Runnable { } public FileDialogPeer createFileDialog(FileDialog target) { - FileDialogPeer peer = new XFileDialogPeer(target); + // The current GtkFileChooser is available from GTK+ 2.4 + FileDialogPeer peer = checkGtkVersion(2, 4, 0) ? new GtkFileDialogPeer( + target) : new XFileDialogPeer(target); targetCreatedPeer(target, peer); return peer; } diff --git a/jdk/src/solaris/native/sun/awt/awt_UNIXToolkit.c b/jdk/src/solaris/native/sun/awt/awt_UNIXToolkit.c index f802f9f7c68..b315832b106 100644 --- a/jdk/src/solaris/native/sun/awt/awt_UNIXToolkit.c +++ b/jdk/src/solaris/native/sun/awt/awt_UNIXToolkit.c @@ -260,3 +260,23 @@ Java_sun_awt_SunToolkit_closeSplashScreen(JNIEnv *env, jclass cls) } dlclose(hSplashLib); } + +/* + * Class: sun_awt_UNIXToolkit + * Method: gtkCheckVersionImpl + * Signature: (III)Ljava/lang/String; + */ +JNIEXPORT jboolean JNICALL +Java_sun_awt_UNIXToolkit_gtkCheckVersionImpl(JNIEnv *env, jobject this, + jint major, jint minor, jint micro) +{ + char *ret; + + ret = fp_gtk_check_version(major, minor, micro); + if (ret == NULL) { + return TRUE; + } + + free(ret); + return FALSE; +} diff --git a/jdk/src/solaris/native/sun/awt/gtk2_interface.c b/jdk/src/solaris/native/sun/awt/gtk2_interface.c index e6ede306824..dfa7ef1dfb4 100644 --- a/jdk/src/solaris/native/sun/awt/gtk2_interface.c +++ b/jdk/src/solaris/native/sun/awt/gtk2_interface.c @@ -32,6 +32,7 @@ #include "java_awt_Transparency.h" #define GTK2_LIB "libgtk-x11-2.0.so.0" +#define GTHREAD_LIB "libgthread-2.0.so.0" #define G_TYPE_INVALID G_TYPE_MAKE_FUNDAMENTAL (0) #define G_TYPE_NONE G_TYPE_MAKE_FUNDAMENTAL (1) @@ -75,6 +76,7 @@ const gint SELECTED = 1 << 9; const gint DEFAULT = 1 << 10; static void *gtk2_libhandle = NULL; +static void *gthread_libhandle = NULL; static jmp_buf j; /* Widgets */ @@ -150,7 +152,6 @@ static GtkWidget *gtk2_widgets[_GTK_WIDGET_TYPE_SIZE]; /************************* * Glib function pointers *************************/ -static void (*fp_g_free)(gpointer mem); static gboolean (*fp_g_main_context_iteration)(GMainContext *context, gboolean may_block); @@ -204,9 +205,6 @@ static void (*fp_gdk_drawable_get_size)(GdkDrawable *drawable, /************************ * Gtk function pointers ************************/ -static gchar* (*fp_gtk_check_version)(guint required_major, - guint required_minor, - guint required_micro); static gboolean (*fp_gtk_init_check)(int* argc, char** argv); /* Painting */ @@ -330,7 +328,6 @@ static void (*fp_gtk_menu_shell_append)(GtkMenuShell *menu_shell, static void (*fp_gtk_menu_item_set_submenu)(GtkMenuItem *menu_item, GtkWidget *submenu); static void (*fp_gtk_widget_realize)(GtkWidget *widget); -static void (*fp_gtk_widget_destroy)(GtkWidget *widget); static GdkPixbuf* (*fp_gtk_widget_render_icon)(GtkWidget *widget, const gchar *stock_id, GtkIconSize size, const gchar *detail); static void (*fp_gtk_widget_set_name)(GtkWidget *widget, const gchar *name); @@ -388,6 +385,15 @@ static void* dl_symbol(const char* name) return result; } +static void* dl_symbol_gthread(const char* name) +{ + void* result = dlsym(gthread_libhandle, name); + if (!result) + longjmp(j, NO_SYMBOL_EXCEPTION); + + return result; +} + gboolean gtk2_check_version() { if (gtk2_libhandle != NULL) { @@ -414,6 +420,33 @@ gboolean gtk2_check_version() } } +/** + * Functions for sun_awt_X11_GtkFileDialogPeer.c + */ +void gtk2_file_chooser_load() +{ + fp_gtk_file_chooser_get_filename = dl_symbol( + "gtk_file_chooser_get_filename"); + fp_gtk_file_chooser_dialog_new = dl_symbol("gtk_file_chooser_dialog_new"); + fp_gtk_file_chooser_set_current_folder = dl_symbol( + "gtk_file_chooser_set_current_folder"); + fp_gtk_file_chooser_set_filename = dl_symbol( + "gtk_file_chooser_set_filename"); + fp_gtk_file_filter_add_custom = dl_symbol("gtk_file_filter_add_custom"); + fp_gtk_file_chooser_set_filter = dl_symbol("gtk_file_chooser_set_filter"); + fp_gtk_file_chooser_get_type = dl_symbol("gtk_file_chooser_get_type"); + fp_gtk_file_filter_new = dl_symbol("gtk_file_filter_new"); + fp_gtk_file_chooser_set_do_overwrite_confirmation = dl_symbol( + "gtk_file_chooser_set_do_overwrite_confirmation"); + fp_gtk_file_chooser_set_select_multiple = dl_symbol( + "gtk_file_chooser_set_select_multiple"); + fp_gtk_file_chooser_get_current_folder = dl_symbol( + "gtk_file_chooser_get_current_folder"); + fp_gtk_file_chooser_get_filenames = dl_symbol( + "gtk_file_chooser_get_filenames"); + fp_gtk_g_slist_length = dl_symbol("g_slist_length"); +} + gboolean gtk2_load() { gboolean result; @@ -423,7 +456,9 @@ gboolean gtk2_load() char *gtk_modules_env; gtk2_libhandle = dlopen(GTK2_LIB, RTLD_LAZY | RTLD_LOCAL); - if (gtk2_libhandle == NULL) + gthread_libhandle = dlopen(GTHREAD_LIB, RTLD_LAZY | RTLD_LOCAL); + + if (gtk2_libhandle == NULL || gthread_libhandle == NULL) return FALSE; if (setjmp(j) == 0) @@ -597,6 +632,30 @@ gboolean gtk2_load() fp_gtk_range_get_adjustment = dl_symbol("gtk_range_get_adjustment"); + fp_gtk_widget_hide = dl_symbol("gtk_widget_hide"); + fp_gtk_main_quit = dl_symbol("gtk_main_quit"); + fp_g_signal_connect_data = dl_symbol("g_signal_connect_data"); + fp_gtk_widget_show = dl_symbol("gtk_widget_show"); + fp_gtk_main = dl_symbol("gtk_main"); + + /** + * GLib thread system + */ + fp_g_thread_get_initialized = dl_symbol_gthread( + "g_thread_get_initialized"); + fp_g_thread_init = dl_symbol_gthread("g_thread_init"); + fp_gdk_threads_init = dl_symbol("gdk_threads_init"); + fp_gdk_threads_enter = dl_symbol("gdk_threads_enter"); + fp_gdk_threads_leave = dl_symbol("gdk_threads_leave"); + + /** + * Functions for sun_awt_X11_GtkFileDialogPeer.c + */ + if (fp_gtk_check_version(2, 4, 0) == NULL) { + // The current GtkFileChooser is available from GTK+ 2.4 + gtk2_file_chooser_load(); + } + /* Some functions may be missing in pre-2.4 GTK. We handle them specially here. */ @@ -626,6 +685,10 @@ gboolean gtk2_load() { dlclose(gtk2_libhandle); gtk2_libhandle = NULL; + + dlclose(gthread_libhandle); + gthread_libhandle = NULL; + return FALSE; } @@ -678,6 +741,17 @@ gboolean gtk2_load() */ handler = XSetErrorHandler(NULL); io_handler = XSetIOErrorHandler(NULL); + + if (fp_gtk_check_version(2, 2, 0) == NULL) { + // Init the thread system to use GLib in a thread-safe mode + if (!fp_g_thread_get_initialized()) { + fp_g_thread_init(NULL); + + //According the GTK documentation, gdk_threads_init() should be + //called before gtk_init() or gtk_init_check() + fp_gdk_threads_init(); + } + } result = (*fp_gtk_init_check)(NULL, NULL); XSetErrorHandler(handler); @@ -722,6 +796,7 @@ int gtk2_unload() dlerror(); dlclose(gtk2_libhandle); + dlclose(gthread_libhandle); if ((gtk2_error = dlerror()) != NULL) { return FALSE; diff --git a/jdk/src/solaris/native/sun/awt/gtk2_interface.h b/jdk/src/solaris/native/sun/awt/gtk2_interface.h index bde5ec1bc19..95ca3cecaad 100644 --- a/jdk/src/solaris/native/sun/awt/gtk2_interface.h +++ b/jdk/src/solaris/native/sun/awt/gtk2_interface.h @@ -28,6 +28,21 @@ #include #include +#define _G_TYPE_CIC(ip, gt, ct) ((ct*) ip) +#define G_TYPE_CHECK_INSTANCE_CAST(instance, g_type, c_type) (_G_TYPE_CIC ((instance), (g_type), c_type)) +#define GTK_TYPE_FILE_CHOOSER (fp_gtk_file_chooser_get_type ()) +#define GTK_FILE_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FILE_CHOOSER, GtkFileChooser)) +#define fp_g_signal_connect(instance, detailed_signal, c_handler, data) \ + fp_g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0) +#define G_CALLBACK(f) ((GCallback) (f)) +#define G_TYPE_FUNDAMENTAL_SHIFT (2) +#define G_TYPE_MAKE_FUNDAMENTAL(x) ((GType) ((x) << G_TYPE_FUNDAMENTAL_SHIFT)) +#define G_TYPE_OBJECT G_TYPE_MAKE_FUNDAMENTAL (20) +#define G_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), G_TYPE_OBJECT, GObject)) +#define GTK_STOCK_CANCEL "gtk-cancel" +#define GTK_STOCK_SAVE "gtk-save" +#define GTK_STOCK_OPEN "gtk-open" + typedef enum _WidgetType { BUTTON, /* GtkButton */ @@ -254,7 +269,13 @@ typedef enum /* We define all structure pointers to be void* */ typedef void GError; typedef void GMainContext; -typedef void GSList; + +typedef struct _GSList GSList; +struct _GSList +{ + gpointer data; + GSList *next; +}; typedef void GdkColormap; typedef void GdkDrawable; @@ -556,6 +577,65 @@ struct _GtkProgressBar guint ellipsize : 3; }; +typedef enum { + GTK_RESPONSE_NONE = -1, + GTK_RESPONSE_REJECT = -2, + GTK_RESPONSE_ACCEPT = -3, + GTK_RESPONSE_DELETE_EVENT = -4, + GTK_RESPONSE_OK = -5, + GTK_RESPONSE_CANCEL = -6, + GTK_RESPONSE_CLOSE = -7, + GTK_RESPONSE_YES = -8, + GTK_RESPONSE_NO = -9, + GTK_RESPONSE_APPLY = -10, + GTK_RESPONSE_HELP = -11 +} GtkResponseType; + +typedef struct _GtkWindow GtkWindow; + +typedef struct _GtkFileChooser GtkFileChooser; + +typedef enum { + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, + GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER +} GtkFileChooserAction; + +typedef struct _GtkFileFilter GtkFileFilter; + +typedef enum { + GTK_FILE_FILTER_FILENAME = 1 << 0, + GTK_FILE_FILTER_URI = 1 << 1, + GTK_FILE_FILTER_DISPLAY_NAME = 1 << 2, + GTK_FILE_FILTER_MIME_TYPE = 1 << 3 +} GtkFileFilterFlags; + +typedef struct { + GtkFileFilterFlags contains; + const gchar *filename; + const gchar *uri; + const gchar *display_name; + const gchar *mime_type; +} GtkFileFilterInfo; + +typedef gboolean (*GtkFileFilterFunc)(const GtkFileFilterInfo *filter_info, + gpointer data); + +typedef void (*GDestroyNotify)(gpointer data); + +typedef void (*GCallback)(void); + +typedef struct _GClosure GClosure; + +typedef void (*GClosureNotify)(gpointer data, GClosure *closure); + +typedef enum { + G_CONNECT_AFTER = 1 << 0, G_CONNECT_SWAPPED = 1 << 1 +} GConnectFlags; + +typedef struct _GThreadFunctions GThreadFunctions; + /* * Converts java.lang.String object to UTF-8 character string. */ @@ -569,6 +649,13 @@ const char *getStrFor(JNIEnv *env, jstring value); */ gboolean gtk2_check_version(); +/** + * Returns : + * NULL if the GTK+ library is compatible with the given version, or a string + * describing the version mismatch. + */ +gchar* (*fp_gtk_check_version)(guint required_major, guint required_minor, + guint required_micro); /* * Load the gtk2 library. If the library is already loaded this method has no * effect and returns success. @@ -651,6 +738,7 @@ jobject gtk2_get_setting(JNIEnv *env, Setting property); void gtk2_set_range_value(WidgetType widget_type, jdouble value, jdouble min, jdouble max, jdouble visible); +void (*fp_g_free)(gpointer mem); void (*fp_g_object_unref)(gpointer object); int (*fp_gdk_pixbuf_get_bits_per_sample)(const GdkPixbuf *pixbuf); guchar *(*fp_gdk_pixbuf_get_pixels)(const GdkPixbuf *pixbuf); @@ -660,5 +748,48 @@ int (*fp_gdk_pixbuf_get_n_channels)(const GdkPixbuf *pixbuf); int (*fp_gdk_pixbuf_get_rowstride)(const GdkPixbuf *pixbuf); int (*fp_gdk_pixbuf_get_width)(const GdkPixbuf *pixbuf); GdkPixbuf *(*fp_gdk_pixbuf_new_from_file)(const char *filename, GError **error); +void (*fp_gtk_widget_destroy)(GtkWidget *widget); + + +/** + * Function Pointers for GtkFileChooser + */ +gchar* (*fp_gtk_file_chooser_get_filename)(GtkFileChooser *chooser); +void (*fp_gtk_widget_hide)(GtkWidget *widget); +void (*fp_gtk_main_quit)(void); +GtkWidget* (*fp_gtk_file_chooser_dialog_new)(const gchar *title, + GtkWindow *parent, GtkFileChooserAction action, + const gchar *first_button_text, ...); +gboolean (*fp_gtk_file_chooser_set_current_folder)(GtkFileChooser *chooser, + const gchar *filename); +gboolean (*fp_gtk_file_chooser_set_filename)(GtkFileChooser *chooser, + const char *filename); +void (*fp_gtk_file_filter_add_custom)(GtkFileFilter *filter, + GtkFileFilterFlags needed, GtkFileFilterFunc func, gpointer data, + GDestroyNotify notify); +void (*fp_gtk_file_chooser_set_filter)(GtkFileChooser *chooser, + GtkFileFilter *filter); +GType (*fp_gtk_file_chooser_get_type)(void); +GtkFileFilter* (*fp_gtk_file_filter_new)(void); +void (*fp_gtk_file_chooser_set_do_overwrite_confirmation)( + GtkFileChooser *chooser, gboolean do_overwrite_confirmation); +void (*fp_gtk_file_chooser_set_select_multiple)( + GtkFileChooser *chooser, gboolean select_multiple); +gchar* (*fp_gtk_file_chooser_get_current_folder)(GtkFileChooser *chooser); +GSList* (*fp_gtk_file_chooser_get_filenames)(GtkFileChooser *chooser); +guint (*fp_gtk_g_slist_length)(GSList *list); +gulong (*fp_g_signal_connect_data)(gpointer instance, + const gchar *detailed_signal, GCallback c_handler, gpointer data, + GClosureNotify destroy_data, GConnectFlags connect_flags); +void (*fp_gtk_widget_show)(GtkWidget *widget); +void (*fp_gtk_main)(void); +guint (*fp_gtk_main_level)(void); + + +gboolean (*fp_g_thread_get_initialized)(void); +void (*fp_g_thread_init)(GThreadFunctions *vtable); +void (*fp_gdk_threads_init)(void); +void (*fp_gdk_threads_enter)(void); +void (*fp_gdk_threads_leave)(void); #endif /* !_GTK2_INTERFACE_H */ diff --git a/jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c b/jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c new file mode 100644 index 00000000000..717a38382d7 --- /dev/null +++ b/jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c @@ -0,0 +1,225 @@ +#include +#include +#include +#include +#include "gtk2_interface.h" +#include "sun_awt_X11_GtkFileDialogPeer.h" + +static JavaVM *jvm; +static GtkWidget *dialog = NULL; + +/* To cache some method IDs */ +static jmethodID filenameFilterCallbackMethodID = NULL; +static jmethodID setFileInternalMethodID = NULL; + +static gboolean filenameFilterCallback(const GtkFileFilterInfo * filter_info, gpointer obj) +{ + JNIEnv *env; + jclass cx; + jstring filename; + + env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2); + + if (filenameFilterCallbackMethodID == NULL) { + cx = (*env)->GetObjectClass(env, (jobject) obj); + if (cx == NULL) { + JNU_ThrowInternalError(env, "Could not get file filter class"); + return 0; + } + + filenameFilterCallbackMethodID = (*env)->GetMethodID(env, cx, + "filenameFilterCallback", "(Ljava/lang/String;)Z"); + if (filenameFilterCallbackMethodID == NULL) { + JNU_ThrowInternalError(env, + "Could not get filenameFilterCallback method id"); + return 0; + } + } + + filename = (*env)->NewStringUTF(env, filter_info->filename); + + return (*env)->CallBooleanMethod(env, obj, filenameFilterCallbackMethodID, + filename); +} + +/* + * Class: sun_awt_X11_GtkFileDialogPeer + * Method: quit + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_quit +(JNIEnv * env, jobject jpeer) +{ + if (dialog != NULL) + { + fp_gtk_widget_hide (dialog); + fp_gtk_widget_destroy (dialog); + + fp_gtk_main_quit (); + dialog = NULL; + } +} + +/** + * Convert a GSList to an array of filenames (without the parent folder) + */ +static jobjectArray toFilenamesArray(JNIEnv *env, GSList* list) +{ + jstring str; + jclass stringCls; + GSList *iterator; + jobjectArray array; + int i; + char* entry; + + if (NULL == list) { + return NULL; + } + + stringCls = (*env)->FindClass(env, "java/lang/String"); + if (stringCls == NULL) { + JNU_ThrowInternalError(env, "Could not get java.lang.String class"); + return NULL; + } + + array = (*env)->NewObjectArray(env, fp_gtk_g_slist_length(list), stringCls, + NULL); + if (array == NULL) { + JNU_ThrowInternalError(env, "Could not instantiate array files array"); + return NULL; + } + + i = 0; + for (iterator = list; iterator; iterator = iterator->next) { + entry = (char*) iterator->data; + entry = strrchr(entry, '/') + 1; + str = (*env)->NewStringUTF(env, entry); + (*env)->SetObjectArrayElement(env, array, i, str); + i++; + } + + return array; +} + +static void handle_response(GtkWidget* aDialog, gint responseId, gpointer obj) +{ + JNIEnv *env; + char *current_folder; + GSList *filenames; + jclass cx; + jstring jcurrent_folder; + jobjectArray jfilenames; + + env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2); + current_folder = NULL; + filenames = NULL; + + if (responseId == GTK_RESPONSE_ACCEPT) { + current_folder = fp_gtk_file_chooser_get_current_folder( + GTK_FILE_CHOOSER(dialog)); + filenames = fp_gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog)); + } + + if (setFileInternalMethodID == NULL) { + cx = (*env)->GetObjectClass(env, (jobject) obj); + if (cx == NULL) { + JNU_ThrowInternalError(env, "Could not get GTK peer class"); + return; + } + + setFileInternalMethodID = (*env)->GetMethodID(env, cx, + "setFileInternal", "(Ljava/lang/String;[Ljava/lang/String;)V"); + if (setFileInternalMethodID == NULL) { + JNU_ThrowInternalError(env, + "Could not get setFileInternalMethodID method id"); + return; + } + } + + jcurrent_folder = (*env)->NewStringUTF(env, current_folder); + jfilenames = toFilenamesArray(env, filenames); + + (*env)->CallVoidMethod(env, obj, setFileInternalMethodID, jcurrent_folder, + jfilenames); + fp_g_free(current_folder); + + Java_sun_awt_X11_GtkFileDialogPeer_quit(NULL, NULL); +} + +/* + * Class: sun_awt_X11_GtkFileDialogPeer + * Method: run + * Signature: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/io/FilenameFilter;Z;)V + */ +JNIEXPORT void JNICALL +Java_sun_awt_X11_GtkFileDialogPeer_run(JNIEnv * env, jobject jpeer, + jstring jtitle, jint mode, jstring jdir, jstring jfile, + jobject jfilter, jboolean multiple) +{ + GtkFileFilter *filter; + + if (jvm == NULL) { + (*env)->GetJavaVM(env, &jvm); + } + + fp_gdk_threads_init(); + fp_gdk_threads_enter(); + + const char *title = (*env)->GetStringUTFChars(env, jtitle, 0); + + if (mode == 1) { + /* Save action */ + dialog = fp_gtk_file_chooser_dialog_new(title, NULL, + GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); + } + else { + /* Default action OPEN */ + dialog = fp_gtk_file_chooser_dialog_new(title, NULL, + GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); + + /* Set multiple selection mode, that is allowed only in OPEN action */ + if (multiple) { + fp_gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), + multiple); + } + } + + (*env)->ReleaseStringUTFChars(env, jtitle, title); + + /* Set the directory */ + if (jdir != NULL) { + const char *dir = (*env)->GetStringUTFChars(env, jdir, 0); + fp_gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), dir); + (*env)->ReleaseStringUTFChars(env, jdir, dir); + } + + /* Set the filename */ + if (jfile != NULL) { + const char *filename = (*env)->GetStringUTFChars(env, jfile, 0); + fp_gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), filename); + (*env)->ReleaseStringUTFChars(env, jfile, filename); + } + + /* Set the file filter */ + if (jfilter != NULL) { + filter = fp_gtk_file_filter_new(); + fp_gtk_file_filter_add_custom(filter, GTK_FILE_FILTER_FILENAME, + filenameFilterCallback, jpeer, NULL); + fp_gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter); + } + + /* Other Properties */ + if (fp_gtk_check_version(2, 8, 0) == NULL) { + fp_gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER( + dialog), TRUE); + } + + fp_g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK( + handle_response), jpeer); + fp_gtk_widget_show(dialog); + + fp_gtk_main(); + fp_gdk_threads_leave(); +} diff --git a/jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.h b/jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.h new file mode 100644 index 00000000000..91334b4ebee --- /dev/null +++ b/jdk/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.h @@ -0,0 +1,31 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class sun_awt_X11_GtkFileDialogPeer */ + +#ifndef _Included_sun_awt_X11_GtkFileDialogPeer +#define _Included_sun_awt_X11_GtkFileDialogPeer +#ifdef __cplusplus +extern "C" +{ +#endif + +/* + * Class: sun_awt_X11_GtkFileDialogPeer + * Method: run + * Signature: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/io/FilenameFilter;Z;)V + */ +JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_run +(JNIEnv *, jobject, jstring, jint, jstring, jstring, jobject, jboolean); + +/* + * Class: sun_awt_X11_GtkFileDialogPeer + * Method: quit + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_quit +(JNIEnv *, jobject); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/jdk/src/solaris/native/sun/awt/swing_GTKEngine.c b/jdk/src/solaris/native/sun/awt/swing_GTKEngine.c index c213a17c62d..d0a4aa864fb 100644 --- a/jdk/src/solaris/native/sun/awt/swing_GTKEngine.c +++ b/jdk/src/solaris/native/sun/awt/swing_GTKEngine.c @@ -38,8 +38,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1arrow( jint widget_type, jint state, jint shadow_type, jstring detail, jint x, jint y, jint w, jint h, jint arrow_type) { + fp_gdk_threads_enter(); gtk2_paint_arrow(widget_type, state, shadow_type, getStrFor(env, detail), x, y, w, h, arrow_type, TRUE); + fp_gdk_threads_leave(); } /* @@ -54,8 +56,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1box( jint x, jint y, jint w, jint h, jint synth_state, jint dir) { + fp_gdk_threads_enter(); gtk2_paint_box(widget_type, state, shadow_type, getStrFor(env, detail), x, y, w, h, synth_state, dir); + fp_gdk_threads_leave(); } /* @@ -70,8 +74,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1box_1gap( jint x, jint y, jint w, jint h, jint gap_side, jint gap_x, jint gap_w) { + fp_gdk_threads_enter(); gtk2_paint_box_gap(widget_type, state, shadow_type, getStrFor(env, detail), x, y, w, h, gap_side, gap_x, gap_w); + fp_gdk_threads_leave(); } /* @@ -85,8 +91,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1check( jint widget_type, jint synth_state, jstring detail, jint x, jint y, jint w, jint h) { + fp_gdk_threads_enter(); gtk2_paint_check(widget_type, synth_state, getStrFor(env, detail), x, y, w, h); + fp_gdk_threads_leave(); } /* @@ -100,8 +108,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1expander( jint widget_type, jint state, jstring detail, jint x, jint y, jint w, jint h, jint expander_style) { + fp_gdk_threads_enter(); gtk2_paint_expander(widget_type, state, getStrFor(env, detail), x, y, w, h, expander_style); + fp_gdk_threads_leave(); } /* @@ -115,8 +125,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1extension( jint widget_type, jint state, jint shadow_type, jstring detail, jint x, jint y, jint w, jint h, jint placement) { + fp_gdk_threads_enter(); gtk2_paint_extension(widget_type, state, shadow_type, getStrFor(env, detail), x, y, w, h, placement); + fp_gdk_threads_leave(); } /* @@ -130,8 +142,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1flat_1box( jint widget_type, jint state, jint shadow_type, jstring detail, jint x, jint y, jint w, jint h, jboolean has_focus) { + fp_gdk_threads_enter(); gtk2_paint_flat_box(widget_type, state, shadow_type, getStrFor(env, detail), x, y, w, h, has_focus); + fp_gdk_threads_leave(); } /* @@ -145,8 +159,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1focus( jint widget_type, jint state, jstring detail, jint x, jint y, jint w, jint h) { + fp_gdk_threads_enter(); gtk2_paint_focus(widget_type, state, getStrFor(env, detail), x, y, w, h); + fp_gdk_threads_leave(); } /* @@ -160,8 +176,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1handle( jint widget_type, jint state, jint shadow_type, jstring detail, jint x, jint y, jint w, jint h, jint orientation) { + fp_gdk_threads_enter(); gtk2_paint_handle(widget_type, state, shadow_type, getStrFor(env, detail), x, y, w, h, orientation); + fp_gdk_threads_leave(); } /* @@ -175,8 +193,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1hline( jint widget_type, jint state, jstring detail, jint x, jint y, jint w, jint h) { + fp_gdk_threads_enter(); gtk2_paint_hline(widget_type, state, getStrFor(env, detail), x, y, w, h); + fp_gdk_threads_leave(); } /* @@ -190,8 +210,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1option( jint widget_type, jint synth_state, jstring detail, jint x, jint y, jint w, jint h) { + fp_gdk_threads_enter(); gtk2_paint_option(widget_type, synth_state, getStrFor(env, detail), x, y, w, h); + fp_gdk_threads_leave(); } /* @@ -206,8 +228,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1shadow( jint x, jint y, jint w, jint h, jint synth_state, jint dir) { + fp_gdk_threads_enter(); gtk2_paint_shadow(widget_type, state, shadow_type, getStrFor(env, detail), x, y, w, h, synth_state, dir); + fp_gdk_threads_leave(); } /* @@ -221,8 +245,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1slider( jint widget_type, jint state, jint shadow_type, jstring detail, jint x, jint y, jint w, jint h, jint orientation) { + fp_gdk_threads_enter(); gtk2_paint_slider(widget_type, state, shadow_type, getStrFor(env, detail), x, y, w, h, orientation); + fp_gdk_threads_leave(); } /* @@ -236,8 +262,10 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1vline( jint widget_type, jint state, jstring detail, jint x, jint y, jint w, jint h) { + fp_gdk_threads_enter(); gtk2_paint_vline(widget_type, state, getStrFor(env, detail), x, y, w, h); + fp_gdk_threads_leave(); } /* @@ -250,7 +278,9 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1paint_1background( JNIEnv *env, jobject this, jint widget_type, jint state, jint x, jint y, jint w, jint h) { + fp_gdk_threads_enter(); gtk_paint_background(widget_type, state, x, y, w, h); + fp_gdk_threads_leave(); } /* @@ -262,7 +292,9 @@ JNIEXPORT void JNICALL Java_com_sun_java_swing_plaf_gtk_GTKEngine_nativeStartPainting( JNIEnv *env, jobject this, jint w, jint h) { + fp_gdk_threads_enter(); gtk2_init_painting(w, h); + fp_gdk_threads_leave(); } /* @@ -276,7 +308,9 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_nativeFinishPainting( { jint transparency; gint *buffer = (gint*) (*env)->GetPrimitiveArrayCritical(env, dest, 0); + fp_gdk_threads_enter(); transparency = gtk2_copy_image(buffer, width, height); + fp_gdk_threads_leave(); (*env)->ReleasePrimitiveArrayCritical(env, dest, buffer, 0); return transparency; } @@ -289,7 +323,9 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_nativeFinishPainting( JNIEXPORT void JNICALL Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1switch_1theme( JNIEnv *env, jobject this) { + fp_gdk_threads_enter(); flush_gtk_event_loop(); + fp_gdk_threads_leave(); } /* @@ -300,7 +336,11 @@ JNIEXPORT void JNICALL Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1switch JNIEXPORT jobject JNICALL Java_com_sun_java_swing_plaf_gtk_GTKEngine_native_1get_1gtk_1setting( JNIEnv *env, jobject this, jint property) { - return gtk2_get_setting(env, property); + jobject obj; + fp_gdk_threads_enter(); + obj = gtk2_get_setting(env, property); + fp_gdk_threads_leave(); + return obj; } /* @@ -313,5 +353,7 @@ Java_com_sun_java_swing_plaf_gtk_GTKEngine_nativeSetRangeValue( JNIEnv *env, jobject this, jint widget_type, jdouble value, jdouble min, jdouble max, jdouble visible) { + fp_gdk_threads_enter(); gtk2_set_range_value(widget_type, value, min, max, visible); + fp_gdk_threads_leave(); } diff --git a/jdk/src/solaris/native/sun/awt/swing_GTKStyle.c b/jdk/src/solaris/native/sun/awt/swing_GTKStyle.c index 111ae47b311..076e701681b 100644 --- a/jdk/src/solaris/native/sun/awt/swing_GTKStyle.c +++ b/jdk/src/solaris/native/sun/awt/swing_GTKStyle.c @@ -36,7 +36,11 @@ JNIEXPORT jint JNICALL Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetXThickness( JNIEnv *env, jclass klass, jint widget_type) { - return gtk2_get_xthickness(env, widget_type); + jint ret; + fp_gdk_threads_enter(); + ret = gtk2_get_xthickness(env, widget_type); + fp_gdk_threads_leave(); + return ret; } /* @@ -48,7 +52,11 @@ JNIEXPORT jint JNICALL Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetYThickness( JNIEnv *env, jclass klass, jint widget_type) { - return gtk2_get_ythickness(env, widget_type); + jint ret; + fp_gdk_threads_enter(); + ret = gtk2_get_ythickness(env, widget_type); + fp_gdk_threads_leave(); + return ret; } /* @@ -61,7 +69,11 @@ Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetColorForState( JNIEnv *env, jclass klass, jint widget_type, jint state_type, jint type_id) { - return gtk2_get_color_for_state(env, widget_type, state_type, type_id); + jint ret; + fp_gdk_threads_enter(); + ret = gtk2_get_color_for_state(env, widget_type, state_type, type_id); + fp_gdk_threads_leave(); + return ret; } /* @@ -73,7 +85,11 @@ JNIEXPORT jobject JNICALL Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetClassValue( JNIEnv *env, jclass klass, jint widget_type, jstring key) { - return gtk2_get_class_value(env, widget_type, key); + jobject ret; + fp_gdk_threads_enter(); + ret = gtk2_get_class_value(env, widget_type, key); + fp_gdk_threads_leave(); + return ret; } /* @@ -85,5 +101,9 @@ JNIEXPORT jstring JNICALL Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetPangoFontName( JNIEnv *env, jclass klass, jint widget_type) { - return gtk2_get_pango_font_name(env, widget_type); + jstring ret; + fp_gdk_threads_enter(); + ret = gtk2_get_pango_font_name(env, widget_type); + fp_gdk_threads_leave(); + return ret; } From 46ebf10e260dbc24210c4dd6cf8f2cde166ff40b Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Thu, 29 Apr 2010 15:50:40 +0800 Subject: [PATCH 09/38] 6947487: use HexDumpEncoder.encodeBuffer() Reviewed-by: mullan --- .../com/sun/security/auth/module/Krb5LoginModule.java | 4 ++-- .../com/sun/security/jgss/AuthorizationDataEntry.java | 4 ++-- .../classes/javax/security/auth/kerberos/KeyImpl.java | 4 ++-- jdk/src/share/classes/sun/security/krb5/EncryptionKey.java | 7 ++++--- .../classes/sun/security/provider/certpath/CertId.java | 6 +++--- jdk/src/share/classes/sun/security/tools/KeyTool.java | 2 +- 6 files changed, 14 insertions(+), 13 deletions(-) diff --git a/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java b/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java index 55972eefe89..8e16c4d4a55 100644 --- a/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java +++ b/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2010 Sun Microsystems, Inc. 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 @@ -717,7 +717,7 @@ public class Krb5LoginModule implements LoginModule { for (int i = 0; i < encKeys.length; i++) { System.out.println("EncryptionKey: keyType=" + encKeys[i].getEType() + " keyBytes (hex dump)=" + - hd.encode(encKeys[i].getBytes())); + hd.encodeBuffer(encKeys[i].getBytes())); } } diff --git a/jdk/src/share/classes/com/sun/security/jgss/AuthorizationDataEntry.java b/jdk/src/share/classes/com/sun/security/jgss/AuthorizationDataEntry.java index 0386792a7c2..b885b037d50 100644 --- a/jdk/src/share/classes/com/sun/security/jgss/AuthorizationDataEntry.java +++ b/jdk/src/share/classes/com/sun/security/jgss/AuthorizationDataEntry.java @@ -1,5 +1,5 @@ /* - * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009-2010 Sun Microsystems, Inc. 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 @@ -63,6 +63,6 @@ final public class AuthorizationDataEntry { public String toString() { return "AuthorizationDataEntry: type="+type+", data=" + data.length + " bytes:\n" + - new sun.misc.HexDumpEncoder().encode(data); + new sun.misc.HexDumpEncoder().encodeBuffer(data); } } diff --git a/jdk/src/share/classes/javax/security/auth/kerberos/KeyImpl.java b/jdk/src/share/classes/javax/security/auth/kerberos/KeyImpl.java index a91f3925267..f7a724b146b 100644 --- a/jdk/src/share/classes/javax/security/auth/kerberos/KeyImpl.java +++ b/jdk/src/share/classes/javax/security/auth/kerberos/KeyImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2010 Sun Microsystems, Inc. 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 @@ -205,7 +205,7 @@ class KeyImpl implements SecretKey, Destroyable, Serializable { + " keyBytes (hex dump)=" + (keyBytes == null || keyBytes.length == 0 ? " Empty Key" : - '\n' + hd.encode(keyBytes) + '\n' + hd.encodeBuffer(keyBytes) + '\n'); diff --git a/jdk/src/share/classes/sun/security/krb5/EncryptionKey.java b/jdk/src/share/classes/sun/security/krb5/EncryptionKey.java index 15d6d78c04d..e67d504f617 100644 --- a/jdk/src/share/classes/sun/security/krb5/EncryptionKey.java +++ b/jdk/src/share/classes/sun/security/krb5/EncryptionKey.java @@ -1,5 +1,5 @@ /* - * Portions Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved. + * Portions Copyright 2000-2010 Sun Microsystems, Inc. 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 @@ -499,8 +499,9 @@ public class EncryptionKey + " kvno=" + kvno + " keyValue (hex dump)=" + (keyValue == null || keyValue.length == 0 ? - " Empty Key" : '\n' + Krb5.hexDumper.encode(keyValue) - + '\n')); + " Empty Key" : '\n' + + Krb5.hexDumper.encodeBuffer(keyValue) + + '\n')); } /** diff --git a/jdk/src/share/classes/sun/security/provider/certpath/CertId.java b/jdk/src/share/classes/sun/security/provider/certpath/CertId.java index 20e9aa2a789..e85ed531b99 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/CertId.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/CertId.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2010 Sun Microsystems, Inc. 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 @@ -96,9 +96,9 @@ public class CertId { HexDumpEncoder encoder = new HexDumpEncoder(); System.out.println("Issuer Certificate is " + issuerCert); System.out.println("issuerNameHash is " + - encoder.encode(issuerNameHash)); + encoder.encodeBuffer(issuerNameHash)); System.out.println("issuerKeyHash is " + - encoder.encode(issuerKeyHash)); + encoder.encodeBuffer(issuerKeyHash)); System.out.println("SerialNumber is " + serialNumber.getNumber()); } } diff --git a/jdk/src/share/classes/sun/security/tools/KeyTool.java b/jdk/src/share/classes/sun/security/tools/KeyTool.java index bd03c696e0e..2539d43e14b 100644 --- a/jdk/src/share/classes/sun/security/tools/KeyTool.java +++ b/jdk/src/share/classes/sun/security/tools/KeyTool.java @@ -2620,7 +2620,7 @@ public final class KeyTool { if (v.length == 0) { out.println(rb.getString("(Empty value)")); } else { - new sun.misc.HexDumpEncoder().encode(ext.getExtensionValue(), out); + new sun.misc.HexDumpEncoder().encodeBuffer(ext.getExtensionValue(), out); out.println(); } } From 20fbeb53cdd1dacc3f5967842aa782a4eb872e0a Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Thu, 29 Apr 2010 15:51:10 +0800 Subject: [PATCH 10/38] 6844193: support max_retries in krb5.conf Reviewed-by: valeriep --- .../classes/sun/security/krb5/Config.java | 4 +- .../classes/sun/security/krb5/KrbKdcReq.java | 141 +++++++----- .../sun/security/krb5/auto/MaxRetries.java | 203 ++++++++++++++++++ 3 files changed, 293 insertions(+), 55 deletions(-) create mode 100644 jdk/test/sun/security/krb5/auto/MaxRetries.java diff --git a/jdk/src/share/classes/sun/security/krb5/Config.java b/jdk/src/share/classes/sun/security/krb5/Config.java index 3cc209c9f21..3980deb8e2d 100644 --- a/jdk/src/share/classes/sun/security/krb5/Config.java +++ b/jdk/src/share/classes/sun/security/krb5/Config.java @@ -1,5 +1,5 @@ /* - * Portions Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved. + * Portions Copyright 2000-2010 Sun Microsystems, Inc. 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 @@ -109,7 +109,7 @@ public class Config { public static synchronized void refresh() throws KrbException { singleton = new Config(); KeyTab.refresh(); - KrbKdcReq.KdcAccessibility.reset(); + KrbKdcReq.initStatic(); } diff --git a/jdk/src/share/classes/sun/security/krb5/KrbKdcReq.java b/jdk/src/share/classes/sun/security/krb5/KrbKdcReq.java index 389fd04be4e..74c5edab291 100644 --- a/jdk/src/share/classes/sun/security/krb5/KrbKdcReq.java +++ b/jdk/src/share/classes/sun/security/krb5/KrbKdcReq.java @@ -1,5 +1,5 @@ /* - * Portions Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved. + * Portions Copyright 2000-2010 Sun Microsystems, Inc. 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 @@ -51,28 +51,31 @@ import java.util.HashSet; public abstract class KrbKdcReq { - // Currently there is no option to specify retries - // in the kerberos configuration file - - private static final int DEFAULT_KDC_RETRY_LIMIT = Krb5.KDC_RETRY_LIMIT; + // The following settings can be configured in [libdefaults] + // section of krb5.conf, which are global for all realms. Each of + // them can also be defined in a realm, which overrides value here. /** - * Default timeout period when requesting a ticket from a KDC. - * If not specified in the configuration file, - * a value of 30 seconds is used. + * max retry time for a single KDC, default Krb5.KDC_RETRY_LIMIT (3) */ - public static final int DEFAULT_KDC_TIMEOUT; // milliseconds + private static int defaultKdcRetryLimit; + /** + * timeout requesting a ticket from KDC, in millisec, default 30 sec + */ + private static int defaultKdcTimeout; + /** + * max UDP packet size, default unlimited (-1) + */ + private static int defaultUdpPrefLimit; private static final boolean DEBUG = Krb5.DEBUG; - private static int udpPrefLimit = -1; - private static final String BAD_POLICY_KEY = "krb5.kdc.bad.policy"; /** * What to do when a KDC is unavailable, specified in the * java.security file with key krb5.kdc.bad.policy. - * Possible values can be TRY_LAST or TRY_LESS + * Possible values can be TRY_LAST or TRY_LESS. Reloaded when refreshed. */ private enum BpType { NONE, TRY_LAST, TRY_LESS @@ -80,9 +83,16 @@ public abstract class KrbKdcReq { private static int tryLessMaxRetries = 1; private static int tryLessTimeout = 5000; - private static final BpType badPolicy; + private static BpType badPolicy; static { + initStatic(); + } + + /** + * Read global settings + */ + public static void initStatic() { String value = AccessController.doPrivileged( new PrivilegedAction() { public String run() { @@ -95,9 +105,21 @@ public abstract class KrbKdcReq { if ("tryless".equals(ss[0])) { if (ss.length > 1) { String[] params = ss[1].split(","); - tryLessMaxRetries = Integer.parseInt(params[0]); - if (params.length > 1) { - tryLessTimeout = Integer.parseInt(params[1]); + try { + int tmp0 = Integer.parseInt(params[0]); + if (params.length > 1) { + tryLessTimeout = Integer.parseInt(params[1]); + } + // Assign here in case of exception at params[1] + tryLessMaxRetries = tmp0; + } catch (NumberFormatException nfe) { + // Ignored. Please note that tryLess is recognized and + // used, parameters using default values + if (DEBUG) { + System.out.println("Invalid " + BAD_POLICY_KEY + + " parameter for tryLess: " + + value + ", use default"); + } } } badPolicy = BpType.TRY_LESS; @@ -110,30 +132,33 @@ public abstract class KrbKdcReq { badPolicy = BpType.NONE; } - /* - * Get default timeout. - */ int timeout = -1; + int max_retries = -1; + int udf_pref_limit = -1; + try { Config cfg = Config.getInstance(); String temp = cfg.getDefault("kdc_timeout", "libdefaults"); timeout = parsePositiveIntString(temp); + temp = cfg.getDefault("max_retries", "libdefaults"); + max_retries = parsePositiveIntString(temp); temp = cfg.getDefault("udp_preference_limit", "libdefaults"); - udpPrefLimit = parsePositiveIntString(temp); + udf_pref_limit = parsePositiveIntString(temp); } catch (Exception exc) { - // ignore any exceptions; use the default time out values + // ignore any exceptions; use default values if (DEBUG) { - System.out.println ("Exception in getting kdc_timeout value, " + - "using default value " + + System.out.println ("Exception in getting KDC communication " + + "settings, using default value " + exc.getMessage()); } } + defaultKdcTimeout = timeout > 0 ? timeout : 30*1000; // 30 seconds + defaultKdcRetryLimit = + max_retries > 0 ? max_retries : Krb5.KDC_RETRY_LIMIT; + defaultUdpPrefLimit = udf_pref_limit; - if (timeout > 0) - DEFAULT_KDC_TIMEOUT = timeout; - else - DEFAULT_KDC_TIMEOUT = 30*1000; // 30 seconds + KdcAccessibility.reset(); } protected byte[] obuf; @@ -151,6 +176,9 @@ public abstract class KrbKdcReq { public String send(String realm) throws IOException, KrbException { + int udpPrefLimit = getRealmSpecificValue( + realm, "udp_preference_limit", defaultUdpPrefLimit); + boolean useTCP = (udpPrefLimit > 0 && (obuf != null && obuf.length > udpPrefLimit)); @@ -213,9 +241,10 @@ public abstract class KrbKdcReq { return; int port = Krb5.KDC_INET_DEFAULT_PORT; - int retries = DEFAULT_KDC_RETRY_LIMIT; - int timeout = getKdcTimeout(realm); - + int retries = getRealmSpecificValue( + realm, "max_retries", defaultKdcRetryLimit); + int timeout = getRealmSpecificValue( + realm, "kdc_timeout", defaultKdcTimeout); if (badPolicy == BpType.TRY_LESS && KdcAccessibility.isBad(tempKdc)) { if (retries > tryLessMaxRetries) { @@ -322,6 +351,12 @@ public abstract class KrbKdcReq { if (useTCP) { TCPClient kdcClient = new TCPClient(kdc, port); + if (DEBUG) { + System.out.println(">>> KDCCommunication: kdc=" + kdc + + " TCP:" + + port + + ", #bytes=" + obuf.length); + } try { /* * Send the data to the kdc. @@ -336,7 +371,7 @@ public abstract class KrbKdcReq { } } else { - // For each KDC we try DEFAULT_KDC_RETRY_LIMIT (3) times to + // For each KDC we try defaultKdcRetryLimit times to // get the response for (int i=1; i <= retries; i++) { UDPClient kdcClient = new UDPClient(kdc, port, timeout); @@ -382,37 +417,37 @@ public abstract class KrbKdcReq { } /** - * Returns a timeout value for the KDC of the given realm. - * A KDC-specific timeout, if specified in the config file, - * overrides the default timeout (which may also be specified - * in the config file). Default timeout is returned if null - * is specified for realm. - * @param realm the realm which kdc's timeout is requested - * @return KDC timeout + * Returns krb5.conf setting of {@code key} for a specfic realm, + * which can be: + * 1. defined in the sub-stanza for the given realm inside [realms], or + * 2. defined in [libdefaults], or + * 3. defValue + * @param realm the given realm in which the setting is requested. Returns + * the global setting if null + * @param key the key for the setting + * @param defValue default value + * @return a value for the key */ - private int getKdcTimeout(String realm) - { - int timeout = DEFAULT_KDC_TIMEOUT; + private int getRealmSpecificValue(String realm, String key, int defValue) { + int v = defValue; - if (realm == null) - return timeout; + if (realm == null) return v; - int tempTimeout = -1; + int temp = -1; try { - String temp = - Config.getInstance().getDefault("kdc_timeout", realm); - tempTimeout = parsePositiveIntString(temp); + String value = + Config.getInstance().getDefault(key, realm); + temp = parsePositiveIntString(value); } catch (Exception exc) { + // Ignored, defValue will be picked up } - if (tempTimeout > 0) - timeout = tempTimeout; + if (temp > 0) v = temp; - return timeout; + return v; } - private static int parsePositiveIntString(String intString) - { + private static int parsePositiveIntString(String intString) { if (intString == null) return -1; @@ -461,7 +496,7 @@ public abstract class KrbKdcReq { return bads.contains(kdc); } - public static synchronized void reset() { + private static synchronized void reset() { if (DEBUG) { System.out.println(">>> KdcAccessibility: reset"); } diff --git a/jdk/test/sun/security/krb5/auto/MaxRetries.java b/jdk/test/sun/security/krb5/auto/MaxRetries.java new file mode 100644 index 00000000000..4a995bb7f3e --- /dev/null +++ b/jdk/test/sun/security/krb5/auto/MaxRetries.java @@ -0,0 +1,203 @@ +/* + * Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6844193 + * @run main/timeout=300 MaxRetries + * @summary support max_retries in krb5.conf + */ + +import java.io.*; +import java.security.Security; + +public class MaxRetries { + public static void main(String[] args) + throws Exception { + + System.setProperty("sun.security.krb5.debug", "true"); + new OneKDC(null).writeJAASConf(); + System.setProperty("java.security.krb5.conf", "alternative-krb5.conf"); + + // For tryLast + Security.setProperty("krb5.kdc.bad.policy", "trylast"); + rewriteMaxRetries(4); + test1(4000, 6); // 1 1 1 1 2 2 + test1(4000, 2); // 2 2 + + rewriteMaxRetries(1); + test1(1000, 3); // 1 2 2 + test1(1000, 2); // 2 2 + + rewriteMaxRetries(-1); + test1(5000, 4); // 1 1 2 2 + test1(5000, 2); // 2 2 + + // For tryLess + Security.setProperty("krb5.kdc.bad.policy", "tryless"); + rewriteMaxRetries(4); + test1(4000, 7); // 1 1 1 1 2 1 2 + test1(4000, 4); // 1 2 1 2 + + rewriteMaxRetries(1); + test1(1000, 4); // 1 2 1 2 + test1(1000, 4); // 1 2 1 2 + + rewriteMaxRetries(-1); + test1(5000, 5); // 1 1 2 1 2 + test1(5000, 4); // 1 2 1 2 + + rewriteUdpPrefLimit(-1, -1); // default, no limit + test2("UDP"); + + rewriteUdpPrefLimit(10, -1); // global rules + test2("TCP"); + + rewriteUdpPrefLimit(10, 10000); // realm rules + test2("UDP"); + + rewriteUdpPrefLimit(10000, 10); // realm rules + test2("TCP"); + } + + /** + * One round of test for max_retries and timeout. + * @param timeout the expected timeout + * @param count the expected total try + */ + private static void test1(int timeout, int count) throws Exception { + String timeoutTag = "timeout=" + timeout; + ByteArrayOutputStream bo = new ByteArrayOutputStream(); + PrintStream oldout = System.out; + System.setOut(new PrintStream(bo)); + Context c = Context.fromJAAS("client"); + System.setOut(oldout); + + String[] lines = new String(bo.toByteArray()).split("\n"); + System.out.println("----------------- TEST (" + timeout + "," + + count + ") -----------------"); + for (String line: lines) { + if (line.startsWith(">>> KDCCommunication")) { + System.out.println(line); + if (line.indexOf(timeoutTag) < 0) { + throw new Exception("Wrong timeout value"); + } + count--; + } + } + if (count != 0) { + throw new Exception("Retry count is " + count + " less"); + } + } + + /** + * One round of test for udp_preference_limit. + * @param proto the expected protocol used + */ + private static void test2(String proto) throws Exception { + ByteArrayOutputStream bo = new ByteArrayOutputStream(); + PrintStream oldout = System.out; + System.setOut(new PrintStream(bo)); + Context c = Context.fromJAAS("client"); + System.setOut(oldout); + + int count = 2; + String[] lines = new String(bo.toByteArray()).split("\n"); + System.out.println("----------------- TEST -----------------"); + for (String line: lines) { + if (line.startsWith(">>> KDCCommunication")) { + System.out.println(line); + count--; + if (line.indexOf(proto) < 0) { + throw new Exception("Wrong timeout value"); + } + } + } + if (count != 0) { + throw new Exception("Retry count is " + count + " less"); + } + } + + /** + * Set udp_preference_limit for global and realm + */ + private static void rewriteUdpPrefLimit(int global, int realm) + throws Exception { + BufferedReader fr = new BufferedReader(new FileReader(OneKDC.KRB5_CONF)); + FileWriter fw = new FileWriter("alternative-krb5.conf"); + while (true) { + String s = fr.readLine(); + if (s == null) { + break; + } + if (s.startsWith("[realms]")) { + // Reconfig global setting + if (global != -1) { + fw.write("udp_preference_limit = " + global + "\n"); + } + } else if (s.trim().startsWith("kdc = ")) { + if (realm != -1) { + // Reconfig for realm + fw.write(" udp_preference_limit = " + realm + "\n"); + } + } + fw.write(s + "\n"); + } + fr.close(); + fw.close(); + sun.security.krb5.Config.refresh(); + } + + /** + * Set max_retries and timeout value for realm. The global value is always + * 2 and 5000. + * @param value max_retries and timeout/1000 for a realm, -1 means none. + */ + private static void rewriteMaxRetries(int value) throws Exception { + BufferedReader fr = new BufferedReader(new FileReader(OneKDC.KRB5_CONF)); + FileWriter fw = new FileWriter("alternative-krb5.conf"); + while (true) { + String s = fr.readLine(); + if (s == null) { + break; + } + if (s.startsWith("[realms]")) { + // Reconfig global setting + fw.write("max_retries = 2\n"); + fw.write("kdc_timeout = 5000\n"); + } else if (s.trim().startsWith("kdc = ")) { + if (value != -1) { + // Reconfig for realm + fw.write(" max_retries = " + value + "\n"); + fw.write(" kdc_timeout = " + (value*1000) + "\n"); + } + // Add a bad KDC as the first candidate + fw.write(" kdc = localhost:33333\n"); + } + fw.write(s + "\n"); + } + fr.close(); + fw.close(); + sun.security.krb5.Config.refresh(); + } +} From ac7a6db631d1bb905a0be8b53eafb29cc3a85286 Mon Sep 17 00:00:00 2001 From: Alexander Potochkin Date: Thu, 29 Apr 2010 18:38:25 +0400 Subject: [PATCH 11/38] 6899413: Fix for CR #6878399 should be refactored Reviewed-by: peterz --- .../classes/javax/swing/JEditorPane.java | 15 +++-- jdk/src/share/classes/javax/swing/JList.java | 24 +++---- jdk/src/share/classes/javax/swing/JTable.java | 21 ++++--- .../share/classes/javax/swing/JTextField.java | 2 +- jdk/src/share/classes/javax/swing/JTree.java | 12 ++-- .../classes/javax/swing/SwingUtilities.java | 63 +++++++++---------- .../javax/swing/text/JTextComponent.java | 12 ++-- 7 files changed, 70 insertions(+), 79 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/JEditorPane.java b/jdk/src/share/classes/javax/swing/JEditorPane.java index eaf61f1e60e..acd825c1d96 100644 --- a/jdk/src/share/classes/javax/swing/JEditorPane.java +++ b/jdk/src/share/classes/javax/swing/JEditorPane.java @@ -1330,8 +1330,9 @@ public class JEditorPane extends JTextComponent { */ public Dimension getPreferredSize() { Dimension d = super.getPreferredSize(); - JViewport port = SwingUtilities.getParentViewport(this); - if (port != null) { + Container parent = SwingUtilities.getUnwrappedParent(this); + if (parent instanceof JViewport) { + JViewport port = (JViewport) parent; TextUI ui = getUI(); int prefWidth = d.width; int prefHeight = d.height; @@ -1452,8 +1453,9 @@ public class JEditorPane extends JTextComponent { * match its own, false otherwise */ public boolean getScrollableTracksViewportWidth() { - JViewport port = SwingUtilities.getParentViewport(this); - if (port != null) { + Container parent = SwingUtilities.getUnwrappedParent(this); + if (parent instanceof JViewport) { + JViewport port = (JViewport) parent; TextUI ui = getUI(); int w = port.getWidth(); Dimension min = ui.getMinimumSize(this); @@ -1474,8 +1476,9 @@ public class JEditorPane extends JTextComponent { * false otherwise */ public boolean getScrollableTracksViewportHeight() { - JViewport port = SwingUtilities.getParentViewport(this); - if (port != null) { + Container parent = SwingUtilities.getUnwrappedParent(this); + if (parent instanceof JViewport) { + JViewport port = (JViewport) parent; TextUI ui = getUI(); int h = port.getHeight(); Dimension min = ui.getMinimumSize(this); diff --git a/jdk/src/share/classes/javax/swing/JList.java b/jdk/src/share/classes/javax/swing/JList.java index 8a86bda547d..10aa3adf93d 100644 --- a/jdk/src/share/classes/javax/swing/JList.java +++ b/jdk/src/share/classes/javax/swing/JList.java @@ -25,17 +25,7 @@ package javax.swing; -import java.awt.Color; -import java.awt.Component; -import java.awt.Cursor; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.GraphicsEnvironment; -import java.awt.HeadlessException; -import java.awt.Insets; -import java.awt.Point; -import java.awt.Rectangle; +import java.awt.*; import java.awt.event.*; import java.util.Vector; @@ -2779,9 +2769,9 @@ public class JList extends JComponent implements Scrollable, Accessible getVisibleRowCount() <= 0) { return true; } - JViewport port = SwingUtilities.getParentViewport(this); - if (port != null) { - return port.getWidth() > getPreferredSize().width; + Container parent = SwingUtilities.getUnwrappedParent(this); + if (parent instanceof JViewport) { + return parent.getWidth() > getPreferredSize().width; } return false; } @@ -2805,9 +2795,9 @@ public class JList extends JComponent implements Scrollable, Accessible getVisibleRowCount() <= 0) { return true; } - JViewport port = SwingUtilities.getParentViewport(this); - if (port != null) { - return port.getHeight() > getPreferredSize().height; + Container parent = SwingUtilities.getUnwrappedParent(this); + if (parent instanceof JViewport) { + return parent.getHeight() > getPreferredSize().height; } return false; } diff --git a/jdk/src/share/classes/javax/swing/JTable.java b/jdk/src/share/classes/javax/swing/JTable.java index 236e59102c1..09157ca93f8 100644 --- a/jdk/src/share/classes/javax/swing/JTable.java +++ b/jdk/src/share/classes/javax/swing/JTable.java @@ -719,8 +719,9 @@ public class JTable extends JComponent implements TableModelListener, Scrollable * @see #addNotify */ protected void configureEnclosingScrollPane() { - JViewport port = SwingUtilities.getParentViewport(this); - if (port != null) { + Container parent = SwingUtilities.getUnwrappedParent(this); + if (parent instanceof JViewport) { + JViewport port = (JViewport) parent; Container gp = port.getParent(); if (gp instanceof JScrollPane) { JScrollPane scrollPane = (JScrollPane)gp; @@ -752,8 +753,9 @@ public class JTable extends JComponent implements TableModelListener, Scrollable * from configureEnclosingScrollPane() and updateUI() in a safe manor. */ private void configureEnclosingScrollPaneUI() { - JViewport port = SwingUtilities.getParentViewport(this); - if (port != null) { + Container parent = SwingUtilities.getUnwrappedParent(this); + if (parent instanceof JViewport) { + JViewport port = (JViewport) parent; Container gp = port.getParent(); if (gp instanceof JScrollPane) { JScrollPane scrollPane = (JScrollPane)gp; @@ -822,8 +824,9 @@ public class JTable extends JComponent implements TableModelListener, Scrollable * @since 1.3 */ protected void unconfigureEnclosingScrollPane() { - JViewport port = SwingUtilities.getParentViewport(this); - if (port != null) { + Container parent = SwingUtilities.getUnwrappedParent(this); + if (parent instanceof JViewport) { + JViewport port = (JViewport) parent; Container gp = port.getParent(); if (gp instanceof JScrollPane) { JScrollPane scrollPane = (JScrollPane)gp; @@ -5217,10 +5220,10 @@ public class JTable extends JComponent implements TableModelListener, Scrollable * @see #getFillsViewportHeight */ public boolean getScrollableTracksViewportHeight() { - JViewport port = SwingUtilities.getParentViewport(this); + Container parent = SwingUtilities.getUnwrappedParent(this); return getFillsViewportHeight() - && port != null - && port.getHeight() > getPreferredSize().height; + && parent instanceof JViewport + && parent.getHeight() > getPreferredSize().height; } /** diff --git a/jdk/src/share/classes/javax/swing/JTextField.java b/jdk/src/share/classes/javax/swing/JTextField.java index 24a3408d1b4..e1e6b640c65 100644 --- a/jdk/src/share/classes/javax/swing/JTextField.java +++ b/jdk/src/share/classes/javax/swing/JTextField.java @@ -292,7 +292,7 @@ public class JTextField extends JTextComponent implements SwingConstants { */ @Override public boolean isValidateRoot() { - return SwingUtilities.getParentViewport(this) == null; + return !(SwingUtilities.getUnwrappedParent(this) instanceof JViewport); } diff --git a/jdk/src/share/classes/javax/swing/JTree.java b/jdk/src/share/classes/javax/swing/JTree.java index 55815b81dc2..788aeab1fc1 100644 --- a/jdk/src/share/classes/javax/swing/JTree.java +++ b/jdk/src/share/classes/javax/swing/JTree.java @@ -3498,9 +3498,9 @@ public class JTree extends JComponent implements Scrollable, Accessible * @see Scrollable#getScrollableTracksViewportWidth */ public boolean getScrollableTracksViewportWidth() { - JViewport port = SwingUtilities.getParentViewport(this); - if (port != null) { - return port.getWidth() > getPreferredSize().width; + Container parent = SwingUtilities.getUnwrappedParent(this); + if (parent instanceof JViewport) { + return parent.getWidth() > getPreferredSize().width; } return false; } @@ -3515,9 +3515,9 @@ public class JTree extends JComponent implements Scrollable, Accessible * @see Scrollable#getScrollableTracksViewportHeight */ public boolean getScrollableTracksViewportHeight() { - JViewport port = SwingUtilities.getParentViewport(this); - if (port != null) { - return port.getHeight() > getPreferredSize().height; + Container parent = SwingUtilities.getUnwrappedParent(this); + if (parent instanceof JViewport) { + return parent.getHeight() > getPreferredSize().height; } return false; } diff --git a/jdk/src/share/classes/javax/swing/SwingUtilities.java b/jdk/src/share/classes/javax/swing/SwingUtilities.java index 1221c4bce74..65b267eb8f3 100644 --- a/jdk/src/share/classes/javax/swing/SwingUtilities.java +++ b/jdk/src/share/classes/javax/swing/SwingUtilities.java @@ -1969,58 +1969,53 @@ public class SwingUtilities implements SwingConstants } /** - * Looks for the first ancestor of the {@code component} + * Returns the first ancestor of the {@code component} * which is not an instance of {@link JLayer}. - * If this ancestor is an instance of {@code JViewport}, - * this {@code JViewport} is returned, otherwise returns {@code null}. - * The following way of obtaining the parent {@code JViewport} - * is not recommended any more: - *

-     * JViewport port = null;
-     * Container parent = component.getParent();
-     * // not recommended any more
-     * if(parent instanceof JViewport) {
-     *     port = (JViewport) parent;
-     * }
-     * 
- * Here is the way to go: - *
-     * // the correct way:
-     * JViewport port = SwingUtilities.getParentViewport(component);
-     * 
- * @param component {@code Component} to get the parent {@code JViewport} of. - * @return the {@code JViewport} instance for the {@code component} - * or {@code null} + * + * @param component {@code Component} to get + * the first ancestor of, which is not a {@link JLayer} instance. + * + * @return the first ancestor of the {@code component} + * which is not an instance of {@link JLayer}. + * If such an ancestor can not be found, {@code null} is returned. + * * @throws NullPointerException if {@code component} is {@code null} + * @see JLayer * * @since 1.7 */ - public static JViewport getParentViewport(Component component) { - do { - component = component.getParent(); - if (component instanceof JViewport) { - return (JViewport) component; - } - } while(component instanceof JLayer); - return null; + public static Container getUnwrappedParent(Component component) { + Container parent = component.getParent(); + while(parent instanceof JLayer) { + parent = parent.getParent(); + } + return parent; } /** * Returns the first {@code JViewport}'s descendant - * which is not an instance of {@code JLayer} or {@code null}. + * which is not an instance of {@code JLayer}. + * If such a descendant can not be found, {@code null} is returned. * * If the {@code viewport}'s view component is not a {@code JLayer}, - * this method is equal to {@link JViewport#getView()} - * otherwise {@link JLayer#getView()} will be recursively tested + * this method is equivalent to {@link JViewport#getView()} + * otherwise {@link JLayer#getView()} will be recursively + * called on all descending {@code JLayer}s. + * + * @param viewport {@code JViewport} to get the first descendant of, + * which in not a {@code JLayer} instance. * * @return the first {@code JViewport}'s descendant - * which is not an instance of {@code JLayer} or {@code null}. + * which is not an instance of {@code JLayer}. + * If such a descendant can not be found, {@code null} is returned. * * @throws NullPointerException if {@code viewport} is {@code null} * @see JViewport#getView() * @see JLayer + * + * @since 1.7 */ - static Component getUnwrappedView(JViewport viewport) { + public static Component getUnwrappedView(JViewport viewport) { Component view = viewport.getView(); while (view instanceof JLayer) { view = ((JLayer)view).getView(); diff --git a/jdk/src/share/classes/javax/swing/text/JTextComponent.java b/jdk/src/share/classes/javax/swing/text/JTextComponent.java index 25ddaf9e3cc..832c6095ec2 100644 --- a/jdk/src/share/classes/javax/swing/text/JTextComponent.java +++ b/jdk/src/share/classes/javax/swing/text/JTextComponent.java @@ -2069,9 +2069,9 @@ public abstract class JTextComponent extends JComponent implements Scrollable, A * width to match its own */ public boolean getScrollableTracksViewportWidth() { - JViewport port = SwingUtilities.getParentViewport(this); - if (port != null) { - return port.getWidth() > getPreferredSize().width; + Container parent = SwingUtilities.getUnwrappedParent(this); + if (parent instanceof JViewport) { + return parent.getWidth() > getPreferredSize().width; } return false; } @@ -2090,9 +2090,9 @@ public abstract class JTextComponent extends JComponent implements Scrollable, A * to match its own */ public boolean getScrollableTracksViewportHeight() { - JViewport port = SwingUtilities.getParentViewport(this); - if (port != null) { - return (port.getHeight() > getPreferredSize().height); + Container parent = SwingUtilities.getUnwrappedParent(this); + if (parent instanceof JViewport) { + return parent.getHeight() > getPreferredSize().height; } return false; } From 98a42c6444e70321355a2153f2979d9271ef6982 Mon Sep 17 00:00:00 2001 From: Alexander Potochkin Date: Thu, 29 Apr 2010 18:56:26 +0400 Subject: [PATCH 12/38] 6899453: Remove unnecessary methods from LayerUI Reviewed-by: peterz --- .../classes/javax/swing/plaf/LayerUI.java | 62 ++----------------- 1 file changed, 4 insertions(+), 58 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/plaf/LayerUI.java b/jdk/src/share/classes/javax/swing/plaf/LayerUI.java index 7f2967bf465..e088db33738 100644 --- a/jdk/src/share/classes/javax/swing/plaf/LayerUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/LayerUI.java @@ -72,53 +72,13 @@ public class LayerUI * the specified {@code Graphics} object to * render the content of the component. *

- * If {@code g} is not an instance of {@code Graphics2D}, - * this method is no-op. + * The default implementation paints the passed component as is. * - * @param g the {@code Graphics} context in which to paint; - * @param c the component being painted; - * it can be safely cast to {@code JLayer} - * - * @see #configureGraphics(Graphics2D, JLayer) - * @see #paintLayer(Graphics2D, JLayer) + * @param g the {@code Graphics} context in which to paint + * @param c the component being painted */ public void paint(Graphics g, JComponent c) { - if (g instanceof Graphics2D) { - Graphics2D g2 = (Graphics2D) g.create(); - JLayer l = (JLayer) c; - configureGraphics(g2, l); - paintLayer(g2, l); - g2.dispose(); - } - } - - /** - * This method is called by the {@link #paint} method prior to - * {@link #paintLayer} to configure the {@code Graphics2D} object. - * The default implementation is empty. - * - * @param g2 the {@code Graphics2D} object to configure - * @param l the {@code JLayer} being painted - * - * @see #paintLayer(Graphics2D, JLayer) - */ - protected void configureGraphics(Graphics2D g2, JLayer l) { - } - - /** - * Called by the {@link #paint} method, - * subclasses should override this method - * to perform any custom painting operations. - *

- * The default implementation paints the passed {@code JLayer} as is. - * - * @param g2 the {@code Graphics2D} context in which to paint - * @param l the {@code JLayer} being painted - * - * @see #configureGraphics(Graphics2D, JLayer) - */ - protected void paintLayer(Graphics2D g2, JLayer l) { - l.paint(g2); + c.paint(g); } /** @@ -627,17 +587,6 @@ public class LayerUI propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue); } - /** - * Repaints all {@code JLayer} instances this {@code LayerUI} is set to. - * Call this method when the state of this {@code LayerUI} is changed - * and the visual appearance of its {@code JLayer} objects needs to be updated. - * - * @see Component#repaint() - */ - protected void repaintLayer() { - firePropertyChange("dirty", null, null); - } - /** * Notifies the {@code LayerUI} when any of its property are changed * and enables updating every {@code JLayer} @@ -647,9 +596,6 @@ public class LayerUI * @param l the {@code JLayer} this LayerUI is set to */ public void applyPropertyChange(PropertyChangeEvent evt, JLayer l) { - if ("dirty".equals(evt.getPropertyName())) { - l.repaint(); - } } /** From 16e7bb5c198f60d9d0ae7643c3b3f7b21df87127 Mon Sep 17 00:00:00 2001 From: Alexander Potochkin Date: Thu, 29 Apr 2010 19:07:26 +0400 Subject: [PATCH 13/38] 6899405: Specification for JLayer.setLayerEventMask() should mention that eventDispatch() might not be called Reviewed-by: peterz --- jdk/src/share/classes/javax/swing/JLayer.java | 60 ++++++++----------- .../classes/javax/swing/plaf/LayerUI.java | 9 +-- 2 files changed, 29 insertions(+), 40 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/JLayer.java b/jdk/src/share/classes/javax/swing/JLayer.java index 93f4b799722..ab082cfc588 100644 --- a/jdk/src/share/classes/javax/swing/JLayer.java +++ b/jdk/src/share/classes/javax/swing/JLayer.java @@ -163,18 +163,6 @@ public final class JLayer private static final LayerEventController eventController = new LayerEventController(); - private static final long ACCEPTED_EVENTS = - AWTEvent.COMPONENT_EVENT_MASK | - AWTEvent.CONTAINER_EVENT_MASK | - AWTEvent.FOCUS_EVENT_MASK | - AWTEvent.KEY_EVENT_MASK | - AWTEvent.MOUSE_WHEEL_EVENT_MASK | - AWTEvent.MOUSE_MOTION_EVENT_MASK | - AWTEvent.MOUSE_EVENT_MASK | - AWTEvent.INPUT_METHOD_EVENT_MASK | - AWTEvent.HIERARCHY_EVENT_MASK | - AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK; - /** * Creates a new {@code JLayer} object with a {@code null} view component * and {@code null} {@link javax.swing.plaf.LayerUI}. @@ -396,24 +384,14 @@ public final class JLayer } /** - * Sets the bitmask of event types to receive by this {@code JLayer}. - * Here is the list of the supported event types: - *

    - *
  • AWTEvent.COMPONENT_EVENT_MASK
  • - *
  • AWTEvent.CONTAINER_EVENT_MASK
  • - *
  • AWTEvent.FOCUS_EVENT_MASK
  • - *
  • AWTEvent.KEY_EVENT_MASK
  • - *
  • AWTEvent.MOUSE_WHEEL_EVENT_MASK
  • - *
  • AWTEvent.MOUSE_MOTION_EVENT_MASK
  • - *
  • AWTEvent.MOUSE_EVENT_MASK
  • - *
  • AWTEvent.INPUT_METHOD_EVENT_MASK
  • - *
  • AWTEvent.HIERARCHY_EVENT_MASK
  • - *
  • AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK
  • - *
+ * Enables the events from JLayer and all its descendants + * defined by the specified event mask parameter + * to be delivered to the + * {@link LayerUI#eventDispatched(AWTEvent, JLayer)} method. *

- * If {@code LayerUI} is installed, - * {@link javax.swing.plaf.LayerUI#eventDispatched(AWTEvent, JLayer)} method - * will only receive events that match the event mask. + * Events are delivered provided that {@code LayerUI} is set + * for this {@code JLayer} and the {@code JLayer} + * is displayable. *

* The following example shows how to correclty use this method * in the {@code LayerUI} implementations: @@ -433,19 +411,15 @@ public final class JLayer * } * * - * By default {@code JLayer} receives no events. + * By default {@code JLayer} receives no events and its event mask is {@code 0}. * * @param layerEventMask the bitmask of event types to receive * - * @throws IllegalArgumentException if the {@code layerEventMask} parameter - * contains unsupported event types * @see #getLayerEventMask() + * @see LayerUI#eventDispatched(AWTEvent, JLayer) + * @see Component#isDisplayable() */ public void setLayerEventMask(long layerEventMask) { - if (layerEventMask != (layerEventMask & ACCEPTED_EVENTS)) { - throw new IllegalArgumentException( - "The event bitmask contains unsupported event types"); - } long oldEventMask = getLayerEventMask(); this.eventMask = layerEventMask; firePropertyChange("layerEventMask", oldEventMask, layerEventMask); @@ -629,6 +603,18 @@ public final class JLayer private long currentEventMask; + private static final long ACCEPTED_EVENTS = + AWTEvent.COMPONENT_EVENT_MASK | + AWTEvent.CONTAINER_EVENT_MASK | + AWTEvent.FOCUS_EVENT_MASK | + AWTEvent.KEY_EVENT_MASK | + AWTEvent.MOUSE_WHEEL_EVENT_MASK | + AWTEvent.MOUSE_MOTION_EVENT_MASK | + AWTEvent.MOUSE_EVENT_MASK | + AWTEvent.INPUT_METHOD_EVENT_MASK | + AWTEvent.HIERARCHY_EVENT_MASK | + AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK; + @SuppressWarnings("unchecked") public void eventDispatched(AWTEvent event) { Object source = event.getSource(); @@ -660,6 +646,8 @@ public final class JLayer for (Long mask : layerMaskList) { combinedMask |= mask; } + // filter out all unaccepted events + combinedMask &= ACCEPTED_EVENTS; if (combinedMask == 0) { removeAWTEventListener(); } else if (getCurrentEventMask() != combinedMask) { diff --git a/jdk/src/share/classes/javax/swing/plaf/LayerUI.java b/jdk/src/share/classes/javax/swing/plaf/LayerUI.java index e088db33738..07df96cd411 100644 --- a/jdk/src/share/classes/javax/swing/plaf/LayerUI.java +++ b/jdk/src/share/classes/javax/swing/plaf/LayerUI.java @@ -82,8 +82,8 @@ public class LayerUI } /** - * Dispatches {@code AWTEvent}s for {@code JLayer} - * and all its subcomponents to this {@code LayerUI} instance. + * Processes {@code AWTEvent}s for {@code JLayer} + * and all its descendants to this {@code LayerUI} instance. *

* To enable the {@code AWTEvent}s of a particular type, * you call {@link JLayer#setLayerEventMask} @@ -93,13 +93,14 @@ public class LayerUI * By default this method calls the appropriate * {@code process<event type>Event} * method for the given class of event. + *

+ * Note: Events are processed only for displayable {@code JLayer}s. * * @param e the event to be dispatched * @param l the layer this LayerUI is set to * * @see JLayer#setLayerEventMask(long) - * @see #installUI(javax.swing.JComponent) - * @see #uninstallUI(javax.swing.JComponent) + * @see Component#isDisplayable() * @see #processComponentEvent * @see #processFocusEvent * @see #processKeyEvent From 3b66a751506145160758547b6b90b6b0fb1d970c Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Thu, 29 Apr 2010 14:25:47 -0700 Subject: [PATCH 14/38] 6948251: need to quote args in langtools launcher script Reviewed-by: darcy --- langtools/src/share/bin/launcher.sh-template | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/langtools/src/share/bin/launcher.sh-template b/langtools/src/share/bin/launcher.sh-template index 16ade3e071d..260ee9dffce 100644 --- a/langtools/src/share/bin/launcher.sh-template +++ b/langtools/src/share/bin/launcher.sh-template @@ -66,4 +66,5 @@ for i in "$@" ; do done unset DUALCASE -eval "#TARGET_JAVA#" "${bcp:+-Xbootclasspath/p:"$bcp"}" ${ea} ${javaOpts} -jar "${mydir}"/../lib/#PROGRAM#.jar ${toolOpts} +IFS=$nl +"#TARGET_JAVA#" "${bcp:+-Xbootclasspath/p:"$bcp"}" ${ea} ${javaOpts} -jar "${mydir}"/../lib/#PROGRAM#.jar ${toolOpts} From de2b567108d48ab1e3a9330cfcc3ef585771cc31 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Mon, 3 May 2010 17:12:59 -0700 Subject: [PATCH 15/38] 6943289: Project Coin: Improved Exception Handling for Java (aka 'multicatch') Reviewed-by: jjg, darcy --- .../com/sun/source/tree/DisjointTypeTree.java | 40 ++++++ .../classes/com/sun/source/tree/Tree.java | 5 + .../com/sun/source/tree/TreeVisitor.java | 1 + .../sun/source/util/SimpleTreeVisitor.java | 4 + .../com/sun/source/util/TreeScanner.java | 4 + .../com/sun/tools/javac/code/Flags.java | 5 + .../com/sun/tools/javac/code/Source.java | 3 + .../com/sun/tools/javac/comp/Attr.java | 12 ++ .../com/sun/tools/javac/comp/Flow.java | 75 ++++++++--- .../classes/com/sun/tools/javac/jvm/Gen.java | 32 +++-- .../sun/tools/javac/parser/JavacParser.java | 31 ++++- .../tools/javac/resources/compiler.properties | 8 ++ .../com/sun/tools/javac/tree/JCTree.java | 35 +++++- .../com/sun/tools/javac/tree/Pretty.java | 8 ++ .../com/sun/tools/javac/tree/TreeCopier.java | 6 + .../com/sun/tools/javac/tree/TreeInfo.java | 4 + .../com/sun/tools/javac/tree/TreeMaker.java | 6 + .../com/sun/tools/javac/tree/TreeScanner.java | 4 + .../sun/tools/javac/tree/TreeTranslator.java | 5 + .../test/tools/javac/multicatch/Neg01.java | 28 +++++ .../test/tools/javac/multicatch/Neg01.out | 2 + .../test/tools/javac/multicatch/Neg02.java | 25 ++++ .../test/tools/javac/multicatch/Neg02.out | 2 + .../test/tools/javac/multicatch/Neg03.java | 27 ++++ .../test/tools/javac/multicatch/Neg03.out | 2 + .../test/tools/javac/multicatch/Neg04.java | 31 +++++ .../test/tools/javac/multicatch/Neg04.out | 2 + .../test/tools/javac/multicatch/Pos01.java | 59 +++++++++ .../test/tools/javac/multicatch/Pos02.java | 81 ++++++++++++ .../test/tools/javac/multicatch/Pos03.java | 50 ++++++++ .../test/tools/javac/multicatch/Pos04.java | 92 ++++++++++++++ .../test/tools/javac/multicatch/Pos05.java | 117 ++++++++++++++++++ 32 files changed, 773 insertions(+), 33 deletions(-) create mode 100644 langtools/src/share/classes/com/sun/source/tree/DisjointTypeTree.java create mode 100644 langtools/test/tools/javac/multicatch/Neg01.java create mode 100644 langtools/test/tools/javac/multicatch/Neg01.out create mode 100644 langtools/test/tools/javac/multicatch/Neg02.java create mode 100644 langtools/test/tools/javac/multicatch/Neg02.out create mode 100644 langtools/test/tools/javac/multicatch/Neg03.java create mode 100644 langtools/test/tools/javac/multicatch/Neg03.out create mode 100644 langtools/test/tools/javac/multicatch/Neg04.java create mode 100644 langtools/test/tools/javac/multicatch/Neg04.out create mode 100644 langtools/test/tools/javac/multicatch/Pos01.java create mode 100644 langtools/test/tools/javac/multicatch/Pos02.java create mode 100644 langtools/test/tools/javac/multicatch/Pos03.java create mode 100644 langtools/test/tools/javac/multicatch/Pos04.java create mode 100644 langtools/test/tools/javac/multicatch/Pos05.java diff --git a/langtools/src/share/classes/com/sun/source/tree/DisjointTypeTree.java b/langtools/src/share/classes/com/sun/source/tree/DisjointTypeTree.java new file mode 100644 index 00000000000..513a70a2294 --- /dev/null +++ b/langtools/src/share/classes/com/sun/source/tree/DisjointTypeTree.java @@ -0,0 +1,40 @@ +/* + * Copyright 2010 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.source.tree; + +import java.util.List; + +/** + * A tree node for a disjoint type expression in a multicatch var declaration. + * + * + * @author Maurizio Cimadamore + * + * @since 1.7 + */ +public interface DisjointTypeTree extends Tree { + List getTypeComponents(); +} \ No newline at end of file diff --git a/langtools/src/share/classes/com/sun/source/tree/Tree.java b/langtools/src/share/classes/com/sun/source/tree/Tree.java index d2d2d5a1d58..c5f46904dfa 100644 --- a/langtools/src/share/classes/com/sun/source/tree/Tree.java +++ b/langtools/src/share/classes/com/sun/source/tree/Tree.java @@ -233,6 +233,11 @@ public interface Tree { */ PARAMETERIZED_TYPE(ParameterizedTypeTree.class), + /** + * Used for instances of {@link DisjointTypeTree}. + */ + DISJOINT_TYPE(DisjointTypeTree.class), + /** * Used for instances of {@link TypeCastTree}. */ diff --git a/langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java b/langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java index 99e7063d204..117b716f708 100644 --- a/langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java +++ b/langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java @@ -96,6 +96,7 @@ public interface TreeVisitor { R visitCompilationUnit(CompilationUnitTree node, P p); R visitTry(TryTree node, P p); R visitParameterizedType(ParameterizedTypeTree node, P p); + R visitDisjointType(DisjointTypeTree node, P p); R visitArrayType(ArrayTypeTree node, P p); R visitTypeCast(TypeCastTree node, P p); R visitPrimitiveType(PrimitiveTypeTree node, P p); diff --git a/langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java b/langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java index e6c384bef4c..c96416f9984 100644 --- a/langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java +++ b/langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java @@ -228,6 +228,10 @@ public class SimpleTreeVisitor implements TreeVisitor { return defaultAction(node, p); } + public R visitDisjointType(DisjointTypeTree node, P p) { + return defaultAction(node, p); + } + public R visitTypeParameter(TypeParameterTree node, P p) { return defaultAction(node, p); } diff --git a/langtools/src/share/classes/com/sun/source/util/TreeScanner.java b/langtools/src/share/classes/com/sun/source/util/TreeScanner.java index a1d2a2d881f..9253aa90da8 100644 --- a/langtools/src/share/classes/com/sun/source/util/TreeScanner.java +++ b/langtools/src/share/classes/com/sun/source/util/TreeScanner.java @@ -354,6 +354,10 @@ public class TreeScanner implements TreeVisitor { return r; } + public R visitDisjointType(DisjointTypeTree node, P p) { + return scan(node.getTypeComponents(), p); + } + public R visitTypeParameter(TypeParameterTree node, P p) { R r = scan(node.getAnnotations(), p); r = scanAndReduce(node.getBounds(), p, r); diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java index 88f0bde43da..5ecbcf9c1a2 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java @@ -230,6 +230,11 @@ public class Flags { */ public static final long PROPRIETARY = 1L<<38; + /** + * Flag that marks a disjoint var in a multi-catch clause + */ + public static final long DISJOINT = 1L<<39; + /** Modifier masks. */ public static final int diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java index 4809565d855..98b8365bc74 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java @@ -125,6 +125,9 @@ public enum Source { public boolean allowDiamond() { return compareTo(JDK1_7) >= 0; } + public boolean allowMulticatch() { + return compareTo(JDK1_7) >= 0; + } public boolean allowEnums() { return compareTo(JDK1_5) >= 0; } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index 0d3df466c64..cf1cf2c7f05 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -988,6 +988,13 @@ public class Attr extends JCTree.Visitor { Env catchEnv = env.dup(c, env.info.dup(env.info.scope.dup())); Type ctype = attribStat(c.param, catchEnv); + if (TreeInfo.isMultiCatch(c)) { + //check that multi-catch parameter is marked as final + if ((c.param.sym.flags() & FINAL) == 0) { + log.error(c.param.pos(), "multicatch.param.must.be.final", c.param.sym); + } + c.param.sym.flags_field = c.param.sym.flags() | DISJOINT; + } if (c.param.type.tsym.kind == Kinds.VAR) { c.param.sym.setData(ElementKind.EXCEPTION_PARAMETER); } @@ -2735,6 +2742,11 @@ public class Attr extends JCTree.Visitor { result = check(tree, owntype, TYP, pkind, pt); } + public void visitTypeDisjoint(JCTypeDisjoint tree) { + List componentTypes = attribTypes(tree.components, env); + tree.type = result = check(tree, types.lub(componentTypes), TYP, pkind, pt); + } + public void visitTypeParameter(JCTypeParameter tree) { TypeVar a = (TypeVar)tree.type; Set boundSet = new HashSet(); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java index 626deeed78f..9de6950909a 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java @@ -27,6 +27,8 @@ package com.sun.tools.javac.comp; +import java.util.HashMap; + import com.sun.tools.javac.code.*; import com.sun.tools.javac.tree.*; import com.sun.tools.javac.util.*; @@ -184,6 +186,7 @@ public class Flow extends TreeScanner { private final Check chk; private TreeMaker make; private Lint lint; + private final boolean allowRethrowAnalysis; public static Flow instance(Context context) { Flow instance = context.get(flowKey); @@ -194,13 +197,14 @@ public class Flow extends TreeScanner { protected Flow(Context context) { context.put(flowKey, this); - names = Names.instance(context); log = Log.instance(context); syms = Symtab.instance(context); types = Types.instance(context); chk = Check.instance(context); lint = Lint.instance(context); + Source source = Source.instance(context); + allowRethrowAnalysis = source.allowMulticatch(); } /** A flag that indicates whether the last statement could @@ -216,6 +220,8 @@ public class Flow extends TreeScanner { */ Bits uninits; + HashMap> multicatchTypes; + /** The set of variables that are definitely unassigned everywhere * in current try block. This variable is maintained lazily; it is * updated only when something gets removed from uninits, @@ -355,8 +361,14 @@ public class Flow extends TreeScanner { if (sym.adr >= firstadr && trackable(sym)) { if ((sym.flags() & FINAL) != 0) { if ((sym.flags() & PARAMETER) != 0) { - log.error(pos, "final.parameter.may.not.be.assigned", + if ((sym.flags() & DISJOINT) != 0) { //multi-catch parameter + log.error(pos, "multicatch.parameter.may.not.be.assigned", + sym); + } + else { + log.error(pos, "final.parameter.may.not.be.assigned", sym); + } } else if (!uninits.isMember(sym.adr)) { log.error(pos, loopPassTwo @@ -952,8 +964,14 @@ public class Flow extends TreeScanner { List caughtPrev = caught; List thrownPrev = thrown; thrown = List.nil(); - for (List l = tree.catchers; l.nonEmpty(); l = l.tail) - caught = chk.incl(l.head.param.type, caught); + for (List l = tree.catchers; l.nonEmpty(); l = l.tail) { + List subClauses = TreeInfo.isMultiCatch(l.head) ? + ((JCTypeDisjoint)l.head.param.vartype).components : + List.of(l.head.param.vartype); + for (JCExpression ct : subClauses) { + caught = chk.incl(ct.type, caught); + } + } Bits uninitsTryPrev = uninitsTry; ListBuffer prevPendingExits = pendingExits; pendingExits = new ListBuffer(); @@ -973,27 +991,39 @@ public class Flow extends TreeScanner { for (List l = tree.catchers; l.nonEmpty(); l = l.tail) { alive = true; JCVariableDecl param = l.head.param; - Type exc = param.type; - if (chk.subset(exc, caughtInTry)) { - log.error(l.head.pos(), - "except.already.caught", exc); - } else if (!chk.isUnchecked(l.head.pos(), exc) && - exc.tsym != syms.throwableType.tsym && - exc.tsym != syms.exceptionType.tsym && - !chk.intersects(exc, thrownInTry)) { - log.error(l.head.pos(), - "except.never.thrown.in.try", exc); + List subClauses = TreeInfo.isMultiCatch(l.head) ? + ((JCTypeDisjoint)l.head.param.vartype).components : + List.of(l.head.param.vartype); + List ctypes = List.nil(); + List rethrownTypes = chk.diff(thrownInTry, caughtInTry); + for (JCExpression ct : subClauses) { + Type exc = ct.type; + ctypes = ctypes.append(exc); + if (types.isSameType(exc, syms.objectType)) + continue; + if (chk.subset(exc, caughtInTry)) { + log.error(l.head.pos(), + "except.already.caught", exc); + } else if (!chk.isUnchecked(l.head.pos(), exc) && + exc.tsym != syms.throwableType.tsym && + exc.tsym != syms.exceptionType.tsym && + !chk.intersects(exc, thrownInTry)) { + log.error(l.head.pos(), + "except.never.thrown.in.try", exc); + } + caughtInTry = chk.incl(exc, caughtInTry); } - caughtInTry = chk.incl(exc, caughtInTry); inits = initsTry.dup(); uninits = uninitsTry.dup(); scan(param); inits.incl(param.sym.adr); uninits.excl(param.sym.adr); + multicatchTypes.put(param.sym, chk.intersect(ctypes, rethrownTypes)); scanStat(l.head.body); initsEnd.andSet(inits); uninitsEnd.andSet(uninits); nextadr = nextadrCatch; + multicatchTypes.remove(param.sym); aliveEnd |= alive; } if (tree.finalizer != null) { @@ -1121,7 +1151,19 @@ public class Flow extends TreeScanner { public void visitThrow(JCThrow tree) { scanExpr(tree.expr); - markThrown(tree, tree.expr.type); + Symbol sym = TreeInfo.symbol(tree.expr); + if (sym != null && + sym.kind == VAR && + (sym.flags() & FINAL) != 0 && + multicatchTypes.get(sym) != null && + allowRethrowAnalysis) { + for (Type t : multicatchTypes.get(sym)) { + markThrown(tree, t); + } + } + else { + markThrown(tree, tree.expr.type); + } markDead(); } @@ -1308,6 +1350,7 @@ public class Flow extends TreeScanner { firstadr = 0; nextadr = 0; pendingExits = new ListBuffer(); + multicatchTypes = new HashMap>(); alive = true; this.thrown = this.caught = null; this.classDef = null; diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java index e39115c7af8..41bbbdcbb0b 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java @@ -1454,20 +1454,26 @@ public class Gen extends JCTree.Visitor { int startpc, int endpc, List gaps) { if (startpc != endpc) { - int catchType = makeRef(tree.pos(), tree.param.type); - while (gaps.nonEmpty()) { - int end = gaps.head.intValue(); - registerCatch(tree.pos(), - startpc, end, code.curPc(), - catchType); - gaps = gaps.tail; - startpc = gaps.head.intValue(); - gaps = gaps.tail; + List subClauses = TreeInfo.isMultiCatch(tree) ? + ((JCTypeDisjoint)tree.param.vartype).components : + List.of(tree.param.vartype); + for (JCExpression subCatch : subClauses) { + int catchType = makeRef(tree.pos(), subCatch.type); + List lGaps = gaps; + while (lGaps.nonEmpty()) { + int end = lGaps.head.intValue(); + registerCatch(tree.pos(), + startpc, end, code.curPc(), + catchType); + lGaps = lGaps.tail; + startpc = lGaps.head.intValue(); + lGaps = lGaps.tail; + } + if (startpc < endpc) + registerCatch(tree.pos(), + startpc, endpc, code.curPc(), + catchType); } - if (startpc < endpc) - registerCatch(tree.pos(), - startpc, endpc, code.curPc(), - catchType); VarSymbol exparam = tree.param.sym; code.statBegin(tree.pos); code.markStatBegin(); diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java index 63914e315e6..19d5b2ceff7 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java @@ -132,6 +132,7 @@ public class JavacParser implements Parser { this.allowStaticImport = source.allowStaticImport(); this.allowAnnotations = source.allowAnnotations(); this.allowDiamond = source.allowDiamond(); + this.allowMulticatch = source.allowMulticatch(); this.allowTypeAnnotations = source.allowTypeAnnotations(); this.keepDocComments = keepDocComments; if (keepDocComments) @@ -153,6 +154,10 @@ public class JavacParser implements Parser { */ boolean allowDiamond; + /** Switch: Should multicatch clause be accepted? + */ + boolean allowMulticatch; + /** Switch: Should varargs be recognized? */ boolean allowVarargs; @@ -2011,14 +2016,28 @@ public class JavacParser implements Parser { int pos = S.pos(); accept(CATCH); accept(LPAREN); - JCVariableDecl formal = - variableDeclaratorId(optFinal(Flags.PARAMETER), - qualident()); + JCModifiers mods = optFinal(Flags.PARAMETER); + List catchTypes = catchTypes(); + JCExpression paramType = catchTypes.size() > 1 ? + toP(F.at(catchTypes.head.getStartPosition()).TypeDisjoint(catchTypes)) : + catchTypes.head; + JCVariableDecl formal = variableDeclaratorId(mods, paramType); accept(RPAREN); JCBlock body = block(); return F.at(pos).Catch(formal, body); } + List catchTypes() { + ListBuffer catchTypes = ListBuffer.lb(); + catchTypes.add(parseType()); + while (S.token() == BAR) { + checkMulticatch(); + S.nextToken(); + catchTypes.add(qualident()); + } + return catchTypes.toList(); + } + /** SwitchBlockStatementGroups = { SwitchBlockStatementGroup } * SwitchBlockStatementGroup = SwitchLabel BlockStatements * SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":" @@ -3193,4 +3212,10 @@ public class JavacParser implements Parser { allowDiamond = true; } } + void checkMulticatch() { + if (!allowMulticatch) { + log.error(S.pos(), "multicatch.not.supported.in.source", source.name); + allowMulticatch = true; + } + } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties index 9de74667229..b695e5c7870 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -172,6 +172,10 @@ compiler.err.except.never.thrown.in.try=\ compiler.err.final.parameter.may.not.be.assigned=\ final parameter {0} may not be assigned +compiler.err.multicatch.parameter.may.not.be.assigned=\ + multi-catch parameter {0} may not be assigned +compiler.err.multicatch.param.must.be.final=\ + multi-catch parameter {0} must be final compiler.err.finally.without.try=\ ''finally'' without ''try'' compiler.err.foreach.not.applicable.to.type=\ @@ -1235,6 +1239,10 @@ compiler.err.enums.not.supported.in.source=\ enums are not supported in -source {0}\n\ (use -source 5 or higher to enable enums) +compiler.err.multicatch.not.supported.in.source=\ + multi-catch statement is not supported in -source {0}\n\ +(use -source 7 or higher to enable multi-catch statement) + compiler.err.string.switch.not.supported.in.source=\ strings in switch are not supported in -source {0}\n\ (use -source 7 or higher to enable strings in switch) diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java index 4344961a36b..20352f5b843 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java @@ -236,9 +236,13 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { */ public static final int TYPEAPPLY = TYPEARRAY + 1; + /** Disjunctive types, of type TypeDisjoint. + */ + public static final int TYPEDISJOINT = TYPEAPPLY + 1; + /** Formal type parameters, of type TypeParameter. */ - public static final int TYPEPARAMETER = TYPEAPPLY + 1; + public static final int TYPEPARAMETER = TYPEDISJOINT + 1; /** Type argument. */ @@ -1862,6 +1866,34 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { } } + /** + * A disjoint type, T1 | T2 | ... Tn (used in multicatch statements) + */ + public static class JCTypeDisjoint extends JCExpression implements DisjointTypeTree { + + public List components; + + protected JCTypeDisjoint(List components) { + this.components = components; + } + @Override + public void accept(Visitor v) { v.visitTypeDisjoint(this); } + + public Kind getKind() { return Kind.DISJOINT_TYPE; } + + public List getTypeComponents() { + return components; + } + @Override + public R accept(TreeVisitor v, D d) { + return v.visitDisjointType(this, d); + } + @Override + public int getTag() { + return TYPEDISJOINT; + } + } + /** * A formal class parameter. * @param name name @@ -2220,6 +2252,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { public void visitTypeIdent(JCPrimitiveTypeTree that) { visitTree(that); } public void visitTypeArray(JCArrayTypeTree that) { visitTree(that); } public void visitTypeApply(JCTypeApply that) { visitTree(that); } + public void visitTypeDisjoint(JCTypeDisjoint that) { visitTree(that); } public void visitTypeParameter(JCTypeParameter that) { visitTree(that); } public void visitWildcard(JCWildcard that) { visitTree(that); } public void visitTypeBoundKind(TypeBoundKind that) { visitTree(that); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java index ef4d4dc02dc..578d745d050 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java @@ -1182,6 +1182,14 @@ public class Pretty extends JCTree.Visitor { } } + public void visitTypeDisjoint(JCTypeDisjoint tree) { + try { + printExprs(tree.components, " | "); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + public void visitTypeParameter(JCTypeParameter tree) { try { print(tree.name); diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java index 9e3a9ba761f..c1e8835541b 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java @@ -345,6 +345,12 @@ public class TreeCopier

implements TreeVisitor { return M.at(t.pos).TypeApply(clazz, arguments); } + public JCTree visitDisjointType(DisjointTypeTree node, P p) { + JCTypeDisjoint t = (JCTypeDisjoint) node; + List components = copy(t.components, p); + return M.at(t.pos).TypeDisjoint(components); + } + public JCTree visitArrayType(ArrayTypeTree node, P p) { JCArrayTypeTree t = (JCArrayTypeTree) node; JCExpression elemtype = copy(t.elemtype, p); diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java index 12f25312e6e..d70b609b13c 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java @@ -118,6 +118,10 @@ public class TreeInfo { return false; } + public static boolean isMultiCatch(JCCatch catchClause) { + return catchClause.param.vartype.getTag() == JCTree.TYPEDISJOINT; + } + /** Is statement an initializer for a synthetic field? */ public static boolean isSyntheticInit(JCTree stat) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java index 84229f60fbb..250672d764f 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java @@ -444,6 +444,12 @@ public class TreeMaker implements JCTree.Factory { return tree; } + public JCTypeDisjoint TypeDisjoint(List components) { + JCTypeDisjoint tree = new JCTypeDisjoint(components); + tree.pos = pos; + return tree; + } + public JCTypeParameter TypeParameter(Name name, List bounds) { return TypeParameter(name, bounds, List.nil()); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java index 5721d5d2078..421c0ce51f2 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java @@ -275,6 +275,10 @@ public class TreeScanner extends Visitor { scan(tree.arguments); } + public void visitTypeDisjoint(JCTypeDisjoint tree) { + scan(tree.components); + } + public void visitTypeParameter(JCTypeParameter tree) { scan(tree.annotations); scan(tree.bounds); diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java index 98f5250b4b9..9a95ceb094f 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java @@ -367,6 +367,11 @@ public class TreeTranslator extends JCTree.Visitor { result = tree; } + public void visitTypeDisjoint(JCTypeDisjoint tree) { + tree.components = translate(tree.components); + result = tree; + } + public void visitTypeParameter(JCTypeParameter tree) { tree.annotations = translate(tree.annotations); tree.bounds = translate(tree.bounds); diff --git a/langtools/test/tools/javac/multicatch/Neg01.java b/langtools/test/tools/javac/multicatch/Neg01.java new file mode 100644 index 00000000000..dd0bc5cfe7b --- /dev/null +++ b/langtools/test/tools/javac/multicatch/Neg01.java @@ -0,0 +1,28 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6943289 + * + * @summary Project Coin: Improved Exception Handling for Java (aka 'multicatch') + * @author darcy + * @compile/fail/ref=Neg01.out -XDrawDiagnostics Neg01.java + * @compile -source 6 -XDrawDiagnostics Neg01.java + * + */ + +class Neg01 { + static class A extends Exception {} + static class B1 extends A {} + static class B2 extends A {} + + class Test { + void m() throws A { + try { + throw new B1(); + } catch (final A ex1) { + try { + throw ex1; // used to throw A, now throws B1! + } catch (B2 ex2) { }//unreachable + } + } + } +} diff --git a/langtools/test/tools/javac/multicatch/Neg01.out b/langtools/test/tools/javac/multicatch/Neg01.out new file mode 100644 index 00000000000..328be8c7d48 --- /dev/null +++ b/langtools/test/tools/javac/multicatch/Neg01.out @@ -0,0 +1,2 @@ +Neg01.java:24:19: compiler.err.except.never.thrown.in.try: Neg01.B2 +1 error diff --git a/langtools/test/tools/javac/multicatch/Neg02.java b/langtools/test/tools/javac/multicatch/Neg02.java new file mode 100644 index 00000000000..6312447eb53 --- /dev/null +++ b/langtools/test/tools/javac/multicatch/Neg02.java @@ -0,0 +1,25 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6943289 + * + * @summary Project Coin: Improved Exception Handling for Java (aka 'multicatch') + * @author mcimadamore + * @compile/fail/ref=Neg02.out -XDrawDiagnostics Neg02.java + * + */ + +class Neg02 { + static class A extends Exception {} + static class B extends Exception {} + + void m() { + try { + if (true) { + throw new A(); + } + else { + throw new B(); + } + } catch (A | B ex) { } + } +} diff --git a/langtools/test/tools/javac/multicatch/Neg02.out b/langtools/test/tools/javac/multicatch/Neg02.out new file mode 100644 index 00000000000..f1404578442 --- /dev/null +++ b/langtools/test/tools/javac/multicatch/Neg02.out @@ -0,0 +1,2 @@ +Neg02.java:23:24: compiler.err.multicatch.param.must.be.final: ex +1 error diff --git a/langtools/test/tools/javac/multicatch/Neg03.java b/langtools/test/tools/javac/multicatch/Neg03.java new file mode 100644 index 00000000000..c9e0b202c54 --- /dev/null +++ b/langtools/test/tools/javac/multicatch/Neg03.java @@ -0,0 +1,27 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6943289 + * + * @summary Project Coin: Improved Exception Handling for Java (aka 'multicatch') + * @author mcimadamore + * @compile/fail/ref=Neg03.out -XDrawDiagnostics Neg03.java + * + */ + +class Neg03 { + static class A extends Exception {} + static class B extends Exception {} + + void m() { + try { + if (true) { + throw new A(); + } + else { + throw new B(); + } + } catch (final A | B ex) { + ex = new B(); + } + } +} diff --git a/langtools/test/tools/javac/multicatch/Neg03.out b/langtools/test/tools/javac/multicatch/Neg03.out new file mode 100644 index 00000000000..c854ee991ff --- /dev/null +++ b/langtools/test/tools/javac/multicatch/Neg03.out @@ -0,0 +1,2 @@ +Neg03.java:24:13: compiler.err.multicatch.parameter.may.not.be.assigned: ex +1 error diff --git a/langtools/test/tools/javac/multicatch/Neg04.java b/langtools/test/tools/javac/multicatch/Neg04.java new file mode 100644 index 00000000000..d17de52b157 --- /dev/null +++ b/langtools/test/tools/javac/multicatch/Neg04.java @@ -0,0 +1,31 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6943289 + * + * @summary Project Coin: Improved Exception Handling for Java (aka 'multicatch') + * @author mcimadamore + * @compile/fail/ref=Neg04.out -XDrawDiagnostics Neg04.java + * + */ + +class Neg04 { + static class A extends Exception {} + static class B extends Exception {} + + void test() throws B { + try { + if (true) { + throw new A(); + } else if (false) { + throw new B(); + } else { + throw (Throwable)new Exception(); + } + } + catch (A e) {} + catch (final Exception e) { + throw e; + } + catch (Throwable t) {} + } +} diff --git a/langtools/test/tools/javac/multicatch/Neg04.out b/langtools/test/tools/javac/multicatch/Neg04.out new file mode 100644 index 00000000000..e2e2e3f4493 --- /dev/null +++ b/langtools/test/tools/javac/multicatch/Neg04.out @@ -0,0 +1,2 @@ +Neg04.java:27:13: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception +1 error diff --git a/langtools/test/tools/javac/multicatch/Pos01.java b/langtools/test/tools/javac/multicatch/Pos01.java new file mode 100644 index 00000000000..e48322e4662 --- /dev/null +++ b/langtools/test/tools/javac/multicatch/Pos01.java @@ -0,0 +1,59 @@ +/* + * Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6943289 + * @summary Project Coin: Improved Exception Handling for Java (aka 'multicatch') + * + */ + +public class Pos01 { + + static class A extends Exception {} + static class B extends Exception {} + + static int caughtExceptions = 0; + + static void test(boolean b) { + try { + if (b) { + throw new A(); + } + else { + throw new B(); + } + } + catch (final A | B ex) { + caughtExceptions++; + } + } + + public static void main(String[] args) { + test(true); + test(false); + if (caughtExceptions != 2) { + throw new AssertionError("Exception handler called " + caughtExceptions + "times"); + } + } +} diff --git a/langtools/test/tools/javac/multicatch/Pos02.java b/langtools/test/tools/javac/multicatch/Pos02.java new file mode 100644 index 00000000000..156919c0df5 --- /dev/null +++ b/langtools/test/tools/javac/multicatch/Pos02.java @@ -0,0 +1,81 @@ +/* + * Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6943289 + * @summary Project Coin: Improved Exception Handling for Java (aka 'multicatch') + * + */ + +public class Pos02 { + + static class A extends Exception {} + static class B extends Exception {} + static class C extends Exception {} + static class C1 extends C {} + static class C2 extends C {} + + enum ExceptionKind { + A, + B, + C1, + C2 + } + + static int caughtExceptions = 0; + static int caughtRethrownExceptions = 0; + + static void test(ExceptionKind ekind) throws A, C1 { + try { + switch (ekind) { + case A : throw new A(); + case B : throw new B(); + case C1: throw new C1(); + case C2 : throw new C2(); + } + } + catch (final C2 | B ex) { + caughtExceptions++; + } + catch (final C | A ex) { + caughtExceptions++; + throw ex; + } + } + + public static void main(String[] args) { + for (ExceptionKind ekind : ExceptionKind.values()) { + try { + test(ekind); + } + catch (final C1 | A ex) { + caughtRethrownExceptions++; + } + } + if (caughtExceptions != 4 && caughtRethrownExceptions == 2) { + throw new AssertionError("Exception handler called " + caughtExceptions + "times" + + " rethrown handler called " + caughtRethrownExceptions + "times"); + } + } +} diff --git a/langtools/test/tools/javac/multicatch/Pos03.java b/langtools/test/tools/javac/multicatch/Pos03.java new file mode 100644 index 00000000000..d0438abe746 --- /dev/null +++ b/langtools/test/tools/javac/multicatch/Pos03.java @@ -0,0 +1,50 @@ +/* + * Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6943289 + * @summary Project Coin: Improved Exception Handling for Java (aka 'multicatch') + * @compile Pos03.java + */ + +class Pos03 { + + static class A extends Exception { public void m() {}; public Object f;} + static class B1 extends A {} + static class B2 extends A {} + + void m() { + try { + if (true) { + throw new B1(); + } + else { + throw new B2(); + } + } catch (final B1 | B2 ex) { + ex.m(); + System.out.println(ex.f); + } + } +} diff --git a/langtools/test/tools/javac/multicatch/Pos04.java b/langtools/test/tools/javac/multicatch/Pos04.java new file mode 100644 index 00000000000..05b7bb463fa --- /dev/null +++ b/langtools/test/tools/javac/multicatch/Pos04.java @@ -0,0 +1,92 @@ +/* + * Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6943289 + * @summary Project Coin: Improved Exception Handling for Java (aka 'multicatch') + */ + +import java.lang.annotation.*; + +public class Pos04 { + + enum ExceptionKind { + A(1), + B(2), + C(1); + + int expectedValue; + + ExceptionKind(int expectedValue) { + this.expectedValue = expectedValue; + } + } + + @Retention(RetentionPolicy.RUNTIME) + @interface CatchNumber { + int value(); + } + + @CatchNumber(1) + static class A extends Exception { } + + @CatchNumber(2) + static class B extends Exception { } + + @CatchNumber(1) + static class C extends Exception { } + + static int sum = 0; + + public static void main(String[] args) { + for (ExceptionKind ekind : ExceptionKind.values()) { + test(ekind); + } + if (sum != 4) { + throw new Error("bad checksum - expected:4, found:" + sum); + } + } + + public static void test(ExceptionKind ekind) { + try { + switch(ekind) { + case A: throw new A(); + case B: throw new B(); + case C: throw new C(); + } + } catch(final A | C ex) {// Catch number 1 + CatchNumber catchNumber = ex.getClass().getAnnotation(CatchNumber.class); + if (catchNumber == null || catchNumber.value() != ekind.expectedValue) { + throw new Error("was expecting 1 - got " + catchNumber); + } + sum += catchNumber.value(); + } catch (final B ex) { // Catch number 2 + CatchNumber catchNumber = ex.getClass().getAnnotation(CatchNumber.class); + if (catchNumber == null || catchNumber.value() != ekind.expectedValue) { + throw new Error("was expecting 2 - got " + catchNumber); + } + sum += catchNumber.value(); + } + } +} diff --git a/langtools/test/tools/javac/multicatch/Pos05.java b/langtools/test/tools/javac/multicatch/Pos05.java new file mode 100644 index 00000000000..128450d11bd --- /dev/null +++ b/langtools/test/tools/javac/multicatch/Pos05.java @@ -0,0 +1,117 @@ +/* + * Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6943289 + * @summary Project Coin: Improved Exception Handling for Java (aka 'multicatch') + * @run main Pos05 + */ + +import com.sun.tools.classfile.Attribute; +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.Code_attribute; +import com.sun.tools.classfile.Code_attribute.Exception_data; +import com.sun.tools.classfile.Method; +import java.io.*; + +public class Pos05 { + + static class Pos05sub { + + class A extends Exception {} + class B extends Exception {} + class C extends Exception {} + + void test(boolean b1, boolean b2) { + try { + if (b1) { + throw new A(); + } + else if (b2) { + throw new B(); + } + else { + throw new C(); + } + } + catch (final A | B | C ex) { + System.out.println("Exception caught"); + } + } + } + + static final int TYPES_IN_MULTICATCH = 3; + static final String SUBTEST_NAME = Pos05sub.class.getName() + ".class"; + static final String TEST_METHOD_NAME = "test"; + + public static void main(String... args) throws Exception { + new Pos05().run(); + } + + public void run() throws Exception { + String workDir = System.getProperty("test.classes"); + File compiledTest = new File(workDir, SUBTEST_NAME); + verifyMulticatchExceptionRanges(compiledTest); + } + + void verifyMulticatchExceptionRanges(File f) { + System.err.println("verify: " + f); + try { + int count = 0; + ClassFile cf = ClassFile.read(f); + Method testMethod = null; + for (Method m : cf.methods) { + if (m.getName(cf.constant_pool).equals(TEST_METHOD_NAME)) { + testMethod = m; + break; + } + } + if (testMethod == null) { + throw new Error("Test method not found"); + } + Code_attribute ea = (Code_attribute)testMethod.attributes.get(Attribute.Code); + if (testMethod == null) { + throw new Error("Code attribute for test() method not found"); + } + Exception_data firstExceptionTable = null; + for (int i = 0 ; i < ea.exception_table_langth; i++) { + if (firstExceptionTable == null) { + firstExceptionTable = ea.exception_table[i]; + } + if (ea.exception_table[i].handler_pc != firstExceptionTable.handler_pc || + ea.exception_table[i].start_pc != firstExceptionTable.start_pc || + ea.exception_table[i].end_pc != firstExceptionTable.end_pc) { + throw new Error("Multiple overlapping catch clause found in generated code"); + } + count++; + } + if (count != TYPES_IN_MULTICATCH) { + throw new Error("Wrong number of exception data found: " + count); + } + } catch (Exception e) { + e.printStackTrace(); + throw new Error("error reading " + f +": " + e); + } + } +} From e3e5b8ad72dab169c4353988d3ffb9f2c7a44c89 Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Wed, 5 May 2010 13:18:31 +0100 Subject: [PATCH 16/38] 6886723: light weight http server doesn't return correct status code for HEAD requests Reviewed-by: michaelm --- .../sun/net/httpserver/ExchangeImpl.java | 54 +++++--- .../com/sun/net/httpserver/bugs/HeadTest.java | 117 ++++++++++++++++++ 2 files changed, 151 insertions(+), 20 deletions(-) create mode 100644 jdk/test/com/sun/net/httpserver/bugs/HeadTest.java diff --git a/jdk/src/share/classes/sun/net/httpserver/ExchangeImpl.java b/jdk/src/share/classes/sun/net/httpserver/ExchangeImpl.java index ccb9151b69c..69ed824f67f 100644 --- a/jdk/src/share/classes/sun/net/httpserver/ExchangeImpl.java +++ b/jdk/src/share/classes/sun/net/httpserver/ExchangeImpl.java @@ -26,16 +26,12 @@ package sun.net.httpserver; import java.io.*; -import java.nio.*; -import java.nio.channels.*; import java.net.*; import javax.net.ssl.*; import java.util.*; import java.util.logging.Logger; import java.text.*; -import sun.net.www.MessageHeader; import com.sun.net.httpserver.*; -import com.sun.net.httpserver.spi.*; class ExchangeImpl { @@ -65,6 +61,8 @@ class ExchangeImpl { df.setTimeZone (tz); } + private static final String HEAD = "HEAD"; + /* streams which take care of the HTTP protocol framing * and are passed up to higher layers */ @@ -116,6 +114,10 @@ class ExchangeImpl { return connection.getHttpContext(); } + private boolean isHeadRequest() { + return HEAD.equals(getRequestMethod()); + } + public void close () { if (closed) { return; @@ -220,24 +222,36 @@ class ExchangeImpl { } contentLen = -1; } - if (contentLen == 0) { - if (http10) { - o.setWrappedStream (new UndefLengthOutputStream (this, ros)); - close = true; + + if (isHeadRequest()) { + /* HEAD requests should not set a content length by passing it + * through this API, but should instead manually set the required + * headers.*/ + if (contentLen >= 0) { + final Logger logger = server.getLogger(); + String msg = + "sendResponseHeaders: being invoked with a content length for a HEAD request"; + logger.warning (msg); + } + noContentToSend = true; + contentLen = 0; + } else { /* not a HEAD request */ + if (contentLen == 0) { + if (http10) { + o.setWrappedStream (new UndefLengthOutputStream (this, ros)); + close = true; + } else { + rspHdrs.set ("Transfer-encoding", "chunked"); + o.setWrappedStream (new ChunkedOutputStream (this, ros)); + } } else { - rspHdrs.set ("Transfer-encoding", "chunked"); - o.setWrappedStream (new ChunkedOutputStream (this, ros)); + if (contentLen == -1) { + noContentToSend = true; + contentLen = 0; + } + rspHdrs.set("Content-length", Long.toString(contentLen)); + o.setWrappedStream (new FixedLengthOutputStream (this, ros, contentLen)); } - } else { - if (contentLen == -1) { - noContentToSend = true; - contentLen = 0; - } - /* content len might already be set, eg to implement HEAD resp */ - if (rspHdrs.getFirst ("Content-length") == null) { - rspHdrs.set ("Content-length", Long.toString(contentLen)); - } - o.setWrappedStream (new FixedLengthOutputStream (this, ros, contentLen)); } write (rspHdrs, tmpout); this.rspContentLen = contentLen; diff --git a/jdk/test/com/sun/net/httpserver/bugs/HeadTest.java b/jdk/test/com/sun/net/httpserver/bugs/HeadTest.java new file mode 100644 index 00000000000..8b7055338a1 --- /dev/null +++ b/jdk/test/com/sun/net/httpserver/bugs/HeadTest.java @@ -0,0 +1,117 @@ +/* + * Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6886723 + * @summary light weight http server doesn't return correct status code for HEAD requests + */ + +import java.net.InetSocketAddress; +import java.net.HttpURLConnection; +import java.net.URL; +import java.io.IOException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import com.sun.net.httpserver.HttpContext; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; + +public class HeadTest { + + public static void main(String[] args) throws Exception { + server(); + } + + static void server() throws Exception { + InetSocketAddress inetAddress = new InetSocketAddress(0); + HttpServer server = HttpServer.create(inetAddress, 5); + try { + server.setExecutor(Executors.newFixedThreadPool(5)); + HttpContext chunkedContext = server.createContext("/chunked"); + chunkedContext.setHandler(new HttpHandler() { + @Override + public void handle(HttpExchange msg) { + try { + try { + if (msg.getRequestMethod().equals("HEAD")) { + msg.getRequestBody().close(); + msg.getResponseHeaders().add("Transfer-encoding", "chunked"); + msg.sendResponseHeaders(200, -1); + } + } catch(IOException ioe) { + ioe.printStackTrace(); + } + } finally { + msg.close(); + } + } + }); + HttpContext clContext = server.createContext("/content"); + clContext.setHandler(new HttpHandler() { + @Override + public void handle(HttpExchange msg) { + try { + try { + if (msg.getRequestMethod().equals("HEAD")) { + msg.getRequestBody().close(); + msg.getResponseHeaders().add("Content-length", "1024"); + msg.sendResponseHeaders(200, -1); + } + } catch(IOException ioe) { + ioe.printStackTrace(); + } + } finally { + msg.close(); + } + } + }); + server.start(); + String urlStr = "http://localhost:" + server.getAddress().getPort() + "/"; + System.out.println("Server is at " + urlStr); + + // Run the chunked client + for(int i=0; i < 10; i++) { + runClient(urlStr + "chunked/"); + } + // Run the content length client + for(int i=0; i < 10; i++) { + runClient(urlStr + "content/"); + } + } finally { + // Stop the server + ((ExecutorService)server.getExecutor()).shutdown(); + server.stop(0); + } + } + + static void runClient(String urlStr) throws Exception { + HttpURLConnection conn = (HttpURLConnection) new URL(urlStr).openConnection(); + conn.setRequestMethod("HEAD"); + int status = conn.getResponseCode(); + if (status != 200) { + throw new RuntimeException("HEAD request doesn't return 200, but returns " + status); + } + } +} From a94d06f6b77fe7384c8c47b47022115c71bb41d3 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Thu, 6 May 2010 11:26:16 +0800 Subject: [PATCH 17/38] 6948909: Jarsigner removes MANIFEST.MF info for badly packages jar's Reviewed-by: mullan, xuelei --- .../classes/sun/security/tools/JarSigner.java | 99 ++++++++------- .../sun/security/tools/jarsigner/diffend.sh | 113 ++++++++++++++++++ 2 files changed, 172 insertions(+), 40 deletions(-) create mode 100644 jdk/test/sun/security/tools/jarsigner/diffend.sh diff --git a/jdk/src/share/classes/sun/security/tools/JarSigner.java b/jdk/src/share/classes/sun/security/tools/JarSigner.java index 5c824c5712f..0f7324d7c19 100644 --- a/jdk/src/share/classes/sun/security/tools/JarSigner.java +++ b/jdk/src/share/classes/sun/security/tools/JarSigner.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2010 Sun Microsystems, Inc. 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 @@ -1123,6 +1123,8 @@ public class JarSigner { BASE64Encoder encoder = new JarBASE64Encoder(); Vector mfFiles = new Vector(); + boolean wasSigned = false; + for (Enumeration enum_=zipFile.entries(); enum_.hasMoreElements();) { ZipEntry ze = enum_.nextElement(); @@ -1132,6 +1134,11 @@ public class JarSigner { // out first mfFiles.addElement(ze); + if (SignatureFileVerifier.isBlockOrSF( + ze.getName().toUpperCase(Locale.ENGLISH))) { + wasSigned = true; + } + if (signatureRelated(ze.getName())) { // ignore signature-related and manifest files continue; @@ -1159,37 +1166,41 @@ public class JarSigner { if (mfModified) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); manifest.write(baos); - byte[] newBytes = baos.toByteArray(); - if (mfRawBytes != null - && oldAttr.equals(manifest.getMainAttributes())) { + if (wasSigned) { + byte[] newBytes = baos.toByteArray(); + if (mfRawBytes != null + && oldAttr.equals(manifest.getMainAttributes())) { - /* - * Note: - * - * The Attributes object is based on HashMap and can handle - * continuation columns. Therefore, even if the contents are - * not changed (in a Map view), the bytes that it write() - * may be different from the original bytes that it read() - * from. Since the signature on the main attributes is based - * on raw bytes, we must retain the exact bytes. - */ + /* + * Note: + * + * The Attributes object is based on HashMap and can handle + * continuation columns. Therefore, even if the contents are + * not changed (in a Map view), the bytes that it write() + * may be different from the original bytes that it read() + * from. Since the signature on the main attributes is based + * on raw bytes, we must retain the exact bytes. + */ - int newPos = findHeaderEnd(newBytes); - int oldPos = findHeaderEnd(mfRawBytes); + int newPos = findHeaderEnd(newBytes); + int oldPos = findHeaderEnd(mfRawBytes); - if (newPos == oldPos) { - System.arraycopy(mfRawBytes, 0, newBytes, 0, oldPos); - } else { - // cat oldHead newTail > newBytes - byte[] lastBytes = new byte[oldPos + - newBytes.length - newPos]; - System.arraycopy(mfRawBytes, 0, lastBytes, 0, oldPos); - System.arraycopy(newBytes, newPos, lastBytes, oldPos, - newBytes.length - newPos); - newBytes = lastBytes; + if (newPos == oldPos) { + System.arraycopy(mfRawBytes, 0, newBytes, 0, oldPos); + } else { + // cat oldHead newTail > newBytes + byte[] lastBytes = new byte[oldPos + + newBytes.length - newPos]; + System.arraycopy(mfRawBytes, 0, lastBytes, 0, oldPos); + System.arraycopy(newBytes, newPos, lastBytes, oldPos, + newBytes.length - newPos); + newBytes = lastBytes; + } } + mfRawBytes = newBytes; + } else { + mfRawBytes = baos.toByteArray(); } - mfRawBytes = newBytes; } // Write out the manifest @@ -1411,23 +1422,31 @@ public class JarSigner { } /** - * Find the position of an empty line inside bs + * Find the length of header inside bs. The header is a multiple (>=0) + * lines of attributes plus an empty line. The empty line is included + * in the header. */ private int findHeaderEnd(byte[] bs) { - // An empty line can be at the beginning... - if (bs.length > 1 && bs[0] == '\r' && bs[1] == '\n') { - return 0; - } - // ... or after another line - for (int i=0; i 1 +mkdir META-INF + +# Create a fake .RSA file so that jarsigner believes it's signed + +touch META-INF/x.RSA + +# A MANIFEST.MF using \n as newlines and no double newlines at the end + +cat > META-INF/MANIFEST.MF < Date: Thu, 6 May 2010 13:42:52 +0800 Subject: [PATCH 18/38] 6890876: jarsigner can add CRL info into signed jar Reviewed-by: mullan --- .../jarsigner/ContentSignerParameters.java | 11 +- .../classes/java/security/CodeSigner.java | 44 +- .../classes/java/util/jar/JarVerifier.java | 3 +- .../misc/JavaSecurityCodeSignerAccess.java | 33 ++ .../share/classes/sun/misc/SharedSecrets.java | 15 +- .../classes/sun/security/pkcs/PKCS7.java | 40 +- .../classes/sun/security/tools/JarSigner.java | 79 +++- .../security/tools/JarSignerResources.java | 5 +- .../classes/sun/security/tools/KeyTool.java | 384 ++++++++++++++++-- .../sun/security/tools/TimestampedSigner.java | 3 +- .../classes/sun/security/util/Resources.java | 9 +- .../security/util/SignatureFileVerifier.java | 12 +- .../sun/security/x509/X509CRLImpl.java | 11 +- jdk/test/sun/security/tools/jarsigner/crl.sh | 91 +++++ 14 files changed, 683 insertions(+), 57 deletions(-) create mode 100644 jdk/src/share/classes/sun/misc/JavaSecurityCodeSignerAccess.java create mode 100644 jdk/test/sun/security/tools/jarsigner/crl.sh diff --git a/jdk/src/share/classes/com/sun/jarsigner/ContentSignerParameters.java b/jdk/src/share/classes/com/sun/jarsigner/ContentSignerParameters.java index 5ef30e031fa..942d29070da 100644 --- a/jdk/src/share/classes/com/sun/jarsigner/ContentSignerParameters.java +++ b/jdk/src/share/classes/com/sun/jarsigner/ContentSignerParameters.java @@ -1,5 +1,5 @@ /* - * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2010 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,9 @@ package com.sun.jarsigner; import java.net.URI; +import java.security.cert.X509CRL; import java.security.cert.X509Certificate; +import java.util.Set; import java.util.zip.ZipFile; /** @@ -80,6 +82,13 @@ public interface ContentSignerParameters { */ public X509Certificate[] getSignerCertificateChain(); + /** + * Retrieves the signer's X.509 CRLs. + * + * @return An unmodifiable set of X.509 CRLs (never null) + */ + public Set getCRLs(); + /** * Retrieves the content that was signed. * The content is the JAR file's signature file. diff --git a/jdk/src/share/classes/java/security/CodeSigner.java b/jdk/src/share/classes/java/security/CodeSigner.java index a5ef70b7dce..b7abdf06fb8 100644 --- a/jdk/src/share/classes/java/security/CodeSigner.java +++ b/jdk/src/share/classes/java/security/CodeSigner.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2010 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,10 @@ package java.security; import java.io.Serializable; +import java.security.cert.CRL; import java.security.cert.CertPath; +import sun.misc.JavaSecurityCodeSignerAccess; +import sun.misc.SharedSecrets; /** * This class encapsulates information about a code signer. @@ -163,4 +166,43 @@ public final class CodeSigner implements Serializable { sb.append(")"); return sb.toString(); } + + // A private attribute attached to this CodeSigner object. Can be accessed + // through SharedSecrets.getJavaSecurityCodeSignerAccess().[g|s]etCRLs + // + // Currently called in SignatureFileVerifier.getSigners + private transient CRL[] crls; + + /** + * Sets the CRLs attached + * @param crls, null to clear + */ + void setCRLs(CRL[] crls) { + this.crls = crls; + } + + /** + * Returns the CRLs attached + * @return the crls, initially null + */ + CRL[] getCRLs() { + return crls; + } + + // Set up JavaSecurityCodeSignerAccess in SharedSecrets + static { + SharedSecrets.setJavaSecurityCodeSignerAccess( + new JavaSecurityCodeSignerAccess() { + @Override + public void setCRLs(CodeSigner signer, CRL[] crls) { + signer.setCRLs(crls); + } + + @Override + public CRL[] getCRLs(CodeSigner signer) { + return signer.getCRLs(); + } + }); + } + } diff --git a/jdk/src/share/classes/java/util/jar/JarVerifier.java b/jdk/src/share/classes/java/util/jar/JarVerifier.java index a4ceaa790fd..1c88d226e28 100644 --- a/jdk/src/share/classes/java/util/jar/JarVerifier.java +++ b/jdk/src/share/classes/java/util/jar/JarVerifier.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2010 Sun Microsystems, Inc. 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 @@ -27,7 +27,6 @@ package java.util.jar; import java.io.*; import java.util.*; -import java.util.zip.*; import java.security.*; import java.security.cert.CertificateException; diff --git a/jdk/src/share/classes/sun/misc/JavaSecurityCodeSignerAccess.java b/jdk/src/share/classes/sun/misc/JavaSecurityCodeSignerAccess.java new file mode 100644 index 00000000000..4543b00da5f --- /dev/null +++ b/jdk/src/share/classes/sun/misc/JavaSecurityCodeSignerAccess.java @@ -0,0 +1,33 @@ +/* + * Copyright 2010 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +package sun.misc; + +import java.security.CodeSigner; +import java.security.cert.CRL; + +public interface JavaSecurityCodeSignerAccess { + void setCRLs(CodeSigner signer, CRL[] crls); + CRL[] getCRLs(CodeSigner signer); +} diff --git a/jdk/src/share/classes/sun/misc/SharedSecrets.java b/jdk/src/share/classes/sun/misc/SharedSecrets.java index c9f50728860..76ae42f673a 100644 --- a/jdk/src/share/classes/sun/misc/SharedSecrets.java +++ b/jdk/src/share/classes/sun/misc/SharedSecrets.java @@ -27,8 +27,8 @@ package sun.misc; import java.util.jar.JarFile; import java.io.Console; -import java.io.File; import java.io.FileDescriptor; +import java.security.CodeSigner; import java.security.ProtectionDomain; /** A repository of "shared secrets", which are a mechanism for @@ -49,6 +49,7 @@ public class SharedSecrets { private static JavaNioAccess javaNioAccess; private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess; private static JavaSecurityProtectionDomainAccess javaSecurityProtectionDomainAccess; + private static JavaSecurityCodeSignerAccess javaSecurityCodeSignerAccess; public static JavaUtilJarAccess javaUtilJarAccess() { if (javaUtilJarAccess == null) { @@ -126,4 +127,16 @@ public class SharedSecrets { unsafe.ensureClassInitialized(ProtectionDomain.class); return javaSecurityProtectionDomainAccess; } + + public static void setJavaSecurityCodeSignerAccess + (JavaSecurityCodeSignerAccess jscsa) { + javaSecurityCodeSignerAccess = jscsa; + } + + public static JavaSecurityCodeSignerAccess + getJavaSecurityCodeSignerAccess() { + if (javaSecurityCodeSignerAccess == null) + unsafe.ensureClassInitialized(CodeSigner.class); + return javaSecurityCodeSignerAccess; + } } diff --git a/jdk/src/share/classes/sun/security/pkcs/PKCS7.java b/jdk/src/share/classes/sun/security/pkcs/PKCS7.java index 1a1bcf41cf2..d3342fdb2b5 100644 --- a/jdk/src/share/classes/sun/security/pkcs/PKCS7.java +++ b/jdk/src/share/classes/sun/security/pkcs/PKCS7.java @@ -1,5 +1,5 @@ /* - * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2010 Sun Microsystems, Inc. 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 @@ -28,7 +28,6 @@ package sun.security.pkcs; import java.io.*; import java.math.BigInteger; import java.util.*; -import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.security.cert.CertificateException; import java.security.cert.X509CRL; @@ -173,20 +172,30 @@ public class PKCS7 { * @param digestAlgorithmIds the message digest algorithm identifiers. * @param contentInfo the content information. * @param certificates an array of X.509 certificates. + * @param crls an array of CRLs * @param signerInfos an array of signer information. */ public PKCS7(AlgorithmId[] digestAlgorithmIds, ContentInfo contentInfo, X509Certificate[] certificates, + X509CRL[] crls, SignerInfo[] signerInfos) { version = BigInteger.ONE; this.digestAlgorithmIds = digestAlgorithmIds; this.contentInfo = contentInfo; this.certificates = certificates; + this.crls = crls; this.signerInfos = signerInfos; } + public PKCS7(AlgorithmId[] digestAlgorithmIds, + ContentInfo contentInfo, + X509Certificate[] certificates, + SignerInfo[] signerInfos) { + this(digestAlgorithmIds, contentInfo, certificates, null, signerInfos); + } + private void parseNetscapeCertChain(DerValue val) throws ParsingException, IOException { DerInputStream dis = new DerInputStream(val.toByteArray()); @@ -312,7 +321,7 @@ public class PKCS7 { ByteArrayInputStream bais = null; try { if (certfac == null) - crls[i] = (X509CRL) new X509CRLImpl(crlVals[i]); + crls[i] = new X509CRLImpl(crlVals[i]); else { byte[] encoded = crlVals[i].toByteArray(); bais = new ByteArrayInputStream(encoded); @@ -480,7 +489,30 @@ public class PKCS7 { signedData.putOrderedSetOf((byte)0xA0, implCerts); } - // no crls (OPTIONAL field) + // CRLs (optional) + if (crls != null && crls.length != 0) { + // cast to X509CRLImpl[] since X509CRLImpl implements DerEncoder + Set implCRLs = new HashSet(crls.length); + for (X509CRL crl: crls) { + if (crl instanceof X509CRLImpl) + implCRLs.add((X509CRLImpl) crl); + else { + try { + byte[] encoded = crl.getEncoded(); + implCRLs.add(new X509CRLImpl(encoded)); + } catch (CRLException ce) { + IOException ie = new IOException(ce.getMessage()); + ie.initCause(ce); + throw ie; + } + } + } + + // Add the CRL set (tagged with [1] IMPLICIT) + // to the signed data + signedData.putOrderedSetOf((byte)0xA1, + implCRLs.toArray(new X509CRLImpl[implCRLs.size()])); + } // signerInfos signedData.putOrderedSetOf(DerValue.tag_Set, signerInfos); diff --git a/jdk/src/share/classes/sun/security/tools/JarSigner.java b/jdk/src/share/classes/sun/security/tools/JarSigner.java index 0f7324d7c19..f45a2c93157 100644 --- a/jdk/src/share/classes/sun/security/tools/JarSigner.java +++ b/jdk/src/share/classes/sun/security/tools/JarSigner.java @@ -26,6 +26,7 @@ package sun.security.tools; import java.io.*; +import java.security.cert.X509CRL; import java.util.*; import java.util.zip.*; import java.util.jar.*; @@ -35,6 +36,7 @@ import java.net.URISyntaxException; import java.text.Collator; import java.text.MessageFormat; import java.security.cert.Certificate; +import java.security.cert.CRL; import java.security.cert.X509Certificate; import java.security.cert.CertificateException; import java.security.*; @@ -56,6 +58,7 @@ import java.util.Map.Entry; import sun.security.x509.*; import sun.security.util.*; import sun.misc.BASE64Encoder; +import sun.misc.SharedSecrets; /** @@ -114,14 +117,16 @@ public class JarSigner { static final int SIGNED_BY_ALIAS = 0x08; // signer is in alias list X509Certificate[] certChain; // signer's cert chain (when composing) + Set crls; // signer provided CRLs PrivateKey privateKey; // private key KeyStore store; // the keystore specified by -keystore // or the default keystore, never null String keystore; // key store file + List crlfiles = new ArrayList(); // CRL files to add boolean nullStream = false; // null keystore input stream (NONE) boolean token = false; // token-based keystore - String jarfile; // jar file to sign or verify + String jarfile; // jar files to sign or verify String alias; // alias to sign jar with List ckaliases = new ArrayList(); // aliases in -verify char[] storepass; // keystore password @@ -146,6 +151,7 @@ public class JarSigner { boolean signManifest = true; // "sign" the whole manifest boolean externalSF = true; // leave the .SF out of the PKCS7 block boolean strict = false; // treat warnings as error + boolean autoCRL = false; // Automatcially add CRL defined in cert // read zip entry raw bytes private ByteArrayOutputStream baos = new ByteArrayOutputStream(2048); @@ -226,6 +232,29 @@ public class JarSigner { } else { loadKeyStore(keystore, true); getAliasInfo(alias); + crls = new HashSet(); + if (crlfiles.size() > 0 || autoCRL) { + CertificateFactory fac = + CertificateFactory.getInstance("X509"); + List list = new ArrayList(); + for (String file: crlfiles) { + Collection tmp = KeyTool.loadCRLs(file); + for (CRL crl: tmp) { + if (crl instanceof X509CRL) { + crls.add((X509CRL)crl); + } + } + } + if (autoCRL) { + List crlsFromCert = + KeyTool.readCRLsFromCert(certChain[0]); + for (CRL crl: crlsFromCert) { + if (crl instanceof X509CRL) { + crls.add((X509CRL)crl); + } + } + } + } // load the alternative signing mechanism if (altSignerClass != null) { @@ -367,6 +396,13 @@ public class JarSigner { } else if (collator.compare(flags, "-digestalg") ==0) { if (++n == args.length) usageNoArg(); digestalg = args[n]; + } else if (collator.compare(flags, "-crl") ==0) { + if ("auto".equals(modifier)) { + autoCRL = true; + } else { + if (++n == args.length) usageNoArg(); + crlfiles.add(args[n]); + } } else if (collator.compare(flags, "-certs") ==0) { showcerts = true; } else if (collator.compare(flags, "-strict") ==0) { @@ -515,6 +551,9 @@ public class JarSigner { System.out.println(rb.getString ("[-sigalg ] name of signature algorithm")); System.out.println(); + System.out.println(rb.getString + ("[-crl[:auto| ] include CRL in signed jar")); + System.out.println(); System.out.println(rb.getString ("[-verify] verify a signed JAR file")); System.out.println(); @@ -654,6 +693,20 @@ public class JarSigner { if (showcerts) { sb.append(si); sb.append('\n'); + CRL[] crls = SharedSecrets + .getJavaSecurityCodeSignerAccess() + .getCRLs(signer); + if (crls != null) { + for (CRL crl: crls) { + if (crl instanceof X509CRLImpl) { + sb.append(tab).append("["); + sb.append(String.format( + rb.getString("with a CRL including %d entries"), + ((X509CRLImpl)crl).getRevokedCertificates().size())) + .append("]\n"); + } + } + } } } } else if (showcerts && !verbose.equals("all")) { @@ -1233,7 +1286,7 @@ public class JarSigner { try { block = - sf.generateBlock(privateKey, sigalg, certChain, + sf.generateBlock(privateKey, sigalg, certChain, crls, externalSF, tsaUrl, tsaCert, signingMechanism, args, zipFile); } catch (SocketTimeoutException e) { @@ -2197,6 +2250,7 @@ class SignatureFile { public Block generateBlock(PrivateKey privateKey, String sigalg, X509Certificate[] certChain, + Set crls, boolean externalSF, String tsaUrl, X509Certificate tsaCert, ContentSigner signingMechanism, @@ -2204,7 +2258,7 @@ class SignatureFile { throws NoSuchAlgorithmException, InvalidKeyException, IOException, SignatureException, CertificateException { - return new Block(this, privateKey, sigalg, certChain, externalSF, + return new Block(this, privateKey, sigalg, certChain, crls, externalSF, tsaUrl, tsaCert, signingMechanism, args, zipFile); } @@ -2218,7 +2272,8 @@ class SignatureFile { * Construct a new signature block. */ Block(SignatureFile sfg, PrivateKey privateKey, String sigalg, - X509Certificate[] certChain, boolean externalSF, String tsaUrl, + X509Certificate[] certChain, Set crls, + boolean externalSF, String tsaUrl, X509Certificate tsaCert, ContentSigner signingMechanism, String[] args, ZipFile zipFile) throws NoSuchAlgorithmException, InvalidKeyException, IOException, @@ -2305,7 +2360,7 @@ class SignatureFile { // Assemble parameters for the signing mechanism ContentSignerParameters params = new JarSignerParameters(args, tsaUri, tsaCert, signature, - signatureAlgorithm, certChain, content, zipFile); + signatureAlgorithm, certChain, crls, content, zipFile); // Generate the signature block block = signingMechanism.generateSignedData( @@ -2346,6 +2401,7 @@ class JarSignerParameters implements ContentSignerParameters { private byte[] signature; private String signatureAlgorithm; private X509Certificate[] signerCertificateChain; + private Set crls; private byte[] content; private ZipFile source; @@ -2354,7 +2410,8 @@ class JarSignerParameters implements ContentSignerParameters { */ JarSignerParameters(String[] args, URI tsa, X509Certificate tsaCertificate, byte[] signature, String signatureAlgorithm, - X509Certificate[] signerCertificateChain, byte[] content, + X509Certificate[] signerCertificateChain, Set crls, + byte[] content, ZipFile source) { if (signature == null || signatureAlgorithm == null || @@ -2367,6 +2424,7 @@ class JarSignerParameters implements ContentSignerParameters { this.signature = signature; this.signatureAlgorithm = signatureAlgorithm; this.signerCertificateChain = signerCertificateChain; + this.crls = crls; this.content = content; this.source = source; } @@ -2442,4 +2500,13 @@ class JarSignerParameters implements ContentSignerParameters { public ZipFile getSource() { return source; } + + @Override + public Set getCRLs() { + if (crls == null) { + return Collections.emptySet(); + } else { + return Collections.unmodifiableSet(crls); + } + } } diff --git a/jdk/src/share/classes/sun/security/tools/JarSignerResources.java b/jdk/src/share/classes/sun/security/tools/JarSignerResources.java index 7e259e8e8fe..16cc6863b43 100644 --- a/jdk/src/share/classes/sun/security/tools/JarSignerResources.java +++ b/jdk/src/share/classes/sun/security/tools/JarSignerResources.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2010 Sun Microsystems, Inc. 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 @@ -74,6 +74,8 @@ public class JarSignerResources extends java.util.ListResourceBundle { "[-digestalg ] name of digest algorithm"}, {"[-sigalg ] name of signature algorithm", "[-sigalg ] name of signature algorithm"}, + {"[-crl[:auto| ] include CRL in signed jar", + "[-crl[:auto| ] include CRL in signed jar"}, {"[-verify] verify a signed JAR file", "[-verify] verify a signed JAR file"}, {"[-verbose[:suboptions]] verbose output when signing/verifying.", @@ -191,6 +193,7 @@ public class JarSignerResources extends java.util.ListResourceBundle { {"using an alternative signing mechanism", "using an alternative signing mechanism"}, {"entry was signed on", "entry was signed on {0}"}, + {"with a CRL including %d entries", "with a CRL including %d entries"}, {"Warning: ", "Warning: "}, {"This jar contains unsigned entries which have not been integrity-checked. ", "This jar contains unsigned entries which have not been integrity-checked. "}, diff --git a/jdk/src/share/classes/sun/security/tools/KeyTool.java b/jdk/src/share/classes/sun/security/tools/KeyTool.java index 2539d43e14b..b799bfaa7fc 100644 --- a/jdk/src/share/classes/sun/security/tools/KeyTool.java +++ b/jdk/src/share/classes/sun/security/tools/KeyTool.java @@ -25,6 +25,7 @@ package sun.security.tools; +import sun.misc.SharedSecrets; import java.io.*; import java.security.CodeSigner; import java.security.KeyStore; @@ -42,6 +43,7 @@ import java.security.Principal; import java.security.Provider; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; +import java.security.cert.CRL; import java.security.cert.X509Certificate; import java.security.cert.CertificateException; import java.text.Collator; @@ -50,14 +52,20 @@ import java.util.*; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.lang.reflect.Constructor; +import java.math.BigInteger; +import java.net.URI; import java.net.URL; import java.net.URLClassLoader; +import java.security.cert.CertStore; +import java.security.cert.X509CRL; +import java.security.cert.X509CRLEntry; +import java.security.cert.X509CRLSelector; +import javax.security.auth.x500.X500Principal; import sun.misc.BASE64Encoder; import sun.security.util.ObjectIdentifier; import sun.security.pkcs.PKCS10; import sun.security.provider.X509Factory; -import sun.security.util.DerOutputStream; import sun.security.util.Password; import sun.security.util.PathList; import javax.crypto.KeyGenerator; @@ -72,6 +80,7 @@ import javax.net.ssl.X509TrustManager; import sun.misc.BASE64Decoder; import sun.security.pkcs.PKCS10Attribute; import sun.security.pkcs.PKCS9Attribute; +import sun.security.provider.certpath.ldap.LDAPCertStoreHelper; import sun.security.util.DerValue; import sun.security.x509.*; @@ -147,6 +156,7 @@ public final class KeyTool { private Set passwords = new HashSet (); private String startDate = null; + private List ids = new ArrayList (); // used in GENCRL private List v3ext = new ArrayList (); enum Command { @@ -180,9 +190,6 @@ public final class KeyTool { STARTDATE, EXT, VALIDITY, KEYPASS, KEYSTORE, STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V, PROTECTED), - IDENTITYDB("Imports entries from a JDK 1.1.x-style identity database", - FILEIN, STORETYPE, KEYSTORE, STOREPASS, PROVIDERNAME, - PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V), IMPORTCERT("Imports a certificate or a certificate chain", NOPROMPT, TRUSTCACERTS, PROTECTED, ALIAS, FILEIN, KEYPASS, KEYSTORE, STOREPASS, STORETYPE, @@ -195,10 +202,6 @@ public final class KeyTool { SRCALIAS, DESTALIAS, SRCKEYPASS, DESTKEYPASS, NOPROMPT, PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V), - KEYCLONE("Clones a key entry", - ALIAS, DESTALIAS, KEYPASS, NEW, STORETYPE, - KEYSTORE, STOREPASS, PROVIDERNAME, PROVIDERCLASS, - PROVIDERARG, PROVIDERPATH, V), KEYPASSWD("Changes the key password of an entry", ALIAS, KEYPASS, NEW, KEYSTORE, STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG, @@ -211,12 +214,29 @@ public final class KeyTool { RFC, FILEIN, SSLSERVER, JARFILE, V), PRINTCERTREQ("Prints the content of a certificate request", FILEIN, V), + PRINTCRL("Prints the content of a CRL file", + FILEIN, V), + STOREPASSWD("Changes the store password of a keystore", + NEW, KEYSTORE, STOREPASS, STORETYPE, PROVIDERNAME, + PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V), + + // Undocumented start here, KEYCLONE is used a marker in -help; + + KEYCLONE("Clones a key entry", + ALIAS, DESTALIAS, KEYPASS, NEW, STORETYPE, + KEYSTORE, STOREPASS, PROVIDERNAME, PROVIDERCLASS, + PROVIDERARG, PROVIDERPATH, V), SELFCERT("Generates a self-signed certificate", ALIAS, SIGALG, DNAME, STARTDATE, VALIDITY, KEYPASS, STORETYPE, KEYSTORE, STOREPASS, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V), - STOREPASSWD("Changes the store password of a keystore", - NEW, KEYSTORE, STOREPASS, STORETYPE, PROVIDERNAME, + GENCRL("Generates CRL", + RFC, FILEOUT, ID, + ALIAS, SIGALG, EXT, KEYPASS, KEYSTORE, + STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS, + PROVIDERARG, PROVIDERPATH, V, PROTECTED), + IDENTITYDB("Imports entries from a JDK 1.1.x-style identity database", + FILEIN, STORETYPE, KEYSTORE, STOREPASS, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V); final String description; @@ -244,6 +264,7 @@ public final class KeyTool { EXT("ext", "", "X.509 extension"), FILEOUT("file", "", "output file name"), FILEIN("file", "", "input file name"), + ID("id", "", "Serial ID of cert to revoke"), INFILE("infile", "", "input file name"), KEYALG("keyalg", "", "key algorithm name"), KEYPASS("keypass", "", "key password"), @@ -458,6 +479,8 @@ public final class KeyTool { validity = Long.parseLong(args[++i]); } else if (collator.compare(flags, "-ext") == 0) { v3ext.add(args[++i]); + } else if (collator.compare(flags, "-id") == 0) { + ids.add(args[++i]); } else if (collator.compare(flags, "-file") == 0) { filename = args[++i]; } else if (collator.compare(flags, "-infile") == 0) { @@ -720,7 +743,8 @@ public final class KeyTool { command != GENSECKEY && command != IDENTITYDB && command != IMPORTCERT && - command != IMPORTKEYSTORE) { + command != IMPORTKEYSTORE && + command != PRINTCRL) { throw new Exception(rb.getString ("Keystore file does not exist: ") + ksfname); } @@ -855,10 +879,12 @@ public final class KeyTool { && !KeyStoreUtil.isWindowsKeyStore(storetype) && isKeyStoreRelated(command)) { // here we have EXPORTCERT and LIST (info valid until STOREPASSWD) - System.err.print(rb.getString("Enter keystore password: ")); - System.err.flush(); - storePass = Password.readPassword(System.in); - passwords.add(storePass); + if (command != PRINTCRL) { + System.err.print(rb.getString("Enter keystore password: ")); + System.err.flush(); + storePass = Password.readPassword(System.in); + passwords.add(storePass); + } } // Now load a nullStream-based keystore, @@ -895,7 +921,7 @@ public final class KeyTool { // Create a certificate factory if (command == PRINTCERT || command == IMPORTCERT - || command == IDENTITYDB) { + || command == IDENTITYDB || command == PRINTCRL) { cf = CertificateFactory.getInstance("X509"); } @@ -1086,6 +1112,22 @@ public final class KeyTool { ps.close(); } } + } else if (command == GENCRL) { + if (alias == null) { + alias = keyAlias; + } + PrintStream ps = null; + if (filename != null) { + ps = new PrintStream(new FileOutputStream(filename)); + out = ps; + } + try { + doGenCRL(out); + } finally { + if (ps != null) { + ps.close(); + } + } } else if (command == PRINTCERTREQ) { InputStream inStream = System.in; if (filename != null) { @@ -1098,6 +1140,8 @@ public final class KeyTool { inStream.close(); } } + } else if (command == PRINTCRL) { + doPrintCRL(filename, out); } // If we need to save the keystore, do so. @@ -1152,7 +1196,8 @@ public final class KeyTool { CertificateValidity interval = new CertificateValidity(firstDate, lastDate); - PrivateKey privateKey = (PrivateKey)recoverKey(alias, storePass, keyPass).fst; + PrivateKey privateKey = + (PrivateKey)recoverKey(alias, storePass, keyPass).fst; if (sigAlgName == null) { sigAlgName = getCompatibleSigAlgName(privateKey.getAlgorithm()); } @@ -1221,6 +1266,56 @@ public final class KeyTool { } } + private void doGenCRL(PrintStream out) + throws Exception { + if (ids == null) { + throw new Exception("Must provide -id when -gencrl"); + } + Certificate signerCert = keyStore.getCertificate(alias); + byte[] encoded = signerCert.getEncoded(); + X509CertImpl signerCertImpl = new X509CertImpl(encoded); + X509CertInfo signerCertInfo = (X509CertInfo)signerCertImpl.get( + X509CertImpl.NAME + "." + X509CertImpl.INFO); + X500Name owner = (X500Name)signerCertInfo.get(X509CertInfo.SUBJECT + "." + + CertificateSubjectName.DN_NAME); + + Date firstDate = getStartDate(startDate); + Date lastDate = (Date) firstDate.clone(); + lastDate.setTime(lastDate.getTime() + (long)validity*1000*24*60*60); + CertificateValidity interval = new CertificateValidity(firstDate, + lastDate); + + + PrivateKey privateKey = + (PrivateKey)recoverKey(alias, storePass, keyPass).fst; + if (sigAlgName == null) { + sigAlgName = getCompatibleSigAlgName(privateKey.getAlgorithm()); + } + + X509CRLEntry[] badCerts = new X509CRLEntry[ids.size()]; + for (int i=0; i= 0) { + CRLExtensions ext = new CRLExtensions(); + ext.set("Reason", new CRLReasonCodeExtension(Integer.parseInt(id.substring(d+1)))); + badCerts[i] = new X509CRLEntryImpl(new BigInteger(id.substring(0, d)), + firstDate, ext); + } else { + badCerts[i] = new X509CRLEntryImpl(new BigInteger(ids.get(i)), firstDate); + } + } + X509CRLImpl crl = new X509CRLImpl(owner, firstDate, lastDate, badCerts); + crl.sign(privateKey, sigAlgName); + if (rfc) { + out.println("-----BEGIN X509 CRL-----"); + new BASE64Encoder().encodeBuffer(crl.getEncodedInternal(), out); + out.println("-----END X509 CRL-----"); + } else { + out.write(crl.getEncodedInternal()); + } + } + /** * Creates a PKCS#10 cert signing request, corresponding to the * keys (and name) associated with a given alias. @@ -1925,6 +2020,177 @@ public final class KeyTool { } } + private static Iterable e2i(final Enumeration e) { + return new Iterable() { + @Override + public Iterator iterator() { + return new Iterator() { + @Override + public boolean hasNext() { + return e.hasMoreElements(); + } + @Override + public T next() { + return e.nextElement(); + } + public void remove() { + throw new UnsupportedOperationException("Not supported yet."); + } + }; + } + }; + } + + /** + * Loads CRLs from a source. This method is also called in JarSigner. + * @param src the source, which means System.in if null, or a URI, + * or a bare file path name + */ + public static Collection loadCRLs(String src) throws Exception { + InputStream in = null; + URI uri = null; + if (src == null) { + in = System.in; + } else { + try { + uri = new URI(src); + if (uri.getScheme().equals("ldap")) { + // No input stream for LDAP + } else { + in = uri.toURL().openStream(); + } + } catch (Exception e) { + try { + in = new FileInputStream(src); + } catch (Exception e2) { + if (uri == null || uri.getScheme() == null) { + throw e2; // More likely a bare file path + } else { + throw e; // More likely a protocol or network problem + } + } + } + } + if (in != null) { + try { + // Read the full stream before feeding to X509Factory, + // otherwise, keytool -gencrl | keytool -printcrl + // might not work properly, since -gencrl is slow + // and there's no data in the pipe at the beginning. + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + byte[] b = new byte[4096]; + while (true) { + int len = in.read(b); + if (len < 0) break; + bout.write(b, 0, len); + } + return CertificateFactory.getInstance("X509").generateCRLs( + new ByteArrayInputStream(bout.toByteArray())); + } finally { + if (in != System.in) { + in.close(); + } + } + } else { // must be LDAP, and uri is not null + String path = uri.getPath(); + if (path.charAt(0) == '/') path = path.substring(1); + LDAPCertStoreHelper h = new LDAPCertStoreHelper(); + CertStore s = h.getCertStore(uri); + X509CRLSelector sel = + h.wrap(new X509CRLSelector(), null, path); + return s.getCRLs(sel); + } + } + + /** + * Returns CRLs described in a X509Certificate's CRLDistributionPoints + * Extension. Only those containing a general name of type URI are read. + */ + public static List readCRLsFromCert(X509Certificate cert) + throws Exception { + List crls = new ArrayList(); + CRLDistributionPointsExtension ext = + X509CertImpl.toImpl(cert).getCRLDistributionPointsExtension(); + if (ext == null) return crls; + for (DistributionPoint o: (List) + ext.get(CRLDistributionPointsExtension.POINTS)) { + GeneralNames names = o.getFullName(); + if (names != null) { + for (GeneralName name: names.names()) { + if (name.getType() == GeneralNameInterface.NAME_URI) { + URIName uriName = (URIName)name.getName(); + for (CRL crl: KeyTool.loadCRLs(uriName.getName())) { + if (crl instanceof X509CRL) { + crls.add((X509CRL)crl); + } + } + break; // Different name should point to same CRL + } + } + } + } + return crls; + } + + private static String verifyCRL(KeyStore ks, CRL crl) + throws Exception { + X509CRLImpl xcrl = (X509CRLImpl)crl; + X500Principal issuer = xcrl.getIssuerX500Principal(); + for (String s: e2i(ks.aliases())) { + Certificate cert = ks.getCertificate(s); + if (cert instanceof X509Certificate) { + X509Certificate xcert = (X509Certificate)cert; + if (xcert.getSubjectX500Principal().equals(issuer)) { + try { + ((X509CRLImpl)crl).verify(cert.getPublicKey()); + return s; + } catch (Exception e) { + } + } + } + } + return null; + } + + private void doPrintCRL(String src, PrintStream out) + throws Exception { + for (CRL crl: loadCRLs(src)) { + printCRL(crl, out); + String issuer = null; + if (caks != null) { + issuer = verifyCRL(caks, crl); + if (issuer != null) { + System.out.println("Verified by " + issuer + " in cacerts"); + } + } + if (issuer == null && keyStore != null) { + issuer = verifyCRL(keyStore, crl); + if (issuer != null) { + System.out.println("Verified by " + issuer + " in keystore"); + } + } + if (issuer == null) { + out.println(rb.getString + ("*******************************************")); + out.println("WARNING: not verified. Make sure -keystore and -alias are correct."); + out.println(rb.getString + ("*******************************************\n\n")); + } + } + } + + private void printCRL(CRL crl, PrintStream out) + throws Exception { + if (rfc) { + X509CRL xcrl = (X509CRL)crl; + out.println("-----BEGIN X509 CRL-----"); + new BASE64Encoder().encodeBuffer(xcrl.getEncoded(), out); + out.println("-----END X509 CRL-----"); + } else { + out.println(crl.toString()); + } + } + private void doPrintCertReq(InputStream in, PrintStream out) throws Exception { @@ -2063,6 +2329,16 @@ public final class KeyTool { out.println(); } } + CRL[] crls = SharedSecrets + .getJavaSecurityCodeSignerAccess() + .getCRLs(signer); + if (crls != null) { + out.println(rb.getString("CRLs:")); + out.println(); + for (CRL crl: crls) { + printCRL(crl, out); + } + } } } } @@ -3330,15 +3606,22 @@ public final class KeyTool { /** * Match a command (may be abbreviated) with a command set. * @param s the command provided - * @param list the legal command set + * @param list the legal command set. If there is a null, commands after it + * are regarded experimental, which means they are supported but their + * existence should not be revealed to user. * @return the position of a single match, or -1 if none matched * @throws Exception if s is ambiguous */ private static int oneOf(String s, String... list) throws Exception { int[] match = new int[list.length]; int nmatch = 0; + int experiment = Integer.MAX_VALUE; for (int i = 0; i experiment) { + return match[0]; + } + StringBuffer sb = new StringBuffer(); + MessageFormat form = new MessageFormat(rb.getString + ("command {0} is ambiguous:")); + Object[] source = {s}; + sb.append(form.format(source)); + sb.append("\n "); + for (int i=0; i(); } // Append the new code signer - signers.add(new CodeSigner(certChain, getTimestamp(info))); + CodeSigner signer = new CodeSigner(certChain, getTimestamp(info)); + if (block.getCRLs() != null) { + SharedSecrets.getJavaSecurityCodeSignerAccess().setCRLs( + signer, block.getCRLs()); + } + signers.add(signer); if (debug != null) { debug.println("Signature Block Certificate: " + diff --git a/jdk/src/share/classes/sun/security/x509/X509CRLImpl.java b/jdk/src/share/classes/sun/security/x509/X509CRLImpl.java index b1157799663..f5d159891d9 100644 --- a/jdk/src/share/classes/sun/security/x509/X509CRLImpl.java +++ b/jdk/src/share/classes/sun/security/x509/X509CRLImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2010 Sun Microsystems, Inc. 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 @@ -89,7 +89,7 @@ import sun.misc.HexDumpEncoder; * @author Hemma Prafullchandra * @see X509CRL */ -public class X509CRLImpl extends X509CRL { +public class X509CRLImpl extends X509CRL implements DerEncoder { // CRL data, and its envelope private byte[] signedCRL = null; // DER encoded crl @@ -1189,6 +1189,13 @@ public class X509CRLImpl extends X509CRL { } } + @Override + public void derEncode(OutputStream out) throws IOException { + if (signedCRL == null) + throw new IOException("Null CRL to encode"); + out.write(signedCRL.clone()); + } + /** * Immutable X.509 Certificate Issuer DN and serial number pair */ diff --git a/jdk/test/sun/security/tools/jarsigner/crl.sh b/jdk/test/sun/security/tools/jarsigner/crl.sh new file mode 100644 index 00000000000..73d0c4eae57 --- /dev/null +++ b/jdk/test/sun/security/tools/jarsigner/crl.sh @@ -0,0 +1,91 @@ +# +# Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# + +# @test +# @bug 6890876 +# @summary jarsigner can add CRL info into signed jar +# + +if [ "${TESTJAVA}" = "" ] ; then + JAVAC_CMD=`which javac` + TESTJAVA=`dirname $JAVAC_CMD`/.. +fi + +# set platform-dependent variables +# PF: platform name, say, solaris-sparc + +PF="" + +OS=`uname -s` +case "$OS" in + Windows* ) + FS="\\" + ;; + * ) + FS="/" + ;; +esac + +KS=crl.jks +JFILE=crl.jar + +KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystore $KS" +JAR=$TESTJAVA${FS}bin${FS}jar +JARSIGNER=$TESTJAVA${FS}bin${FS}jarsigner + +rm $KS $JFILE + +# Generates some crl files, each containing two entries + +$KT -alias a -dname CN=a -keyalg rsa -genkey -validity 300 +$KT -alias a -gencrl -id 1:1 -id 2:2 -file crl1 +$KT -alias a -gencrl -id 3:3 -id 4:4 -file crl2 +$KT -alias b -dname CN=b -keyalg rsa -genkey -validity 300 +$KT -alias b -gencrl -id 5:1 -id 6:2 -file crl3 + +$KT -alias c -dname CN=c -keyalg rsa -genkey -validity 300 \ + -ext crl=uri:file://`pwd`/crl1 + +echo A > A + +# Test -crl:auto, cRLDistributionPoints is a local file + +$JAR cvf $JFILE A +$JARSIGNER -keystore $KS -storepass changeit $JFILE c \ + -crl:auto || exit 1 +$JARSIGNER -keystore $KS -verify -debug -strict $JFILE || exit 6 +$KT -printcert -jarfile $JFILE | grep CRLs || exit 7 + +# Test -crl + +$JAR cvf $JFILE A +$JARSIGNER -keystore $KS -storepass changeit $JFILE a \ + -crl crl1 -crl crl2 || exit 1 +$JARSIGNER -keystore $KS -storepass changeit $JFILE b \ + -crl crl3 -crl crl2 || exit 1 +$JARSIGNER -keystore $KS -verify -debug -strict $JFILE || exit 3 +$KT -printcert -jarfile $JFILE | grep CRLs || exit 4 +CRLCOUNT=`$KT -printcert -jarfile $JFILE | grep SerialNumber | wc -l` +if [ $CRLCOUNT != 8 ]; then exit 5; fi + +exit 0 From 5a66416a07a4ba361c31018571a51e9b0dbd7a07 Mon Sep 17 00:00:00 2001 From: Peter Zhelezniakov Date: Thu, 6 May 2010 12:57:30 +0400 Subject: [PATCH 19/38] 6919629: Nimbus L&F Nimbus.Overrides option leaks significant amounts of memory Reviewed-by: rupashka --- .../javax/swing/plaf/nimbus/NimbusStyle.java | 13 ++- .../javax/swing/plaf/nimbus/Test6919629.java | 82 +++++++++++++++++++ 2 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 jdk/test/javax/swing/plaf/nimbus/Test6919629.java diff --git a/jdk/src/share/classes/javax/swing/plaf/nimbus/NimbusStyle.java b/jdk/src/share/classes/javax/swing/plaf/nimbus/NimbusStyle.java index a8f8b3fc5b6..c8672e3c8c9 100644 --- a/jdk/src/share/classes/javax/swing/plaf/nimbus/NimbusStyle.java +++ b/jdk/src/share/classes/javax/swing/plaf/nimbus/NimbusStyle.java @@ -38,6 +38,7 @@ import javax.swing.plaf.synth.SynthStyle; import java.awt.Color; import java.awt.Font; import java.awt.Insets; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -193,7 +194,7 @@ public final class NimbusStyle extends SynthStyle { * UIDefaults which overrides (or supplements) those defaults found in * UIManager. */ - private JComponent component; + private WeakReference component; /** * Create a new NimbusStyle. Only the prefix must be supplied. At the @@ -209,7 +210,9 @@ public final class NimbusStyle extends SynthStyle { * should be null otherwise. */ NimbusStyle(String prefix, JComponent c) { - this.component = c; + if (c != null) { + this.component = new WeakReference(c); + } this.prefix = prefix; this.painter = new SynthPainterImpl(this); } @@ -251,9 +254,11 @@ public final class NimbusStyle extends SynthStyle { // value is an instance of UIDefaults, then these defaults are used // in place of, or in addition to, the defaults in UIManager. if (component != null) { - Object o = component.getClientProperty("Nimbus.Overrides"); + // We know component.get() is non-null here, as if the component + // were GC'ed, we wouldn't be processing its style. + Object o = component.get().getClientProperty("Nimbus.Overrides"); if (o instanceof UIDefaults) { - Object i = component.getClientProperty( + Object i = component.get().getClientProperty( "Nimbus.Overrides.InheritDefaults"); boolean inherit = i instanceof Boolean ? (Boolean)i : true; UIDefaults d = (UIDefaults)o; diff --git a/jdk/test/javax/swing/plaf/nimbus/Test6919629.java b/jdk/test/javax/swing/plaf/nimbus/Test6919629.java new file mode 100644 index 00000000000..38d66a0cf42 --- /dev/null +++ b/jdk/test/javax/swing/plaf/nimbus/Test6919629.java @@ -0,0 +1,82 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* @test + @bug 6919629 + @summary Tests that components with Nimbus.Overrides are GC'ed properly + @author Peter Zhelezniakov + @run main Test6919629 +*/ + +import java.awt.Color; +import java.lang.ref.WeakReference; +import javax.swing.*; +import javax.swing.plaf.nimbus.NimbusLookAndFeel; + +public class Test6919629 +{ + JFrame f; + WeakReference ref; + + public static void main(String[] args) throws Exception { + UIManager.setLookAndFeel(new NimbusLookAndFeel()); + Test6919629 t = new Test6919629(); + t.test(); + System.gc(); + t.check(); + } + + void test() throws Exception { + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + UIDefaults d = new UIDefaults(); + d.put("Label.textForeground", Color.MAGENTA); + + JLabel l = new JLabel(); + ref = new WeakReference(l); + l.putClientProperty("Nimbus.Overrides", d); + + f = new JFrame(); + f.getContentPane().add(l); + f.pack(); + f.setVisible(true); + } + }); + Thread.sleep(2000); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + f.getContentPane().removeAll(); + f.setVisible(false); + f.dispose(); + } + }); + Thread.sleep(2000); + } + + void check() { + if (ref.get() != null) { + throw new RuntimeException("Failed: an unused component wasn't collected"); + } + } +} From 1a12511929ef912eec9a5a470d07ac49955d28af Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Thu, 6 May 2010 17:17:09 +0100 Subject: [PATCH 20/38] 6946825: com.sun.net.httpserver.HttpServer; Memory Leak on Non HTTP conform open socket Reviewed-by: michaelm --- jdk/src/share/classes/sun/net/httpserver/ServerImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java b/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java index 8f5c8bee038..575661e776a 100644 --- a/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java +++ b/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java @@ -451,6 +451,7 @@ class ServerImpl implements TimeSource { if (requestLine == null) { /* connection closed */ connection.close(); + allConnections.remove(connection); return; } int space = requestLine.indexOf (' '); @@ -592,6 +593,8 @@ class ServerImpl implements TimeSource { sendReply ( code, true, "

"+code+Code.msg(code)+"

"+message ); + /* connection is already closed by sendReply, now remove it */ + allConnections.remove(connection); } void sendReply ( From 473182bb12e887e84a433df6273842ec21cacf3c Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Fri, 7 May 2010 10:11:37 +0100 Subject: [PATCH 21/38] 6947917: Error in basic authentication when user name and password are long Reviewed-by: weijun --- .../protocol/http/BasicAuthentication.java | 15 ++- .../protocol/http/BasicLongCredentials.java | 111 ++++++++++++++++++ 2 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 jdk/test/sun/net/www/protocol/http/BasicLongCredentials.java diff --git a/jdk/src/share/classes/sun/net/www/protocol/http/BasicAuthentication.java b/jdk/src/share/classes/sun/net/www/protocol/http/BasicAuthentication.java index 8e9c8a7281d..6755b59b061 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/http/BasicAuthentication.java +++ b/jdk/src/share/classes/sun/net/www/protocol/http/BasicAuthentication.java @@ -29,8 +29,10 @@ import java.net.URL; import java.net.URI; import java.net.URISyntaxException; import java.net.PasswordAuthentication; +import java.io.IOException; +import java.io.OutputStream; import sun.net.www.HeaderParser; - +import sun.misc.BASE64Encoder; /** * BasicAuthentication: Encapsulate an http server authentication using @@ -74,7 +76,7 @@ class BasicAuthentication extends AuthenticationInfo { System.arraycopy(nameBytes, 0, concat, 0, nameBytes.length); System.arraycopy(passwdBytes, 0, concat, nameBytes.length, passwdBytes.length); - this.auth = "Basic " + (new sun.misc.BASE64Encoder()).encode(concat); + this.auth = "Basic " + (new BasicBASE64Encoder()).encode(concat); this.pw = pw; } @@ -114,7 +116,7 @@ class BasicAuthentication extends AuthenticationInfo { System.arraycopy(nameBytes, 0, concat, 0, nameBytes.length); System.arraycopy(passwdBytes, 0, concat, nameBytes.length, passwdBytes.length); - this.auth = "Basic " + (new sun.misc.BASE64Encoder()).encode(concat); + this.auth = "Basic " + (new BasicBASE64Encoder()).encode(concat); this.pw = pw; } @@ -200,4 +202,11 @@ class BasicAuthentication extends AuthenticationInfo { return npath; } + /* It is never expected that the header value will exceed the bytesPerLine */ + private class BasicBASE64Encoder extends BASE64Encoder { + @Override + protected int bytesPerLine() { + return (10000); + } + } } diff --git a/jdk/test/sun/net/www/protocol/http/BasicLongCredentials.java b/jdk/test/sun/net/www/protocol/http/BasicLongCredentials.java new file mode 100644 index 00000000000..5ce3c500097 --- /dev/null +++ b/jdk/test/sun/net/www/protocol/http/BasicLongCredentials.java @@ -0,0 +1,111 @@ +/* + * Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6947917 + * @summary Error in basic authentication when user name and password are long + */ + +import com.sun.net.httpserver.BasicAuthenticator; +import com.sun.net.httpserver.HttpContext; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpPrincipal; +import com.sun.net.httpserver.HttpServer; +import java.io.InputStream; +import java.io.IOException; +import java.net.Authenticator; +import java.net.InetSocketAddress; +import java.net.PasswordAuthentication; +import java.net.HttpURLConnection; +import java.net.URL; + +public class BasicLongCredentials { + + static final String USERNAME = "ThisIsMyReallyReallyReallyReallyReallyReally" + + "LongFirstNameDotLastNameAtCompanyEmailAddress"; + static final String PASSWORD = "AndThisIsALongLongLongLongLongLongLongLongLong" + + "LongLongLongLongLongLongLongLongLongPassword"; + static final String REALM = "foobar@test.realm"; + + public static void main (String[] args) throws Exception { + HttpServer server = HttpServer.create(new InetSocketAddress(0), 0); + try { + Handler handler = new Handler(); + HttpContext ctx = server.createContext("/test", handler); + + BasicAuthenticator a = new BasicAuthenticator(REALM) { + public boolean checkCredentials (String username, String pw) { + return USERNAME.equals(username) && PASSWORD.equals(pw); + } + }; + ctx.setAuthenticator(a); + server.start(); + + Authenticator.setDefault(new MyAuthenticator()); + + URL url = new URL("http://localhost:"+server.getAddress().getPort()+"/test/"); + HttpURLConnection urlc = (HttpURLConnection)url.openConnection(); + InputStream is = urlc.getInputStream(); + int c = 0; + while (is.read()!= -1) { c ++; } + + if (c != 0) { throw new RuntimeException("Test failed c = " + c); } + if (error) { throw new RuntimeException("Test failed: error"); } + + System.out.println ("OK"); + } finally { + server.stop(0); + } + } + + public static boolean error = false; + + static class MyAuthenticator extends java.net.Authenticator { + @Override + public PasswordAuthentication getPasswordAuthentication () { + if (!getRequestingPrompt().equals(REALM)) { + BasicLongCredentials.error = true; + } + return new PasswordAuthentication (USERNAME, PASSWORD.toCharArray()); + } + } + + static class Handler implements HttpHandler { + public void handle (HttpExchange t) throws IOException { + InputStream is = t.getRequestBody(); + while (is.read () != -1) ; + is.close(); + t.sendResponseHeaders(200, -1); + HttpPrincipal p = t.getPrincipal(); + if (!p.getUsername().equals(USERNAME)) { + error = true; + } + if (!p.getRealm().equals(REALM)) { + error = true; + } + t.close(); + } + } +} From 521354406a4e9226aa2fbfe10238d3c9dac3c7a5 Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Fri, 7 May 2010 16:11:13 +0100 Subject: [PATCH 22/38] 6946673: DatagramSocket.connect() documentation contradicts the implementation Reviewed-by: alanb --- .../classes/java/net/DatagramSocket.java | 63 +++++++++++++------ 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/jdk/src/share/classes/java/net/DatagramSocket.java b/jdk/src/share/classes/java/net/DatagramSocket.java index 3e3464c677d..b177423979a 100644 --- a/jdk/src/share/classes/java/net/DatagramSocket.java +++ b/jdk/src/share/classes/java/net/DatagramSocket.java @@ -401,29 +401,40 @@ class DatagramSocket implements java.io.Closeable { * send or receive may throw a PortUnreachableException. Note, there is no * guarantee that the exception will be thrown. * - *

A caller's permission to send and receive datagrams to a - * given host and port are checked at connect time. When a socket - * is connected, receive and send will not - * perform any security checks on incoming and outgoing - * packets, other than matching the packet's and the socket's - * address and port. On a send operation, if the packet's address - * is set and the packet's address and the socket's address do not - * match, an IllegalArgumentException will be thrown. A socket - * connected to a multicast address may only be used to send packets. + *

If a security manager has been installed then it is invoked to check + * access to the remote address. Specifically, if the given {@code address} + * is a {@link InetAddress#isMulticastAddress multicast address}, + * the security manager's {@link + * java.lang.SecurityManager#checkMulticast(InetAddress) + * checkMulticast} method is invoked with the given {@code address}. + * Otherwise, the security manager's {@link + * java.lang.SecurityManager#checkConnect(String,int) checkConnect} + * and {@link java.lang.SecurityManager#checkAccept checkAccept} methods + * are invoked, with the given {@code address} and {@code port}, to + * verify that datagrams are permitted to be sent and received + * respectively. + * + *

When a socket is connected, {@link #receive receive} and + * {@link #send send} will not perform any security checks + * on incoming and outgoing packets, other than matching the packet's + * and the socket's address and port. On a send operation, if the + * packet's address is set and the packet's address and the socket's + * address do not match, an {@code IllegalArgumentException} will be + * thrown. A socket connected to a multicast address may only be used + * to send packets. * * @param address the remote address for the socket * * @param port the remote port for the socket. * - * @exception IllegalArgumentException if the address is null, - * or the port is out of range. + * @throws IllegalArgumentException + * if the address is null, or the port is out of range. * - * @exception SecurityException if the caller is not allowed to - * send datagrams to and receive datagrams from the address and port. + * @throws SecurityException + * if a security manager has been installed and it does + * not permit access to the given remote address * * @see #disconnect - * @see #send - * @see #receive */ public void connect(InetAddress address, int port) { try { @@ -435,13 +446,25 @@ class DatagramSocket implements java.io.Closeable { /** * Connects this socket to a remote socket address (IP address + port number). - *

+ * + *

If given an {@link InetSocketAddress InetSocketAddress}, this method + * behaves as if invoking {@link #connect(InetAddress,int) connect(InetAddress,int)} + * with the the given socket addresses IP address and port number. + * * @param addr The remote address. - * @throws SocketException if the connect fails - * @throws IllegalArgumentException if addr is null or addr is a SocketAddress - * subclass not supported by this socket + * + * @throws SocketException + * if the connect fails + * + * @throws IllegalArgumentException + * if {@code addr} is {@code null}, or {@code addr} is a SocketAddress + * subclass not supported by this socket + * + * @throws SecurityException + * if a security manager has been installed and it does + * not permit access to the given remote address + * * @since 1.4 - * @see #connect */ public void connect(SocketAddress addr) throws SocketException { if (addr == null) From 4a29f05c6ad61db2932750d9799a050e6954bf04 Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Sun, 9 May 2010 00:59:30 -0700 Subject: [PATCH 23/38] 6933217: Huge arrays handled poorly in core libraries Write overflow-conscious array resizing code Reviewed-by: chegar --- .../java/io/ByteArrayOutputStream.java | 56 ++++++-- .../java/lang/AbstractStringBuilder.java | 124 +++++++----------- .../classes/java/util/AbstractCollection.java | 28 +++- .../share/classes/java/util/ArrayList.java | 47 +++++-- .../share/classes/java/util/Hashtable.java | 17 ++- .../classes/java/util/PriorityQueue.java | 31 +++-- jdk/src/share/classes/java/util/Vector.java | 39 ++++-- 7 files changed, 218 insertions(+), 124 deletions(-) diff --git a/jdk/src/share/classes/java/io/ByteArrayOutputStream.java b/jdk/src/share/classes/java/io/ByteArrayOutputStream.java index 6a9b190f20c..a3b0e06bbb4 100644 --- a/jdk/src/share/classes/java/io/ByteArrayOutputStream.java +++ b/jdk/src/share/classes/java/io/ByteArrayOutputStream.java @@ -77,18 +77,51 @@ public class ByteArrayOutputStream extends OutputStream { buf = new byte[size]; } + /** + * Increases the capacity if necessary to ensure that it can hold + * at least the number of elements specified by the minimum + * capacity argument. + * + * @param minCapacity the desired minimum capacity + * @throws OutOfMemoryError if {@code minCapacity < 0}. This is + * interpreted as a request for the unsatisfiably large capacity + * {@code (long) Integer.MAX_VALUE + (minCapacity - Integer.MAX_VALUE)}. + */ + private void ensureCapacity(int minCapacity) { + // overflow-conscious code + if (minCapacity - buf.length > 0) + grow(minCapacity); + } + + /** + * Increases the capacity to ensure that it can hold at least the + * number of elements specified by the minimum capacity argument. + * + * @param minCapacity the desired minimum capacity + */ + private void grow(int minCapacity) { + // overflow-conscious code + int oldCapacity = buf.length; + int newCapacity = oldCapacity << 1; + if (newCapacity - minCapacity < 0) + newCapacity = minCapacity; + if (newCapacity < 0) { + if (minCapacity < 0) // overflow + throw new OutOfMemoryError(); + newCapacity = Integer.MAX_VALUE; + } + buf = Arrays.copyOf(buf, newCapacity); + } + /** * Writes the specified byte to this byte array output stream. * * @param b the byte to be written. */ public synchronized void write(int b) { - int newcount = count + 1; - if (newcount > buf.length) { - buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount)); - } - buf[count] = (byte)b; - count = newcount; + ensureCapacity(count + 1); + buf[count] = (byte) b; + count += 1; } /** @@ -101,17 +134,12 @@ public class ByteArrayOutputStream extends OutputStream { */ public synchronized void write(byte b[], int off, int len) { if ((off < 0) || (off > b.length) || (len < 0) || - ((off + len) > b.length) || ((off + len) < 0)) { + ((off + len) - b.length > 0)) { throw new IndexOutOfBoundsException(); - } else if (len == 0) { - return; - } - int newcount = count + len; - if (newcount > buf.length) { - buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount)); } + ensureCapacity(count + len); System.arraycopy(b, off, buf, count, len); - count = newcount; + count += len; } /** diff --git a/jdk/src/share/classes/java/lang/AbstractStringBuilder.java b/jdk/src/share/classes/java/lang/AbstractStringBuilder.java index 973e0854d61..fd98eb0403c 100644 --- a/jdk/src/share/classes/java/lang/AbstractStringBuilder.java +++ b/jdk/src/share/classes/java/lang/AbstractStringBuilder.java @@ -36,6 +36,8 @@ import java.util.Arrays; * sequence can be changed through certain method calls. * * @author Michael McCloskey + * @author Martin Buchholz + * @author Ulf Zibis * @since 1.5 */ abstract class AbstractStringBuilder implements Appendable, CharSequence { @@ -98,9 +100,16 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { * @param minimumCapacity the minimum desired capacity. */ public void ensureCapacity(int minimumCapacity) { - if (minimumCapacity > value.length) { + ensureCapacityInternal(minimumCapacity); + } + + /** + * This method has the same contract as ensureCapacity, but is + * never synchronized. + */ + private void ensureCapacityInternal(int minimumCapacity) { + if (minimumCapacity - value.length > 0) expandCapacity(minimumCapacity); - } } /** @@ -108,11 +117,13 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { * size check or synchronization. */ void expandCapacity(int minimumCapacity) { - int newCapacity = (value.length + 1) * 2; - if (newCapacity < 0) { - newCapacity = Integer.MAX_VALUE; - } else if (minimumCapacity > newCapacity) { + int newCapacity = value.length * 2; + if (newCapacity - minimumCapacity < 0) newCapacity = minimumCapacity; + if (newCapacity < 0) { + if (minimumCapacity < 0) // overflow + throw new OutOfMemoryError(); + newCapacity = Integer.MAX_VALUE; } value = Arrays.copyOf(value, newCapacity); } @@ -158,8 +169,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { public void setLength(int newLength) { if (newLength < 0) throw new StringIndexOutOfBoundsException(newLength); - if (newLength > value.length) - expandCapacity(newLength); + ensureCapacityInternal(newLength); if (count < newLength) { for (; count < newLength; count++) @@ -400,12 +410,9 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { public AbstractStringBuilder append(String str) { if (str == null) str = "null"; int len = str.length(); - if (len == 0) return this; - int newCount = count + len; - if (newCount > value.length) - expandCapacity(newCount); + ensureCapacityInternal(count + len); str.getChars(0, len, value, count); - count = newCount; + count += len; return this; } @@ -414,11 +421,9 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { if (sb == null) return append("null"); int len = sb.length(); - int newCount = count + len; - if (newCount > value.length) - expandCapacity(newCount); + ensureCapacityInternal(count + len); sb.getChars(0, len, value, count); - count = newCount; + count += len; return this; } @@ -470,14 +475,10 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { "start " + start + ", end " + end + ", s.length() " + s.length()); int len = end - start; - if (len == 0) - return this; - int newCount = count + len; - if (newCount > value.length) - expandCapacity(newCount); - for (int i=start; i value.length) - expandCapacity(newCount); - System.arraycopy(str, 0, value, count, str.length); - count = newCount; + int len = str.length; + ensureCapacityInternal(count + len); + System.arraycopy(str, 0, value, count, len); + count += len; return this; } @@ -529,11 +529,9 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { * or {@code offset+len > str.length} */ public AbstractStringBuilder append(char str[], int offset, int len) { - int newCount = count + len; - if (newCount > value.length) - expandCapacity(newCount); + ensureCapacityInternal(count + len); System.arraycopy(str, offset, value, count, len); - count = newCount; + count += len; return this; } @@ -551,17 +549,13 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { */ public AbstractStringBuilder append(boolean b) { if (b) { - int newCount = count + 4; - if (newCount > value.length) - expandCapacity(newCount); + ensureCapacityInternal(count + 4); value[count++] = 't'; value[count++] = 'r'; value[count++] = 'u'; value[count++] = 'e'; } else { - int newCount = count + 5; - if (newCount > value.length) - expandCapacity(newCount); + ensureCapacityInternal(count + 5); value[count++] = 'f'; value[count++] = 'a'; value[count++] = 'l'; @@ -587,9 +581,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { * @return a reference to this object. */ public AbstractStringBuilder append(char c) { - int newCount = count + 1; - if (newCount > value.length) - expandCapacity(newCount); + ensureCapacityInternal(count + 1); value[count++] = c; return this; } @@ -614,8 +606,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1 : Integer.stringSize(i); int spaceNeeded = count + appendedLength; - if (spaceNeeded > value.length) - expandCapacity(spaceNeeded); + ensureCapacityInternal(spaceNeeded); Integer.getChars(i, spaceNeeded, value); count = spaceNeeded; return this; @@ -641,8 +632,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { int appendedLength = (l < 0) ? Long.stringSize(-l) + 1 : Long.stringSize(l); int spaceNeeded = count + appendedLength; - if (spaceNeeded > value.length) - expandCapacity(spaceNeeded); + ensureCapacityInternal(spaceNeeded); Long.getChars(l, spaceNeeded, value); count = spaceNeeded; return this; @@ -738,10 +728,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { if (codePoint >= Character.MIN_SUPPLEMENTARY_CODE_POINT) { n++; } - int newCount = count + n; - if (newCount > value.length) { - expandCapacity(newCount); - } + ensureCapacityInternal(count + n); if (n == 1) { value[count++] = (char) codePoint; } else { @@ -807,8 +794,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { end = count; int len = str.length(); int newCount = count + len - (end - start); - if (newCount > value.length) - expandCapacity(newCount); + ensureCapacityInternal(newCount); System.arraycopy(value, end, value, start + len, count - end); str.getChars(value, start); @@ -915,12 +901,10 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { throw new StringIndexOutOfBoundsException( "offset " + offset + ", len " + len + ", str.length " + str.length); - int newCount = count + len; - if (newCount > value.length) - expandCapacity(newCount); + ensureCapacityInternal(count + len); System.arraycopy(value, index, value, index + len, count - index); System.arraycopy(str, offset, value, index, len); - count = newCount; + count += len; return this; } @@ -984,12 +968,10 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { if (str == null) str = "null"; int len = str.length(); - int newCount = count + len; - if (newCount > value.length) - expandCapacity(newCount); + ensureCapacityInternal(count + len); System.arraycopy(value, offset, value, offset + len, count - offset); str.getChars(value, offset); - count = newCount; + count += len; return this; } @@ -1021,12 +1003,10 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { if ((offset < 0) || (offset > length())) throw new StringIndexOutOfBoundsException(offset); int len = str.length; - int newCount = count + len; - if (newCount > value.length) - expandCapacity(newCount); + ensureCapacityInternal(count + len); System.arraycopy(value, offset, value, offset + len, count - offset); System.arraycopy(str, 0, value, offset, len); - count = newCount; + count += len; return this; } @@ -1114,16 +1094,12 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence { "start " + start + ", end " + end + ", s.length() " + s.length()); int len = end - start; - if (len == 0) - return this; - int newCount = count + len; - if (newCount > value.length) - expandCapacity(newCount); + ensureCapacityInternal(count + len); System.arraycopy(value, dstOffset, value, dstOffset + len, count - dstOffset); for (int i=start; i value.length) - expandCapacity(newCount); + ensureCapacityInternal(count + 1); System.arraycopy(value, offset, value, offset + 1, count - offset); value[offset] = c; - count = newCount; + count += 1; return this; } diff --git a/jdk/src/share/classes/java/util/AbstractCollection.java b/jdk/src/share/classes/java/util/AbstractCollection.java index 5b13c9b00fd..f40d050589f 100644 --- a/jdk/src/share/classes/java/util/AbstractCollection.java +++ b/jdk/src/share/classes/java/util/AbstractCollection.java @@ -190,6 +190,14 @@ public abstract class AbstractCollection implements Collection { return it.hasNext() ? finishToArray(r, it) : r; } + /** + * The maximum size of array to allocate. + * Some VMs reserve some header words in an array. + * Attempts to allocate larger arrays may result in + * OutOfMemoryError: Requested array size exceeds VM limit + */ + private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; + /** * Reallocates the array being used within toArray when the iterator * returned more elements than expected, and finishes filling it from @@ -205,13 +213,10 @@ public abstract class AbstractCollection implements Collection { while (it.hasNext()) { int cap = r.length; if (i == cap) { - int newCap = ((cap / 2) + 1) * 3; - if (newCap <= cap) { // integer overflow - if (cap == Integer.MAX_VALUE) - throw new OutOfMemoryError - ("Required array size too large"); - newCap = Integer.MAX_VALUE; - } + int newCap = cap + (cap >> 1) + 1; + // overflow-conscious code + if (newCap - MAX_ARRAY_SIZE > 0) + newCap = hugeCapacity(cap + 1); r = Arrays.copyOf(r, newCap); } r[i++] = (T)it.next(); @@ -220,6 +225,15 @@ public abstract class AbstractCollection implements Collection { return (i == r.length) ? r : Arrays.copyOf(r, i); } + private static int hugeCapacity(int minCapacity) { + if (minCapacity < 0) // overflow + throw new OutOfMemoryError + ("Required array size too large"); + return (minCapacity > MAX_ARRAY_SIZE) ? + Integer.MAX_VALUE : + MAX_ARRAY_SIZE; + } + // Modification Operations /** diff --git a/jdk/src/share/classes/java/util/ArrayList.java b/jdk/src/share/classes/java/util/ArrayList.java index dbd46096bf3..92dbfd9c84b 100644 --- a/jdk/src/share/classes/java/util/ArrayList.java +++ b/jdk/src/share/classes/java/util/ArrayList.java @@ -173,18 +173,47 @@ public class ArrayList extends AbstractList * necessary, to ensure that it can hold at least the number of elements * specified by the minimum capacity argument. * - * @param minCapacity the desired minimum capacity + * @param minCapacity the desired minimum capacity */ public void ensureCapacity(int minCapacity) { modCount++; + // overflow-conscious code + if (minCapacity - elementData.length > 0) + grow(minCapacity); + } + + /** + * The maximum size of array to allocate. + * Some VMs reserve some header words in an array. + * Attempts to allocate larger arrays may result in + * OutOfMemoryError: Requested array size exceeds VM limit + */ + private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; + + /** + * Increases the capacity to ensure that it can hold at least the + * number of elements specified by the minimum capacity argument. + * + * @param minCapacity the desired minimum capacity + */ + private void grow(int minCapacity) { + // overflow-conscious code int oldCapacity = elementData.length; - if (minCapacity > oldCapacity) { - int newCapacity = (oldCapacity * 3)/2 + 1; - if (newCapacity < minCapacity) - newCapacity = minCapacity; - // minCapacity is usually close to size, so this is a win: - elementData = Arrays.copyOf(elementData, newCapacity); - } + int newCapacity = oldCapacity + (oldCapacity >> 1); + if (newCapacity - minCapacity < 0) + newCapacity = minCapacity; + if (newCapacity - MAX_ARRAY_SIZE > 0) + newCapacity = hugeCapacity(minCapacity); + // minCapacity is usually close to size, so this is a win: + elementData = Arrays.copyOf(elementData, newCapacity); + } + + private static int hugeCapacity(int minCapacity) { + if (minCapacity < 0) // overflow + throw new OutOfMemoryError(); + return (minCapacity > MAX_ARRAY_SIZE) ? + Integer.MAX_VALUE : + MAX_ARRAY_SIZE; } /** @@ -391,7 +420,7 @@ public class ArrayList extends AbstractList public void add(int index, E element) { rangeCheckForAdd(index); - ensureCapacity(size+1); // Increments modCount!! + ensureCapacity(size + 1); // Increments modCount!! System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; diff --git a/jdk/src/share/classes/java/util/Hashtable.java b/jdk/src/share/classes/java/util/Hashtable.java index 4fbd336ca6c..17267985d2a 100644 --- a/jdk/src/share/classes/java/util/Hashtable.java +++ b/jdk/src/share/classes/java/util/Hashtable.java @@ -364,6 +364,14 @@ public class Hashtable return null; } + /** + * The maximum size of array to allocate. + * Some VMs reserve some header words in an array. + * Attempts to allocate larger arrays may result in + * OutOfMemoryError: Requested array size exceeds VM limit + */ + private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; + /** * Increases the capacity of and internally reorganizes this * hashtable, in order to accommodate and access its entries more @@ -375,7 +383,14 @@ public class Hashtable int oldCapacity = table.length; Entry[] oldMap = table; - int newCapacity = oldCapacity * 2 + 1; + // overflow-conscious code + int newCapacity = (oldCapacity << 1) + 1; + if (newCapacity - MAX_ARRAY_SIZE > 0) { + if (oldCapacity == MAX_ARRAY_SIZE) + // Keep running with MAX_ARRAY_SIZE buckets + return; + newCapacity = MAX_ARRAY_SIZE; + } Entry[] newMap = new Entry[newCapacity]; modCount++; diff --git a/jdk/src/share/classes/java/util/PriorityQueue.java b/jdk/src/share/classes/java/util/PriorityQueue.java index 428792fe1c6..ac87d9fb569 100644 --- a/jdk/src/share/classes/java/util/PriorityQueue.java +++ b/jdk/src/share/classes/java/util/PriorityQueue.java @@ -235,26 +235,39 @@ public class PriorityQueue extends AbstractQueue size = a.length; } + /** + * The maximum size of array to allocate. + * Some VMs reserve some header words in an array. + * Attempts to allocate larger arrays may result in + * OutOfMemoryError: Requested array size exceeds VM limit + */ + private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; + /** * Increases the capacity of the array. * * @param minCapacity the desired minimum capacity */ private void grow(int minCapacity) { - if (minCapacity < 0) // overflow - throw new OutOfMemoryError(); int oldCapacity = queue.length; // Double size if small; else grow by 50% - int newCapacity = ((oldCapacity < 64)? - ((oldCapacity + 1) * 2): - ((oldCapacity / 2) * 3)); - if (newCapacity < 0) // overflow - newCapacity = Integer.MAX_VALUE; - if (newCapacity < minCapacity) - newCapacity = minCapacity; + int newCapacity = oldCapacity + ((oldCapacity < 64) ? + (oldCapacity + 2) : + (oldCapacity >> 1)); + // overflow-conscious code + if (newCapacity - MAX_ARRAY_SIZE > 0) + newCapacity = hugeCapacity(minCapacity); queue = Arrays.copyOf(queue, newCapacity); } + private static int hugeCapacity(int minCapacity) { + if (minCapacity < 0) // overflow + throw new OutOfMemoryError(); + return (minCapacity > MAX_ARRAY_SIZE) ? + Integer.MAX_VALUE : + MAX_ARRAY_SIZE; + } + /** * Inserts the specified element into this priority queue. * diff --git a/jdk/src/share/classes/java/util/Vector.java b/jdk/src/share/classes/java/util/Vector.java index f70d36ee069..6fa6c84f8da 100644 --- a/jdk/src/share/classes/java/util/Vector.java +++ b/jdk/src/share/classes/java/util/Vector.java @@ -235,16 +235,37 @@ public class Vector * @see #ensureCapacity(int) */ private void ensureCapacityHelper(int minCapacity) { + // overflow-conscious code + if (minCapacity - elementData.length > 0) + grow(minCapacity); + } + + /** + * The maximum size of array to allocate. + * Some VMs reserve some header words in an array. + * Attempts to allocate larger arrays may result in + * OutOfMemoryError: Requested array size exceeds VM limit + */ + private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; + + private void grow(int minCapacity) { + // overflow-conscious code int oldCapacity = elementData.length; - if (minCapacity > oldCapacity) { - Object[] oldData = elementData; - int newCapacity = (capacityIncrement > 0) ? - (oldCapacity + capacityIncrement) : (oldCapacity * 2); - if (newCapacity < minCapacity) { - newCapacity = minCapacity; - } - elementData = Arrays.copyOf(elementData, newCapacity); - } + int newCapacity = oldCapacity + ((capacityIncrement > 0) ? + capacityIncrement : oldCapacity); + if (newCapacity - minCapacity < 0) + newCapacity = minCapacity; + if (newCapacity - MAX_ARRAY_SIZE > 0) + newCapacity = hugeCapacity(minCapacity); + elementData = Arrays.copyOf(elementData, newCapacity); + } + + private static int hugeCapacity(int minCapacity) { + if (minCapacity < 0) // overflow + throw new OutOfMemoryError(); + return (minCapacity > MAX_ARRAY_SIZE) ? + Integer.MAX_VALUE : + MAX_ARRAY_SIZE; } /** From b455514c890ea10fbb2104051d2b3b4e347239eb Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Sun, 9 May 2010 00:59:49 -0700 Subject: [PATCH 24/38] 6950540: PriorityQueue(collection) should throw NPE if collection contains a null Rewrite PriorityQueue constructors for best performance and error handling Reviewed-by: dholmes, chegar --- .../classes/java/util/PriorityQueue.java | 63 ++++-- jdk/test/java/util/PriorityQueue/NoNulls.java | 204 ++++++++++++++++++ 2 files changed, 248 insertions(+), 19 deletions(-) create mode 100644 jdk/test/java/util/PriorityQueue/NoNulls.java diff --git a/jdk/src/share/classes/java/util/PriorityQueue.java b/jdk/src/share/classes/java/util/PriorityQueue.java index ac87d9fb569..931c287c0c2 100644 --- a/jdk/src/share/classes/java/util/PriorityQueue.java +++ b/jdk/src/share/classes/java/util/PriorityQueue.java @@ -170,17 +170,21 @@ public class PriorityQueue extends AbstractQueue * @throws NullPointerException if the specified collection or any * of its elements are null */ + @SuppressWarnings("unchecked") public PriorityQueue(Collection c) { - initFromCollection(c); - if (c instanceof SortedSet) - comparator = (Comparator) - ((SortedSet)c).comparator(); - else if (c instanceof PriorityQueue) - comparator = (Comparator) - ((PriorityQueue)c).comparator(); + if (c instanceof SortedSet) { + SortedSet ss = (SortedSet) c; + this.comparator = (Comparator) ss.comparator(); + initElementsFromCollection(ss); + } + else if (c instanceof PriorityQueue) { + PriorityQueue pq = (PriorityQueue) c; + this.comparator = (Comparator) pq.comparator(); + initFromPriorityQueue(pq); + } else { - comparator = null; - heapify(); + this.comparator = null; + initFromCollection(c); } } @@ -198,9 +202,10 @@ public class PriorityQueue extends AbstractQueue * @throws NullPointerException if the specified priority queue or any * of its elements are null */ + @SuppressWarnings("unchecked") public PriorityQueue(PriorityQueue c) { - comparator = (Comparator)c.comparator(); - initFromCollection(c); + this.comparator = (Comparator) c.comparator(); + initFromPriorityQueue(c); } /** @@ -216,9 +221,33 @@ public class PriorityQueue extends AbstractQueue * @throws NullPointerException if the specified sorted set or any * of its elements are null */ + @SuppressWarnings("unchecked") public PriorityQueue(SortedSet c) { - comparator = (Comparator)c.comparator(); - initFromCollection(c); + this.comparator = (Comparator) c.comparator(); + initElementsFromCollection(c); + } + + private void initFromPriorityQueue(PriorityQueue c) { + if (c.getClass() == PriorityQueue.class) { + this.queue = c.toArray(); + this.size = c.size(); + } else { + initFromCollection(c); + } + } + + private void initElementsFromCollection(Collection c) { + Object[] a = c.toArray(); + // If c.toArray incorrectly doesn't return Object[], copy it. + if (a.getClass() != Object[].class) + a = Arrays.copyOf(a, a.length, Object[].class); + int len = a.length; + if (len == 1 || this.comparator != null) + for (int i = 0; i < len; i++) + if (a[i] == null) + throw new NullPointerException(); + this.queue = a; + this.size = a.length; } /** @@ -227,12 +256,8 @@ public class PriorityQueue extends AbstractQueue * @param c the collection */ private void initFromCollection(Collection c) { - Object[] a = c.toArray(); - // If c.toArray incorrectly doesn't return Object[], copy it. - if (a.getClass() != Object[].class) - a = Arrays.copyOf(a, a.length, Object[].class); - queue = a; - size = a.length; + initElementsFromCollection(c); + heapify(); } /** diff --git a/jdk/test/java/util/PriorityQueue/NoNulls.java b/jdk/test/java/util/PriorityQueue/NoNulls.java new file mode 100644 index 00000000000..c40c93be893 --- /dev/null +++ b/jdk/test/java/util/PriorityQueue/NoNulls.java @@ -0,0 +1,204 @@ +/* + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Written by Martin Buchholz with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/licenses/publicdomain + */ + +/* + * @test + * @bug 6950540 + * @summary Attempt to add a null throws NullPointerException + */ + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Collection; +import java.util.Collections; +import java.util.PriorityQueue; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.PriorityBlockingQueue; + +public class NoNulls { + void test(String[] args) throws Throwable { + final Comparator nullTolerantComparator + = new Comparator<>() { + public int compare(String x, String y) { + return (x == null ? -1 : + y == null ? 1 : + x.compareTo(y)); + }}; + + final SortedSet nullSortedSet + = new TreeSet<>(nullTolerantComparator); + nullSortedSet.add(null); + + final PriorityQueue nullPriorityQueue + = new PriorityQueue<>() { + public Object[] toArray() { return new Object[] { null };}}; + + final Collection nullCollection = new ArrayList<>(); + nullCollection.add(null); + + THROWS(NullPointerException.class, + new F() { void f() { + new PriorityQueue(nullCollection); + }}, + new F() { void f() { + new PriorityBlockingQueue(nullCollection); + }}, + new F() { void f() { + new ArrayBlockingQueue(10, false, nullCollection); + }}, + new F() { void f() { + new ArrayBlockingQueue(10, true, nullCollection); + }}, + new F() { void f() { + new LinkedBlockingQueue(nullCollection); + }}, + new F() { void f() { + new LinkedBlockingDeque(nullCollection); + }}, + + new F() { void f() { + new PriorityQueue((Collection) nullPriorityQueue); + }}, + new F() { void f() { + new PriorityBlockingQueue((Collection) nullPriorityQueue); + }}, + + new F() { void f() { + new PriorityQueue(nullSortedSet); + }}, + new F() { void f() { + new PriorityBlockingQueue(nullSortedSet); + }}, + + new F() { void f() { + new PriorityQueue((Collection) nullSortedSet); + }}, + new F() { void f() { + new PriorityBlockingQueue((Collection) nullSortedSet); + }}, + + new F() { void f() { + new PriorityQueue(nullPriorityQueue); + }}, + new F() { void f() { + new PriorityBlockingQueue(nullPriorityQueue); + }}, + + new F() { void f() { + new PriorityQueue().add(null); + }}, + new F() { void f() { + new PriorityBlockingQueue().add(null); + }}, + new F() { void f() { + new ArrayBlockingQueue(10, false).add(null); + }}, + new F() { void f() { + new ArrayBlockingQueue(10, true).add(null); + }}, + new F() { void f() { + new LinkedBlockingQueue().add(null); + }}, + new F() { void f() { + new LinkedBlockingDeque().add(null); + }}, + + new F() { void f() { + new PriorityQueue().offer(null); + }}, + new F() { void f() { + new PriorityBlockingQueue().offer(null); + }}); + + nullSortedSet.add("foo"); + nullCollection.add("foo"); + THROWS(NullPointerException.class, + new F() { void f() { + new PriorityQueue(nullCollection); + }}, + new F() { void f() { + new PriorityBlockingQueue(nullCollection); + }}, + + new F() { void f() { + new PriorityQueue((Collection) nullPriorityQueue); + }}, + new F() { void f() { + new PriorityBlockingQueue((Collection) nullPriorityQueue); + }}, + + new F() { void f() { + new PriorityQueue(nullSortedSet); + }}, + new F() { void f() { + new PriorityBlockingQueue(nullSortedSet); + }}, + + new F() { void f() { + new PriorityQueue((Collection) nullSortedSet); + }}, + new F() { void f() { + new PriorityBlockingQueue((Collection) nullSortedSet); + }}); + + } + + //--------------------- Infrastructure --------------------------- + volatile int passed = 0, failed = 0; + void pass() {passed++;} + void fail() {failed++; Thread.dumpStack();} + void fail(String msg) {System.err.println(msg); fail();} + void unexpected(Throwable t) {failed++; t.printStackTrace();} + void check(boolean cond) {if (cond) pass(); else fail();} + void equal(Object x, Object y) { + if (x == null ? y == null : x.equals(y)) pass(); + else fail(x + " not equal to " + y);} + public static void main(String[] args) throws Throwable { + new NoNulls().instanceMain(args);} + public void instanceMain(String[] args) throws Throwable { + try {test(args);} catch (Throwable t) {unexpected(t);} + System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); + if (failed > 0) throw new AssertionError("Some tests failed");} + abstract class F {abstract void f() throws Throwable;} + void THROWS(Class k, F... fs) { + for (F f : fs) + try {f.f(); fail("Expected " + k.getName() + " not thrown");} + catch (Throwable t) { + if (k.isAssignableFrom(t.getClass())) pass(); + else unexpected(t);}} +} From 75e3cde928811b1931a255bbe70e86ba4369d6dc Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Sun, 9 May 2010 16:03:13 -0700 Subject: [PATCH 25/38] 6937857: Concurrent calls to new Random() not random enough Seed uniquifier should use an independent PRNG Reviewed-by: dl --- jdk/src/share/classes/java/util/Random.java | 29 +++++++++++--- jdk/test/java/util/Random/DistinctSeeds.java | 40 +++++++++++++++++++- 2 files changed, 61 insertions(+), 8 deletions(-) diff --git a/jdk/src/share/classes/java/util/Random.java b/jdk/src/share/classes/java/util/Random.java index efe3f68a01a..b3381252bef 100644 --- a/jdk/src/share/classes/java/util/Random.java +++ b/jdk/src/share/classes/java/util/Random.java @@ -86,8 +86,23 @@ class Random implements java.io.Serializable { * the seed of the random number generator to a value very likely * to be distinct from any other invocation of this constructor. */ - public Random() { this(++seedUniquifier + System.nanoTime()); } - private static volatile long seedUniquifier = 8682522807148012L; + public Random() { + this(seedUniquifier() ^ System.nanoTime()); + } + + private static long seedUniquifier() { + // L'Ecuyer, "Tables of Linear Congruential Generators of + // Different Sizes and Good Lattice Structure", 1999 + for (;;) { + long current = seedUniquifier.get(); + long next = current * 181783497276652981L; + if (seedUniquifier.compareAndSet(current, next)) + return next; + } + } + + private static final AtomicLong seedUniquifier + = new AtomicLong(8682522807148012L); /** * Creates a new random number generator using a single {@code long} seed. @@ -103,8 +118,11 @@ class Random implements java.io.Serializable { * @see #setSeed(long) */ public Random(long seed) { - this.seed = new AtomicLong(0L); - setSeed(seed); + this.seed = new AtomicLong(initialScramble(seed)); + } + + private static long initialScramble(long seed) { + return (seed ^ multiplier) & mask; } /** @@ -127,8 +145,7 @@ class Random implements java.io.Serializable { * @param seed the initial seed */ synchronized public void setSeed(long seed) { - seed = (seed ^ multiplier) & mask; - this.seed.set(seed); + this.seed.set(initialScramble(seed)); haveNextNextGaussian = false; } diff --git a/jdk/test/java/util/Random/DistinctSeeds.java b/jdk/test/java/util/Random/DistinctSeeds.java index 795051b0298..736761ebb77 100644 --- a/jdk/test/java/util/Random/DistinctSeeds.java +++ b/jdk/test/java/util/Random/DistinctSeeds.java @@ -33,18 +33,54 @@ /* * @test - * @bug 4949279 + * @bug 4949279 6937857 * @summary Independent instantiations of Random() have distinct seeds. */ +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; import java.util.Random; public class DistinctSeeds { public static void main(String[] args) throws Exception { // Strictly speaking, it is possible for these to randomly fail, - // but the probability should be *extremely* small (< 2**-63). + // but the probability should be small (approximately 2**-48). if (new Random().nextLong() == new Random().nextLong() || new Random().nextLong() == new Random().nextLong()) throw new RuntimeException("Random() seeds not unique."); + + // Now try generating seeds concurrently + class RandomCollector implements Runnable { + long[] randoms = new long[1<<17]; + public void run() { + for (int i = 0; i < randoms.length; i++) + randoms[i] = new Random().nextLong(); + } + } + final int threadCount = 2; + List collectors = new ArrayList(); + List threads = new ArrayList(); + for (int i = 0; i < threadCount; i++) { + RandomCollector r = new RandomCollector(); + collectors.add(r); + threads.add(new Thread(r)); + } + for (Thread thread : threads) + thread.start(); + for (Thread thread : threads) + thread.join(); + int collisions = 0; + HashSet s = new HashSet(); + for (RandomCollector r : collectors) { + for (long x : r.randoms) { + if (s.contains(x)) + collisions++; + s.add(x); + } + } + System.out.printf("collisions=%d%n", collisions); + if (collisions > 10) + throw new Error("too many collisions"); } } From 3adf1d8538179a0a788bdaa34621e39c1eb7e8a2 Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Sun, 9 May 2010 16:37:06 -0700 Subject: [PATCH 26/38] 6937842: Unreadable \uXXXX in javadoc Replace \uXXXX by \u005CXXXX, or simply delete Reviewed-by: sherman --- jdk/src/share/classes/java/lang/String.java | 8 ++++---- jdk/src/share/classes/java/util/zip/Deflater.java | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/jdk/src/share/classes/java/lang/String.java b/jdk/src/share/classes/java/lang/String.java index 2aead0f545d..918b4dee02e 100644 --- a/jdk/src/share/classes/java/lang/String.java +++ b/jdk/src/share/classes/java/lang/String.java @@ -2551,8 +2551,8 @@ public final class String * Examples are programming language identifiers, protocol keys, and HTML * tags. * For instance, "TITLE".toLowerCase() in a Turkish locale - * returns "t\u0131tle", where '\u0131' is the LATIN SMALL - * LETTER DOTLESS I character. + * returns "t\u005Cu0131tle", where '\u005Cu0131' is the + * LATIN SMALL LETTER DOTLESS I character. * To obtain correct results for locale insensitive strings, use * toLowerCase(Locale.ENGLISH). *

@@ -2714,8 +2714,8 @@ public final class String * Examples are programming language identifiers, protocol keys, and HTML * tags. * For instance, "title".toUpperCase() in a Turkish locale - * returns "T\u0130TLE", where '\u0130' is the LATIN CAPITAL - * LETTER I WITH DOT ABOVE character. + * returns "T\u005Cu0130TLE", where '\u005Cu0130' is the + * LATIN CAPITAL LETTER I WITH DOT ABOVE character. * To obtain correct results for locale insensitive strings, use * toUpperCase(Locale.ENGLISH). *

diff --git a/jdk/src/share/classes/java/util/zip/Deflater.java b/jdk/src/share/classes/java/util/zip/Deflater.java index 9c4c0ce6c8c..abc1b6541ed 100644 --- a/jdk/src/share/classes/java/util/zip/Deflater.java +++ b/jdk/src/share/classes/java/util/zip/Deflater.java @@ -40,7 +40,7 @@ package java.util.zip; *

  * try {
  *     // Encode a String into bytes
- *     String inputString = "blahblahblah\u20AC\u20AC";
+ *     String inputString = "blahblahblah";
  *     byte[] input = inputString.getBytes("UTF-8");
  *
  *     // Compress the bytes

From 9c93404ddea826ea632b161083d0d1b9914160b0 Mon Sep 17 00:00:00 2001
From: Michael Wilkerson 
Date: Thu, 13 May 2010 13:22:08 -0700
Subject: [PATCH 27/38] Added tag jdk7-b93 for changeset 30b170e85ca5

---
 .hgtags-top-repo | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.hgtags-top-repo b/.hgtags-top-repo
index 9616468e283..1f88fddf975 100644
--- a/.hgtags-top-repo
+++ b/.hgtags-top-repo
@@ -67,3 +67,4 @@ cf26288a114be67c39f2758959ce50b60f5ae330 jdk7-b85
 425ba3efabbfe0b188105c10aaf7c3c8fa8d1a38 jdk7-b90
 97d8b6c659c29c8493a8b2b72c2796a021a8cf79 jdk7-b91
 5f5c33d417f3a14706b09a4a95e65fa7b6fa54d6 jdk7-b92
+5fc102ff48f0e787ce9cc77249841d5ff0941b75 jdk7-b93

From 2362acb347f1142322d79e3df000f8f5e1772e53 Mon Sep 17 00:00:00 2001
From: Michael Wilkerson 
Date: Thu, 13 May 2010 13:22:09 -0700
Subject: [PATCH 28/38] Added tag jdk7-b93 for changeset ed71fb20ba0f

---
 corba/.hgtags | 1 +
 1 file changed, 1 insertion(+)

diff --git a/corba/.hgtags b/corba/.hgtags
index 1e431bb8e8f..cfbe3470546 100644
--- a/corba/.hgtags
+++ b/corba/.hgtags
@@ -67,3 +67,4 @@ bb4424c5e778b842c064a8b1aa902b35f4397654 jdk7-b89
 56ce07b0eb47b93a98a72adef0f21e602c460623 jdk7-b90
 bcd2fc089227559ac5be927923609fac29f067fa jdk7-b91
 930582f667a13391cd0b3e41e8cb760f55e3a5c0 jdk7-b92
+9718d624864c29dca44373d541e93cdd309a994f jdk7-b93

From a0f06a97b076d59d05629d47eb7cf62f78a303c3 Mon Sep 17 00:00:00 2001
From: Michael Wilkerson 
Date: Thu, 13 May 2010 13:22:16 -0700
Subject: [PATCH 29/38] Added tag jdk7-b93 for changeset b698288c7b9b

---
 jaxp/.hgtags | 1 +
 1 file changed, 1 insertion(+)

diff --git a/jaxp/.hgtags b/jaxp/.hgtags
index cd9b5fbe099..c550db6a874 100644
--- a/jaxp/.hgtags
+++ b/jaxp/.hgtags
@@ -67,3 +67,4 @@ d2818fd2b036f3b3154a9a7de41afcf4ac679c1b jdk7-b89
 c5d932ee326d6f7fd4634b11c7185ea82d184df2 jdk7-b90
 b89b2c3044a298d542f84a2e9d957202b7d8cdb9 jdk7-b91
 e6a40e4bb10499fb6ee9db71ab5654e5a17ab75b jdk7-b92
+c725ca829c5aa4b50a8ed5728579ec8809fbfb1d jdk7-b93

From 8843a8a083e43fef12c33bb6188f14315e9edf2b Mon Sep 17 00:00:00 2001
From: Michael Wilkerson 
Date: Thu, 13 May 2010 13:22:17 -0700
Subject: [PATCH 30/38] Added tag jdk7-b93 for changeset cd6bd47caa4d

---
 jaxws/.hgtags | 1 +
 1 file changed, 1 insertion(+)

diff --git a/jaxws/.hgtags b/jaxws/.hgtags
index 0ebeaeab91b..885fc0025e1 100644
--- a/jaxws/.hgtags
+++ b/jaxws/.hgtags
@@ -67,3 +67,4 @@ bf3675aa7f20fc6f241ce95760005aef2a30ff41 jdk7-b89
 ead7c4566a0017bcb44b468b3ac03b60dc5333ce jdk7-b90
 cf4686bf35abd1e573f09fa43cbec66403160ae9 jdk7-b91
 df7c033f6a11c0973ab0e74701b1248aee9b659f jdk7-b92
+797bef19197566ffb056edaa1b34db43bd9bf7b0 jdk7-b93

From 24b484a01574addcba10b2b29185ab01f40d76d2 Mon Sep 17 00:00:00 2001
From: Michael Wilkerson 
Date: Thu, 13 May 2010 13:22:22 -0700
Subject: [PATCH 31/38] Added tag jdk7-b93 for changeset e415207ac256

---
 jdk/.hgtags | 1 +
 1 file changed, 1 insertion(+)

diff --git a/jdk/.hgtags b/jdk/.hgtags
index 44a2cf3239e..ec3ff96ec96 100644
--- a/jdk/.hgtags
+++ b/jdk/.hgtags
@@ -67,3 +67,4 @@ b3c69282f6d3c90ec21056cd1ab70dc0c895b069 jdk7-b88
 7f90d0b9dbb7ab4c60d0b0233e4e77fb4fac597c jdk7-b90
 08a31cab971fcad4695e913d0f3be7bde3a90747 jdk7-b91
 f2dce7210cc00453c23e53edeec7156f112ca382 jdk7-b92
+219b84b9533ae4fe3c6c2083f8a8962cb579f1de jdk7-b93

From e07663d108403bcd64c645278df15a4a75aa0ab3 Mon Sep 17 00:00:00 2001
From: Michael Wilkerson 
Date: Thu, 13 May 2010 13:22:31 -0700
Subject: [PATCH 32/38] Added tag jdk7-b93 for changeset 19b9aa23e950

---
 langtools/.hgtags | 1 +
 1 file changed, 1 insertion(+)

diff --git a/langtools/.hgtags b/langtools/.hgtags
index cc2b2673c04..b4e162baccf 100644
--- a/langtools/.hgtags
+++ b/langtools/.hgtags
@@ -67,3 +67,4 @@ f9b5d4867a26f8c4b90ad37fe2c345b721e93d6b jdk7-b88
 71c2c23a7c35b2896c87004023b9743b6d1b7758 jdk7-b90
 97b6fa97b8ddb3a49394011c2a0ec5d6535e594c jdk7-b91
 98cba5876cb50fa3c58a313ddd668f5014ff14f6 jdk7-b92
+683cd1f6bc4b562b0ddf29d5f80f05c2123b76b0 jdk7-b93

From 5545514e602ec90fcc1632095b1f270e56f260fb Mon Sep 17 00:00:00 2001
From: Anthony Petrov 
Date: Tue, 18 May 2010 19:35:41 +0400
Subject: [PATCH 33/38] 6953275: Many Swing tests are failing because of a GTK
 lib

Reviewed-by: art, dcherepanov
---
 jdk/src/solaris/native/sun/awt/gtk2_interface.c | 13 ++++++++-----
 jdk/src/solaris/native/sun/awt/gtk2_interface.h |  1 -
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/jdk/src/solaris/native/sun/awt/gtk2_interface.c b/jdk/src/solaris/native/sun/awt/gtk2_interface.c
index dfa7ef1dfb4..ee1c3cc7856 100644
--- a/jdk/src/solaris/native/sun/awt/gtk2_interface.c
+++ b/jdk/src/solaris/native/sun/awt/gtk2_interface.c
@@ -77,6 +77,7 @@ const gint DEFAULT    = 1 << 10;
 
 static void *gtk2_libhandle = NULL;
 static void *gthread_libhandle = NULL;
+static gboolean flag_g_thread_get_initialized = FALSE;
 static jmp_buf j;
 
 /* Widgets */
@@ -436,8 +437,10 @@ void gtk2_file_chooser_load()
     fp_gtk_file_chooser_set_filter = dl_symbol("gtk_file_chooser_set_filter");
     fp_gtk_file_chooser_get_type = dl_symbol("gtk_file_chooser_get_type");
     fp_gtk_file_filter_new = dl_symbol("gtk_file_filter_new");
-    fp_gtk_file_chooser_set_do_overwrite_confirmation = dl_symbol(
-            "gtk_file_chooser_set_do_overwrite_confirmation");
+    if (fp_gtk_check_version(2, 8, 0) == NULL) {
+        fp_gtk_file_chooser_set_do_overwrite_confirmation = dl_symbol(
+                "gtk_file_chooser_set_do_overwrite_confirmation");
+    }
     fp_gtk_file_chooser_set_select_multiple = dl_symbol(
             "gtk_file_chooser_set_select_multiple");
     fp_gtk_file_chooser_get_current_folder = dl_symbol(
@@ -641,8 +644,6 @@ gboolean gtk2_load()
         /**
          * GLib thread system
          */
-        fp_g_thread_get_initialized = dl_symbol_gthread(
-                "g_thread_get_initialized");
         fp_g_thread_init = dl_symbol_gthread("g_thread_init");
         fp_gdk_threads_init = dl_symbol("gdk_threads_init");
         fp_gdk_threads_enter = dl_symbol("gdk_threads_enter");
@@ -744,7 +745,9 @@ gboolean gtk2_load()
 
     if (fp_gtk_check_version(2, 2, 0) == NULL) {
         // Init the thread system to use GLib in a thread-safe mode
-        if (!fp_g_thread_get_initialized()) {
+        if (!flag_g_thread_get_initialized) {
+            flag_g_thread_get_initialized = TRUE;
+
             fp_g_thread_init(NULL);
 
             //According the GTK documentation, gdk_threads_init() should be
diff --git a/jdk/src/solaris/native/sun/awt/gtk2_interface.h b/jdk/src/solaris/native/sun/awt/gtk2_interface.h
index 95ca3cecaad..fc401c1bc12 100644
--- a/jdk/src/solaris/native/sun/awt/gtk2_interface.h
+++ b/jdk/src/solaris/native/sun/awt/gtk2_interface.h
@@ -786,7 +786,6 @@ void (*fp_gtk_main)(void);
 guint (*fp_gtk_main_level)(void);
 
 
-gboolean (*fp_g_thread_get_initialized)(void);
 void (*fp_g_thread_init)(GThreadFunctions *vtable);
 void (*fp_gdk_threads_init)(void);
 void (*fp_gdk_threads_enter)(void);

From 184c523bdb842259671c3747f8b9e3d6cbb0d8b6 Mon Sep 17 00:00:00 2001
From: Phil Race 
Date: Wed, 19 May 2010 09:44:19 -0700
Subject: [PATCH 34/38] 6903970: VS2008/VS2010 build fails in make/sun/jkernel
 because of "afxres.h" missing

Reviewed-by: ohair, art
---
 README-builds.html | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/README-builds.html b/README-builds.html
index 41da91d1f8f..0b6fd25722b 100644
--- a/README-builds.html
+++ b/README-builds.html
@@ -970,9 +970,9 @@ including non-open portions.
 So for now you should be able to build with either VS2003 or VS2010.
 We do not guarantee that VS2008 will work, although there is sufficient
 makefile support to make at least basic JDK builds plausible.
-Visual Studio 2010 Express compilers are likely to be able to build all the
-"open" sources, with only small adjustments, but this has yet to be made
-to work. Also we have not yet seen the 7.1 Windows SDK with the 64 bit
+Visual Studio 2010 Express compilers are now able to build all the
+open source repositories, but this is 32 bit only, since
+we have not yet seen the 7.1 Windows SDK with the 64 bit
 compilers. END WARNING.
 

The 32-bit OpenJDK Windows build From ca5f8bd9bb540cfb36c8e77e3991ac7a0968689a Mon Sep 17 00:00:00 2001 From: Phil Race Date: Wed, 19 May 2010 09:45:05 -0700 Subject: [PATCH 35/38] 6903970: VS2008/VS2010 build fails in make/sun/jkernel because of "afxres.h" missing Reviewed-by: ohair, art --- jdk/make/common/shared/Defs-windows.gmk | 12 ++++++++---- jdk/make/sun/jkernel/Makefile | 7 +++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/jdk/make/common/shared/Defs-windows.gmk b/jdk/make/common/shared/Defs-windows.gmk index c632f3d1579..13c3964eab3 100644 --- a/jdk/make/common/shared/Defs-windows.gmk +++ b/jdk/make/common/shared/Defs-windows.gmk @@ -287,11 +287,15 @@ ifeq ($(ARCH_DATA_MODEL), 32) # Assume VS100, then VS90, then VS80, then VS71 _redist_sdk :=$(call FullPath,$(_msvc_dir)/redist/x86/Microsoft.VC100.CRT) ifeq ($(_redist_sdk),) - _redist_sdk :=$(call FullPath,$(_msvc_dir)/redist/x86/Microsoft.VC90.CRT) - ifeq ($(_redist_sdk),) - _redist_sdk :=$(call FullPath,$(_msvc_dir)/redist/x86/Microsoft.VC80.CRT) + ifneq ($(VS100COMNTOOLS),) + _redist_sdk :=c:/windows/system32 + else + _redist_sdk :=$(call FullPath,$(_msvc_dir)/redist/x86/Microsoft.VC90.CRT) ifeq ($(_redist_sdk),) - _redist_sdk :=$(call FullPath,$(_msvc_dir)/../SDK/v1.1/Bin) + _redist_sdk :=$(call FullPath,$(_msvc_dir)/redist/x86/Microsoft.VC80.CRT) + ifeq ($(_redist_sdk),) + _redist_sdk :=$(call FullPath,$(_msvc_dir)/../SDK/v1.1/Bin) + endif endif endif endif diff --git a/jdk/make/sun/jkernel/Makefile b/jdk/make/sun/jkernel/Makefile index 7a7a6a3645f..74643c13532 100644 --- a/jdk/make/sun/jkernel/Makefile +++ b/jdk/make/sun/jkernel/Makefile @@ -52,6 +52,11 @@ ifeq ($(ARCH_DATA_MODEL), 32) ifeq ($(PLATFORM), windows) +# If this is the VS Express compiler it will lack vc/atlmfc/ +ATL_MFC_DIR :=$(call DirExists,$(COMPILER_PATH)/../atlmfc,,) + +ifneq ($(ATL_MFC_DIR),) + include FILES_c_windows.gmk vpath %.cpp $(PLATFORM_SRC)/native/sun/jkernel @@ -67,6 +72,8 @@ endif endif +endif + # # Resources # From 56be4c0b46a02f684b6b8d551b7007c2d3f928dd Mon Sep 17 00:00:00 2001 From: Phil Race Date: Wed, 19 May 2010 10:21:41 -0700 Subject: [PATCH 36/38] 6953588: hotspot\src\share\vm\interpreter\bytecodes.cpp doesn't compile with VS2010 on AMD64 Reviewed-by: dcubed --- hotspot/src/share/vm/interpreter/bytecodes.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hotspot/src/share/vm/interpreter/bytecodes.cpp b/hotspot/src/share/vm/interpreter/bytecodes.cpp index cb2a7ecb234..1a270e78644 100644 --- a/hotspot/src/share/vm/interpreter/bytecodes.cpp +++ b/hotspot/src/share/vm/interpreter/bytecodes.cpp @@ -26,11 +26,13 @@ #include "incls/_bytecodes.cpp.incl" +#if defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER < 1600)) // Windows AMD64 Compiler Hangs compiling this file // unless optimization is off #ifdef _M_AMD64 #pragma optimize ("", off) #endif +#endif bool Bytecodes::_is_initialized = false; From 12917806fbdd021338e6aa07f8d70a31971798bd Mon Sep 17 00:00:00 2001 From: "J. Duke" Date: Wed, 5 Jul 2017 17:11:37 +0200 Subject: [PATCH 37/38] Added tag jdk7-b93 for changeset b5dab6a313fd --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 74131d1722f..19fa4171ace 100644 --- a/.hgtags +++ b/.hgtags @@ -67,3 +67,4 @@ b7456c473862048fa70ed8092313a4ef0a55d403 jdk7-b87 1d1927f9ec097b62c913921e2dfa5dbaf5dc325b jdk7-b90 308ad8f68b8dd68e22d73dd490e110059b732422 jdk7-b91 ff9031a745d9cc52318f2148e43ca3b07ee08098 jdk7-b92 +b5dab6a313fdff4c043250e4d9c8f66fd624d27e jdk7-b93 From cb7c059235050aa694824ebe9f99cdc45ac1912b Mon Sep 17 00:00:00 2001 From: Michael Wilkerson Date: Thu, 20 May 2010 16:00:15 -0700 Subject: [PATCH 38/38] Added tag jdk7-b94 for changeset 84ace44cf876 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index bd907d7a9e5..ebcfe738d24 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -95,3 +95,4 @@ e0a1a502e402dbe7bf2d9102b4084a7e79a99a9b jdk7-b91 3221d1887d30341bedfdac1dbf365ea41beff20f jdk7-b92 310cdbc355355a13aa53c002b6bde4a8c5ba67ff hs18-b04 9d865fc2f644fdd9a0108fd6407944ee610aadd9 jdk7-b93 +d38f45079fe98792a7381dbb4b64f5b589ec8c58 jdk7-b94