summaryrefslogtreecommitdiff
path: root/java/openjdk6/files/icedtea/openjdk/7064279-resource_release.patch
diff options
context:
space:
mode:
Diffstat (limited to 'java/openjdk6/files/icedtea/openjdk/7064279-resource_release.patch')
-rw-r--r--java/openjdk6/files/icedtea/openjdk/7064279-resource_release.patch436
1 files changed, 436 insertions, 0 deletions
diff --git a/java/openjdk6/files/icedtea/openjdk/7064279-resource_release.patch b/java/openjdk6/files/icedtea/openjdk/7064279-resource_release.patch
new file mode 100644
index 000000000000..22d0e2caecd4
--- /dev/null
+++ b/java/openjdk6/files/icedtea/openjdk/7064279-resource_release.patch
@@ -0,0 +1,436 @@
+# HG changeset patch
+# User andrew
+# Date 1365712268 -3600
+# Node ID 4d66f7ebcf99c1b322f47ff0aa6adadcd995f8f4
+# Parent df591e0dfd349dc5986cc17949939c588d5a9690
+7064279: Introspector.getBeanInfo() should release some resources in timely manner
+Reviewed-by: art, alexp
+
+diff --git a/src/share/classes/java/beans/Beans.java b/src/share/classes/java/beans/Beans.java
+--- jdk/src/share/classes/java/beans/Beans.java
++++ jdk/src/share/classes/java/beans/Beans.java
+@@ -32,7 +32,6 @@
+ import java.applet.AppletStub;
+ import java.applet.AudioClip;
+
+-import java.awt.GraphicsEnvironment;
+ import java.awt.Image;
+
+ import java.beans.beancontext.BeanContext;
+@@ -53,15 +52,11 @@
+ import java.util.Iterator;
+ import java.util.Vector;
+
+-import sun.awt.AppContext;
+-
+ /**
+ * This class provides some general purpose beans control methods.
+ */
+
+ public class Beans {
+- private static final Object DESIGN_TIME = new Object();
+- private static final Object GUI_AVAILABLE = new Object();
+
+ /**
+ * <p>
+@@ -395,8 +390,7 @@
+ * @see DesignMode
+ */
+ public static boolean isDesignTime() {
+- Object value = AppContext.getAppContext().get(DESIGN_TIME);
+- return (value instanceof Boolean) && (Boolean) value;
++ return ThreadGroupContext.getContext().isDesignTime();
+ }
+
+ /**
+@@ -413,8 +407,7 @@
+ *
+ */
+ public static boolean isGuiAvailable() {
+- Object value = AppContext.getAppContext().get(GUI_AVAILABLE);
+- return (value instanceof Boolean) ? (Boolean) value : !GraphicsEnvironment.isHeadless();
++ return ThreadGroupContext.getContext().isGuiAvailable();
+ }
+
+ /**
+@@ -440,7 +433,7 @@
+ if (sm != null) {
+ sm.checkPropertiesAccess();
+ }
+- AppContext.getAppContext().put(DESIGN_TIME, Boolean.valueOf(isDesignTime));
++ ThreadGroupContext.getContext().setDesignTime(isDesignTime);
+ }
+
+ /**
+@@ -466,7 +459,7 @@
+ if (sm != null) {
+ sm.checkPropertiesAccess();
+ }
+- AppContext.getAppContext().put(GUI_AVAILABLE, Boolean.valueOf(isGuiAvailable));
++ ThreadGroupContext.getContext().setGuiAvailable(isGuiAvailable);
+ }
+ }
+
+diff --git a/src/share/classes/java/beans/Introspector.java b/src/share/classes/java/beans/Introspector.java
+--- jdk/src/share/classes/java/beans/Introspector.java
++++ jdk/src/share/classes/java/beans/Introspector.java
+@@ -38,7 +38,6 @@
+ import java.util.EventListener;
+ import java.util.List;
+ import java.util.TreeMap;
+-import sun.awt.AppContext;
+ import sun.reflect.misc.ReflectUtil;
+
+ /**
+@@ -103,10 +102,7 @@
+ public final static int IGNORE_ALL_BEANINFO = 3;
+
+ // Static Caches to speed up introspection.
+- private static WeakCache<Class<?>, Method[]> declaredMethodCache =
+- new WeakCache<Class<?>, Method[]>();
+-
+- private static final Object BEANINFO_CACHE = new Object();
++ private static final WeakCache<Class<?>, Method[]> declaredMethodCache = new WeakCache<>();
+
+ private Class beanClass;
+ private BeanInfo explicitBeanInfo;
+@@ -170,21 +166,15 @@
+ if (!ReflectUtil.isPackageAccessible(beanClass)) {
+ return (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo();
+ }
+- WeakCache<Class<?>, BeanInfo> beanInfoCache;
++ ThreadGroupContext context = ThreadGroupContext.getContext();
+ BeanInfo beanInfo;
+- synchronized (BEANINFO_CACHE) {
+- beanInfoCache = (WeakCache<Class<?>, BeanInfo>) AppContext.getAppContext().get(BEANINFO_CACHE);
+-
+- if (beanInfoCache == null) {
+- beanInfoCache = new WeakCache<Class<?>, BeanInfo>();
+- AppContext.getAppContext().put(BEANINFO_CACHE, beanInfoCache);
+- }
+- beanInfo = beanInfoCache.get(beanClass);
++ synchronized (declaredMethodCache) {
++ beanInfo = context.getBeanInfo(beanClass);
+ }
+ if (beanInfo == null) {
+ beanInfo = (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo();
+- synchronized (BEANINFO_CACHE) {
+- beanInfoCache.put(beanClass, beanInfo);
++ synchronized (declaredMethodCache) {
++ context.putBeanInfo(beanClass, beanInfo);
+ }
+ }
+ return beanInfo;
+@@ -334,11 +324,8 @@
+ */
+
+ public static void flushCaches() {
+- synchronized (BEANINFO_CACHE) {
+- WeakCache beanInfoCache = (WeakCache) AppContext.getAppContext().get(BEANINFO_CACHE);
+- if (beanInfoCache != null) {
+- beanInfoCache.clear();
+- }
++ synchronized (declaredMethodCache) {
++ ThreadGroupContext.getContext().clearBeanInfoCache();
+ declaredMethodCache.clear();
+ }
+ }
+@@ -362,11 +349,8 @@
+ if (clz == null) {
+ throw new NullPointerException();
+ }
+- synchronized (BEANINFO_CACHE) {
+- WeakCache beanInfoCache = (WeakCache) AppContext.getAppContext().get(BEANINFO_CACHE);
+- if (beanInfoCache != null) {
+- beanInfoCache.put(clz, null);
+- }
++ synchronized (declaredMethodCache) {
++ ThreadGroupContext.getContext().removeBeanInfo(clz);
+ declaredMethodCache.put(clz, null);
+ }
+ }
+@@ -1313,7 +1297,7 @@
+ if (!ReflectUtil.isPackageAccessible(clz)) {
+ return new Method[0];
+ }
+- synchronized (BEANINFO_CACHE) {
++ synchronized (declaredMethodCache) {
+ Method[] result = declaredMethodCache.get(clz);
+ if (result == null) {
+ result = clz.getMethods();
+diff --git a/src/share/classes/java/beans/ThreadGroupContext.java b/src/share/classes/java/beans/ThreadGroupContext.java
+new file mode 100644
+--- /dev/null
++++ jdk/src/share/classes/java/beans/ThreadGroupContext.java
+@@ -0,0 +1,133 @@
++/*
++ * Copyright (c) 2011, 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.beans;
++
++import com.sun.beans.finder.BeanInfoFinder;
++import com.sun.beans.finder.PropertyEditorFinder;
++
++import java.awt.GraphicsEnvironment;
++import java.util.HashMap;
++import java.util.Map;
++import java.util.WeakHashMap;
++
++/**
++ * The {@code ThreadGroupContext} is an application-dependent
++ * context referenced by the specific {@link ThreadGroup}.
++ * This is a replacement for the {@link sun.awt.AppContext}.
++ *
++ * @author Sergey Malenkov
++ */
++final class ThreadGroupContext {
++
++ private static final Map<ThreadGroup, ThreadGroupContext> contexts = new WeakHashMap<>();
++
++ /**
++ * Returns the appropriate {@code AppContext} for the caller,
++ * as determined by its {@code ThreadGroup}.
++ *
++ * @return the application-dependent context
++ */
++ static ThreadGroupContext getContext() {
++ ThreadGroup group = Thread.currentThread().getThreadGroup();
++ synchronized (contexts) {
++ ThreadGroupContext context = contexts.get(group);
++ if (context == null) {
++ context = new ThreadGroupContext();
++ contexts.put(group, context);
++ }
++ return context;
++ }
++ }
++
++ private volatile boolean isDesignTime;
++ private volatile Boolean isGuiAvailable;
++
++ private Map<Class<?>, BeanInfo> beanInfoCache;
++ private BeanInfoFinder beanInfoFinder;
++ private PropertyEditorFinder propertyEditorFinder;
++
++
++ boolean isDesignTime() {
++ return this.isDesignTime;
++ }
++
++ void setDesignTime(boolean isDesignTime) {
++ this.isDesignTime = isDesignTime;
++ }
++
++
++ boolean isGuiAvailable() {
++ Boolean isGuiAvailable = this.isGuiAvailable;
++ return (isGuiAvailable != null)
++ ? isGuiAvailable.booleanValue()
++ : !GraphicsEnvironment.isHeadless();
++ }
++
++ void setGuiAvailable(boolean isGuiAvailable) {
++ this.isGuiAvailable = Boolean.valueOf(isGuiAvailable);
++ }
++
++
++ BeanInfo getBeanInfo(Class<?> type) {
++ return (this.beanInfoCache != null)
++ ? this.beanInfoCache.get(type)
++ : null;
++ }
++
++ BeanInfo putBeanInfo(Class<?> type, BeanInfo info) {
++ if (this.beanInfoCache == null) {
++ this.beanInfoCache = new WeakHashMap<>();
++ }
++ return this.beanInfoCache.put(type, info);
++ }
++
++ void removeBeanInfo(Class<?> type) {
++ if (this.beanInfoCache != null) {
++ this.beanInfoCache.remove(type);
++ }
++ }
++
++ void clearBeanInfoCache() {
++ if (this.beanInfoCache != null) {
++ this.beanInfoCache.clear();
++ }
++ }
++
++
++ synchronized BeanInfoFinder getBeanInfoFinder() {
++ if (this.beanInfoFinder == null) {
++ this.beanInfoFinder = new BeanInfoFinder();
++ }
++ return this.beanInfoFinder;
++ }
++
++ synchronized PropertyEditorFinder getPropertyEditorFinder() {
++ if (this.propertyEditorFinder == null) {
++ this.propertyEditorFinder = new PropertyEditorFinder();
++ }
++ return this.propertyEditorFinder;
++ }
++}
+diff --git a/test/java/beans/Beans/6669869/TestDesignTime.java b/test/java/beans/Beans/6669869/TestDesignTime.java
+--- jdk/test/java/beans/Beans/6669869/TestDesignTime.java
++++ jdk/test/java/beans/Beans/6669869/TestDesignTime.java
+@@ -29,7 +29,6 @@
+ */
+
+ import java.beans.Beans;
+-import sun.awt.SunToolkit;
+
+ public class TestDesignTime implements Runnable {
+ public static void main(String[] args) throws InterruptedException {
+@@ -44,7 +43,6 @@
+ }
+
+ public void run() {
+- SunToolkit.createNewAppContext();
+ if (Beans.isDesignTime()) {
+ throw new Error("shared DesignTime property");
+ }
+diff --git a/test/java/beans/Beans/6669869/TestGuiAvailable.java b/test/java/beans/Beans/6669869/TestGuiAvailable.java
+--- jdk/test/java/beans/Beans/6669869/TestGuiAvailable.java
++++ jdk/test/java/beans/Beans/6669869/TestGuiAvailable.java
+@@ -30,7 +30,6 @@
+
+ import java.awt.GraphicsEnvironment;
+ import java.beans.Beans;
+-import sun.awt.SunToolkit;
+
+ public class TestGuiAvailable implements Runnable {
+ public static void main(String[] args) throws InterruptedException {
+@@ -45,7 +44,6 @@
+ }
+
+ public void run() {
+- SunToolkit.createNewAppContext();
+ if (Beans.isGuiAvailable() == GraphicsEnvironment.isHeadless()) {
+ throw new Error("shared GuiAvailable property");
+ }
+diff --git a/test/java/beans/Introspector/7064279/Test7064279.java b/test/java/beans/Introspector/7064279/Test7064279.java
+new file mode 100644
+--- /dev/null
++++ jdk/test/java/beans/Introspector/7064279/Test7064279.java
+@@ -0,0 +1,75 @@
++/*
++ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++/*
++ * @test
++ * @bug 7064279
++ * @summary Tests that Introspector does not have strong references to context class loader
++ * @author Sergey Malenkov
++ */
++
++import java.beans.Introspector;
++import java.io.File;
++import java.lang.ref.WeakReference;
++import java.net.URL;
++import java.net.URLClassLoader;
++
++public class Test7064279 {
++
++ public static void main(String[] args) throws Exception {
++ WeakReference ref = new WeakReference(test("test.jar", "test.Test"));
++ try {
++ int[] array = new int[1024];
++ while (true) {
++ array = new int[array.length << 1];
++ }
++ }
++ catch (OutOfMemoryError error) {
++ System.gc();
++ }
++ if (null != ref.get()) {
++ throw new Error("ClassLoader is not released");
++ }
++ }
++
++ private static Object test(String jarName, String className) throws Exception {
++ StringBuilder sb = new StringBuilder(256);
++ sb.append("file:");
++ sb.append(System.getProperty("test.src", "."));
++ sb.append(File.separatorChar);
++ sb.append(jarName);
++
++ ClassLoader newLoader = new URLClassLoader(new URL[] { new URL(sb.toString()) });
++ ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
++
++ Thread.currentThread().setContextClassLoader(newLoader);
++ test(newLoader.loadClass(className));
++ Thread.currentThread().setContextClassLoader(oldLoader);
++
++ return newLoader;
++ }
++
++ private static void test(Class type) throws Exception {
++ Introspector.getBeanInfo(type);
++ }
++}
+diff --git a/test/java/beans/Introspector/Test6660539.java b/test/java/beans/Introspector/Test6660539.java
+--- jdk/test/java/beans/Introspector/Test6660539.java
++++ jdk/test/java/beans/Introspector/Test6660539.java
+@@ -28,8 +28,6 @@
+ * @author Sergey Malenkov
+ */
+
+-import sun.awt.SunToolkit;
+-
+ import java.beans.BeanInfo;
+ import java.beans.IntrospectionException;
+ import java.beans.Introspector;
+@@ -49,7 +47,6 @@
+ }
+
+ public void run() {
+- SunToolkit.createNewAppContext();
+ for (PropertyDescriptor pd : getPropertyDescriptors()) {
+ if (pd.getDisplayName().equals(NAME))
+ throw new Error("shared BeanInfo cache");