提交 b2a2c099 编写于 作者: M malenkov

7064279: Introspector.getBeanInfo() should release some resources in timely manner

Reviewed-by: art, alexp
上级 82b0bea5
...@@ -32,7 +32,6 @@ import java.applet.AppletContext; ...@@ -32,7 +32,6 @@ import java.applet.AppletContext;
import java.applet.AppletStub; import java.applet.AppletStub;
import java.applet.AudioClip; import java.applet.AudioClip;
import java.awt.GraphicsEnvironment;
import java.awt.Image; import java.awt.Image;
import java.beans.beancontext.BeanContext; import java.beans.beancontext.BeanContext;
...@@ -53,15 +52,11 @@ import java.util.Hashtable; ...@@ -53,15 +52,11 @@ import java.util.Hashtable;
import java.util.Iterator; import java.util.Iterator;
import java.util.Vector; import java.util.Vector;
import sun.awt.AppContext;
/** /**
* This class provides some general purpose beans control methods. * This class provides some general purpose beans control methods.
*/ */
public class Beans { public class Beans {
private static final Object DESIGN_TIME = new Object();
private static final Object GUI_AVAILABLE = new Object();
/** /**
* <p> * <p>
...@@ -395,8 +390,7 @@ public class Beans { ...@@ -395,8 +390,7 @@ public class Beans {
* @see DesignMode * @see DesignMode
*/ */
public static boolean isDesignTime() { public static boolean isDesignTime() {
Object value = AppContext.getAppContext().get(DESIGN_TIME); return ThreadGroupContext.getContext().isDesignTime();
return (value instanceof Boolean) && (Boolean) value;
} }
/** /**
...@@ -413,8 +407,7 @@ public class Beans { ...@@ -413,8 +407,7 @@ public class Beans {
* *
*/ */
public static boolean isGuiAvailable() { public static boolean isGuiAvailable() {
Object value = AppContext.getAppContext().get(GUI_AVAILABLE); return ThreadGroupContext.getContext().isGuiAvailable();
return (value instanceof Boolean) ? (Boolean) value : !GraphicsEnvironment.isHeadless();
} }
/** /**
...@@ -440,7 +433,7 @@ public class Beans { ...@@ -440,7 +433,7 @@ public class Beans {
if (sm != null) { if (sm != null) {
sm.checkPropertiesAccess(); sm.checkPropertiesAccess();
} }
AppContext.getAppContext().put(DESIGN_TIME, Boolean.valueOf(isDesignTime)); ThreadGroupContext.getContext().setDesignTime(isDesignTime);
} }
/** /**
...@@ -466,7 +459,7 @@ public class Beans { ...@@ -466,7 +459,7 @@ public class Beans {
if (sm != null) { if (sm != null) {
sm.checkPropertiesAccess(); sm.checkPropertiesAccess();
} }
AppContext.getAppContext().put(GUI_AVAILABLE, Boolean.valueOf(isGuiAvailable)); ThreadGroupContext.getContext().setGuiAvailable(isGuiAvailable);
} }
} }
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
package java.beans; package java.beans;
import com.sun.beans.WeakCache; import com.sun.beans.WeakCache;
import com.sun.beans.finder.BeanInfoFinder;
import com.sun.beans.finder.ClassFinder; import com.sun.beans.finder.ClassFinder;
import java.awt.Component; import java.awt.Component;
...@@ -44,9 +43,7 @@ import java.util.EventListener; ...@@ -44,9 +43,7 @@ import java.util.EventListener;
import java.util.EventObject; import java.util.EventObject;
import java.util.List; import java.util.List;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.WeakHashMap;
import sun.awt.AppContext;
import sun.reflect.misc.ReflectUtil; import sun.reflect.misc.ReflectUtil;
/** /**
...@@ -98,10 +95,7 @@ public class Introspector { ...@@ -98,10 +95,7 @@ public class Introspector {
public final static int IGNORE_ALL_BEANINFO = 3; public final static int IGNORE_ALL_BEANINFO = 3;
// Static Caches to speed up introspection. // Static Caches to speed up introspection.
private static WeakCache<Class<?>, Method[]> declaredMethodCache = private static final WeakCache<Class<?>, Method[]> declaredMethodCache = new WeakCache<>();
new WeakCache<Class<?>, Method[]>();
private static final Object BEANINFO_CACHE = new Object();
private Class beanClass; private Class beanClass;
private BeanInfo explicitBeanInfo; private BeanInfo explicitBeanInfo;
...@@ -134,8 +128,6 @@ public class Introspector { ...@@ -134,8 +128,6 @@ public class Introspector {
static final String SET_PREFIX = "set"; static final String SET_PREFIX = "set";
static final String IS_PREFIX = "is"; static final String IS_PREFIX = "is";
private static final Object FINDER_KEY = new Object();
//====================================================================== //======================================================================
// Public methods // Public methods
//====================================================================== //======================================================================
...@@ -160,20 +152,15 @@ public class Introspector { ...@@ -160,20 +152,15 @@ public class Introspector {
if (!ReflectUtil.isPackageAccessible(beanClass)) { if (!ReflectUtil.isPackageAccessible(beanClass)) {
return (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo(); return (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo();
} }
Map<Class<?>, BeanInfo> beanInfoCache; ThreadGroupContext context = ThreadGroupContext.getContext();
BeanInfo beanInfo; BeanInfo beanInfo;
synchronized (BEANINFO_CACHE) { synchronized (declaredMethodCache) {
beanInfoCache = (Map<Class<?>, BeanInfo>) AppContext.getAppContext().get(BEANINFO_CACHE); beanInfo = context.getBeanInfo(beanClass);
if (beanInfoCache == null) {
beanInfoCache = new WeakHashMap<Class<?>, BeanInfo>();
AppContext.getAppContext().put(BEANINFO_CACHE, beanInfoCache);
}
beanInfo = beanInfoCache.get(beanClass);
} }
if (beanInfo == null) { if (beanInfo == null) {
beanInfo = new Introspector(beanClass, null, USE_ALL_BEANINFO).getBeanInfo(); beanInfo = new Introspector(beanClass, null, USE_ALL_BEANINFO).getBeanInfo();
synchronized (BEANINFO_CACHE) { synchronized (declaredMethodCache) {
beanInfoCache.put(beanClass, beanInfo); context.putBeanInfo(beanClass, beanInfo);
} }
} }
return beanInfo; return beanInfo;
...@@ -306,7 +293,7 @@ public class Introspector { ...@@ -306,7 +293,7 @@ public class Introspector {
*/ */
public static String[] getBeanInfoSearchPath() { public static String[] getBeanInfoSearchPath() {
return getFinder().getPackages(); return ThreadGroupContext.getContext().getBeanInfoFinder().getPackages();
} }
/** /**
...@@ -330,7 +317,7 @@ public class Introspector { ...@@ -330,7 +317,7 @@ public class Introspector {
if (sm != null) { if (sm != null) {
sm.checkPropertiesAccess(); sm.checkPropertiesAccess();
} }
getFinder().setPackages(path); ThreadGroupContext.getContext().getBeanInfoFinder().setPackages(path);
} }
...@@ -342,11 +329,8 @@ public class Introspector { ...@@ -342,11 +329,8 @@ public class Introspector {
*/ */
public static void flushCaches() { public static void flushCaches() {
synchronized (BEANINFO_CACHE) { synchronized (declaredMethodCache) {
Map beanInfoCache = (Map) AppContext.getAppContext().get(BEANINFO_CACHE); ThreadGroupContext.getContext().clearBeanInfoCache();
if (beanInfoCache != null) {
beanInfoCache.clear();
}
declaredMethodCache.clear(); declaredMethodCache.clear();
} }
} }
...@@ -370,11 +354,8 @@ public class Introspector { ...@@ -370,11 +354,8 @@ public class Introspector {
if (clz == null) { if (clz == null) {
throw new NullPointerException(); throw new NullPointerException();
} }
synchronized (BEANINFO_CACHE) { synchronized (declaredMethodCache) {
Map beanInfoCache = (Map) AppContext.getAppContext().get(BEANINFO_CACHE); ThreadGroupContext.getContext().removeBeanInfo(clz);
if (beanInfoCache != null) {
beanInfoCache.put(clz, null);
}
declaredMethodCache.put(clz, null); declaredMethodCache.put(clz, null);
} }
} }
...@@ -452,7 +433,7 @@ public class Introspector { ...@@ -452,7 +433,7 @@ public class Introspector {
* @return Instance of an explicit BeanInfo class or null if one isn't found. * @return Instance of an explicit BeanInfo class or null if one isn't found.
*/ */
private static BeanInfo findExplicitBeanInfo(Class beanClass) { private static BeanInfo findExplicitBeanInfo(Class beanClass) {
return getFinder().find(beanClass); return ThreadGroupContext.getContext().getBeanInfoFinder().find(beanClass);
} }
/** /**
...@@ -1275,7 +1256,7 @@ public class Introspector { ...@@ -1275,7 +1256,7 @@ public class Introspector {
if (!ReflectUtil.isPackageAccessible(clz)) { if (!ReflectUtil.isPackageAccessible(clz)) {
return new Method[0]; return new Method[0];
} }
synchronized (BEANINFO_CACHE) { synchronized (declaredMethodCache) {
Method[] result = declaredMethodCache.get(clz); Method[] result = declaredMethodCache.get(clz);
if (result == null) { if (result == null) {
result = clz.getMethods(); result = clz.getMethods();
...@@ -1426,17 +1407,6 @@ public class Introspector { ...@@ -1426,17 +1407,6 @@ public class Introspector {
return false; return false;
} }
private static BeanInfoFinder getFinder() {
AppContext context = AppContext.getAppContext();
Object object = context.get(FINDER_KEY);
if (object instanceof BeanInfoFinder) {
return (BeanInfoFinder) object;
}
BeanInfoFinder finder = new BeanInfoFinder();
context.put(FINDER_KEY, finder);
return finder;
}
/** /**
* Try to create an instance of a named class. * Try to create an instance of a named class.
* First try the classloader of "sibling", then try the system * First try the classloader of "sibling", then try the system
......
...@@ -25,9 +25,6 @@ ...@@ -25,9 +25,6 @@
package java.beans; package java.beans;
import com.sun.beans.finder.PropertyEditorFinder;
import sun.awt.AppContext;
/** /**
* The PropertyEditorManager can be used to locate a property editor for * The PropertyEditorManager can be used to locate a property editor for
* any given type name. This property editor must support the * any given type name. This property editor must support the
...@@ -55,8 +52,6 @@ import sun.awt.AppContext; ...@@ -55,8 +52,6 @@ import sun.awt.AppContext;
public class PropertyEditorManager { public class PropertyEditorManager {
private static final Object FINDER_KEY = new Object();
/** /**
* Registers an editor class to edit values of the given target class. * Registers an editor class to edit values of the given target class.
* If the editor class is {@code null}, * If the editor class is {@code null},
...@@ -81,7 +76,7 @@ public class PropertyEditorManager { ...@@ -81,7 +76,7 @@ public class PropertyEditorManager {
if (sm != null) { if (sm != null) {
sm.checkPropertiesAccess(); sm.checkPropertiesAccess();
} }
getFinder().register(targetType, editorClass); ThreadGroupContext.getContext().getPropertyEditorFinder().register(targetType, editorClass);
} }
/** /**
...@@ -92,7 +87,7 @@ public class PropertyEditorManager { ...@@ -92,7 +87,7 @@ public class PropertyEditorManager {
* The result is null if no suitable editor can be found. * The result is null if no suitable editor can be found.
*/ */
public static PropertyEditor findEditor(Class<?> targetType) { public static PropertyEditor findEditor(Class<?> targetType) {
return getFinder().find(targetType); return ThreadGroupContext.getContext().getPropertyEditorFinder().find(targetType);
} }
/** /**
...@@ -104,7 +99,7 @@ public class PropertyEditorManager { ...@@ -104,7 +99,7 @@ public class PropertyEditorManager {
* e.g. Sun implementation initially sets to {"sun.beans.editors"}. * e.g. Sun implementation initially sets to {"sun.beans.editors"}.
*/ */
public static String[] getEditorSearchPath() { public static String[] getEditorSearchPath() {
return getFinder().getPackages(); return ThreadGroupContext.getContext().getPropertyEditorFinder().getPackages();
} }
/** /**
...@@ -125,17 +120,6 @@ public class PropertyEditorManager { ...@@ -125,17 +120,6 @@ public class PropertyEditorManager {
if (sm != null) { if (sm != null) {
sm.checkPropertiesAccess(); sm.checkPropertiesAccess();
} }
getFinder().setPackages(path); ThreadGroupContext.getContext().getPropertyEditorFinder().setPackages(path);
}
private static PropertyEditorFinder getFinder() {
AppContext context = AppContext.getAppContext();
Object object = context.get(FINDER_KEY);
if (object instanceof PropertyEditorFinder) {
return (PropertyEditorFinder) object;
}
PropertyEditorFinder finder = new PropertyEditorFinder();
context.put(FINDER_KEY, finder);
return finder;
} }
} }
/*
* 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;
}
}
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
*/ */
import java.beans.Beans; import java.beans.Beans;
import sun.awt.SunToolkit;
public class TestDesignTime implements Runnable { public class TestDesignTime implements Runnable {
public static void main(String[] args) throws InterruptedException { public static void main(String[] args) throws InterruptedException {
...@@ -44,7 +43,6 @@ public class TestDesignTime implements Runnable { ...@@ -44,7 +43,6 @@ public class TestDesignTime implements Runnable {
} }
public void run() { public void run() {
SunToolkit.createNewAppContext();
if (Beans.isDesignTime()) { if (Beans.isDesignTime()) {
throw new Error("shared DesignTime property"); throw new Error("shared DesignTime property");
} }
......
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
import java.awt.GraphicsEnvironment; import java.awt.GraphicsEnvironment;
import java.beans.Beans; import java.beans.Beans;
import sun.awt.SunToolkit;
public class TestGuiAvailable implements Runnable { public class TestGuiAvailable implements Runnable {
public static void main(String[] args) throws InterruptedException { public static void main(String[] args) throws InterruptedException {
...@@ -45,7 +44,6 @@ public class TestGuiAvailable implements Runnable { ...@@ -45,7 +44,6 @@ public class TestGuiAvailable implements Runnable {
} }
public void run() { public void run() {
SunToolkit.createNewAppContext();
if (Beans.isGuiAvailable() == GraphicsEnvironment.isHeadless()) { if (Beans.isGuiAvailable() == GraphicsEnvironment.isHeadless()) {
throw new Error("shared GuiAvailable property"); throw new Error("shared GuiAvailable property");
} }
......
...@@ -41,8 +41,6 @@ import java.beans.Introspector; ...@@ -41,8 +41,6 @@ import java.beans.Introspector;
import java.lang.ref.Reference; import java.lang.ref.Reference;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import sun.awt.SunToolkit;
public class TestBeanInfo implements Runnable { public class TestBeanInfo implements Runnable {
private static final String[] SEARCH_PATH = { "infos" }; // NON-NLS: package name private static final String[] SEARCH_PATH = { "infos" }; // NON-NLS: package name
...@@ -81,9 +79,6 @@ public class TestBeanInfo implements Runnable { ...@@ -81,9 +79,6 @@ public class TestBeanInfo implements Runnable {
private boolean passed; private boolean passed;
public void run() { public void run() {
if (this.passed) {
SunToolkit.createNewAppContext();
}
Introspector.flushCaches(); Introspector.flushCaches();
test(FirstBean.class, FirstBeanBeanInfo.class); test(FirstBean.class, FirstBeanBeanInfo.class);
...@@ -98,7 +93,5 @@ public class TestBeanInfo implements Runnable { ...@@ -98,7 +93,5 @@ public class TestBeanInfo implements Runnable {
test(SecondBean.class, SecondBeanBeanInfo.class); test(SecondBean.class, SecondBeanBeanInfo.class);
test(ThirdBean.class, null); test(ThirdBean.class, null);
test(ThirdBeanBeanInfo.class, ThirdBeanBeanInfo.class); test(ThirdBeanBeanInfo.class, ThirdBeanBeanInfo.class);
this.passed = true;
} }
} }
/*
* 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);
}
}
...@@ -28,8 +28,6 @@ ...@@ -28,8 +28,6 @@
* @author Sergey Malenkov * @author Sergey Malenkov
*/ */
import sun.awt.SunToolkit;
import java.beans.BeanInfo; import java.beans.BeanInfo;
import java.beans.IntrospectionException; import java.beans.IntrospectionException;
import java.beans.Introspector; import java.beans.Introspector;
...@@ -49,7 +47,6 @@ public class Test6660539 implements Runnable { ...@@ -49,7 +47,6 @@ public class Test6660539 implements Runnable {
} }
public void run() { public void run() {
SunToolkit.createNewAppContext();
for (PropertyDescriptor pd : getPropertyDescriptors()) { for (PropertyDescriptor pd : getPropertyDescriptors()) {
if (pd.getDisplayName().equals(NAME)) if (pd.getDisplayName().equals(NAME))
throw new Error("shared BeanInfo cache"); throw new Error("shared BeanInfo cache");
......
...@@ -36,7 +36,6 @@ import java.awt.Font; ...@@ -36,7 +36,6 @@ import java.awt.Font;
import java.beans.PropertyEditor; import java.beans.PropertyEditor;
import java.beans.PropertyEditorManager; import java.beans.PropertyEditorManager;
import sun.awt.SunToolkit;
import sun.beans.editors.BooleanEditor; import sun.beans.editors.BooleanEditor;
import sun.beans.editors.ByteEditor; import sun.beans.editors.ByteEditor;
import sun.beans.editors.ColorEditor; import sun.beans.editors.ColorEditor;
...@@ -77,12 +76,7 @@ public class TestPropertyEditor implements Runnable { ...@@ -77,12 +76,7 @@ public class TestPropertyEditor implements Runnable {
} }
} }
private boolean passed;
public void run() { public void run() {
if (this.passed) {
SunToolkit.createNewAppContext();
}
PropertyEditorManager.registerEditor(ThirdBean.class, ThirdBeanEditor.class); PropertyEditorManager.registerEditor(ThirdBean.class, ThirdBeanEditor.class);
test(FirstBean.class, FirstBeanEditor.class); test(FirstBean.class, FirstBeanEditor.class);
...@@ -135,7 +129,5 @@ public class TestPropertyEditor implements Runnable { ...@@ -135,7 +129,5 @@ public class TestPropertyEditor implements Runnable {
test(Color.class, null); test(Color.class, null);
test(Font.class, null); test(Font.class, null);
test(Enumeration.class, EnumEditor.class); test(Enumeration.class, EnumEditor.class);
this.passed = true;
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册