0N/A/*
3261N/A * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
0N/A * published by the Free Software Foundation.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/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.
0N/A */
0N/A/*
0N/A @test 1.3 99/02/15
0N/A @summary test Resource Bundle for bug 4179766
0N/A @build Bug4179766Class Bug4179766Resource Bug4179766Getter
0N/A @run main TestBug4179766
0N/A @bug 4179766
0N/A*/
0N/A/*
0N/A *
0N/A *
0N/A * (C) Copyright IBM Corp. 1996 - 1999 - All Rights Reserved
0N/A *
0N/A * Portions copyright (c) 2007 Sun Microsystems, Inc.
0N/A * All Rights Reserved.
0N/A *
0N/A * The original version of this source code and documentation
0N/A * is copyrighted and owned by Taligent, Inc., a wholly-owned
0N/A * subsidiary of IBM. These materials are provided under terms
0N/A * of a License Agreement between Taligent and Sun. This technology
0N/A * is protected by multiple US and International patents.
0N/A *
0N/A * This notice and attribution to Taligent may not be removed.
0N/A * Taligent is a registered trademark of Taligent, Inc.
0N/A *
0N/A * Permission to use, copy, modify, and distribute this software
0N/A * and its documentation for NON-COMMERCIAL purposes and without
0N/A * fee is hereby granted provided that this copyright notice
0N/A * appears in all copies. Please refer to the file "copyright.html"
0N/A * for further important copyright and licensing information.
0N/A *
0N/A * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
0N/A * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
0N/A * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
0N/A * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
0N/A * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
0N/A * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
0N/A *
0N/A */
0N/A
0N/Aimport java.util.Hashtable;
0N/Aimport java.util.ResourceBundle;
0N/Aimport java.util.MissingResourceException;
0N/Aimport java.util.Hashtable;
0N/Aimport java.io.File;
0N/Aimport java.io.FileInputStream;
0N/A
0N/A/**
0N/A * This class tests the behavior of the ResourceBundle cache with
0N/A * respect to ClassLoaders. The same resource loaded by different
0N/A * loaders should be cached as separate objects, one for each loader.
0N/A * In order to test this behavior, this test constructs a custom
0N/A * class loader to load its resources. It does not delegate resource
0N/A * loading to the system loader to load the class files, but loads
0N/A * them from the current directory instead. This is so that the
0N/A * defining class loader for the resources is different. If it
0N/A * delegated to the system loader to load the resources, the
0N/A * defining ClassLoader would be the same even though the initiating
0N/A * loader differered, and the resource would only be cached once.
0N/A */
0N/Apublic class TestBug4179766 extends RBTestFmwk {
0N/A //hash code used by class loaders when sameHash is true
0N/A private static final int SAME_HASH_CODE = 0;
0N/A //the next unique hash code
0N/A private static int nextHashCode = SAME_HASH_CODE + 1;
0N/A //suffix on class files
0N/A private static final String CLASS_SUFFIX = ".class";
0N/A
0N/A //generate a unique hashcode for a class loader
0N/A private static synchronized int getNextHashCode() {
0N/A return nextHashCode++;
0N/A }
0N/A
0N/A public static void main(String[] args) throws Exception {
0N/A //static links so all needed classes get compiled
0N/A Object o1 = new Bug4179766Class();
0N/A Object o2 = new Bug4179766Resource();
0N/A new TestBug4179766().run(args);
0N/A }
0N/A
0N/A /**
0N/A * Ensure the resource cache is working correctly for a single
0N/A * resource from a single loader. If we get the same resource
0N/A * from the same loader twice, we should get the same resource.
0N/A */
0N/A public void testCache() throws Exception {
0N/A Loader loader = new Loader(false);
0N/A ResourceBundle b1 = getResourceBundle(loader, "Bug4179766Resource");
0N/A if (b1 == null) {
0N/A errln("Resource not found: Bug4179766Resource");
0N/A }
0N/A ResourceBundle b2 = getResourceBundle(loader, "Bug4179766Resource");
0N/A if (b2 == null) {
0N/A errln("Resource not found: Bug4179766Resource");
0N/A }
0N/A printIDInfo("[bundle1]",b1);
0N/A printIDInfo("[bundle2]",b2);
0N/A if (b1 != b2) {
0N/A errln("Different objects returned by same ClassLoader");
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Test that loaders with the same hash key still
0N/A * cache resources seperately
0N/A */
0N/A public void testSameHash() throws Exception {
0N/A doTest(true);
0N/A }
0N/A
0N/A /**
0N/A * Test that loaders with different hash keys
0N/A * cache resources seperately
0N/A */
0N/A public void testDifferentHash() throws Exception {
0N/A doTest(false);
0N/A }
0N/A
0N/A /**
0N/A * Ensure that cached resources for different ClassLoaders
0N/A * are cached seperately
0N/A */
0N/A private void doTest(boolean sameHash) throws Exception {
0N/A ResourceBundle b1 = getResourceBundle(new Loader(sameHash), "Bug4179766Resource");
0N/A if (b1 == null) {
0N/A errln("Resource not found: Bug4179766Resource");
0N/A }
0N/A ResourceBundle b2 = getResourceBundle(new Loader(sameHash), "Bug4179766Resource");
0N/A if (b2 == null) {
0N/A errln("Resource not found: Bug4179766Resource");
0N/A }
0N/A printIDInfo("[bundle1]",b1);
0N/A printIDInfo("[bundle2]",b2);
0N/A if (b1 == b2) {
0N/A errln("Same object returned by different ClassLoaders");
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Get a resource using a specified class loader to load the resource
0N/A */
0N/A private ResourceBundle getResourceBundle(Loader loader, String name) throws Exception {
0N/A try {
0N/A Class c = loader.loadClass("Bug4179766Class");
0N/A Bug4179766Getter test = (Bug4179766Getter)c.newInstance();
0N/A return test.getResourceBundle(name);
0N/A } catch (ClassNotFoundException e) {
0N/A errln("Class not found by custom class loader: "+name);
0N/A throw e;
0N/A } catch (InstantiationException e) {
0N/A errln("Error instantiating: "+name);
0N/A throw e;
0N/A } catch (IllegalAccessException e) {
0N/A errln("IllegalAccessException instantiating: "+name);
0N/A throw e;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Print information about an object
0N/A * [message][object's identity][object's class][object's loader][loaders hash][loaders identity]
0N/A */
0N/A private void printIDInfo(String message, Object o) {
0N/A if (o == null) {
0N/A return;
0N/A }
0N/A Class c = o.getClass();
0N/A ClassLoader l = c.getClassLoader();
0N/A int hash = -1;
0N/A if (l != null) {
0N/A hash = l.hashCode();
0N/A }
0N/A logln(message + System.identityHashCode(o) + " Class: " + c
0N/A + " ClassLoader: " + l + " loaderHash: " + hash
0N/A + " loaderPrimHash: " + System.identityHashCode(l));
0N/A }
0N/A
0N/A /**
0N/A * A simple class loader that loads classes from the current
0N/A * working directory. The hash code of the loader can be
0N/A * set to be either the loaders identity or 0, allowing several
0N/A * loaders to have the same hashCode value.
0N/A */
0N/A public class Loader extends ClassLoader {
0N/A private int thisHashCode;
0N/A
0N/A /**
0N/A * Create a new loader
0N/A */
0N/A public Loader(boolean sameHash) {
2484N/A super(Loader.class.getClassLoader());
0N/A if (sameHash) {
0N/A thisHashCode = SAME_HASH_CODE;
0N/A } else {
0N/A thisHashCode = getNextHashCode();
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Return the hash code for this loader.
0N/A */
0N/A public int hashCode() {
0N/A return thisHashCode;
0N/A }
0N/A
0N/A /**
0N/A * Get the data from the class file for the specified class. If
0N/A * the file can't be found, or the class is not one of the
0N/A * special ones listed below, return null.
0N/A * Bug4179766Class
0N/A * Bug4179766Resource
0N/A */
0N/A private byte[] getClassData(String className) {
0N/A boolean shouldLoad = className.equals("Bug4179766Class");
0N/A shouldLoad = shouldLoad || className.equals("Bug4179766Resource");
0N/A
0N/A if (shouldLoad) {
0N/A try {
0N/A File file = new File(System.getProperty("test.classes", "."), className+CLASS_SUFFIX);
0N/A FileInputStream fi = new FileInputStream(file);
0N/A byte[] result = new byte[fi.available()];
0N/A fi.read(result);
0N/A return result;
0N/A } catch (Exception e) {
0N/A return null;
0N/A }
0N/A } else {
0N/A return null;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Load a class. Files we can load take preference over ones the system
0N/A * can load.
0N/A */
0N/A public synchronized Class loadClass(String className, boolean resolveIt)
0N/A throws ClassNotFoundException {
0N/A
0N/A Class result = findLoadedClass(className);
0N/A if (result != null) {
0N/A printInfo(" ***Returning cached class: "+className, result);
0N/A return result;
0N/A }
0N/A
0N/A byte[] classData = getClassData(className);
0N/A if (classData == null) {
0N/A //we don't have a local copy of this one
0N/A return loadFromSystem(className);
0N/A }
0N/A
0N/A result = defineClass(classData, 0, classData.length);
0N/A if (result == null) {
0N/A //there was an error defining the class
0N/A return loadFromSystem(className);
0N/A }
0N/A
0N/A if (resolveIt) {
0N/A resolveClass(result);
0N/A }
0N/A
0N/A printInfo(" ***Loaded local class: "+className, result);
0N/A return result;
0N/A }
0N/A
0N/A /**
0N/A * Delegate loading to the system loader
0N/A */
0N/A private Class loadFromSystem(String className) throws ClassNotFoundException {
0N/A try {
2484N/A Class result = getParent().loadClass(className);
0N/A printInfo(" ***Returning system class: "+className, result);
0N/A return result;
0N/A } catch (ClassNotFoundException e) {
0N/A printInfo(" ***Class not found: "+className, null);
0N/A throw e;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Print information about a class that was loaded
0N/A * [loader identity][message][class identity]
0N/A */
0N/A private void printInfo(String message, Class c) {
0N/A if (c != null) {
0N/A logln(""+System.identityHashCode(this)+" "+message+" "+System.identityHashCode(c));
0N/A } else {
0N/A logln(""+System.identityHashCode(this)+" "+message);
0N/A }
0N/A }
0N/A }
0N/A}