1987N/A/*
2362N/A * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
1987N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1987N/A *
1987N/A * This code is free software; you can redistribute it and/or modify it
1987N/A * under the terms of the GNU General Public License version 2 only, as
1987N/A * published by the Free Software Foundation.
1987N/A *
1987N/A * This code is distributed in the hope that it will be useful, but WITHOUT
1987N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1987N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1987N/A * version 2 for more details (a copy is included in the LICENSE file that
1987N/A * accompanied this code).
1987N/A *
1987N/A * You should have received a copy of the GNU General Public License version
1987N/A * 2 along with this work; if not, write to the Free Software Foundation,
1987N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1987N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
1987N/A */
1987N/A
1987N/A/*
1987N/A * @test
1987N/A * @bug 5102804
1987N/A * @summary Tests memory leak
1987N/A * @author Sergey Malenkov
2149N/A * @run main/othervm -ms16m -mx16m Test5102804
1987N/A */
1987N/A
1987N/Aimport java.beans.BeanInfo;
1987N/Aimport java.beans.IntrospectionException;
1987N/Aimport java.beans.Introspector;
1987N/Aimport java.beans.PropertyDescriptor;
1987N/Aimport java.beans.SimpleBeanInfo;
1987N/Aimport java.lang.ref.Reference;
1987N/Aimport java.lang.ref.WeakReference;
1987N/Aimport java.net.URL;
1987N/Aimport java.net.URLClassLoader;
1987N/A
1987N/Apublic class Test5102804 {
1987N/A private static final String BEAN_NAME = "Test5102804$Example";
1987N/A private static final String BEAN_INFO_NAME = BEAN_NAME + "BeanInfo";
1987N/A
1987N/A public static void main(String[] args) {
1987N/A if (!isCollectible(getReference()))
1987N/A throw new Error("Reference is not collected");
1987N/A }
1987N/A
1987N/A private static Reference getReference() {
1987N/A try {
1987N/A ClassLoader loader = new Loader();
1987N/A Class type = Class.forName(BEAN_NAME, true, loader);
1987N/A if (!type.getClassLoader().equals(loader)) {
1987N/A throw new Error("Wrong class loader");
1987N/A }
1987N/A BeanInfo info = Introspector.getBeanInfo(type);
1987N/A if (0 != info.getDefaultPropertyIndex()) {
1987N/A throw new Error("Wrong bean info found");
1987N/A }
1987N/A return new WeakReference<Class>(type);
1987N/A }
1987N/A catch (IntrospectionException exception) {
1987N/A throw new Error("Introspection Error", exception);
1987N/A }
1987N/A catch (ClassNotFoundException exception) {
1987N/A throw new Error("Class Not Found", exception);
1987N/A }
1987N/A }
1987N/A
1987N/A private static boolean isCollectible(Reference reference) {
1987N/A int[] array = new int[10];
1987N/A while (true) {
1987N/A try {
1987N/A array = new int[array.length + array.length / 3];
1987N/A }
1987N/A catch (OutOfMemoryError error) {
1987N/A return null == reference.get();
1987N/A }
1987N/A }
1987N/A }
1987N/A
1987N/A /**
1987N/A * Custom class loader to load the Example class by itself.
1987N/A * Could also load it from a different code source, but this is easier to set up.
1987N/A */
1987N/A private static final class Loader extends URLClassLoader {
1987N/A Loader() {
1987N/A super(new URL[] {
1987N/A Test5102804.class.getProtectionDomain().getCodeSource().getLocation()
1987N/A });
1987N/A }
1987N/A
1987N/A @Override
1987N/A protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
1987N/A Class c = findLoadedClass(name);
1987N/A if (c == null) {
1987N/A if (BEAN_NAME.equals(name) || BEAN_INFO_NAME.equals(name)) {
1987N/A c = findClass(name);
1987N/A }
1987N/A else try {
1987N/A c = getParent().loadClass(name);
1987N/A }
1987N/A catch (ClassNotFoundException exception) {
1987N/A c = findClass(name);
1987N/A }
1987N/A }
1987N/A if (resolve) {
1987N/A resolveClass(c);
1987N/A }
1987N/A return c;
1987N/A }
1987N/A }
1987N/A
1987N/A /**
1987N/A * A simple bean to load from the Loader class, not main class loader.
1987N/A */
1987N/A public static final class Example {
1987N/A private int value;
1987N/A
1987N/A public int getValue() {
1987N/A return value;
1987N/A }
1987N/A
1987N/A public void setValue(int value) {
1987N/A this.value = value;
1987N/A }
1987N/A }
1987N/A
1987N/A /**
1987N/A * The BeanInfo for the Example class.
1987N/A * It is also loaded from the Loader class.
1987N/A */
1987N/A public static final class ExampleBeanInfo extends SimpleBeanInfo {
1987N/A @Override
1987N/A public int getDefaultPropertyIndex() {
1987N/A return 0;
1987N/A }
1987N/A
1987N/A @Override
1987N/A public PropertyDescriptor[] getPropertyDescriptors() {
1987N/A try {
1987N/A return new PropertyDescriptor[] {
1987N/A new PropertyDescriptor("value", Class.forName(BEAN_NAME))
1987N/A };
1987N/A }
1987N/A catch (ClassNotFoundException exception) {
1987N/A return null;
1987N/A }
1987N/A catch (IntrospectionException exception) {
1987N/A return null;
1987N/A }
1987N/A }
1987N/A }
1987N/A}