# HG changeset patch # User naoto # Date 1404429579 25200 # Node ID 2c53e38b77aa73ec4391f763cb1226a1c526843b # Parent f161e8748e8d1b325ceb64f5d78a8cc23a345565 8038092: Re-examine Bidi reflective dependency on java.awt.font Reviewed-by: alanb diff -r f161e8748e8d -r 2c53e38b77aa jdk/src/share/classes/java/awt/font/JavaAWTFontAccessImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/java/awt/font/JavaAWTFontAccessImpl.java Thu Jul 03 16:19:39 2014 -0700 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.awt.font; + +import java.lang.reflect.Field; +import sun.misc.JavaAWTFontAccess; + +class JavaAWTFontAccessImpl implements sun.misc.JavaAWTFontAccess { + + // java.awt.font.TextAttribute constants + public Object getTextAttributeConstant(String name) { + switch (name) { + case "RUN_DIRECTION": + case "NUMERIC_SHAPING": + case "BIDI_EMBEDDING": + case "RUN_DIRECTION_LTR": + try { + Field f = TextAttribute.class.getField(name); + return f.get(null); + } catch (NoSuchFieldException | IllegalAccessException x) { + throw new AssertionError(x); + } + } + + throw new AssertionError("Constant name is not recognized"); + } + + // java.awt.font.NumericShaper + public void shape(Object shaper, char[] text, int start, int count) { + assert shaper instanceof NumericShaper; + ((NumericShaper)shaper).shape(text, start,count); + } + +} diff -r f161e8748e8d -r 2c53e38b77aa jdk/src/share/classes/java/awt/font/NumericShaper.java --- a/jdk/src/share/classes/java/awt/font/NumericShaper.java Thu Jul 03 18:20:42 2014 +0200 +++ b/jdk/src/share/classes/java/awt/font/NumericShaper.java Thu Jul 03 16:19:39 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,7 @@ import java.util.Comparator; import java.util.EnumSet; import java.util.Set; +import sun.misc.SharedSecrets; /** * The NumericShaper class is used to convert Latin-1 (European) @@ -134,6 +135,14 @@ */ public final class NumericShaper implements java.io.Serializable { + + // For access from java.text.Bidi + static { + if (SharedSecrets.getJavaAWTFontAccess() == null) { + SharedSecrets.setJavaAWTFontAccess(new JavaAWTFontAccessImpl()); + } + } + /** * A {@code NumericShaper.Range} represents a Unicode range of a * script having its own decimal digits. For example, the {@link diff -r f161e8748e8d -r 2c53e38b77aa jdk/src/share/classes/java/awt/font/TextAttribute.java --- a/jdk/src/share/classes/java/awt/font/TextAttribute.java Thu Jul 03 18:20:42 2014 +0200 +++ b/jdk/src/share/classes/java/awt/font/TextAttribute.java Thu Jul 03 16:19:39 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,6 +44,7 @@ import java.text.AttributedCharacterIterator.Attribute; import java.util.Map; import java.util.HashMap; +import sun.misc.SharedSecrets; /** * The TextAttribute class defines attribute keys and @@ -257,6 +258,13 @@ private static final Map instanceMap = new HashMap(29); + // For access from java.text.Bidi + static { + if (SharedSecrets.getJavaAWTFontAccess() == null) { + SharedSecrets.setJavaAWTFontAccess(new JavaAWTFontAccessImpl()); + } + } + /** * Constructs a TextAttribute with the specified name. * @param name the attribute name to assign to this diff -r f161e8748e8d -r 2c53e38b77aa jdk/src/share/classes/sun/misc/JavaAWTFontAccess.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/sun/misc/JavaAWTFontAccess.java Thu Jul 03 16:19:39 2014 -0700 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * SharedSecrets interface used for the access from java.text.Bidi + */ + +package sun.misc; + +public interface JavaAWTFontAccess { + + // java.awt.font.TextAttribute constants + public Object getTextAttributeConstant(String name); + + // java.awt.font.NumericShaper + public void shape(Object shaper, char[] text, int start, int count); +} diff -r f161e8748e8d -r 2c53e38b77aa jdk/src/share/classes/sun/misc/SharedSecrets.java --- a/jdk/src/share/classes/sun/misc/SharedSecrets.java Thu Jul 03 18:20:42 2014 +0200 +++ b/jdk/src/share/classes/sun/misc/SharedSecrets.java Thu Jul 03 16:19:39 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,6 +55,7 @@ private static JavaSecurityAccess javaSecurityAccess; private static JavaUtilZipFileAccess javaUtilZipFileAccess; private static JavaAWTAccess javaAWTAccess; + private static JavaAWTFontAccess javaAWTFontAccess; private static JavaBeansIntrospectorAccess javaBeansIntrospectorAccess; public static JavaUtilJarAccess javaUtilJarAccess() { @@ -180,12 +181,19 @@ public static JavaAWTAccess getJavaAWTAccess() { // this may return null in which case calling code needs to // provision for. - if (javaAWTAccess == null) { - return null; - } return javaAWTAccess; } + public static void setJavaAWTFontAccess(JavaAWTFontAccess jafa) { + javaAWTFontAccess = jafa; + } + + public static JavaAWTFontAccess getJavaAWTFontAccess() { + // this may return null in which case calling code needs to + // provision for. + return javaAWTFontAccess; + } + public static JavaBeansIntrospectorAccess getJavaBeansIntrospectorAccess() { return javaBeansIntrospectorAccess; } diff -r f161e8748e8d -r 2c53e38b77aa jdk/src/share/classes/sun/text/bidi/BidiBase.java --- a/jdk/src/share/classes/sun/text/bidi/BidiBase.java Thu Jul 03 18:20:42 2014 +0200 +++ b/jdk/src/share/classes/sun/text/bidi/BidiBase.java Thu Jul 03 16:19:39 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,13 +54,12 @@ import java.io.IOException; import java.lang.reflect.Array; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.InvocationTargetException; import java.text.AttributedCharacterIterator; import java.text.Bidi; import java.util.Arrays; import java.util.MissingResourceException; +import sun.misc.JavaAWTFontAccess; +import sun.misc.SharedSecrets; import sun.text.normalizer.UBiDiProps; import sun.text.normalizer.UCharacter; import sun.text.normalizer.UTF16; @@ -3446,7 +3445,13 @@ * java.awt.font.TextAttribute without creating a static dependency. */ private static class TextAttributeConstants { - private static final Class clazz = getClass("java.awt.font.TextAttribute"); + // Make sure to load the AWT's TextAttribute class before using the constants, if any. + static { + try { + Class.forName("java.awt.font.TextAttribute", true, null); + } catch (ClassNotFoundException e) {} + } + static final JavaAWTFontAccess jafa = SharedSecrets.getJavaAWTFontAccess(); /** * TextAttribute instances (or a fake Attribute type if @@ -3462,88 +3467,41 @@ /** * TextAttribute.RUN_DIRECTION_LTR */ - static final Boolean RUN_DIRECTION_LTR = (clazz == null) ? - Boolean.FALSE : (Boolean)getStaticField(clazz, "RUN_DIRECTION_LTR"); - - - private static Class getClass(String name) { - try { - return Class.forName(name, true, null); - } catch (ClassNotFoundException e) { - return null; - } - } - - private static Object getStaticField(Class clazz, String name) { - try { - Field f = clazz.getField(name); - return f.get(null); - } catch (NoSuchFieldException | IllegalAccessException x) { - throw new AssertionError(x); - } - } + static final Boolean RUN_DIRECTION_LTR = (jafa == null) ? + Boolean.FALSE : (Boolean)jafa.getTextAttributeConstant("RUN_DIRECTION_LTR"); @SuppressWarnings("serial") private static AttributedCharacterIterator.Attribute getTextAttribute(String name) { - if (clazz == null) { + if (jafa == null) { // fake attribute return new AttributedCharacterIterator.Attribute(name) { }; } else { - return (AttributedCharacterIterator.Attribute)getStaticField(clazz, name); + return (AttributedCharacterIterator.Attribute)jafa.getTextAttributeConstant(name); } } } /** - * A class that provides access to java.awt.font.NumericShaping without + * A class that provides access to java.awt.font.NumericShaper without * creating a static dependency. */ private static class NumericShapings { - private static final Class clazz = - getClass("java.awt.font.NumericShaper"); - private static final Method shapeMethod = - getMethod(clazz, "shape", char[].class, int.class, int.class); - - private static Class getClass(String name) { + // Make sure to load the AWT's NumericShaper class before calling shape, if any. + static { try { - return Class.forName(name, true, null); - } catch (ClassNotFoundException e) { - return null; - } + Class.forName("java.awt.font.NumericShaper", true, null); + } catch (ClassNotFoundException e) {} } - - private static Method getMethod(Class clazz, - String name, - Class... paramTypes) - { - if (clazz != null) { - try { - return clazz.getMethod(name, paramTypes); - } catch (NoSuchMethodException e) { - throw new AssertionError(e); - } - } else { - return null; - } - } + static final JavaAWTFontAccess jafa = SharedSecrets.getJavaAWTFontAccess(); /** * Invokes NumericShaping shape(text,start,count) method. */ static void shape(Object shaper, char[] text, int start, int count) { - if (shapeMethod == null) - throw new AssertionError("Should not get here"); - try { - shapeMethod.invoke(shaper, text, start, count); - } catch (InvocationTargetException e) { - Throwable cause = e.getCause(); - if (cause instanceof RuntimeException) - throw (RuntimeException)cause; - throw new AssertionError(e); - } catch (IllegalAccessException iae) { - throw new AssertionError(iae); + if (jafa != null) { + jafa.shape(shaper, text, start, count); } } } diff -r f161e8748e8d -r 2c53e38b77aa jdk/test/java/text/Bidi/Bug7051769.java --- a/jdk/test/java/text/Bidi/Bug7051769.java Thu Jul 03 18:20:42 2014 +0200 +++ b/jdk/test/java/text/Bidi/Bug7051769.java Thu Jul 03 16:19:39 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,11 @@ /* * @test - * @bug 7051769 + * @bug 7051769 8038092 * @summary verify that Bidi.toString() returns the corect result. + * The second run is intended to test lazy SharedSectets init for 8038092 + * @run main Bug7051769 + * @run main/othervm -DpreloadBidi=true Bug7051769 */ import java.awt.font.*; import java.text.*; @@ -32,6 +35,18 @@ public class Bug7051769 { + static { + if (System.getProperty("preloadBidi", "").equals("true")) { + // Make sure the SharedSecret is lazily initialized correctly + try { + Class.forName("sun.text.bidi.BidiBase"); + System.out.println("BidiBase class has been pre-loaded."); + } catch (ClassNotFoundException e) { + System.out.println("BidiBase class could not be pre-loaded."); + } + } + } + private static boolean err = false; public static void main(String[] args) {