8038092: Re-examine Bidi reflective dependency on java.awt.font
Reviewed-by: alanb
--- /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);
+ }
+
+}
--- 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 <code>NumericShaper</code> 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
--- 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 <code>TextAttribute</code> class defines attribute keys and
@@ -257,6 +258,13 @@
private static final Map<String, TextAttribute>
instanceMap = new HashMap<String, TextAttribute>(29);
+ // For access from java.text.Bidi
+ static {
+ if (SharedSecrets.getJavaAWTFontAccess() == null) {
+ SharedSecrets.setJavaAWTFontAccess(new JavaAWTFontAccessImpl());
+ }
+ }
+
/**
* Constructs a <code>TextAttribute</code> with the specified name.
* @param name the attribute name to assign to this
--- /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);
+}
--- 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;
}
--- 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);
}
}
}
--- 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) {