/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4898478
* @summary Tests client default class loader used before JSR 160 loader
* @author Eamonn McManus
* @run clean MethodResultTest
* @run build MethodResultTest
* @run main MethodResultTest
*/
import javax.management.*;
/*
This test checks that the class loader that is used to deserialize
the return values from remote MBean server operations is indeed the
one specified by the user. The only MBean server operations that
matter are those than can return an arbitrary Object. We don't
care about getMBeanCount or queryNames or whatever because their
return values are always of classes loaded by the bootstrap loader.
But for the operations getAttribute, getAttributes, setAttributes,
and invoke, the return value can include any Java class. This is
also true of getMBeanInfo, since the return value can be an exotic
subclass of MBeanInfo, or a ModelMBeanInfo that refers to an
arbitrary Object. The JMX Remote API spec requires that these
return values be deserialized using the class loader supplied by
the user (default is context class loader). In particular it must
not be deserialized using the system class loader, which it will be
with RMI unless special precautions are taken.
*/
public class MethodResultTest {
if (!(testClassLoader instanceof URLClassLoader)) {
"URLClassLoader: " + testClassLoader);
}
new String[] {exoticClassName,
ExoticMBeanInfo.class.getName(),
ExoticException.class.getName()});
if (cl == exoticClass) {
"same class as test class loader");
}
boolean ok = true;
try {
} catch (Exception e) {
ok = false;
}
}
if (ok)
else {
}
}
throws Exception {
try {
mbs);
} catch (MalformedURLException e) {
"; ignoring");
return true;
}
try {
try {
throw noException("getAttribute");
} catch (Exception e) {
}
try {
throw noException("setAttribute");
} catch (Exception e) {
}
try {
throw noException("invoke");
} catch (Exception e) {
invokeException = e;
}
} finally {
}
boolean ok = true;
ExoticException.class);
ExoticException.class);
ExoticException.class);
if (ok)
return ok;
}
return new IllegalStateException(msg);
}
}
Class wrongClass) {
}
":");
"classloader");
return false;
}
" has wrong class name: " + className);
return false;
}
" has same class name but is not same class");
return true;
}
Class wrongClass) {
if (!(exception instanceof MBeanException)) {
MBeanException.class.getName() +
":");
return false;
}
}
" does not have size 1: " + attrs);
return false;
}
"attribute: " + attr);
return false;
}
return true;
}
public static class Thing
extends StandardMBean implements ThingMBean {
super(ThingMBean.class);
}
if (exception)
throw new ExoticException();
return new Exotic();
}
if (exception)
throw new ExoticException();
}
if (exception)
throw new ExoticException();
return new Exotic();
}
super.cacheMBeanInfo(mbi);
}
public void setException(boolean x) {
this.exception = x;
}
private boolean exception;
}
public static interface ThingMBean {
public void setException(boolean x);
}
super(mbi.getClassName(),
mbi.getAttributes(),
mbi.getOperations(),
mbi.getNotifications());
}
}
String[] shadowClassNames) {
this.realLoader = realLoader;
}
else
}
}
}