blob: 5befd094bd3aed484e8ed8b47c765bb9d05bb12c [file] [log] [blame]
/*
* Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.tests.performance.java;
import java.lang.reflect.*;
import java.security.AccessController;
import org.eclipse.persistence.Version;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;
import org.eclipse.persistence.internal.security.PrivilegedGetClassLoaderForClass;
import org.eclipse.persistence.internal.security.PrivilegedGetConstructorFor;
import org.eclipse.persistence.internal.security.PrivilegedGetContextClassLoader;
import org.eclipse.persistence.internal.security.PrivilegedGetDeclaredConstructorFor;
import org.eclipse.persistence.internal.security.PrivilegedGetDeclaredField;
import org.eclipse.persistence.internal.security.PrivilegedGetFields;
import org.eclipse.persistence.internal.security.PrivilegedGetMethod;
import org.eclipse.persistence.internal.security.PrivilegedGetMethodParameterTypes;
import org.eclipse.persistence.internal.security.PrivilegedGetMethodReturnType;
import org.eclipse.persistence.internal.security.PrivilegedGetValueFromField;
import org.eclipse.persistence.internal.security.PrivilegedInvokeConstructor;
import org.eclipse.persistence.internal.security.PrivilegedMethodInvoker;
import org.eclipse.persistence.internal.security.PrivilegedNewInstanceFromClass;
import org.eclipse.persistence.internal.security.PrivilegedSetValueInField;
import org.eclipse.persistence.testing.framework.*;
/**
* This test compares the performance for
* 1. Direct calls - Baseline
* 2. doPrivileged actions in org.eclipse.persistence.internal.security.PriviledgedAccessController
* 3. Bypassing doPrivileged actions in org.eclipse.persistence.internal.security.PriviledgedAccessController
*/
public class DoPrivilegedTest extends PerformanceComparisonTestCase {
public DoPrivilegedTest() {
setName("Direct calls vs. doPrivileged vs. Bypassing doPrivileged PerformanceComparisonTest");
setDescription("This test compares the performance for doPrivileged.");
// check TopLink and OC4j doPrivileged flag.
String usePrivileged = System.getProperty("eclipselink.security.usedoprivileged");
if ((System.getSecurityManager() == null) || ((usePrivileged == null) || usePrivileged.equalsIgnoreCase("false"))) {
addBypassDoPrivilegedTest();
} else {
addDoPrivilegedTest();
}
}
/**
* Direct calls
*/
@Override
public void test() throws Exception {
String className = "org.eclipse.persistence.Version";
String fieldName = "buildNumber";
String fieldValue = "TopLink Blah";
String methodName = "setProduct";
Class clazz = null;
Version version = null;
Method method = null;
try {
clazz = Class.forName(className);
Class[] methodParameterTypes = { Class.forName("java.lang.String") };
ClassLoader clazzloader = clazz.getClassLoader();
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
Class.forName(className, true, clazzloader);
version = (Version)clazz.getConstructor().newInstance();
Field[] fields = clazz.getFields();
Field field = getDeclaredField(clazz, fieldName, true);
try {
int intValueFromField = field.getInt(version);
} catch (Exception e) {
}
field.get(version);
try {
field.set(version, fieldValue);
} catch (Exception e) {
}
String lineSeparator = System.getProperty("file.separator");
method = getDeclaredMethod(clazz, methodName, methodParameterTypes, true);
method.getParameterTypes();
method.getReturnType();
Object[] parameters = { "TopLink Blah." };
method.invoke(version, parameters);
Constructor constructor = clazz.getConstructor((Class[])null);
constructor.setAccessible(true);
Constructor declaredConstructor = clazz.getDeclaredConstructor((Class[])null);
declaredConstructor.setAccessible(true);
constructor.newInstance((Object[])null);
// new XMLSessionConfigLoader().loadInternal(new SessionManager(), clazzloader, false, false);
} catch (Exception e) {
throw (new TestProblemException("An exception has been caught."));
}
}
/**
* doPrivileged
*/
public void addDoPrivilegedTest() {
PerformanceComparisonTestCase test = new PerformanceComparisonTestCase() {
@Override
public void test() {
testDoPrivileged();
}
};
test.setName("DoPrivilegedTest");
test.setAllowableDecrease(-35);
addTest(test);
}
/**
* Bypassing doPrivileged
*/
public void addBypassDoPrivilegedTest() {
PerformanceComparisonTestCase test = new PerformanceComparisonTestCase() {
@Override
public void test() {
testDoPrivileged();
}
};
test.setName("BypassDoPrivilegedTest");
test.setAllowableDecrease(-10);
addTest(test);
}
public void testDoPrivileged() {
String className = "org.eclipse.persistence.Version";
String fieldName = "product";
String fieldValue = "TopLink Blah";
String methodName = "setProduct";
Class<?> clazz = null;
Version version = null;
Method method = null;
try {
clazz = AccessController.doPrivileged(new PrivilegedClassForName<>(className));
Class<?>[] methodParameterTypes = { AccessController.doPrivileged(new PrivilegedClassForName<>("java.lang.String")) };
ClassLoader clazzloader = AccessController.doPrivileged(new PrivilegedGetClassLoaderForClass(clazz));
ClassLoader classloader = AccessController.doPrivileged(new PrivilegedGetContextClassLoader(Thread.currentThread()));
AccessController.doPrivileged(new PrivilegedClassForName<>(className, true, clazzloader));
version = (Version)AccessController.doPrivileged(new PrivilegedNewInstanceFromClass<>(clazz));
Field[] fields = AccessController.doPrivileged(new PrivilegedGetFields(clazz));
Field field = AccessController.doPrivileged(new PrivilegedGetDeclaredField(clazz, fieldName, true));
try {
int intValueFromField = (Integer) AccessController.doPrivileged(new PrivilegedGetValueFromField(field, version));
} catch (Exception e) {
}
AccessController.doPrivileged(new PrivilegedGetValueFromField(field, version));
try {
AccessController.doPrivileged(new PrivilegedSetValueInField(field, version, fieldValue));
} catch (Exception e) {
}
String lineSeparator = PrivilegedAccessHelper.getLineSeparator();
method = AccessController.doPrivileged(new PrivilegedGetMethod(clazz, methodName, methodParameterTypes, true));
AccessController.doPrivileged(new PrivilegedGetMethodParameterTypes(method));
AccessController.doPrivileged(new PrivilegedGetMethodReturnType(method));
Object[] parameters = { "TopLink Blah." };
AccessController.doPrivileged(new PrivilegedMethodInvoker(method, version, parameters));
Constructor<?> constructor = AccessController.doPrivileged(new PrivilegedGetConstructorFor<>(clazz, null, true));
Constructor declaredConstructor = AccessController.doPrivileged(new PrivilegedGetDeclaredConstructorFor(clazz, null, true));
AccessController.doPrivileged(new PrivilegedInvokeConstructor(constructor, null));
// PrivilegedAccessController.loadDeploymentXML(new XMLSessionConfigLoader(),new SessionManager(), clazzloader, false, false);
} catch (Exception e) {
throw (new TestProblemException("An exception has been caught."));
}
}
public Field getDeclaredField(final Class javaClass, final String fieldName, final boolean shouldSetAccessible) throws NoSuchFieldException {
Field field = findDeclaredField(javaClass, fieldName);
if (shouldSetAccessible) {
field.setAccessible(true);
}
return field;
}
public Method getDeclaredMethod(final Class javaClass, final String methodName, final Class[] methodParameterTypes, final boolean shouldSetAccessible) throws NoSuchMethodException {
Method method = findDeclaredMethod(javaClass, methodName, methodParameterTypes);
if (shouldSetAccessible) {
method.setAccessible(true);
}
return method;
}
/**
* Finding a field within a class potentially has to navigate through it's superclasses to eventually
* find the field. This method is called by the public getDeclaredField() method and does a recursive
* search for the named field in the given classes or it's superclasses.
*/
private Field findDeclaredField(Class javaClass, String fieldName) throws NoSuchFieldException {
try {
return javaClass.getDeclaredField(fieldName);
} catch (NoSuchFieldException ex) {
Class superclass = javaClass.getSuperclass();
if (superclass == null) {
throw ex;
} else {
return findDeclaredField(superclass, fieldName);
}
}
}
/**
* Finding a method within a class potentially has to navigate through it's superclasses to eventually
* find the method. This method is called by the public getDeclaredMethod() method and does a recursive
* search for the named method in the given classes or it's superclasses.
*/
private Method findDeclaredMethod(Class javaClass, String methodName, Class[] methodParameterTypes) throws NoSuchMethodException {
try {
return javaClass.getDeclaredMethod(methodName, methodParameterTypes);
} catch (NoSuchMethodException ex) {
Class superclass = javaClass.getSuperclass();
if (superclass == null) {
throw ex;
} else {
return findDeclaredMethod(superclass, methodName, methodParameterTypes);
}
}
}
}