You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by sm...@apache.org on 2007/06/08 18:35:10 UTC

svn commit: r545554 [12/13] - in /harmony/enhanced/buildtest/branches/2.0/tests/reliability: ./ run/ src/ src/java/ src/java/org/ src/java/org/apache/ src/java/org/apache/harmony/ src/java/org/apache/harmony/test/ src/java/org/apache/harmony/test/relia...

Added: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassAttributesTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassAttributesTest.java?view=auto&rev=545554
==============================================================================
--- harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassAttributesTest.java (added)
+++ harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassAttributesTest.java Fri Jun  8 09:34:52 2007
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2007 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+    
+/**
+ * @author Aleksey Ignatenko
+ * @version $Revision: 1.0 $
+ */
+
+/**
+ *  GOAL: the test checks that for each loaded class (from "java.home") invocation of java.lang.Class methods 
+ *             in multiple threads running in parallel does not cause unexpected errors (crashes, hangs, exceptions).
+ *
+ *  NOTE: see additional description in ClassMultiBase class.
+ *
+ *  The test does:
+ *    1. Reads parameter, which is:
+ *            param[0] - number of threads to launch for parallel classes processing
+ *
+ *     2. Overrides method testContent(Class) in which almost all methods of java.lang.Class are invoked.
+ *         Finally, newInstance() is invoked only for "java." classes.
+ *
+ *     3. The test fails if crash or hang or unexpected runtime exception occurred while invocations of 
+ *         java.lang.Class methods in testContent(Class).
+ *
+ */
+
+package org.apache.harmony.test.reliability.vm.classloading;
+
+import java.lang.reflect.GenericSignatureFormatError;
+import java.lang.reflect.MalformedParameterizedTypeException;
+
+public class ClassAttributesTest extends ClassMultiTestBase{
+
+    public static void main(String[] args){
+        System.exit(new ClassAttributesTest().test(args));
+    }
+    
+    void testContent(Class cls) {
+        cls.getName();        
+        cls.getAnnotations();
+        try{
+            cls.getClassLoader();
+        } catch (SecurityException e){ 
+            // Expected
+        }
+        cls.getComponentType();
+        cls.getDeclaredAnnotations();
+        cls.getDeclaringClass();
+        cls.getEnclosingConstructor();
+        cls.getEnumConstants();
+        cls.getGenericInterfaces();
+        cls.getModifiers();
+        
+        // check package info
+        Package pk = cls.getPackage();
+        pk.getName();
+        pk.getImplementationTitle();
+        pk.getImplementationVendor();
+        pk.getImplementationVersion();
+        pk.getSpecificationTitle();
+        pk.getSpecificationVendor();
+        pk.getSpecificationVersion();
+        pk.isSealed();
+        
+        try{
+            cls.getProtectionDomain();
+        } catch (SecurityException e){
+            // Expected
+        }
+
+        try{
+            cls.getGenericSuperclass();
+        } catch(GenericSignatureFormatError e){
+            // Expected
+        } catch (TypeNotPresentException e){
+            // Expected
+        } catch (MalformedParameterizedTypeException e){
+            // Expected
+        }
+
+        try{        
+            cls.getProtectionDomain();
+        } catch (SecurityException e){
+            // Expected
+        }
+           
+        cls.getSigners();
+        cls.isAnonymousClass();
+        cls.getCanonicalName();
+        cls.getSimpleName();
+        
+        cls.getSuperclass();
+        
+        try{
+            cls.getTypeParameters();
+        } catch(GenericSignatureFormatError e){
+            // Expected
+        }
+        cls.hashCode();
+        cls.isAnnotation();
+        cls.isArray();
+        cls.isEnum();
+        cls.isInterface();
+        cls.isLocalClass();
+        cls.isPrimitive();
+        cls.isSynthetic();
+        cls.toString();
+
+        // make newInstance only for "java." classes to avoid hangs, avoid "awt" and "swing" to avoid XServer up requirement
+        if (cls.getName().startsWith("java.") && !cls.getName().contains("awt") && !cls.getName().contains("swing")){
+            try {
+                cls.newInstance();
+            } catch(IllegalAccessException e){
+                // Expected
+            } catch (InstantiationException e){
+                // Expected
+            } catch (ExceptionInInitializerError e){
+                // Expected
+            } catch (SecurityException e){
+                // Expected
+            }catch (Exception e){
+                // Expected - propogated exception from class default constructor
+            }
+        }       
+
+    }
+
+}
\ No newline at end of file

Propchange: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassAttributesTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassMultiTestBase.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassMultiTestBase.java?view=auto&rev=545554
==============================================================================
--- harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassMultiTestBase.java (added)
+++ harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassMultiTestBase.java Fri Jun  8 09:34:52 2007
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2007 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Aleksey Ignatenko
+ * @version $Revision: 1.0 $
+ */
+
+/**
+ * NOTE: this class is not a test for running, it is a base class for other tests which
+ *            process classes from "java.home"'s jar files.
+ *
+ * The class does:
+ *    1. Reads parameter, which is:
+ *            param[0] - number of threads to launch for parallel classes processing
+ *            param[1] - flag indicates what OS is used, true == linux, it is required not to initialize loaded classes as it requires 
+ *            XServer to be up.
+ *
+ *    2. Gets names of all classes from all jar files found in "java.home" and its subdirectories.
+ *
+ *    2. Starts param[0] threads. 
+ *          Each thread:
+ *              For each class name:
+ *                 - tries to load the class by Class.forName() (classes are not initialized on linux because it requires XServer to be up)
+ *                 - if class could not be loaded for any reason, it is ignored, otherwise, 
+ *                 - testContent() method which must be overridden in real tests is invoked.
+ *
+ *    3. If there are no unexpected exceptions, PASS status is returned, otherwise, FAIL
+ */
+
+package org.apache.harmony.test.reliability.vm.classloading;
+
+import java.util.ArrayList;
+import java.lang.reflect.*;
+import java.lang.annotation.*;
+
+import org.apache.harmony.test.reliability.share.Test;
+import org.apache.harmony.test.reliability.share.JarFilesScanner;
+
+
+public class ClassMultiTestBase extends Test implements Runnable{
+    volatile boolean failed = false;
+    final static String classFilesExt = ".class";
+    final static char slashCharDelimiter1 = '/';
+    final static char slashCharDelimiter2 = '\\';
+    final static char dotCharDelimiter = '.';
+    final static int NUMBER_OF_THREADS = 3;
+    int numberOfThreads = NUMBER_OF_THREADS;
+    int classCounter = 0;
+    ArrayList<String> jarFiles;
+    
+    void testContent(Class cls) {
+        fail("The " + this.getClass().getName() + " class is for infra purposes only! - NOT TEST!");
+    }
+    
+    public int test(String []args){
+        parseParams(args);        
+        jarFiles = new JarFilesScanner().getClassFilesInJRE();
+
+        
+        Thread[] thrds = new Thread[numberOfThreads];
+        for (int i = 0; i< thrds.length; i++){
+            thrds[i] = new Thread(this);
+            thrds[i].start();
+        }
+        
+        for (int i = 0; i< thrds.length; i++){
+            try {
+                thrds[i].join();
+            } catch (InterruptedException e) {
+                failed = true;
+                log.add("Failed to join thread " + e);
+            }
+        }
+
+        if (failed){
+            return fail("FAILED");
+        }
+        //System.out.println("Number of classes tested "+ classCounter);
+        return pass("OK");
+    }
+    
+    
+    public void run(){
+        for (int i=0; i<jarFiles.size(); i++){
+            Class jlClass = null;
+            String classPureName = jarFiles.get(i).substring(0, jarFiles.get(i).length()-classFilesExt.length());
+            classPureName = classPureName.replace(slashCharDelimiter1, dotCharDelimiter);
+            classPureName = classPureName.replace(slashCharDelimiter2, dotCharDelimiter);
+            try {
+                // do not initialize loaded classes
+                jlClass = Class.forName(classPureName, false, this.getClass().getClassLoader());
+            } catch (Throwable e) {
+                continue;
+            }
+            if (jlClass != null){
+                classCounter++;
+                try{
+                    testContent(jlClass);
+                } catch (Throwable e){
+                    if (e.getClass().getName() == "java.lang.InternalError") continue; // enables 100% pass on RI
+                    //log.add("Failed to test class: " + classPureName + " Issue:" + e);
+                    //e.printStackTrace();
+                    failed = true;
+                }
+            }
+        }
+    }
+
+    public void parseParams(String[] params) {
+        if (params.length >= 1) {
+            numberOfThreads = Integer.parseInt(params[0]);
+        }
+    }
+
+}
+

Propchange: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassMultiTestBase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassReflectionTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassReflectionTest.java?view=auto&rev=545554
==============================================================================
--- harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassReflectionTest.java (added)
+++ harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassReflectionTest.java Fri Jun  8 09:34:52 2007
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2007 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Aleksey Ignatenko
+ * @version $Revision: 1.0 $
+ */
+
+/**
+ *  GOAL: the test checks that for each loaded class (from "java.home") invocation of java.lang.reflect methods 
+ *             in multiple threads running in parallel does not cause unexpected errors (crashes, hangs, exceptions).
+ *
+ *  NOTE: see additional description in ClassMultiBase class.
+ *
+ *  The test does:
+ *    1. Reads parameter, which is:
+ *            param[0] - number of threads to launch for parallel classes processing
+ *
+ *     2. Overrides method testContent(Class) in which functionality of java.lang.reflect package is used.
+ *
+ *     3. The test fails if crash or hang or unexpected runtime exception occurred while processing
+ *        in testContent(Class).
+ *
+ */
+
+package org.apache.harmony.test.reliability.vm.classloading;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.GenericSignatureFormatError;
+import java.lang.reflect.MalformedParameterizedTypeException;
+import java.lang.reflect.Method;
+
+public class ClassReflectionTest extends ClassMultiTestBase{
+
+    public static void main(String[] args){
+        System.exit(new ClassReflectionTest().test(args));
+    }
+    
+    void testContent(Class cls) {
+        Constructor[] ctrs = null;
+        try{
+            ctrs = cls.getConstructors();
+        } catch (SecurityException e){
+            // Expected
+        }
+        if (ctrs != null){
+            for (int i=0; i<ctrs.length; i++){
+                Annotation[] antns = ctrs[i].getAnnotations();
+                for (int j=0; j<antns.length; j++){
+                    antns[j].toString();
+                }
+                ctrs[i].getDeclaringClass();
+                ctrs[i].getExceptionTypes();
+                try{
+                    ctrs[i].getGenericParameterTypes();
+                } catch(GenericSignatureFormatError e){
+                    // Expected
+                } catch(TypeNotPresentException e){
+                    // Expected
+                } catch(MalformedParameterizedTypeException e){
+                    // Expected
+                }
+                
+                ctrs[i].getName();
+                try{
+                    ctrs[i].getGenericExceptionTypes();
+                } catch(GenericSignatureFormatError e){
+                    // Expected
+                } catch(TypeNotPresentException e){
+                    // Expected
+                } catch(MalformedParameterizedTypeException e){
+                    // Expected
+                }
+                try{
+                    ctrs[i].getGenericParameterTypes();
+                } catch(GenericSignatureFormatError e){
+                    // Expected
+                } catch(TypeNotPresentException e){
+                    // Expected
+                } catch(MalformedParameterizedTypeException e){
+                    // Expected
+                }
+                
+                ctrs[i].getModifiers();
+                ctrs[i].getParameterAnnotations();
+                ctrs[i].getParameterTypes();
+                ctrs[i].isAccessible();
+                try{
+                    ctrs[i].getTypeParameters();
+                } catch (GenericSignatureFormatError e){
+                    // Expected
+                }
+            }
+        }
+        Field[] flds = null; 
+        try {
+            flds = cls.getFields();
+        } catch (SecurityException e){
+            // Expected
+        }
+
+        if (flds != null){
+            for (int i=0; i< flds.length; i++){
+                flds[i].getClass();
+                flds[i].getDeclaredAnnotations();
+                flds[i].getDeclaringClass();
+                try{
+                    flds[i].getGenericType();
+                } catch(GenericSignatureFormatError e){
+                    // Expected
+                } catch(TypeNotPresentException e){
+                    // Expected
+                } catch(MalformedParameterizedTypeException e){
+                    // Expected
+                }
+                    
+                flds[i].getModifiers();
+                flds[i].getName();
+                flds[i].getType();
+                flds[i].isAccessible();
+                flds[i].isEnumConstant();
+                flds[i].isSynthetic();
+                flds[i].toGenericString();
+                flds[i].toString();
+            }
+        }
+
+        Method[] mthds = null;
+        try {
+            mthds = cls.getMethods();
+        } catch (SecurityException e){
+            // Expected
+        }
+            
+        if (mthds != null){
+            for (int i=0; i<mthds.length;i++){
+                mthds[i].getExceptionTypes();
+                try{
+                    mthds[i].getGenericExceptionTypes();
+                } catch(GenericSignatureFormatError e){
+                    // Expected
+                } catch(TypeNotPresentException e){
+                    // Expected
+                } catch(MalformedParameterizedTypeException e){
+                    // Expected
+                }
+                
+                try{
+                    mthds[i].getGenericParameterTypes();
+                } catch(GenericSignatureFormatError e){
+                    // Expected
+                } catch(TypeNotPresentException e){
+                    // Expected
+                } catch(MalformedParameterizedTypeException e){
+                    // Expected
+                }
+                
+                try{
+                    mthds[i].getGenericReturnType();
+                } catch(GenericSignatureFormatError e){
+                    // Expected
+                } catch(TypeNotPresentException e){
+                    // Expected
+                } catch(MalformedParameterizedTypeException e){
+                    // Expected
+                }
+                
+                mthds[i].getModifiers();
+                mthds[i].getName();
+                mthds[i].getReturnType();
+                mthds[i].getParameterTypes();
+                try{
+                    mthds[i].getTypeParameters();
+                } catch (GenericSignatureFormatError e){
+                    // Expected
+                }
+                mthds[i].isAccessible();
+                mthds[i].isBridge();
+                mthds[i].isSynthetic();
+                mthds[i].isVarArgs();
+                mthds[i].toGenericString();
+                mthds[i].toString();
+            }
+        }
+        
+    }
+}
\ No newline at end of file

Propchange: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassReflectionTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassUnloadingTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassUnloadingTest.java?view=auto&rev=545554
==============================================================================
--- harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassUnloadingTest.java (added)
+++ harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassUnloadingTest.java Fri Jun  8 09:34:52 2007
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2007 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Aleksey Ignatenko
+ * @version $Revision: 1.0 $
+ */
+
+package org.apache.harmony.test.reliability.vm.classloading;
+
+import org.apache.harmony.test.reliability.share.Test;
+import java.lang.reflect.Method;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+/**
+ * Goal: check that class loading and unloading work without OOME or other unexpected 
+ *       problems when classes are loaded by user-defined classloader from binary file
+ *       in numerous threads in parallel. 
+ * 
+ * The test does:
+ *    1. Reads parameters, which are:
+ *       param[0] - path to classes/ directory, relatively to which auxilliary 
+ *                  class TestUnloadingClass.class can be found.
+ *       param[1] - number of classes to load via custom class loader in each thread
+ *       param[2] - number of classloading threads
+ *       
+ *    2. Starts param[2] of classloading threads. Each thread:
+ *       a. Runs param[1] iterations. On each iteration:
+ *       b. New instance of custom classloader (class CustomLoader) is created.
+ *       c. Loading of some class (represented by org.apache....TestUnloadingClass.class)
+ *          by the new instance of the loader is initiated.
+ *       d. After the class is loaded, it is checked that classes' loader (as returned
+ *          by Class.getClassLoader()) is definitely instance of the used custom loder.
+ *       e. Then, some method of the loaded class is invoked.
+ *       f. Finally, reference to the class, custom classloader which loaded the class 
+ *          are null-ed, expecting that it will allow to unload the class and custom loader.
+ */
+
+public class ClassUnloadingTest extends Test {
+    
+    static int NUMBER_OF_CLASSES_TO_LOAD = 100;
+    
+    static int NUMBER_OF_THREADS_TO_START = 100;
+
+    static String CLASS_DIR = "";
+    
+    static String pckgName = "org.apache.harmony.test.reliability.vm.classloading";
+    
+    static String testedClassName = "TestUnloadingClass";
+        
+    volatile Boolean failed = false; 
+
+    public static void main(String[] args){
+        System.exit(new ClassUnloadingTest().test(args));
+    }
+        
+    public int test(String[] args){
+    
+        parseParams(args);
+        failed = false;
+        
+        Thread thrds[] = new Thread[NUMBER_OF_THREADS_TO_START];
+        for (int i = 0; i < thrds.length; i++){
+            thrds[i] = new LoadingThread(this);
+            thrds[i].run();
+        }
+        
+        for (int i = 0; i < thrds.length; i++){
+            try {
+                thrds[i].join();
+            } catch (InterruptedException e) {
+                failed = true;
+                log.add("InterruptedException was thrown: " + e.getMessage());
+            }
+        }
+        if (failed){
+            return fail("");
+        }
+        return pass("OK");
+    }
+
+    public void parseParams(String[] params) {        
+        if (params.length >= 1) {
+            CLASS_DIR = params[0];
+        }
+        if (params.length >= 2) {
+            NUMBER_OF_CLASSES_TO_LOAD = Integer.parseInt(params[1]);
+        }
+        if (params.length >= 3) {
+            NUMBER_OF_THREADS_TO_START = Integer.parseInt(params[2]);
+        }
+    }
+    
+    String getTestedClassURI() {
+        String s = pckgName + "." + testedClassName;
+        return (s.replace('.', '/') + ".class");
+    }
+    
+}
+
+
+class LoadingThread extends Thread {
+    
+    ClassUnloadingTest base;
+    
+    LoadingThread (ClassUnloadingTest base) {
+        this.base = base;
+    }
+    
+    public void run() {
+        
+        for (int i = 0; i < base.NUMBER_OF_CLASSES_TO_LOAD; i++) {
+            CustomLoader cl = new CustomLoader(base);
+            try {
+                String className = base.pckgName + "." + base.testedClassName;
+                String classFileName = base.testedClassName + ".class";
+                Class cls = cl.loadClass(className, classFileName);
+                
+                if (cls == null){
+                    base.failed = true;
+                    continue;
+                }
+                if (cls.getClassLoader() != cl) {
+                    base.log.add("getClassLoader() returned not the custom classloader");
+                    base.failed = true;
+                    continue;
+                }
+                
+                Object obj = cls.newInstance();
+                Method meth = cls.getMethod("test", new Class[0]);
+                meth.invoke(obj, new Object[0]);
+                
+                // Force unloading
+                meth = null;
+                obj   = null;
+                cls = null;
+                cl = null;
+            } catch (Throwable t) {
+                base.log.add("Thread " + this.getId() + ": unexpected exception was thrown: " + t.getMessage());
+                base.failed = true;
+            }
+        }
+    }
+}
+
+class CustomLoader extends ClassLoader {
+    
+    ClassUnloadingTest base;
+    
+    CustomLoader(ClassUnloadingTest base) {
+        this.base = base;
+    }
+
+    protected URL findResource(String name){
+        URL ret = null;
+        try {
+            File workDir = new File(base.CLASS_DIR);
+            ret = new URL(workDir.toURI().toString() + "/" + base.getTestedClassURI());
+        } catch (MalformedURLException e) {
+            throw new Error(e);
+        }
+        return ret;
+    }
+    
+    public Class loadClass(String cname, String fname) {
+        
+        InputStream is = getResourceAsStream(fname);
+        
+        if (is == null) {
+            throw new RuntimeException("Couldn't find resource: " + fname);
+        }
+        
+        byte[] data = new byte[0];
+        byte[] piece = new byte[512];
+        int len;
+        try {
+            while ((len = is.read(piece)) != -1) {
+                byte[] tmp = data;
+                data = new byte[tmp.length + len];
+                System.arraycopy(tmp, 0, data, 0, tmp.length);
+                System.arraycopy(piece, 0, data, tmp.length, len);
+                tmp = null;
+            }
+        } catch (IOException ex) {
+            throw new Error(ex);
+        }
+        
+        try {
+            is.close();
+        } catch (IOException ex) {
+            throw new Error(ex);
+        }
+        return defineClass(cname, data, 0, data.length);
+    }
+}
+
+

Propchange: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/ClassUnloadingTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/DelegationModelTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/DelegationModelTest.java?view=auto&rev=545554
==============================================================================
--- harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/DelegationModelTest.java (added)
+++ harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/DelegationModelTest.java Fri Jun  8 09:34:52 2007
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2007 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Aleksey Ignatenko
+ * @version $Revision: 1.0 $
+ */
+
+package org.apache.harmony.test.reliability.vm.classloading;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import org.apache.harmony.test.reliability.share.Test;
+
+/*
+ * Goal: Test class loading delegation model
+ * The main idea is to make chain of User Defined classloaders where
+ * every part of chain could load only definite classes
+ * Therefore, covering all classes with appropriate classloaders we
+ * can garantee that loading class we'll not meet ClassNotFoundException
+ * 
+ *  passed parameters:
+ *  parameter[0] - number of threads to start
+ *  parameter[1] - folder where to scan class files
+ *  
+ *  The test Thread does the following:
+ *  * scans class.path for class folders with class files 
+ *  * for every folder found UserDefined classloader is created which can find classes
+ *  only in this folder, every previous classloader is parent for a next one 
+ *  * in the cycle start loading of found classes with child classloader
+ *  * No ClassNotFoundException is to be raised!   
+ *  */
+
+public class DelegationModelTest extends Test{
+    static volatile boolean failed = false;
+    static final int NUMBER_OF_THREADS = 10;
+    static int numberOfThreads = NUMBER_OF_THREADS;
+    public static String classFolder = System.getProperty("java.class.path");;
+    
+    public static void main(String[] params){
+        System.exit(new DelegationModelTest().test(params));
+    }
+    
+    public int test(String[] params){
+        parseParams(params);
+        
+        Thread[] thrds = new Thread[numberOfThreads];
+        for (int i=0; i< numberOfThreads; i++){
+            thrds[i] = new Delegation();
+            thrds[i].start();
+        }
+        
+        for (int i=0; i< numberOfThreads; i++){
+            try {
+                thrds[i].join();
+            } catch (InterruptedException e) {
+                failed = true;
+            }
+        }
+        
+        if (failed == true){
+            return fail("FAILED");
+        }
+        return pass("OK");
+    }
+    
+    public void parseParams(String[] params) {
+
+        if (params.length >= 1) {
+            numberOfThreads = Integer.parseInt(params[0]);
+        }
+        if (params.length >= 2) {
+            classFolder = params[1];
+        }
+    }
+}
+
+class Delegation extends Thread{
+    public void run (){
+        ClassLoader cCl = null;
+        HashMap<String,ArrayList<String> > classFilesFolders = new HashMap<String,ArrayList<String> >();
+        String cp = DelegationModelTest.classFolder;
+        
+        scanClassFilesFolders(cp, classFilesFolders);
+        if (classFilesFolders.size() == 0){
+            DelegationModelTest.failed = true;
+        }
+        
+        // create classloaders, each previous is parent for next one
+        Iterator it = classFilesFolders.entrySet().iterator();
+        if (it.hasNext()){
+            Map.Entry<String, ArrayList<String>> entry = (Map.Entry)it.next();
+            String key = (String)entry.getKey();
+            cCl = new CustomELoader(key, ClassLoader.getSystemClassLoader());
+        }
+        while (it.hasNext()){
+            Map.Entry<String, ArrayList<String>> entry = (Map.Entry)it.next();
+            String key = (String)entry.getKey();
+            cCl = new CustomELoader(key, cCl); 
+        }
+        
+        // trying to load something
+        Iterator itr = classFilesFolders.entrySet().iterator();
+        while (itr.hasNext()){
+            Map.Entry<String, ArrayList<String>> entry = (Map.Entry)itr.next();
+            String key = (String)entry.getKey();
+            ArrayList<String> val = (ArrayList<String>)entry.getValue();
+            for (int i = 0; i < val.size(); i++){
+                String nm = val.get(i);
+                nm = nm.replace(".class", "");
+                try{
+                    // try to load class with the top classloader in hierarchy
+                    Class c = cCl.loadClass(nm);
+                }
+                catch (ClassNotFoundException e){
+                    // garanteed to find class because all folders are covered with classloaders
+                    DelegationModelTest.failed = true;
+                }
+                // Expected: linkage and other errors
+                catch (Exception e){
+
+                }catch (Error e){
+                
+                }
+            }            
+            
+        }
+    }
+
+    //     scan class files in test folder
+    void scanClassFilesFolders(String dir, HashMap<String,ArrayList<String> > classFoldersFiles){
+        File root = new File(dir);
+        File[] files = root.listFiles();
+        if (files.length > 0){
+            ArrayList<String> filesInFolder = new ArrayList<String>();
+            classFoldersFiles.put(dir, filesInFolder);
+            for (int i=0; i< files.length; i++){
+                String name = files[i].getName();
+                if (name.endsWith(".class") && !name.contains("$")){
+                    filesInFolder.add(name);
+                }
+                if (files[i].isDirectory()){
+                    scanClassFilesFolders(files[i].getAbsolutePath(), classFoldersFiles);
+                }
+            }
+        }
+        files = null;
+        root = null;
+    }
+    
+}
+
+class CustomELoader extends ClassLoader {
+    File resourceFolder = null;
+    CustomELoader(String folder, ClassLoader parent){
+        super(parent);
+        resourceFolder = new File(folder);
+    }
+
+    private byte[] loadBinary(String className){
+        String fullPath = resourceFolder.getAbsolutePath() + "/" + className + ".class";
+        byte[] b = null;
+        try {
+            FileInputStream fis = new FileInputStream(fullPath);
+            b = new byte[fis.available()];
+            fis.read(b);
+            fis.close();
+        } catch (Exception e) {
+            return null;
+        }
+        
+        return b;
+    }
+    
+    protected Class<?> findClass(String name) throws ClassNotFoundException {
+        byte[] b = loadBinary(name);
+        if (b == null){
+            throw new ClassNotFoundException();
+        }
+        return defineClass(b, 0, b.length);
+    }
+}

Propchange: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/DelegationModelTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/MultiThreadedLoading.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/MultiThreadedLoading.java?view=auto&rev=545554
==============================================================================
--- harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/MultiThreadedLoading.java (added)
+++ harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/MultiThreadedLoading.java Fri Jun  8 09:34:52 2007
@@ -0,0 +1,257 @@
+/*
+ * Copyright 2007 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Aleksey Ignatenko
+ * @version $Revision: 1.0 $
+ */
+
+package org.apache.harmony.test.reliability.vm.classloading;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Random;
+import org.apache.harmony.test.reliability.share.Test;
+
+/*
+ * Goal: Test class loading in MT environment
+ * The main idea is to test loading of the same class in many threads
+ * All synchronizations are to be done on classloader level in VM
+ * The main members of the test are: initiating, defining classloaders, 
+ * delegation model
+ * 
+ *  passed parameters:
+ *  parameter[0] - number of threads to start
+ *  
+ *  The test Thread does the following:
+ *  * scans class.path for class folders with class files 
+ *  * for every folder found 10 UserDefined classloaders are created which can find classes
+ *  only in this folder
+ *  * start threads which load the same class with classloaders chosen by Random (but related to the folder where class is located) 
+ *  * Check that classes loaded w different classloaders are different types!   
+ *  */
+
+public class MultiThreadedLoading extends Test{
+    static volatile boolean failed = false;
+    static final int NUMBER_OF_THREADS = 30;
+    static int numberOfThreads = NUMBER_OF_THREADS;
+    static final int NUMBER_OF_CLASSLOADERS = 10;
+    static volatile Entry sharedEntry = null;
+    static ArrayList<Class> reportedClasses = new ArrayList<Class>();
+    public static String classFolder = System.getProperty("java.class.path"); 
+    
+    static void reportClass(Class c){
+        synchronized(reportedClasses){
+            reportedClasses.add(c);
+        }
+    }
+
+    public static void main(String[] params){
+        System.exit(new MultiThreadedLoading().test(params));
+    }
+    
+    public int test(String[] params){
+        parseParams(params);
+
+        ClassLoader[] cCl = null;
+        String cp = classFolder;
+        
+        HashMap<String, ArrayList<String> > classFilesFolders = new HashMap<String, ArrayList<String> >(); 
+        scanClassFilesFolders(cp, classFilesFolders);
+        if (classFilesFolders.size() == 0){
+            log.add("Did not found any golden file!");
+            return fail("FAILED");
+        }
+
+        // create classloaders, each previous is parent for next one
+        ArrayList<Entry> classFilesLoaders = new ArrayList<Entry>();
+        Iterator it = classFilesFolders.entrySet().iterator();
+        while (it.hasNext()){
+            Map.Entry<String, ArrayList<String>> entry = (Map.Entry)it.next();
+            
+            // create classloaders - number is randomized, not more than 10
+            String key = (String)entry.getKey();
+            cCl = new ClassLoader[NUMBER_OF_CLASSLOADERS];
+            for (int i=0; i< cCl.length; i++){
+                cCl[i] = new MultiClassloader(key);
+            }
+
+            // create relations between class and classloader
+            
+            ArrayList<String> classFiles = (ArrayList<String>)entry.getValue();
+            for (int i=0; i < classFiles.size(); i++){
+                classFilesLoaders.add(new Entry(classFiles.get(i), cCl));
+            }
+        }
+        
+        if (classFilesLoaders.size() == 0){
+            log.add("Unknown error happent!");
+            return fail("FAILED");
+        }
+        
+        for (int j = 0; j < classFilesLoaders.size(); j++){
+            // choose entry to process
+            reportedClasses.clear();
+            sharedEntry = classFilesLoaders.get(j);
+            
+            // start processing
+            Thread[] thrds = new Thread[numberOfThreads];
+            for (int i=0; i<thrds.length; i++){
+                thrds[i] = new ThreadLoader();
+                thrds[i].start();
+            }
+        
+            for (int i=0; i<thrds.length; i++){
+                try {
+                    thrds[i].join();
+                } catch (InterruptedException e) {
+                    return fail("FAILED3");
+                }
+            }
+            
+            // check that all loaded classes are loaded w different classloaders
+            // + try to create new instance
+            Object objToCompare = null;
+            HashSet<Class> hs = new HashSet<Class>();
+            if (reportedClasses.size() > 0){
+                for (int i=1; i<reportedClasses.size();i++){
+                    Class c = reportedClasses.get(i);
+                    boolean res = hs.add(c);
+                    Object obj = null;
+                    if (res = false)
+                    {
+                        return fail("FAILED");
+                    }
+                    try {
+                        obj = c.newInstance();
+                    } catch(Throwable e){
+                        // Expected
+                    }
+                    objToCompare = obj;
+                }
+            }
+            reportedClasses.clear();
+            hs = null;
+            
+        }        
+        
+        if (failed == true){
+            return fail("FAILED");
+        }
+        
+        return pass("OK");
+    }
+    
+    public void parseParams(String[] params) {
+
+        if (params.length >= 1) {
+            numberOfThreads = Integer.parseInt(params[0]);
+        }
+        if (params.length >= 2) {
+            classFolder = params[1];
+        }
+    }
+    
+    //     scan class files in test folder
+    void scanClassFilesFolders(String dir, HashMap<String,ArrayList<String> > classFoldersFiles){
+        File root = new File(dir);
+        File[] files = root.listFiles();
+        if (files.length > 0){
+            ArrayList<String> filesInFolder = new ArrayList<String>();
+            classFoldersFiles.put(dir, filesInFolder);
+            for (int i=0; i< files.length; i++){
+                String name = files[i].getName();
+                if (name.endsWith(".class") && !name.contains("$")){
+                    filesInFolder.add(name.replace(".class", ""));
+                }
+                if (files[i].isDirectory()){
+                    scanClassFilesFolders(files[i].getAbsolutePath(), classFoldersFiles);
+                }
+            }
+        }
+        files = null;
+        root = null;
+    }
+    
+}
+
+class ThreadLoader extends Thread{
+    public void run (){
+        Random rm  = new Random(); 
+        String className = MultiThreadedLoading.sharedEntry.className;
+        int len = MultiThreadedLoading.sharedEntry.cls.length;
+        int ind = rm.nextInt(len);
+        ClassLoader cl = MultiThreadedLoading.sharedEntry.cls[ind];
+        
+        Class c = null;
+        try{
+            c = cl.loadClass(className);
+            MultiThreadedLoading.reportClass(c);
+        }catch (LinkageError e){
+            // Expected
+        }catch(ClassNotFoundException e){
+            // Expected
+        }catch (Throwable t){
+            // Expected something else
+        }
+    }
+}
+    
+class MultiClassloader extends ClassLoader {
+    String classFileFolder = null;
+
+    MultiClassloader(String fileFolderPath){
+        classFileFolder = fileFolderPath;
+    }
+
+    private byte[] loadBinary(String className){
+        byte[] b = null;
+        try {
+            String classFileFullPath = classFileFolder + "/" + className + ".class";
+            FileInputStream fis = new FileInputStream(classFileFullPath);
+            b = new byte[fis.available()];
+            fis.read(b);
+            fis.close();
+        } catch (Exception e) {
+            return null;
+        }
+        
+        return b;
+    }
+    
+    protected Class<?> findClass(String name) throws ClassNotFoundException {
+        byte[] b = loadBinary(name);
+        if (b == null){
+            throw new ClassNotFoundException();
+        }
+        return defineClass(b, 0, b.length);
+    }
+}
+
+class Entry{
+    Entry(String nm, ClassLoader[] c_l){
+        className = nm;
+        cls = c_l;
+    }
+    public String className;
+    public ClassLoader cls[];
+}
\ No newline at end of file

Propchange: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/MultiThreadedLoading.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/TestUnloadingClass.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/TestUnloadingClass.java?view=auto&rev=545554
==============================================================================
--- harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/TestUnloadingClass.java (added)
+++ harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/TestUnloadingClass.java Fri Jun  8 09:34:52 2007
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2007 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Aleksey Ignatenko
+ * @version $Revision: 1.0 $
+ */
+
+/**
+ * The class is loaded by User Defined Classloader
+ * test function emulates some work
+**/
+
+package org.apache.harmony.test.reliability.vm.classloading;
+
+import java.math.BigInteger;
+import java.util.Random;
+
+public class TestUnloadingClass {
+    public void test(){
+        res = sum(v1,v2);
+    }
+    int v1 = 5,v2 = 7;
+    int res;
+    int sum(int p1, int p2) {
+        Random rm = new Random();
+        int res = 0;
+        for (int i = 0; i < 10; i++ ){
+            BigInteger bi = new BigInteger(10, rm); 
+            res =  p1+p2 + bi.intValue();
+        }
+        return res;
+    }
+}

Propchange: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/classloading/TestUnloadingClass.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/exceptions/ExceptionsTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/exceptions/ExceptionsTest.java?view=auto&rev=545554
==============================================================================
--- harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/exceptions/ExceptionsTest.java (added)
+++ harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/exceptions/ExceptionsTest.java Fri Jun  8 09:34:52 2007
@@ -0,0 +1,492 @@
+/*
+ * Copyright 2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.test.reliability.vm.exceptions;
+
+import org.apache.harmony.test.reliability.share.Test;
+import org.apache.harmony.test.reliability.share.Result;
+import java.util.Random;
+import java.util.Hashtable;
+
+/**
+ * Two scenarios are executed:
+ * 
+ * 1. There are 5 methods which can call each other recursively
+ * up to specified depth. Each method calls randomly selected method
+ * and then throws a particular exception which is caught within
+ * this method. When recursion depth reaches the specified value,
+ * the method doesn't call more methods and only throws and catches
+ *
+ * 2. There are 8 methods which reproduce 8 situations of try-catch-finally
+ * block execution described in JLS14.20.2. The runner method consequently
+ * calls each of these methods and checks that there are no exceptions
+ * raised when there shouldn't be any exceptions, and there are expected
+ * exceptions raised when they should be raised according to specification.
+ *
+ * Parameters: number of threads, the length of handler's chain (recursion depth)
+ */
+
+public class ExceptionsTest extends Test implements Runnable {    
+
+    private static final Random rnd = new Random();
+
+    private static int invCount;
+    private static int numThreads;
+    private int result = Result.PASS;
+
+    public static void main(String[] args) {
+        System.exit(new ExceptionsTest().test(args));
+    }
+
+    public int test(String[] args) {
+        if(args.length != 2) {
+            log.add("2 parameters expected: number of threads and chain length");
+            return error("ERROR");
+        }
+        invCount = Integer.parseInt(args[1]);
+        numThreads = Integer.parseInt(args[0]);
+        Thread[] th = new Thread[numThreads];
+
+        for (int i = 0; i < th.length; i++) {
+            th[i] = new Thread(new ExceptionsTest());
+            th[i].start();
+        }
+        for (int i = 0; i < th.length; i++) {
+            try {
+                th[i].join();
+            } catch (InterruptedException e) {
+            }
+        }
+        if (result == Result.PASS) {
+            return pass("PASSED");
+        }
+        return result;        
+    }
+
+    public void run() {
+        int res;
+        res = new Scenario1().run();
+        if (res != Result.PASS) {
+            result = res;
+            return;
+        }
+        res = new Scenario3().run();
+        if (res != Result.PASS) {
+            result = res;
+        }
+    }
+
+
+    private static class Scenario1 {
+        private int count = 0;        
+        public int run() {
+            int next = rnd.nextInt(5);
+            int res = Result.FAIL;
+            switch (next) {
+                case 0:
+                    res = methNPE();
+                    break;
+                case 1:
+                    res = methAE();
+                    break;
+                case 2:
+                    res = methAIOOBE();
+                    break;
+                case 3:
+                    res = methULE();
+                    break;
+                case 4:
+                    res = methUserException();
+                    break;
+            }            
+            return res;
+        }
+        private int methNPE() {
+            int next = -1;
+            try {
+                count++;
+                if (count == invCount) {
+                    return Result.PASS;
+                }                
+                next = rnd.nextInt(5);
+                int res = Result.FAIL;
+                switch (next) {
+                    case 0:
+                        res = methNPE();
+                        break;
+                    case 1:
+                        res = methAE();
+                        break;
+                    case 2:
+                        res = methAIOOBE();
+                        break;
+                    case 3:
+                        res = methULE();
+                        break;
+                    case 4:
+                        res = methUserException();
+                        break;
+                }
+                if (res != Result.PASS) {
+                    log.add("in methNPE(): invocation of " + next + " resulted \"FAILED\"");
+                    return res;
+                }
+
+                // Cause a NPE
+                new Hashtable().get(new Object()).toString();
+            } catch (NullPointerException e) {
+                return Result.PASS;
+            } catch (Throwable t) {
+                log.add("in methNPE(): invocation of " + next + " caused an unexpected exception " + t.getClass().getName());
+                return Result.FAIL;
+            }
+            log.add("in methNPE(): NPE wasn't thrown");
+            return Result.FAIL;
+        }
+        private int methAE() {
+            int next = -1;
+            try {
+                count++;
+                if (count == invCount) {
+                    return Result.PASS;
+                }
+                next = rnd.nextInt(5);
+                int res = Result.FAIL;
+                switch (next) {
+                    case 0:
+                        res = methNPE();
+                        break;
+                    case 1:
+                        res = methAE();
+                        break;
+                    case 2:
+                        res = methAIOOBE();
+                        break;
+                    case 3:
+                        res = methULE();
+                        break;
+                    case 4:
+                        res = methUserException();
+                        break;
+                }
+                if (res != Result.PASS) {
+                    log.add("in methAE(): invocation of " + next + " resulted \"FAILED\"");
+                    return res;
+                }
+
+                // Cause an AE
+                int i = count / (count / (2 * invCount));
+            } catch (ArithmeticException e) {
+                return Result.PASS;
+            } catch (Throwable t) {
+                log.add("in methAE(): invocation of " + next + " caused an unexpected exception " + t.getClass().getName());
+                return Result.FAIL;
+            }
+            log.add("in methAE: AE wasn't thrown");
+            return Result.FAIL;
+        }
+        private int methAIOOBE() {
+            int next = -1;
+            try {
+                count++;
+                if (count == invCount) {
+                    return Result.PASS;
+                }
+                next = rnd.nextInt(5);
+                int res = Result.FAIL;
+                switch (next) {
+                    case 0:
+                        res = methNPE();
+                        break;
+                    case 1:
+                        res = methAE();
+                        break;
+                    case 2:
+                        res = methAIOOBE();
+                        break;
+                    case 3:
+                        res = methULE();
+                        break;
+                    case 4:
+                        res = methUserException();
+                        break;
+                }
+                if (res != Result.PASS) {
+                    log.add("in methAIOOBE(): invocation of " + next + " resulted \"FAILED\"");
+                    return res;
+                }
+
+                // Cause an AIOOBE
+                int[] arr = new int[count];
+                int a = arr[invCount];
+            } catch (ArrayIndexOutOfBoundsException e) {
+                return Result.PASS;
+            } catch (Throwable t) {
+                log.add("in methAIOOBE(): invocation of " + next + " caused an unexpected exception " + t.getClass().getName());
+                return Result.FAIL;
+            }
+            log.add("in methAIOOBE: AIOOBE wasn't thrown");
+            return Result.FAIL;
+        }
+        private int methULE() {
+            int next = -1;
+            try {
+                count++;
+                if (count == invCount) {
+                    return Result.PASS;
+                }
+                next = rnd.nextInt(5);
+                int res = Result.FAIL;
+                switch (next) {
+                    case 0:
+                        res = methNPE();
+                        break;
+                    case 1:
+                        res = methAE();
+                        break;
+                    case 2:
+                        res = methAIOOBE();
+                        break;
+                    case 3:
+                        res = methULE();
+                        break;
+                    case 4:
+                        res = methUserException();
+                        break;
+                }
+                if (res != Result.PASS) {
+                    log.add("in methULE(): invocation of " + next + " resulted \"FAILED\"");
+                    return res;
+                }
+
+                // Cause an ULE
+                nativeMethod();
+            } catch (UnsatisfiedLinkError e) {
+                return Result.PASS;
+            } catch (Throwable t) {
+                log.add("in methULE(): invocation of " + next + " caused an unexpected exception " + t.getClass().getName());
+                return Result.FAIL;
+            }
+            log.add("in methULE: ULE wasn't thrown");
+            return Result.FAIL;
+        }
+        private int methUserException() {
+            int next = -1;
+            class UserException extends Exception {
+                public UserException() {
+                    super("User exception");
+                }
+            }
+            try {
+                count++;
+                if (count == invCount) {
+                    return Result.PASS;
+                }
+                next = rnd.nextInt(5);
+                int res = Result.FAIL;
+                switch (next) {
+                    case 0:
+                        res = methNPE();
+                        break;
+                    case 1:
+                        res = methAE();
+                        break;
+                    case 2:
+                        res = methAIOOBE();
+                        break;
+                    case 3:
+                        res = methULE();
+                        break;
+                    case 4:
+                        res = methUserException();
+                        break;
+                }
+                if (res != Result.PASS) {
+                    log.add("in methUserException(): invocation of " + next + " resulted \"FAILED\"");
+                    return res;
+                }
+
+                // Cause a UserException
+                throw new UserException();
+            } catch (UserException e) {
+                return Result.PASS;
+            } catch (Throwable t) {
+                log.add("in methUserException(): invocation of " + next + " caused an unexpected exception " + t.getClass().getName());
+                return Result.FAIL;
+            }
+        }
+    }
+
+    private static class Scenario3 {
+        int res = Result.FAIL;
+        public int run() {            
+            res = doTry11();            
+            if (res != Result.PASS) {
+                log.add("doTry11() failed");
+                return res;
+            }
+
+            try {
+                doTry12();
+                log.add("Expected exception was not thrown in doTry12()");
+                return Result.FAIL;
+            } catch (NullPointerException e) {
+            } catch (Throwable t) {
+                log.add("Unexpected exception thrown in doTry12()");
+                return Result.FAIL;
+            }
+
+            res = doTry2111();
+            if (res != Result.PASS) {
+                log.add("doTry2111() failed");
+                return res;
+            }
+
+            try {
+                doTry2112();
+            } catch (NullPointerException e) {
+            } catch (Throwable t) {
+                log.add("Unexpected exception thrown in doTry2112()");
+                return Result.FAIL;
+            }
+
+            try {
+                doTry2121();
+            } catch (NullPointerException e) {
+            } catch (Throwable t) {
+                log.add("Unexpected exception thrown in doTry2121()");
+                return Result.FAIL;
+            }
+
+            try {
+                doTry2122();
+            } catch (NullPointerException e) {
+            } catch (Throwable t) {
+                log.add("Unexpected exception thrown in doTry2122()");
+                return Result.FAIL;
+            }
+
+            try {
+                doTry221();
+            } catch (NullPointerException e) {
+            } catch (Throwable t) {
+                log.add("Unexpected exception thrown in doTry221()");
+                return Result.FAIL;
+            }
+
+            try {
+                doTry222();
+            } catch (NullPointerException e) {
+            } catch (Throwable t) {
+                log.add("Unexpected exception thrown in doTry222()");
+                return Result.FAIL;
+            }
+            return Result.PASS;
+        }
+
+        private int doTry11() {
+            try {
+            } catch (Throwable t) {
+                log.add("Unexpected exception caught in doTry11()");
+                return Result.FAIL;
+            } finally {
+            }
+            return Result.PASS;
+        }
+        private void doTry12() throws MyException {
+            try {
+            } catch (Throwable t) {
+                log.add("Unexpected exception caught in doTry12()");
+                throw new MyException("Unexpected exception caught");
+            } finally {
+                new Hashtable().get(new Object()).toString();
+            }
+        }
+        private int doTry2111() {
+            try {
+                throw new MyException("MyException thrown");
+            } catch (MyException e) {
+            } catch (Throwable t) {
+                log.add("Unexpected exception caught in doTry2111()");
+                return Result.FAIL;
+            } finally {
+            }
+            return Result.PASS;
+        }
+        private void doTry2112() throws MyException {
+            try {
+                throw new MyException("MyException thrown");
+            } catch (MyException e) {
+            } catch (Throwable t) {
+                log.add("Unexpected exception caught in doTry2112()");
+                throw new MyException("Unexpected exception caught");
+            } finally {
+                new Hashtable().get(new Object()).toString();
+            }
+        }
+        private void doTry2121() throws MyException {
+            try {
+                throw new MyException("MyException thrown");
+            } catch (MyException e) {
+                new Hashtable().get(new Object()).toString();
+            } catch (Throwable t) {
+                log.add("Unexpected exception caught in doTry2121()");
+                throw new MyException("Unexpected exception caught");
+            } finally {                
+            }
+        }
+        private void doTry2122() throws MyException {
+            try {
+                throw new MyException("MyException thrown");
+            } catch (MyException e) {
+                throw new MyException("MyException caught");
+            } catch (Throwable t) {
+                log.add("Unexpected exception caught in doTry2122()");
+                throw new MyException("Unexpected exception caught");
+            } finally {
+                new Hashtable().get(new Object()).toString();
+            }
+        }
+        private void doTry221() throws MyException {
+            try {
+                new Hashtable().get(new Object()).toString();
+            } catch (ClassCircularityError e) {
+                log.add("Unexpected exception caught in doTry221()");
+                throw new MyException("Unexpected OOME caught");
+            } finally {              
+            }
+        }
+        private void doTry222() throws MyException {
+            try {
+                throw new MyException("MyException thrown");
+            } catch (NullPointerException e) {
+                log.add("Unexpected exception caught in doTry222()");
+                throw new MyException("Unexpected NPE caught");
+            } finally {
+                new Hashtable().get(new Object()).toString();
+            }
+        }
+    }
+
+    private static native void nativeMethod();
+
+    private static class MyException extends Exception {
+        public MyException(String msg) {
+            super(msg);
+        }
+    }
+}

Propchange: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/exceptions/ExceptionsTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/finalization/ArrayElemFinalizationTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/finalization/ArrayElemFinalizationTest.java?view=auto&rev=545554
==============================================================================
--- harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/finalization/ArrayElemFinalizationTest.java (added)
+++ harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/finalization/ArrayElemFinalizationTest.java Fri Jun  8 09:34:52 2007
@@ -0,0 +1,523 @@
+/*
+ * Copyright 2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Tatyana V. Doubtsova
+ * @version $Revision: 1.1 $
+ */
+
+package org.apache.harmony.test.reliability.vm.finalization;
+
+import org.apache.harmony.test.reliability.share.Test;
+import java.util.Random;
+
+/*
+ * Goal: check that no memory leaks occur and finalization works with objects of various types 
+ *       created and then lost for GC-ing being elemnents of static or instance arrays. 
+ *
+ * The test does:
+ *
+ *   1. For each of the types: Object, Thread, Classloader
+ *
+ *      a. Initializes instance and static arrays of the given type.
+ *
+ *      b. For each of mode: synchronized array, synchronized array's element
+ * 
+ *        * Runs N_OF_THREADS Threads. Each Thread randomly chooses range of array indexes
+ *          to substitute objects and substitutes the objects (the elements of the array), 
+ *          either locking the whole array or just element being substituted.
+ * 
+ *        * Runs Runtime.runFinalization() and System.gc().
+ *
+ *        * The test is not to crash, hang or throw OOME
+ */
+
+public class ArrayElemFinalizationTest extends Test {
+
+    // These are tested object arrays holders:
+ 
+    static Object[] static_object_array = null;
+    Object[] instance_object_array = null;
+
+    static Object[] static_thread_array = null;
+    Object[] instance_thread_array = null;
+
+    static Object[] static_classloader_array = null;
+    Object[] instance_classloader_array = null;
+
+
+    static final int ARRAY_SIZE = 1000;
+
+    static final int BYTE_ARRAY_SIZE = 1000;
+
+    static final int N_OF_THREADS = 100;
+
+    static final int SYNCED_OBJECT = 1;
+    static final int SYNCED_ARRAY = 2;
+
+
+    public static void main(String[] args) {
+        System.exit(new ArrayElemFinalizationTest().test(args));
+    }
+
+
+    public int test(String[] params) {
+
+        boolean passed = true;
+        boolean status = false;
+        Object[][] arr;
+
+        parseParams(params);
+
+        //------------------ CASE 1:
+
+        // Initialize 2 arrays (static anf instance) of Object objects:
+
+        arr = initializeObjectArrays();
+
+        // Run threads which lock Objects of arrays, substitute objects 
+
+        status = (new TestObjectFinalization(this)).finalizeObjectsInArray(arr, SYNCED_OBJECT);
+        passed &= status;
+
+        //log.add("Finalization of Objects in array, Objects are synchronized. Passed? " + status);
+
+        //------------------ CASE 2:
+
+        // Run threads which lock arrays of Objects, substitute objects 
+
+        status = (new TestObjectFinalization(this)).finalizeObjectsInArray(arr, SYNCED_ARRAY);
+        passed &= status;
+
+        //log.add("Finalization of Objects, array is synchronized. Passed? " + status);
+
+
+        //------------------ CASE 3:
+
+        // Initialize 2 arrays (static anf instance) of Thread objects:
+
+        arr = initializeThreadArrays();
+
+        // Run threads which lock Thread objects of arrays, substitute threads in array 
+
+        status = (new TestThreadObjectFinalization(this)).finalizeObjectsInArray(arr, SYNCED_OBJECT);
+        passed &= status;
+
+        //log.add("Finalization of Thread objects in array, Thread objects are synchronized. Passed? " + status);
+
+
+        //------------------ CASE 4:
+
+        // Run threads which lock arrays of Threads, substitute Thread objects 
+
+        status = (new TestThreadObjectFinalization(this)).finalizeObjectsInArray(arr, SYNCED_ARRAY);
+        passed &= status;
+
+        //log.add("Finalization of Thread objects, array is synchronized. Passed? " + status);
+
+
+        //------------------ CASE 5:
+
+        // Initialize 2 arrays (static anf instance) of Classloader objects:
+
+        arr = initializeClArrays();
+
+        // Run threads which lock Classloader objects of arrays, substitute classloaders in array 
+
+        status = (new TestClassLoaderObjectFinalization(this)).finalizeObjectsInArray(arr, SYNCED_OBJECT);
+        passed &= status;
+
+        //log.add("Finalization of classloader objects in array, classloader objects are synchronized. Passed? " + status);
+
+
+        //------------------ CASE 6:
+
+        // Run threads which lock arrays of Classloaders objects, substitute Classloader objects
+
+        status = (new TestClassLoaderObjectFinalization(this)).finalizeObjectsInArray(arr, SYNCED_ARRAY);
+        passed &= status;
+
+        //log.add("Finalization of Classloader objects, array is synchronized. Passed? " + status);
+
+        if (!passed) {
+            return fail("Failed");
+        }
+
+        return pass("OK");
+    }
+
+
+    Object[][] initializeObjectArrays() {
+
+        // The method initializes instance and static arrays of Objects
+
+        static_object_array = new Object[ARRAY_SIZE];
+        instance_object_array = new Object[ARRAY_SIZE];
+
+        Object[][] arr = new Object[2][];
+
+        arr[0] = static_object_array;
+        arr[1] = instance_object_array;
+
+        for (int i = 0; i < arr.length; ++i) {
+            for (int j = 0; j < arr[i].length; ++j) {
+                arr[i][j] = new FinalizableObject();  // simple Object
+            }
+        }
+
+        return arr;
+    }
+
+    Object[][] initializeThreadArrays() {
+
+        // The method initializes instance and static arrays of Thread objects
+
+        static_thread_array = new Object[ARRAY_SIZE];
+        instance_thread_array = new Object[ARRAY_SIZE];
+
+        Object[][] arr = new Object[2][];
+
+        arr[0] = static_thread_array;
+        arr[1] = instance_thread_array;
+
+        for (int i = 0; i < arr.length; ++i) {
+            for (int j = 0; j < arr[i].length; ++j) {
+                arr[i][j] = new FinalizableThreadObject(); // Thread object
+            }
+        }
+        return arr;
+    }
+
+
+    Object[][] initializeClArrays() {
+
+        // The method initializes instance and static arrays of Classloader objects
+
+        static_classloader_array = new Object[ARRAY_SIZE];
+        instance_classloader_array = new Object[ARRAY_SIZE];
+
+        Object[][] arr = new Object[2][];
+
+        arr[0] = static_classloader_array;
+        arr[1] = instance_classloader_array;
+
+        for (int i = 0; i < arr.length; ++i) {
+            for (int j = 0; j < arr[i].length; ++j) {
+                arr[i][j] = new FinalizableClassloaderObject(); // Classloader object
+            }
+        }
+        return arr;
+    }
+
+
+    public void parseParams(String[] params) {
+
+    }
+
+}
+
+
+class TestObjectFinalization {
+
+    // This is the base class for the other 2 classes (which work with 
+    // arrays of Thread and Classloader objects).
+
+    ArrayElemFinalizationTest base;
+
+    public TestObjectFinalization(ArrayElemFinalizationTest base){
+
+        // Why we need the base? - just to use "log" to print output to.
+
+        this.base = base;
+    }
+
+    boolean finalizeObjectsInArray(Object[][] arr, int type) {
+
+        // The method just creates N_OF_THREADS Threads each substituting 
+        // objects in the "arr" arrays. arr[0] is instance array, arr[1] is
+        // static array.
+
+        Thread[] t = new Thread[ArrayElemFinalizationTest.N_OF_THREADS];
+
+        for (int j = 0; j < arr.length; ++j) {
+
+            for (int i = 0; i < t.length ; ++i) {
+                t[i] = createThread(arr[j], type);
+                t[i].start();
+            }
+
+            for (int i = 0; i < t.length ; ++i) {
+                try {
+                    t[i].join();          
+                } catch (InterruptedException ie) {
+                    ArrayElemFinalizationTest.log.add("Thread " + t[i] + " was interrupted.");
+                    return false;
+                }
+            }
+
+            Runtime.getRuntime().runFinalization();
+            System.gc();
+        }
+
+        return true;
+    }
+
+
+    Thread createThread(Object[] arr, int type) {
+
+        // The method is overriden in 2 subclasses which use own Threads
+        // for substitution objects in arrays.
+
+        return new TSubstSyncedObectInArray(arr, type);
+    }
+
+    long get_num_of_created_objects() {
+        return FinalizableObject.num_of_created_objects;
+    }
+
+    long get_num_of_finalized_objects() {
+        return FinalizableObject.num_of_finalized_objects;
+    }
+
+    void null_num_of_finalized_objects() {
+        FinalizableObject.num_of_finalized_objects = 0;
+    }
+
+    void null_num_of_created_objects() {
+        FinalizableObject.num_of_created_objects = 0;
+    }
+}
+
+
+class TestThreadObjectFinalization extends TestObjectFinalization {
+
+    public TestThreadObjectFinalization(ArrayElemFinalizationTest base){
+        super(base);
+    }
+
+    Thread createThread(Object[] arr, int type) {
+        return new TSubstSyncedThrObectInArray(arr, type);
+    }
+
+    long get_num_of_created_objects() {
+        return FinalizableThreadObject.num_of_created_objects;
+    }
+
+    long get_num_of_finalized_objects() {
+        return FinalizableThreadObject.num_of_finalized_objects;
+    }
+
+    void null_num_of_finalized_objects() {
+        FinalizableThreadObject.num_of_finalized_objects = 0;
+    }
+
+    void null_num_of_created_objects() {
+        FinalizableThreadObject.num_of_created_objects = 0;
+    }
+}
+
+
+class TestClassLoaderObjectFinalization extends TestObjectFinalization {
+
+    public TestClassLoaderObjectFinalization(ArrayElemFinalizationTest base){
+        super(base);
+    }
+
+    Thread createThread(Object[] arr, int type) {
+        return new TSubstSyncedClObectInArray(arr, type);
+    }
+
+    long get_num_of_created_objects() {
+        return FinalizableClassloaderObject.num_of_created_objects;
+    }
+
+    long get_num_of_finalized_objects() {
+        return FinalizableClassloaderObject.num_of_finalized_objects;
+    }
+
+    void null_num_of_finalized_objects() {
+        FinalizableClassloaderObject.num_of_finalized_objects = 0;
+    }
+
+    void null_num_of_created_objects() {
+        FinalizableClassloaderObject.num_of_created_objects = 0;
+    }
+}
+
+
+class TSubstSyncedObectInArray extends Thread {
+
+    static Random r = new Random(10);
+    int type = ArrayElemFinalizationTest.SYNCED_OBJECT;
+
+    Object[] obj_array;
+
+    static final int SLEEP_TIMEOUT = 20;
+
+    public TSubstSyncedObectInArray(Object[] obj_array, int type) {
+        this.obj_array = obj_array;
+        this.type = type;
+    }
+
+    public void run() {
+
+        // When thread starts it sleeps for some arbitrary time:
+
+        try {
+            Thread.sleep(r.nextInt(SLEEP_TIMEOUT));
+        } catch (InterruptedException ie){
+        }
+
+        // Then, we select index from which substitute objects in array
+        // and index up to which substitute objects:
+
+        int i = r.nextInt(obj_array.length);
+        int j = r.nextInt(obj_array.length);
+
+        int from = i < j ? i : j;
+        int to = i >= j ? i : j;
+
+        // Finally, substitute objects either locking the whole array or locking 
+        // just beings substituted object.
+
+        if (type == ArrayElemFinalizationTest.SYNCED_OBJECT) {
+
+            for (int x = from; x < to; ++x) {
+                synchronized(obj_array[x]){
+                    obj_array[x] = createObject();
+                }
+            }
+
+        } else if (type == ArrayElemFinalizationTest.SYNCED_ARRAY) {
+
+            synchronized(obj_array){
+                for (int x = from; x < to; ++x) {
+                    obj_array[x] = createObject();
+                }
+            }
+        }
+
+        // System.out.println(" " + from + ", " + to);
+    }
+
+
+    Object createObject() {
+        return new FinalizableObject();
+    }
+}
+
+
+class TSubstSyncedThrObectInArray extends TSubstSyncedObectInArray {
+
+    public TSubstSyncedThrObectInArray(Object[] obj_array, int type) {
+        super(obj_array, type);
+    }
+
+    Object createObject() {
+        return new FinalizableThreadObject();
+    }
+
+}
+
+
+class TSubstSyncedClObectInArray extends TSubstSyncedObectInArray {
+ 
+    public TSubstSyncedClObectInArray(Object[] obj_array, int type) {
+        super(obj_array, type);
+    }
+
+    Object createObject() {
+        return new FinalizableClassloaderObject();
+    }
+
+}
+
+
+class FinalizableObject {
+
+    volatile public static long num_of_created_objects = 0;
+
+    volatile public static long num_of_finalized_objects = 0;
+
+    byte[] b;
+
+    public FinalizableObject() {
+        num_of_created_objects++;
+        b = new byte[ArrayElemFinalizationTest.BYTE_ARRAY_SIZE];
+    }
+
+    protected void finalize() {
+        synchronized(this) { // just in case
+            num_of_finalized_objects++;
+        }
+    }
+
+}
+
+
+class FinalizableThreadObject extends Thread {
+
+    volatile public static long num_of_created_objects = 0;
+
+    volatile public static long num_of_finalized_objects = 0;
+
+    byte[] b;
+
+    public FinalizableThreadObject() {
+        num_of_created_objects++;
+        b = new byte[ArrayElemFinalizationTest.BYTE_ARRAY_SIZE];
+    }
+
+    protected void finalize() {
+        synchronized(this) { // just in case
+            num_of_finalized_objects++;
+        }
+    }
+
+    public void run() {
+    }
+    
+}
+
+
+class FinalizableClassloaderObject extends ClassLoader {
+
+    volatile public static long num_of_created_objects = 0;
+
+    volatile public static long num_of_finalized_objects = 0;
+
+    byte[] b;
+
+    public FinalizableClassloaderObject() {
+        num_of_created_objects++;
+        b = new byte[ArrayElemFinalizationTest.BYTE_ARRAY_SIZE];
+    }
+
+    protected void finalize() {
+        synchronized(this) { // just in case
+            num_of_finalized_objects++;
+        }
+    }
+
+
+}
+
+
+
+
+
+

Propchange: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/vm/finalization/ArrayElemFinalizationTest.java
------------------------------------------------------------------------------
    svn:eol-style = native