From 64bc185e5502ed93d84f3106038b55cb5b7e6dd9 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Fri, 3 Jul 2009 16:56:29 +0400 Subject: [PATCH] 6329581: RFE: LTP: java.beans.XMLEncoder does not manage ClassLoader Reviewed-by: rupashka, alexp --- jdk/src/share/classes/java/beans/Encoder.java | 11 ++- .../share/classes/java/beans/MetaData.java | 6 +- .../share/classes/java/beans/Statement.java | 3 +- .../beans/XMLEncoder/6329581/Test6329581.java | 75 +++++++++++++++++++ 4 files changed, 86 insertions(+), 9 deletions(-) create mode 100644 jdk/test/java/beans/XMLEncoder/6329581/Test6329581.java diff --git a/jdk/src/share/classes/java/beans/Encoder.java b/jdk/src/share/classes/java/beans/Encoder.java index 92e3d695bcb..e7f63397340 100644 --- a/jdk/src/share/classes/java/beans/Encoder.java +++ b/jdk/src/share/classes/java/beans/Encoder.java @@ -246,12 +246,11 @@ public class Encoder { for (int i = 0; i < oldArgs.length; i++) { newArgs[i] = writeObject1(oldArgs[i]); } - if (oldExp.getClass() == Statement.class) { - return new Statement(newTarget, oldExp.getMethodName(), newArgs); - } - else { - return new Expression(newTarget, oldExp.getMethodName(), newArgs); - } + Statement newExp = Statement.class.equals(oldExp.getClass()) + ? new Statement(newTarget, oldExp.getMethodName(), newArgs) + : new Expression(newTarget, oldExp.getMethodName(), newArgs); + newExp.loader = oldExp.loader; + return newExp; } /** diff --git a/jdk/src/share/classes/java/beans/MetaData.java b/jdk/src/share/classes/java/beans/MetaData.java index f4d307090a5..96607db806f 100644 --- a/jdk/src/share/classes/java/beans/MetaData.java +++ b/jdk/src/share/classes/java/beans/MetaData.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -219,7 +219,9 @@ class java_lang_Class_PersistenceDelegate extends PersistenceDelegate { return new Expression(oldInstance, String.class, "getClass", new Object[]{}); } else { - return new Expression(oldInstance, Class.class, "forName", new Object[]{c.getName()}); + Expression newInstance = new Expression(oldInstance, Class.class, "forName", new Object[] { c.getName() }); + newInstance.loader = c.getClassLoader(); + return newInstance; } } } diff --git a/jdk/src/share/classes/java/beans/Statement.java b/jdk/src/share/classes/java/beans/Statement.java index 7bf2fccda56..6169f92742f 100644 --- a/jdk/src/share/classes/java/beans/Statement.java +++ b/jdk/src/share/classes/java/beans/Statement.java @@ -66,6 +66,7 @@ public class Statement { Object target; String methodName; Object[] arguments; + ClassLoader loader; /** * Creates a new Statement object with a target, @@ -157,7 +158,7 @@ public class Statement { // of core from a class inside core. Special // case this method. if (target == Class.class && methodName.equals("forName")) { - return ClassFinder.resolveClass((String)arguments[0]); + return ClassFinder.resolveClass((String)arguments[0], this.loader); } Class[] argClasses = new Class[arguments.length]; for(int i = 0; i < arguments.length; i++) { diff --git a/jdk/test/java/beans/XMLEncoder/6329581/Test6329581.java b/jdk/test/java/beans/XMLEncoder/6329581/Test6329581.java new file mode 100644 index 00000000000..c307dab1267 --- /dev/null +++ b/jdk/test/java/beans/XMLEncoder/6329581/Test6329581.java @@ -0,0 +1,75 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6329581 + * @summary Tests encoding of a class with custom ClassLoader + * @author Sergey Malenkov + */ + +import java.beans.ExceptionListener; +import java.beans.XMLDecoder; +import java.beans.XMLEncoder; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.net.URL; +import java.net.URLClassLoader; + +public class Test6329581 implements ExceptionListener { + + public static void main(String[] args) throws Exception { + ExceptionListener listener = new Test6329581(); + // write bean to byte array + ByteArrayOutputStream out = new ByteArrayOutputStream(); + XMLEncoder encoder = new XMLEncoder(out); + encoder.setExceptionListener(listener); + encoder.writeObject(getClassLoader("beans.jar").loadClass("test.Bean").newInstance()); + encoder.close(); + // read bean from byte array + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + XMLDecoder decoder = new XMLDecoder(in, null, listener, getClassLoader("beans.jar")); + Object object = decoder.readObject(); + decoder.close(); + + if (!object.getClass().getClassLoader().getClass().equals(URLClassLoader.class)) { + throw new Error("bean is loaded with unexpected class loader"); + } + } + + private static ClassLoader getClassLoader(String name) throws Exception { + StringBuilder sb = new StringBuilder(256); + sb.append("file:"); + sb.append(System.getProperty("test.src", ".")); + sb.append(File.separatorChar); + sb.append(name); + + URL[] url = { new URL(sb.toString()) }; + return new URLClassLoader(url); + } + + public void exceptionThrown(Exception exception) { + throw new Error("unexpected exception", exception); + } +}