/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library 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 Lesser General Public License for more
* details.
*/
package com.liferay.portal.nio.intraband.proxy;
import com.liferay.portal.asm.ASMUtil;
import com.liferay.portal.asm.MethodNodeGenerator;
import com.liferay.portal.kernel.io.Deserializer;
import com.liferay.portal.kernel.io.Serializer;
import com.liferay.portal.kernel.log.Jdk14LogImpl;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.log.LogWrapper;
import com.liferay.portal.kernel.nio.intraband.Datagram;
import com.liferay.portal.kernel.nio.intraband.Intraband;
import com.liferay.portal.kernel.nio.intraband.RegistrationReference;
import com.liferay.portal.kernel.nio.intraband.SystemDataType;
import com.liferay.portal.kernel.nio.intraband.proxy.ExceptionHandler;
import com.liferay.portal.kernel.nio.intraband.proxy.IntrabandProxySkeleton;
import com.liferay.portal.kernel.nio.intraband.proxy.TargetLocator;
import com.liferay.portal.kernel.nio.intraband.proxy.annotation.Id;
import com.liferay.portal.kernel.nio.intraband.proxy.annotation.Proxy;
import com.liferay.portal.kernel.nio.intraband.rpc.RPCResponse;
import com.liferay.portal.kernel.nio.intraband.test.MockIntraband;
import com.liferay.portal.kernel.nio.intraband.test.MockRegistrationReference;
import com.liferay.portal.kernel.test.CaptureHandler;
import com.liferay.portal.kernel.test.JDKLoggerTestUtil;
import com.liferay.portal.kernel.test.ReflectionTestUtil;
import com.liferay.portal.kernel.test.rule.AggregateTestRule;
import com.liferay.portal.kernel.test.rule.CodeCoverageAssertor;
import com.liferay.portal.kernel.test.rule.NewEnv;
import com.liferay.portal.kernel.util.CharPool;
import com.liferay.portal.kernel.util.FileUtil;
import com.liferay.portal.kernel.util.MethodHandler;
import com.liferay.portal.kernel.util.ProxyUtil;
import com.liferay.portal.kernel.util.ReflectionUtil;
import com.liferay.portal.kernel.util.StringBundler;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.SystemProperties;
import com.liferay.portal.kernel.util.TextFormatter;
import com.liferay.portal.nio.intraband.proxy.IntrabandProxyUtil.MethodComparator;
import com.liferay.portal.nio.intraband.proxy.IntrabandProxyUtil.MethodsBag;
import com.liferay.portal.nio.intraband.proxy.IntrabandProxyUtil.TemplateSkeleton;
import com.liferay.portal.nio.intraband.proxy.IntrabandProxyUtil.TemplateStub;
import com.liferay.portal.test.aspects.ReflectionUtilAdvice;
import com.liferay.portal.test.rule.AdviseWith;
import com.liferay.portal.test.rule.AspectJNewEnvTestRule;
import com.liferay.portal.util.FileImpl;
import com.liferay.portal.util.PropsValues;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.junit.Assert;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.IntInsnNode;
import org.objectweb.asm.tree.JumpInsnNode;
import org.objectweb.asm.tree.LabelNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.VarInsnNode;
/**
* @author Shuyang Zhou
*/
public class IntrabandProxyUtilTest {
@ClassRule
@Rule
public static final AggregateTestRule aggregateTestRule =
new AggregateTestRule(
CodeCoverageAssertor.INSTANCE, AspectJNewEnvTestRule.INSTANCE);
@Before
public void setUp() {
FileUtil fileUtil = new FileUtil();
fileUtil.setFile(new FileImpl());
}
@Test
public void testCheckField() {
class TestClass {
@SuppressWarnings("unused")
private String _testField;
}
Field[] fields = TestClass.class.getDeclaredFields();
IntrabandProxyUtil.checkField(
fields, "noSuchField", String.class, true);
IntrabandProxyUtil.checkField(
fields, "_testField", String.class, false);
try {
IntrabandProxyUtil.checkField(
fields, "_testField", Object.class, false);
Assert.fail();
}
catch (IllegalArgumentException iae) {
Assert.assertEquals(
"Field " + fields[0] + " is expected to be of type " +
Object.class + " and not static",
iae.getMessage());
}
try {
IntrabandProxyUtil.checkField(
fields, "_testField", String.class, true);
Assert.fail();
}
catch (IllegalArgumentException iae) {
Assert.assertEquals(
"Field " + fields[0] + " is expected to be of type " +
String.class + " and static",
iae.getMessage());
}
}
@Test
public void testConstructor() {
new IntrabandProxyUtil();
}
@Test
public void testCreateProxyMethodNode() {
List<Method> methods = new ArrayList<>(
Arrays.asList(
TestProxyMethodsInterface.class.getDeclaredMethods()));
Collections.addAll(
methods, TestProxyMethodsClass.class.getDeclaredMethods());
for (int i = 0; i < methods.size(); i++) {
_doTestCreateProxyMethodNode(
methods.get(i), i, "skeletonId", "TestClassStub");
}
}
@Test
public void testDeserializerRead() {
MethodNode methodNode = new MethodNode(
Opcodes.ACC_PUBLIC, "name", "()V", null, null);
MethodNodeGenerator methodNodeGenerator = new MethodNodeGenerator(
methodNode);
InsnList insnList = methodNode.instructions;
for (Type type : _types) {
IntrabandProxyUtil.deserializerRead(methodNodeGenerator, type);
AbstractInsnNode abstractInsnNode = insnList.getLast();
String methodName = "readObject";
Type returnType = Type.getType(Serializable.class);
if (type.getSort() <= Type.DOUBLE) {
String name = TextFormatter.format(
type.getClassName(), TextFormatter.G);
methodName = "read".concat(name);
returnType = type;
}
else if (type.equals(Type.getType(String.class))) {
methodName = "readString";
returnType = Type.getType(String.class);
_assertMethodInsnNode(
abstractInsnNode, Opcodes.INVOKEVIRTUAL,
Type.getInternalName(Deserializer.class), "readString",
Type.getType(String.class));
}
_assertMethodInsnNode(
abstractInsnNode, Opcodes.INVOKEVIRTUAL,
Type.getInternalName(Deserializer.class), methodName,
returnType);
}
}
@Test
public void testExtractMethods() throws Exception {
try {
IntrabandProxyUtil.extractMethods(TestExtractMethodsClass1.class);
Assert.fail();
}
catch (IllegalArgumentException iae) {
Assert.assertEquals(
"The @Id annotated method " +
TestExtractMethodsClass1.class.getMethod("getId") +
" must not be static",
iae.getMessage());
}
try {
IntrabandProxyUtil.extractMethods(TestExtractMethodsClass2.class);
Assert.fail();
}
catch (IllegalArgumentException iae) {
Method method = TestExtractMethodsClass2.class.getMethod(
"getId", Object.class);
Assert.assertEquals(
"The @Id annotated method " + method +
" must not have parameters",
iae.getMessage());
}
try {
IntrabandProxyUtil.extractMethods(TestExtractMethodsClass3.class);
Assert.fail();
}
catch (IllegalArgumentException iae) {
Assert.assertEquals(
"The @Id annotated method " +
TestExtractMethodsClass3.class.getMethod("getId") +
" must not return String",
iae.getMessage());
}
try {
IntrabandProxyUtil.extractMethods(TestExtractMethodsClass4.class);
Assert.fail();
}
catch (IllegalArgumentException iae) {
Assert.assertEquals(
"Static proxy method violation for " +
TestExtractMethodsClass4.class.getMethod("doStuff"),
iae.getMessage());
}
MethodsBag methodsBag = IntrabandProxyUtil.extractMethods(
TestExtractMethodsClass5.class);
List<Method> idMethods = methodsBag.idMethods;
Assert.assertEquals(idMethods.toString(), 2, idMethods.size());
Assert.assertTrue(
idMethods.contains(
TestExtractMethodsClass5.class.getMethod("getId1")));
Assert.assertTrue(
idMethods.contains(
TestExtractMethodsClass5.class.getMethod("getId2")));
List<Method> proxyMethods = methodsBag.proxyMethods;
Assert.assertEquals(proxyMethods.toString(), 2, proxyMethods.size());
Assert.assertEquals(
TestExtractMethodsClass5.class.getMethod("doStuff1"),
proxyMethods.get(0));
Assert.assertEquals(
TestExtractMethodsClass5.class.getMethod("doStuff2"),
proxyMethods.get(1));
List<Method> emptyMethods = methodsBag.emptyMethods;
Assert.assertEquals(emptyMethods.toString(), 1, emptyMethods.size());
Assert.assertEquals(
TestExtractMethodsClass5.class.getMethod("doStuff4"),
emptyMethods.get(0));
String[] proxyMethodSignatures = methodsBag.proxyMethodSignatures;
Assert.assertEquals(
Arrays.toString(proxyMethodSignatures), 2,
proxyMethodSignatures.length);
Assert.assertEquals("doStuff1-()V", proxyMethodSignatures[0]);
Assert.assertEquals("doStuff2-()V", proxyMethodSignatures[1]);
}
@NewEnv(type = NewEnv.Type.CLASSLOADER)
@Test
public void testGenerateSkeletonClassFunction() throws Exception {
_doTestGenerateSkeletonClassFunction(TestGenerateInterface1.class);
_doTestGenerateSkeletonClassFunction(TestGenerateInterface2.class);
}
@NewEnv(type = NewEnv.Type.CLASSLOADER)
@Test
public void testGenerateSkeletonClassStructure() throws Exception {
_doTestGenerateSkeletonClassStructure(TestGenerateInterface1.class);
_doTestGenerateSkeletonClassStructure(TestGenerateInterface2.class);
_doTestGenerateSkeletonClassStructure(TestGenerateClass1.class);
_doTestGenerateSkeletonClassStructure(TestGenerateClass2.class);
}
@NewEnv(type = NewEnv.Type.CLASSLOADER)
@Test
public void testGenerateStubClassFunction() throws Exception {
// <clinit> and <init> appending
String skeletonId = "skeletonId";
Class<?> stubClass = IntrabandProxyUtil.generateStubClass(
_classLoader, TestGenerateStubFunction1.class, skeletonId);
Constructor<?> constructor = stubClass.getConstructor(
String.class, RegistrationReference.class, ExceptionHandler.class);
String testId = "testId";
AutoReplyMockIntraband autoReplyMockIntraband =
new AutoReplyMockIntraband(skeletonId, testId);
RegistrationReference registrationReference =
new MockRegistrationReference(autoReplyMockIntraband);
Object stubObject = null;
try (CaptureHandler captureHandler =
JDKLoggerTestUtil.configureJDKLogger(
stubClass.getName(), Level.INFO)) {
List<LogRecord> logRecords = captureHandler.getLogRecords();
stubObject = constructor.newInstance(
testId, registrationReference,
WarnLogExceptionHandler.INSTANCE);
Assert.assertEquals(logRecords.toString(), 2, logRecords.size());
LogRecord logRecord = logRecords.get(0);
Assert.assertEquals(
stubClass.getName() + " in <clinit>", logRecord.getMessage());
logRecord = logRecords.get(1);
Assert.assertEquals(
stubClass.getName() + " in <init>", logRecord.getMessage());
}
Assert.assertSame(
registrationReference,
ReflectionTestUtil.getFieldValue(
stubObject, "_registrationReference"));
Assert.assertSame(
WarnLogExceptionHandler.INSTANCE,
ReflectionTestUtil.getFieldValue(stubObject, "_exceptionHandler"));
Assert.assertSame(
autoReplyMockIntraband,
ReflectionTestUtil.getFieldValue(stubObject, "_intraband"));
// Id methods
stubClass = IntrabandProxyUtil.generateStubClass(
_classLoader, TestGenerateStubFunction2.class, skeletonId);
constructor = stubClass.getConstructor(
String.class, RegistrationReference.class, ExceptionHandler.class);
stubObject = constructor.newInstance(
testId, registrationReference, WarnLogExceptionHandler.INSTANCE);
for (Method idMethod : _getIdMethods(TestGenerateStubFunction2.class)) {
Assert.assertEquals(
testId,
ReflectionTestUtil.invoke(
stubObject, idMethod.getName(), new Class<?>[0]));
}
// Proxy methods
List<Method> proxyMethods = _getProxyMethods(
TestGenerateStubFunction2.class);
for (int i = 0; i < proxyMethods.size(); i++) {
Method proxyMethod = proxyMethods.get(i);
Class<?>[] parameterTypes = proxyMethod.getParameterTypes();
Object[] args = new Object[parameterTypes.length];
for (int j = 0; j < args.length; j++) {
args[j] = _sampleValueMap.get(parameterTypes[j]);
}
autoReplyMockIntraband.setInvocation(proxyMethod, i);
Object object = ReflectionTestUtil.invoke(
stubObject, proxyMethod.getName(),
proxyMethod.getParameterTypes(), args);
Assert.assertEquals(
_sampleValueMap.get(proxyMethod.getReturnType()), object);
}
// Empty methods
for (Method emptyMethod :
_getEmptyMethods(TestGenerateStubFunction2.class)) {
Assert.assertEquals(
_defaultValueMap.get(emptyMethod.getReturnType()),
ReflectionTestUtil.invoke(
stubObject, emptyMethod.getName(), new Class<?>[0]));
}
// Copied methods
List<Method> copiedMethods = _getCopiedMethods(
TestGenerateStubFunction2.class);
Collections.sort(
copiedMethods,
new Comparator<Method>() {
@Override
public int compare(Method method1, Method method2) {
String name1 = method1.getName();
String name2 = method2.getName();
return name1.compareTo(name2);
}
});
try (CaptureHandler captureHandler =
JDKLoggerTestUtil.configureJDKLogger(
stubClass.getName(), Level.INFO)) {
List<LogRecord> logRecords = captureHandler.getLogRecords();
for (Method copiedMethod : copiedMethods) {
ReflectionTestUtil.invoke(
stubObject, copiedMethod.getName(), new Class<?>[0]);
LogRecord logRecord = logRecords.get(logRecords.size() - 1);
Assert.assertEquals(
copiedMethod.getName(), logRecord.getMessage());
}
}
}
@NewEnv(type = NewEnv.Type.CLASSLOADER)
@Test
public void testGenerateStubClassStructure() throws Exception {
_doTestGenerateStubClassStructure(
TestGenerateInterface1.class, "skeletonId");
_doTestGenerateStubClassStructure(
TestGenerateInterface2.class, "skeletonId");
_doTestGenerateStubClassStructure(
TestGenerateClass1.class, "skeletonId");
_doTestGenerateStubClassStructure(
TestGenerateClass2.class, "skeletonId");
}
@Test
public void testGetClass() throws Exception {
// getSkeletonClass()
class TestClass {
}
ClassLoader classLoader = TestClass.class.getClassLoader();
_doTestGetClass(
classLoader,
new MethodHandler(
IntrabandProxyUtil.class.getDeclaredMethod(
"getSkeletonClass", ClassLoader.class, Class.class),
classLoader, TestClass.class));
// getStubClass()
_doTestGetClass(
classLoader,
new MethodHandler(
IntrabandProxyUtil.class.getMethod(
"getStubClass", Class.class, String.class),
TestClass.class, "skeletonId"));
}
@Test
public void testGetProxyMethodSignatures() {
class TestClass {
}
Assert.assertNull(
IntrabandProxyUtil.getProxyMethodSignatures(TestClass.class));
}
@AdviseWith(adviceClasses = {ReflectionUtilAdvice.class})
@NewEnv(type = NewEnv.Type.CLASSLOADER)
@Test
public void testInitializationFailure() throws ClassNotFoundException {
Throwable throwable = new Throwable();
ReflectionUtilAdvice.setDeclaredMethodThrowable(throwable);
try {
new IntrabandProxyUtil();
Assert.fail();
}
catch (ExceptionInInitializerError eiie) {
Assert.assertSame(throwable, eiie.getCause());
}
}
@Test
public void testLoadClass() {
Assert.assertNull(
IntrabandProxyUtil.loadClass(_classLoader, Thread.class, "Proxy"));
Assert.assertSame(
ThreadLocal.class,
IntrabandProxyUtil.loadClass(_classLoader, Thread.class, "Local"));
}
@Test
public void testNewStubInstance() {
Class<?> stubClass = IntrabandProxyUtil.getStubClass(
TestGenerateInterface1.class, "skeletonId");
IntrabandProxyUtil.newStubInstance(
stubClass, "id", new MockRegistrationReference(null),
WarnLogExceptionHandler.INSTANCE);
try {
IntrabandProxyUtil.newStubInstance(
stubClass, "id", null, WarnLogExceptionHandler.INSTANCE);
Assert.fail();
}
catch (RuntimeException re) {
Throwable throwable = re.getCause();
throwable = throwable.getCause();
Assert.assertSame(NullPointerException.class, throwable.getClass());
Assert.assertEquals(
"Registration reference is null", throwable.getMessage());
}
stubClass = IntrabandProxyUtil.getStubClass(
TestGenerateInterface2.class, "skeletonId");
try {
IntrabandProxyUtil.newStubInstance(
stubClass, "id", null, WarnLogExceptionHandler.INSTANCE);
Assert.fail();
}
catch (RuntimeException re) {
Throwable throwable = re.getCause();
throwable = throwable.getCause();
Assert.assertSame(NullPointerException.class, throwable.getClass());
Assert.assertEquals(
"Registration reference is null", throwable.getMessage());
}
IntrabandProxyUtil.newStubInstance(
stubClass, "id", new MockRegistrationReference(null),
WarnLogExceptionHandler.INSTANCE);
}
@Test
public void testRewriteGetProxyMethodSignaturesMethodNode() {
class TestClass {
@SuppressWarnings("unused")
public final String[] PROXY_METHOD_SIGNATURES =
_getProxyMethodSignatures();
private String[] _getProxyMethodSignatures() {
return new String[0];
}
}
ClassNode classNode = _loadClass(TestClass.class);
String[] proxyMethodSignatures =
{"testSignature1", "testSignature2", "testSignature3"};
IntrabandProxyUtil.rewriteGetProxyMethodSignaturesMethodNode(
classNode, proxyMethodSignatures);
MethodNode methodNode = ASMUtil.findMethodNode(
classNode.methods, "_getProxyMethodSignatures",
Type.getType(String[].class));
InsnList insnList = methodNode.instructions;
Iterator<AbstractInsnNode> iterator = insnList.iterator();
_assertInsnNode(iterator.next(), Opcodes.ICONST_3);
_assertTypeInsnNode(iterator.next(), Opcodes.ANEWARRAY, String.class);
for (int i = 0; i < proxyMethodSignatures.length; i++) {
_assertInsnNode(iterator.next(), Opcodes.DUP);
_assertInsnNode(iterator.next(), Opcodes.ICONST_0 + i);
_assertLdcInsnNode(
iterator.next(), Opcodes.LDC, proxyMethodSignatures[i]);
_assertInsnNode(iterator.next(), Opcodes.AASTORE);
}
_assertInsnNode(iterator.next(), Opcodes.ARETURN);
Assert.assertFalse(iterator.hasNext());
}
@Test
public void testSerializerWrite() {
MethodNode methodNode = new MethodNode(
Opcodes.ACC_PUBLIC, "name", "()V", null, null);
MethodNodeGenerator methodNodeGenerator = new MethodNodeGenerator(
methodNode);
InsnList insnList = methodNode.instructions;
for (Type type : _types) {
IntrabandProxyUtil.serializerWrite(methodNodeGenerator, type);
AbstractInsnNode abstractInsnNode = insnList.getLast();
Assert.assertTrue(abstractInsnNode instanceof MethodInsnNode);
MethodInsnNode methodInsnNode = (MethodInsnNode)abstractInsnNode;
Assert.assertEquals(
Opcodes.INVOKEVIRTUAL, abstractInsnNode.getOpcode());
Assert.assertEquals(
Type.getInternalName(Serializer.class), methodInsnNode.owner);
if (type.getSort() <= Type.DOUBLE) {
String name = TextFormatter.format(
type.getClassName(), TextFormatter.G);
Assert.assertEquals("write".concat(name), methodInsnNode.name);
Assert.assertEquals(
Type.getMethodDescriptor(Type.VOID_TYPE, type),
methodInsnNode.desc);
}
else if (type.equals(Type.getType(String.class))) {
Assert.assertEquals("writeString", methodInsnNode.name);
Assert.assertEquals(
Type.getMethodDescriptor(
Type.VOID_TYPE, Type.getType(String.class)),
methodInsnNode.desc);
}
else {
Assert.assertEquals("writeObject", methodInsnNode.name);
Assert.assertEquals(
Type.getMethodDescriptor(
Type.VOID_TYPE, Type.getType(Serializable.class)),
methodInsnNode.desc);
}
}
}
@Test
public void testTemplateSkeleton() throws ClassNotFoundException {
class TestTemplateSkeleton extends TemplateSkeleton {
TestTemplateSkeleton(TargetLocator targetLocator) {
super(targetLocator);
}
@Override
protected void doDispatch(
RegistrationReference registrationReference, Datagram datagram,
Deserializer deserializer) {
int i = deserializer.readInt();
if (i == 0) {
ReflectionTestUtil.invoke(
this, "_sendResponse",
new Class<?>[] {
RegistrationReference.class, Datagram.class,
RPCResponse.class
},
registrationReference, datagram,
new RPCResponse("syncCall"));
}
else if (i == 1) {
ReflectionTestUtil.invoke(
this, "_unknownMethodIndex", new Class<?>[] {int.class},
1);
}
}
}
try {
new TestTemplateSkeleton(null);
Assert.fail();
}
catch (NullPointerException npe) {
Assert.assertEquals("Target locator is null", npe.getMessage());
}
TestGenerateTargetLocator testGenerateTargetLocator =
new TestGenerateTargetLocator(TestGenerateInterface1.class);
TestTemplateSkeleton testTemplateSkeleton = new TestTemplateSkeleton(
testGenerateTargetLocator);
Assert.assertSame(
testGenerateTargetLocator,
ReflectionTestUtil.getFieldValue(
testTemplateSkeleton, "_targetLocator"));
MockIntraband mockIntraband = new MockIntraband();
MockRegistrationReference mockRegistrationReference =
new MockRegistrationReference(mockIntraband);
Serializer serializer = new Serializer();
serializer.writeInt(0);
testTemplateSkeleton.dispatch(
mockRegistrationReference,
Datagram.createRequestDatagram(
SystemDataType.PROXY.getValue(), new byte[0]),
new Deserializer(serializer.toByteBuffer()));
Datagram datagram = mockIntraband.getDatagram();
Deserializer deserializer = new Deserializer(
datagram.getDataByteBuffer());
RPCResponse rpcResponse = deserializer.readObject();
Assert.assertEquals("syncCall", rpcResponse.getResult());
serializer = new Serializer();
serializer.writeInt(1);
try (CaptureHandler captureHandler =
JDKLoggerTestUtil.configureJDKLogger(
TemplateSkeleton.class.getName(), Level.SEVERE)) {
testTemplateSkeleton.dispatch(
mockRegistrationReference,
Datagram.createRequestDatagram(
SystemDataType.PROXY.getValue(), new byte[0]),
new Deserializer(serializer.toByteBuffer()));
List<LogRecord> logRecords = captureHandler.getLogRecords();
Assert.assertEquals(logRecords.toString(), 1, logRecords.size());
LogRecord logRecord = logRecords.get(0);
Assert.assertEquals("Unable to dispatch", logRecord.getMessage());
Throwable throwable = logRecord.getThrown();
Assert.assertSame(
IllegalArgumentException.class, throwable.getClass());
Assert.assertEquals(
"Unknow method index 1 for proxy methods mappings {}",
throwable.getMessage());
}
Assert.assertEquals(
"{0 -> a, 1 -> b, 2 -> c}",
ReflectionTestUtil.invoke(
testTemplateSkeleton, "_getProxyMethodsMapping",
new Class<?>[] {String[].class},
new Object[] {new String[] {"a", "b", "c"}}));
}
@Test
public void testTemplateStub() {
try {
new TemplateStub(null, null, null);
Assert.fail();
}
catch (NullPointerException npe) {
Assert.assertEquals("Id is null", npe.getMessage());
}
try {
new TemplateStub("id", null, null);
Assert.fail();
}
catch (NullPointerException npe) {
Assert.assertEquals(
"Registration reference is null", npe.getMessage());
}
final AtomicReference<RPCResponse> rpcResponseReference =
new AtomicReference<>();
MockIntraband mockIntraband = new MockIntraband() {
@Override
protected Datagram processDatagram(Datagram datagram) {
Serializer serializer = new Serializer();
serializer.writeObject(rpcResponseReference.get());
return Datagram.createResponseDatagram(
datagram, serializer.toByteBuffer());
}
};
MockRegistrationReference mockRegistrationReference =
new MockRegistrationReference(mockIntraband);
TemplateStub templateStub = new TemplateStub(
"id", mockRegistrationReference, null);
Assert.assertEquals(
"id", ReflectionTestUtil.getFieldValue(templateStub, "_id"));
Assert.assertSame(
mockRegistrationReference,
ReflectionTestUtil.getFieldValue(
templateStub, "_registrationReference"));
Assert.assertNull(
ReflectionTestUtil.getFieldValue(
templateStub, "_exceptionHandler"));
Assert.assertSame(
mockIntraband,
ReflectionTestUtil.getFieldValue(templateStub, "_intraband"));
templateStub = new TemplateStub(
"id", mockRegistrationReference, WarnLogExceptionHandler.INSTANCE);
Assert.assertEquals(
"id", ReflectionTestUtil.getFieldValue(templateStub, "_id"));
Assert.assertSame(
mockRegistrationReference,
ReflectionTestUtil.getFieldValue(
templateStub, "_registrationReference"));
Assert.assertSame(
WarnLogExceptionHandler.INSTANCE,
ReflectionTestUtil.getFieldValue(
templateStub, "_exceptionHandler"));
Assert.assertSame(
mockIntraband,
ReflectionTestUtil.getFieldValue(templateStub, "_intraband"));
ReflectionTestUtil.invoke(
templateStub, "_send", new Class<?>[] {Serializer.class},
new Serializer());
Assert.assertSame(
mockRegistrationReference,
mockIntraband.getRegistrationReference());
Datagram datagram = mockIntraband.getDatagram();
Assert.assertEquals(
SystemDataType.PROXY.getValue(), datagram.getType());
rpcResponseReference.set(new RPCResponse("syncSend"));
Assert.assertEquals(
"syncSend",
ReflectionTestUtil.invoke(
templateStub, "_syncSend", new Class<?>[] {Serializer.class},
new Serializer()));
try (CaptureHandler captureHandler =
JDKLoggerTestUtil.configureJDKLogger(
WarnLogExceptionHandler.class.getName(), Level.WARNING)) {
String message = "RPC failure";
rpcResponseReference.set(new RPCResponse(new Exception(message)));
Assert.assertNull(
ReflectionTestUtil.invoke(
templateStub, "_syncSend",
new Class<?>[] {Serializer.class}, new Serializer()));
List<LogRecord> logRecords = captureHandler.getLogRecords();
Assert.assertEquals(logRecords.toString(), 1, logRecords.size());
LogRecord logRecord = logRecords.get(0);
Throwable throwable = logRecord.getThrown();
Assert.assertEquals(message, throwable.getMessage());
logRecords.clear();
rpcResponseReference.set(new RPCResponse((Serializable)null));
Assert.assertNull(
ReflectionTestUtil.invoke(
templateStub, "_syncSend",
new Class<?>[] {Serializer.class}, new Serializer()));
Assert.assertTrue(logRecords.isEmpty());
rpcResponseReference.set(null);
ReflectionTestUtil.setFieldValue(
templateStub, "_exceptionHandler", null);
Assert.assertNull(
ReflectionTestUtil.invoke(
templateStub, "_syncSend",
new Class<?>[] {Serializer.class}, new Serializer()));
Assert.assertTrue(logRecords.isEmpty());
}
}
@AdviseWith(adviceClasses = {DisableProxyClassesDump.class})
@NewEnv(type = NewEnv.Type.CLASSLOADER)
@Test
public void testToClassProxyClassesDumpDisabled()
throws FileNotFoundException {
_doTestToClass(false, false);
}
@AdviseWith(adviceClasses = {EnableProxyClassesDump.class})
@NewEnv(type = NewEnv.Type.CLASSLOADER)
@Test
public void testToClassProxyClassesDumpEnabled()
throws FileNotFoundException {
_doTestToClass(true, true);
_doTestToClass(true, false);
}
@Test
public void testValidate() throws Exception {
_doTestValidate(true);
_doTestValidate(false);
}
@Aspect
public static class DisableProxyClassesDump {
@Around(
"set(* com.liferay.portal.util.PropsValues." +
"INTRABAND_PROXY_DUMP_CLASSES_ENABLED)"
)
public Object disableClusterLink(
ProceedingJoinPoint proceedingJoinPoint)
throws Throwable {
return proceedingJoinPoint.proceed(new Object[] {Boolean.FALSE});
}
}
@Aspect
public static class EnableProxyClassesDump {
@Around(
"set(* com.liferay.portal.util.PropsValues." +
"INTRABAND_PROXY_DUMP_CLASSES_ENABLED)"
)
public Object enableClusterLink(ProceedingJoinPoint proceedingJoinPoint)
throws Throwable {
return proceedingJoinPoint.proceed(new Object[] {Boolean.TRUE});
}
}
private static Object _readFromDeserializer(
Deserializer deserializer, Class<?> clazz) {
if (clazz == boolean.class) {
return deserializer.readBoolean();
}
else if (clazz == byte.class) {
return deserializer.readByte();
}
else if (clazz == char.class) {
return deserializer.readChar();
}
else if (clazz == double.class) {
return deserializer.readDouble();
}
else if (clazz == float.class) {
return deserializer.readFloat();
}
else if (clazz == int.class) {
return deserializer.readInt();
}
else if (clazz == long.class) {
return deserializer.readLong();
}
else if (clazz == short.class) {
return deserializer.readShort();
}
else if (clazz == String.class) {
return deserializer.readString();
}
else {
try {
return deserializer.readObject();
}
catch (ClassNotFoundException cnfe) {
throw new RuntimeException(cnfe);
}
}
}
private static void _writeToSerializer(
Serializer serializer, Class<?> clazz) {
if (clazz == boolean.class) {
serializer.writeBoolean(
(Boolean)_sampleValueMap.get(boolean.class));
}
else if (clazz == byte.class) {
serializer.writeByte((Byte)_sampleValueMap.get(byte.class));
}
else if (clazz == char.class) {
serializer.writeChar((Character)_sampleValueMap.get(char.class));
}
else if (clazz == double.class) {
serializer.writeDouble((Double)_sampleValueMap.get(double.class));
}
else if (clazz == float.class) {
serializer.writeFloat((Float)_sampleValueMap.get(float.class));
}
else if (clazz == int.class) {
serializer.writeInt((Integer)_sampleValueMap.get(int.class));
}
else if (clazz == long.class) {
serializer.writeLong((Long)_sampleValueMap.get(long.class));
}
else if (clazz == short.class) {
serializer.writeShort((Short)_sampleValueMap.get(short.class));
}
else if (clazz == String.class) {
serializer.writeString((String)_sampleValueMap.get(String.class));
}
else {
serializer.writeObject((Serializable)_sampleValueMap.get(clazz));
}
}
private Field _assertDeclaredField(
Class<?> clazz, String name, int modifiers, Class<?> type)
throws Exception {
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
Assert.assertEquals(modifiers, field.getModifiers());
Assert.assertSame(type, field.getType());
return field;
}
private void _assertDeclaredMethod(
Class<?> clazz, String name, Class<?>[] parameterTypes,
int modifiers, Class<?> returnType, Class<?>... exceptionTypes)
throws Exception {
Method method = clazz.getDeclaredMethod(name, parameterTypes);
Assert.assertEquals(modifiers, method.getModifiers());
Assert.assertSame(returnType, method.getReturnType());
Assert.assertArrayEquals(exceptionTypes, method.getExceptionTypes());
}
private void _assertFieldInsnNode(
AbstractInsnNode abstractInsnNode, int opcode, String owner,
String name, Class<?> clazz) {
Assert.assertEquals(opcode, abstractInsnNode.getOpcode());
FieldInsnNode fieldInsnNode = (FieldInsnNode)abstractInsnNode;
Assert.assertEquals(owner, fieldInsnNode.owner);
Assert.assertEquals(name, fieldInsnNode.name);
Assert.assertEquals(Type.getDescriptor(clazz), fieldInsnNode.desc);
}
private void _assertInsnNode(
AbstractInsnNode abstractInsnNode, int opcode) {
Assert.assertEquals(opcode, abstractInsnNode.getOpcode());
}
private void _assertIntInsnNode(
AbstractInsnNode abstractInsnNode, int opcode, int operand) {
Assert.assertEquals(opcode, abstractInsnNode.getOpcode());
IntInsnNode intInsnNode = (IntInsnNode)abstractInsnNode;
Assert.assertEquals(operand, intInsnNode.operand);
}
private LabelNode _assertJumpInsnNode(
AbstractInsnNode abstractInsnNode, int opcode) {
Assert.assertEquals(opcode, abstractInsnNode.getOpcode());
JumpInsnNode jumpInsnNode = (JumpInsnNode)abstractInsnNode;
return jumpInsnNode.label;
}
private void _assertLdcInsnNode(
AbstractInsnNode abstractInsnNode, int opcode, Object obj) {
Assert.assertEquals(opcode, abstractInsnNode.getOpcode());
LdcInsnNode ldcInsnNode = (LdcInsnNode)abstractInsnNode;
Assert.assertEquals(obj, ldcInsnNode.cst);
}
private void _assertMethodInsnNode(
AbstractInsnNode abstractInsnNode, int opcode, String owner,
String name, Type returnType, Type... argumentTypes) {
Assert.assertEquals(opcode, abstractInsnNode.getOpcode());
MethodInsnNode methodInsnNode = (MethodInsnNode)abstractInsnNode;
Assert.assertEquals(owner, methodInsnNode.owner);
Assert.assertEquals(name, methodInsnNode.name);
Assert.assertEquals(
Type.getMethodDescriptor(returnType, argumentTypes),
methodInsnNode.desc);
}
private void _assertMethodNodeSignature(
MethodNode methodNode, int access, String name, String desc,
Class<?>... exceptionClasses) {
Assert.assertEquals(access, methodNode.access);
Assert.assertEquals(name, methodNode.name);
Assert.assertEquals(desc, methodNode.desc);
List<String> exceptions = new ArrayList<>(exceptionClasses.length);
for (Class<?> exceptionClass : exceptionClasses) {
exceptions.add(Type.getInternalName(exceptionClass));
}
Assert.assertEquals(exceptions, methodNode.exceptions);
}
private void _assertTypeInsnNode(
AbstractInsnNode abstractInsnNode, int opcode, Class<?> clazz) {
Assert.assertEquals(opcode, abstractInsnNode.getOpcode());
TypeInsnNode typeInsnNode = (TypeInsnNode)abstractInsnNode;
Assert.assertEquals(Type.getInternalName(clazz), typeInsnNode.desc);
}
private void _assertVarInsnNode(
AbstractInsnNode abstractInsnNode, int opcode, int var) {
Assert.assertEquals(opcode, abstractInsnNode.getOpcode());
VarInsnNode varInsnNode = (VarInsnNode)abstractInsnNode;
Assert.assertEquals(var, varInsnNode.var);
}
private String[] _buildProxyMethodSignatures(Class<?> clazz) {
List<Method> proxyMethods = new ArrayList<>();
for (Method method : ReflectionUtil.getVisibleMethods(clazz)) {
if (method.getAnnotation(Proxy.class) != null) {
proxyMethods.add(method);
}
}
Collections.sort(proxyMethods, new MethodComparator());
String[] proxyMethodSignatures = new String[proxyMethods.size()];
for (int i = 0; i < proxyMethodSignatures.length; i++) {
Method proxyMethod = proxyMethods.get(i);
String name = proxyMethod.getName();
proxyMethodSignatures[i] = name.concat(StringPool.DASH).concat(
Type.getMethodDescriptor(proxyMethod));
}
return proxyMethodSignatures;
}
private void _doTestCreateProxyMethodNode(
Method method, int index, String skeletonId, String stubInternalName) {
MethodNode proxyMethodNode = IntrabandProxyUtil.createProxyMethodNode(
method, index, skeletonId, Type.getType(stubInternalName));
_assertMethodNodeSignature(
proxyMethodNode, method.getModifiers() & ~Modifier.ABSTRACT,
method.getName(), Type.getMethodDescriptor(method),
method.getExceptionTypes());
InsnList insnList = proxyMethodNode.instructions;
Iterator<AbstractInsnNode> iterator = insnList.iterator();
// NEW com/liferay/portal/kernel/io/Serializer
_assertTypeInsnNode(iterator.next(), Opcodes.NEW, Serializer.class);
// DUP
_assertInsnNode(iterator.next(), Opcodes.DUP);
// INVOKESPECIAL com/liferay/portal/kernel/io/Serializer <init> ()V
_assertMethodInsnNode(
iterator.next(), Opcodes.INVOKESPECIAL,
Type.getInternalName(Serializer.class), "<init>", Type.VOID_TYPE);
// ASTORE argumentsSize
Type methodType = Type.getType(method);
int argumentsAndReturnSizes = methodType.getArgumentsAndReturnSizes();
int argumentsSize = argumentsAndReturnSizes >> 2;
_assertVarInsnNode(iterator.next(), Opcodes.ASTORE, argumentsSize);
// ALOAD argumentsSize
_assertVarInsnNode(iterator.next(), Opcodes.ALOAD, argumentsSize);
// LDC skeletonId
_assertLdcInsnNode(iterator.next(), Opcodes.LDC, skeletonId);
// INVOKEVIRTUAL com/liferay/portal/kernel/io/Serializer writeString
// (Ljava/lang/String;)V
_assertMethodInsnNode(
iterator.next(), Opcodes.INVOKEVIRTUAL,
Type.getInternalName(Serializer.class), "writeString",
Type.VOID_TYPE, Type.getType(String.class));
// ALOAD argumentsSize
_assertVarInsnNode(iterator.next(), Opcodes.ALOAD, argumentsSize);
// ALOAD 0
_assertVarInsnNode(iterator.next(), Opcodes.ALOAD, 0);
// GETFIELD stubInternalName _id Ljava/lang/String;
_assertFieldInsnNode(
iterator.next(), Opcodes.GETFIELD, stubInternalName, "_id",
String.class);
// INVOKEVIRTUAL com/liferay/portal/kernel/io/Serializer writeString
// (Ljava/lang/String;)V
_assertMethodInsnNode(
iterator.next(), Opcodes.INVOKEVIRTUAL,
Type.getInternalName(Serializer.class), "writeString",
Type.VOID_TYPE, Type.getType(String.class));
// ALOAD argumentsSize
_assertVarInsnNode(iterator.next(), Opcodes.ALOAD, argumentsSize);
if (index <= 5) {
// ICONST_index
_assertInsnNode(iterator.next(), Opcodes.ICONST_0 + index);
}
else {
// BIPUSH index
_assertIntInsnNode(iterator.next(), Opcodes.BIPUSH, index);
}
// INVOKEVIRTUAL com/liferay/portal/kernel/io/Serializer writeInt (I)V
_assertMethodInsnNode(
iterator.next(), Opcodes.INVOKEVIRTUAL,
Type.getInternalName(Serializer.class), "writeInt", Type.VOID_TYPE,
Type.INT_TYPE);
Class<?>[] parameterTypes = method.getParameterTypes();
int offset = 1;
for (int i = 0; i < parameterTypes.length; i++) {
Class<?> parameterClass = parameterTypes[i];
// ALOAD argumentsSize
_assertVarInsnNode(iterator.next(), Opcodes.ALOAD, argumentsSize);
// xLOAD i
Type parameterType = Type.getType(parameterClass);
_assertVarInsnNode(
iterator.next(), parameterType.getOpcode(Opcodes.ILOAD),
offset);
offset += parameterType.getSize();
if (parameterClass.isPrimitive() ||
(parameterClass == String.class)) {
String name = TextFormatter.format(
parameterClass.getSimpleName(), TextFormatter.G);
_assertMethodInsnNode(
iterator.next(), Opcodes.INVOKEVIRTUAL,
Type.getInternalName(Serializer.class),
"write".concat(name), Type.VOID_TYPE, parameterType);
}
else {
_assertMethodInsnNode(
iterator.next(), Opcodes.INVOKEVIRTUAL,
Type.getInternalName(Serializer.class), "writeObject",
Type.VOID_TYPE, Type.getType(Serializable.class));
}
}
// ALOAD 0
_assertVarInsnNode(iterator.next(), Opcodes.ALOAD, 0);
// ALOAD argumentsSize
_assertVarInsnNode(iterator.next(), Opcodes.ALOAD, argumentsSize);
Class<?> returnClass = method.getReturnType();
Type returnType = Type.getType(returnClass);
if (returnClass == void.class) {
// INVOKESPECIAL stubInternalName _send
// (Lcom/liferay/portal/kernel/io/Serializer;)V
_assertMethodInsnNode(
iterator.next(), Opcodes.INVOKESPECIAL, stubInternalName,
"_send", Type.VOID_TYPE, Type.getType(Serializer.class));
_assertInsnNode(iterator.next(), Opcodes.RETURN);
}
else {
// INVOKESPECIAL stubInternalName _syncSend
// (Lcom/liferay/portal/kernel/io/Serializer;)Ljava/io/Serializable;
_assertMethodInsnNode(
iterator.next(), Opcodes.INVOKESPECIAL, stubInternalName,
"_syncSend", Type.getType(Serializable.class),
Type.getType(Serializer.class));
if (returnClass.isPrimitive()) {
// ASTORE argumentsSize + 1
_assertVarInsnNode(
iterator.next(), Opcodes.ASTORE, argumentsSize + 1);
// ALOAD argumentsSize + 1
_assertVarInsnNode(
iterator.next(), Opcodes.ALOAD, argumentsSize + 1);
// IFNULL nullCheckLabel
LabelNode nullCheckLabelNode = _assertJumpInsnNode(
iterator.next(), Opcodes.IFNULL);
// ALOAD argumentsSize + 1
_assertVarInsnNode(
iterator.next(), Opcodes.ALOAD, argumentsSize + 1);
// CHECKCAST returnType
_assertTypeInsnNode(
iterator.next(), Opcodes.CHECKCAST,
_autoboxingMap.get(returnClass));
if (returnClass == boolean.class) {
// INVOKEVIRTUAL java/lang/Boolean booleanValue ()Z
_assertMethodInsnNode(
iterator.next(), Opcodes.INVOKEVIRTUAL,
Type.getInternalName(Boolean.class), "booleanValue",
Type.BOOLEAN_TYPE);
}
else if (returnClass == byte.class) {
// INVOKEVIRTUAL java/lang/Number intValue ()I
_assertMethodInsnNode(
iterator.next(), Opcodes.INVOKEVIRTUAL,
Type.getInternalName(Number.class), "intValue",
Type.INT_TYPE);
}
else if (returnClass == char.class) {
// INVOKEVIRTUAL java/lang/Character charValue ()C
_assertMethodInsnNode(
iterator.next(), Opcodes.INVOKEVIRTUAL,
Type.getInternalName(Character.class), "charValue",
Type.CHAR_TYPE);
}
else if (returnClass == double.class) {
// INVOKEVIRTUAL java/lang/Number doubleValue ()D
_assertMethodInsnNode(
iterator.next(), Opcodes.INVOKEVIRTUAL,
Type.getInternalName(Number.class), "doubleValue",
Type.DOUBLE_TYPE);
}
else if (returnClass == float.class) {
// INVOKEVIRTUAL java/lang/Number floatValue ()F
_assertMethodInsnNode(
iterator.next(), Opcodes.INVOKEVIRTUAL,
Type.getInternalName(Number.class), "floatValue",
Type.FLOAT_TYPE);
}
else if (returnClass == int.class) {
// INVOKEVIRTUAL java/lang/Number intValue ()I
_assertMethodInsnNode(
iterator.next(), Opcodes.INVOKEVIRTUAL,
Type.getInternalName(Number.class), "intValue",
Type.INT_TYPE);
}
else if (returnClass == long.class) {
// INVOKEVIRTUAL java/lang/Number longValue ()J
_assertMethodInsnNode(
iterator.next(), Opcodes.INVOKEVIRTUAL,
Type.getInternalName(Number.class), "longValue",
Type.LONG_TYPE);
}
else if (returnClass == short.class) {
// INVOKEVIRTUAL java/lang/Number intValue ()I
_assertMethodInsnNode(
iterator.next(), Opcodes.INVOKEVIRTUAL,
Type.getInternalName(Number.class), "intValue",
Type.INT_TYPE);
}
// xRETURN
_assertInsnNode(
iterator.next(), returnType.getOpcode(Opcodes.IRETURN));
// nullCheckLabel
Assert.assertSame(nullCheckLabelNode, iterator.next());
// xRETURN null/0
if (!returnClass.isPrimitive()) {
_assertInsnNode(iterator.next(), Opcodes.ACONST_NULL);
_assertInsnNode(iterator.next(), Opcodes.ARETURN);
}
else if (returnClass == void.class) {
_assertInsnNode(iterator.next(), Opcodes.RETURN);
}
else if (returnClass == float.class) {
_assertInsnNode(iterator.next(), Opcodes.FCONST_0);
_assertInsnNode(iterator.next(), Opcodes.FRETURN);
}
else if (returnClass == double.class) {
_assertInsnNode(iterator.next(), Opcodes.DCONST_0);
_assertInsnNode(iterator.next(), Opcodes.DRETURN);
}
else if (returnClass == long.class) {
_assertInsnNode(iterator.next(), Opcodes.LCONST_0);
_assertInsnNode(iterator.next(), Opcodes.LRETURN);
}
else {
_assertInsnNode(iterator.next(), Opcodes.ICONST_0);
_assertInsnNode(iterator.next(), Opcodes.IRETURN);
}
}
else {
if (returnClass != Object.class) {
// CHECKCAST
_assertTypeInsnNode(
iterator.next(), Opcodes.CHECKCAST, returnClass);
}
// ARETURN
_assertInsnNode(iterator.next(), Opcodes.ARETURN);
}
}
Assert.assertFalse(iterator.hasNext());
}
private void _doTestGenerateSkeletonClassFunction(Class<?> clazz)
throws Exception {
Class<? extends IntrabandProxySkeleton> skeletonClass =
IntrabandProxyUtil.generateSkeletonClass(_classLoader, clazz);
Constructor<? extends IntrabandProxySkeleton> constructor =
skeletonClass.getConstructor(TargetLocator.class);
TestGenerateTargetLocator testGenerateTargetLocator =
new TestGenerateTargetLocator(clazz);
IntrabandProxySkeleton intrabandProxySkeleton = constructor.newInstance(
testGenerateTargetLocator);
Assert.assertSame(
testGenerateTargetLocator,
ReflectionTestUtil.getFieldValue(
intrabandProxySkeleton, "_targetLocator"));
MockIntraband mockIntraband = new MockIntraband();
MockRegistrationReference mockRegistrationReference =
new MockRegistrationReference(mockIntraband);
Datagram datagram = Datagram.createRequestDatagram(
SystemDataType.PROXY.getValue(), new byte[0]);
String targetId = "targetId";
List<Method> proxyMethods = _getProxyMethods(clazz);
for (int i = 0; i < proxyMethods.size() + 1; i++) {
Serializer serializer = new Serializer();
serializer.writeString(targetId);
serializer.writeInt(i);
if (i == proxyMethods.size()) {
try (CaptureHandler captureHandler =
JDKLoggerTestUtil.configureJDKLogger(
skeletonClass.getName(), Level.SEVERE)) {
intrabandProxySkeleton.dispatch(
mockRegistrationReference, datagram,
new Deserializer(serializer.toByteBuffer()));
List<LogRecord> logRecords = captureHandler.getLogRecords();
Assert.assertEquals(
logRecords.toString(), 1, logRecords.size());
LogRecord logRecord = logRecords.get(0);
Assert.assertEquals(
"Unable to dispatch", logRecord.getMessage());
Throwable throwable = logRecord.getThrown();
Assert.assertSame(
IllegalArgumentException.class, throwable.getClass());
Assert.assertEquals(
"Unknow method index " + i +
" for proxy methods mappings " +
ReflectionTestUtil.getFieldValue(
skeletonClass, "_PROXY_METHODS_MAPPING"),
throwable.getMessage());
}
break;
}
Method proxyMethod = proxyMethods.get(i);
for (Class<?> parameterType : proxyMethod.getParameterTypes()) {
_writeToSerializer(serializer, parameterType);
}
Deserializer deserializer = new Deserializer(
serializer.toByteBuffer());
intrabandProxySkeleton.dispatch(
mockRegistrationReference, datagram, deserializer);
Class<?> returnType = proxyMethod.getReturnType();
if (returnType == void.class) {
Assert.assertNull(mockIntraband.getDatagram());
Assert.assertNull(mockIntraband.getRegistrationReference());
}
else {
Datagram responseDatagram = mockIntraband.getDatagram();
deserializer = new Deserializer(
responseDatagram.getDataByteBuffer());
RPCResponse rpcResponse = deserializer.readObject();
Assert.assertEquals(
_sampleValueMap.get(returnType), rpcResponse.getResult());
Assert.assertSame(
mockRegistrationReference,
mockIntraband.getRegistrationReference());
}
}
}
private void _doTestGenerateSkeletonClassStructure(Class<?> clazz)
throws Exception {
Class<?> skeletonClass = IntrabandProxyUtil.generateSkeletonClass(
_classLoader, clazz);
// Class signature
Assert.assertEquals(Modifier.PUBLIC, skeletonClass.getModifiers());
Assert.assertArrayEquals(
new Class<?>[] {IntrabandProxySkeleton.class},
skeletonClass.getInterfaces());
// Fields
_assertDeclaredField(
skeletonClass, "PROXY_METHOD_SIGNATURES",
Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL, String[].class);
String[] proxyMethodSignatures =
IntrabandProxyUtil.getProxyMethodSignatures(skeletonClass);
Assert.assertArrayEquals(
_buildProxyMethodSignatures(clazz), proxyMethodSignatures);
StringBundler sb = new StringBundler(
proxyMethodSignatures.length * 4 + 1);
sb.append(StringPool.OPEN_CURLY_BRACE);
for (int i = 0; i < proxyMethodSignatures.length; i++) {
sb.append(i);
sb.append(" -> ");
sb.append(proxyMethodSignatures[i]);
sb.append(StringPool.COMMA_AND_SPACE);
}
if (proxyMethodSignatures.length > 0) {
sb.setIndex(sb.index() - 1);
}
sb.append(StringPool.CLOSE_CURLY_BRACE);
Field proxyMethodsMappingField = _assertDeclaredField(
skeletonClass, "_PROXY_METHODS_MAPPING",
Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL, String.class);
Assert.assertEquals(sb.toString(), proxyMethodsMappingField.get(null));
Field logField = _assertDeclaredField(
skeletonClass, "_log",
Modifier.FINAL | Modifier.PRIVATE | Modifier.STATIC, Log.class);
LogWrapper logWrapper = (LogWrapper)logField.get(null);
Jdk14LogImpl jdk14LogImpl = (Jdk14LogImpl)logWrapper.getWrappedLog();
Logger logger = jdk14LogImpl.getWrappedLogger();
Assert.assertEquals(skeletonClass.getName(), logger.getName());
_assertDeclaredField(
skeletonClass, "_targetLocator", Modifier.PRIVATE | Modifier.FINAL,
TargetLocator.class);
// Constructors
Constructor<?>[] constructors = skeletonClass.getConstructors();
Assert.assertEquals(
Arrays.toString(constructors), 1, constructors.length);
Constructor<?> constructor = constructors[0];
Assert.assertArrayEquals(
new Class<?>[] {TargetLocator.class},
constructor.getParameterTypes());
// Methods
_assertDeclaredMethod(
skeletonClass, "dispatch",
new Class<?>[] {
RegistrationReference.class, Datagram.class, Deserializer.class
},
Modifier.PUBLIC, void.class);
_assertDeclaredMethod(
skeletonClass, "doDispatch",
new Class<?>[] {
RegistrationReference.class, Datagram.class, Deserializer.class
},
Modifier.PROTECTED, void.class, Exception.class);
_assertDeclaredMethod(
skeletonClass, "_getProxyMethodSignatures", new Class<?>[0],
Modifier.STATIC | Modifier.PRIVATE, String[].class);
_assertDeclaredMethod(
skeletonClass, "_getProxyMethodsMapping",
new Class<?>[] {String[].class}, Modifier.STATIC | Modifier.PRIVATE,
String.class);
_assertDeclaredMethod(
skeletonClass, "_sendResponse",
new Class<?>[] {
RegistrationReference.class, Datagram.class, RPCResponse.class
},
Modifier.PRIVATE, void.class);
_assertDeclaredMethod(
skeletonClass, "_unknownMethodIndex", new Class<?>[] {int.class},
Modifier.PRIVATE, void.class);
Method[] declaredMethods = skeletonClass.getDeclaredMethods();
Assert.assertEquals(
Arrays.toString(declaredMethods), 6, declaredMethods.length);
}
private void _doTestGenerateStubClassStructure(
Class<?> clazz, String skeletonId)
throws Exception {
Class<?> stubClass = IntrabandProxyUtil.generateStubClass(
_classLoader, clazz, skeletonId);
// Class signature
Assert.assertEquals(Modifier.PUBLIC, stubClass.getModifiers());
if (clazz.isInterface()) {
Assert.assertArrayEquals(
new Class<?>[] {clazz}, stubClass.getInterfaces());
}
else {
Assert.assertArrayEquals(
clazz.getInterfaces(), stubClass.getInterfaces());
}
// Fields
_assertDeclaredField(
stubClass, "PROXY_METHOD_SIGNATURES",
Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL, String[].class);
Assert.assertArrayEquals(
_buildProxyMethodSignatures(clazz),
IntrabandProxyUtil.getProxyMethodSignatures(stubClass));
_assertDeclaredField(
stubClass, "_id", Modifier.PRIVATE | Modifier.FINAL, String.class);
Field proxyTypeField = _assertDeclaredField(
stubClass, "_PROXY_TYPE",
Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL, byte.class);
Assert.assertEquals(
SystemDataType.PROXY.getValue(), proxyTypeField.getByte(null));
_assertDeclaredField(
stubClass, "_intraband", Modifier.PRIVATE | Modifier.FINAL,
Intraband.class);
_assertDeclaredField(
stubClass, "_registrationReference",
Modifier.PRIVATE | Modifier.FINAL, RegistrationReference.class);
_assertDeclaredField(
stubClass, "_exceptionHandler", Modifier.PRIVATE | Modifier.FINAL,
ExceptionHandler.class);
Field[] fields = stubClass.getDeclaredFields();
Assert.assertEquals(Arrays.toString(fields), 6, fields.length);
// Constructors
Constructor<?>[] constructors = stubClass.getConstructors();
Assert.assertEquals(
Arrays.toString(constructors), 1, constructors.length);
Constructor<?> constructor = constructors[0];
Assert.assertArrayEquals(
new Class<?>[] {
String.class, RegistrationReference.class,
ExceptionHandler.class
},
constructor.getParameterTypes());
// Methods
_assertDeclaredMethod(
stubClass, "_getProxyMethodSignatures", new Class<?>[0],
Modifier.STATIC | Modifier.PRIVATE, String[].class);
_assertDeclaredMethod(
stubClass, "_syncSend", new Class<?>[] {Serializer.class},
Modifier.PRIVATE, Serializable.class);
_assertDeclaredMethod(
stubClass, "_send", new Class<?>[] {Serializer.class},
Modifier.PRIVATE, void.class);
List<Method> idMethods = _getIdMethods(clazz);
for (Method idMethod : idMethods) {
_assertDeclaredMethod(
stubClass, idMethod.getName(), idMethod.getParameterTypes(),
Modifier.PUBLIC, idMethod.getReturnType(),
idMethod.getExceptionTypes());
}
List<Method> proxyMethods = _getProxyMethods(clazz);
for (Method proxyMethod : proxyMethods) {
_assertDeclaredMethod(
stubClass, proxyMethod.getName(),
proxyMethod.getParameterTypes(),
proxyMethod.getModifiers() & ~Modifier.ABSTRACT,
proxyMethod.getReturnType(), proxyMethod.getExceptionTypes());
}
List<Method> emptyMethods = _getEmptyMethods(clazz);
for (Method emptyMethod : emptyMethods) {
_assertDeclaredMethod(
stubClass, emptyMethod.getName(),
emptyMethod.getParameterTypes(), Modifier.PUBLIC,
emptyMethod.getReturnType(), emptyMethod.getExceptionTypes());
}
Method[] declaredMethods = stubClass.getDeclaredMethods();
Assert.assertEquals(
Arrays.toString(declaredMethods),
3 + idMethods.size() + proxyMethods.size() + emptyMethods.size(),
declaredMethods.length);
}
private void _doTestGetClass(
ClassLoader classLoader, final MethodHandler methodHandler)
throws Exception {
FutureTask<Class<?>> futureTask = new FutureTask<Class<?>>(
new Callable<Class<?>>() {
@Override
public Class<?> call() throws Exception {
return (Class<?>)methodHandler.invoke();
}
});
Thread thread = new Thread(futureTask);
Class<?> stubClass = null;
synchronized (classLoader) {
thread.start();
while (thread.getState() != Thread.State.BLOCKED);
stubClass = (Class<?>)methodHandler.invoke();
}
Assert.assertSame(stubClass, futureTask.get());
// Load from ClassLoader cache
Assert.assertSame(stubClass, methodHandler.invoke());
}
private void _doTestToClass(
boolean proxyClassesDumpEnabled, boolean logEnabled)
throws FileNotFoundException {
class TestClass {
}
ClassNode classNode = _loadClass(TestClass.class);
MethodNode methodNode = new MethodNode(
Opcodes.ACC_PUBLIC, "<clinit>", "()V", null, null);
methodNode.visitCode();
methodNode.visitInsn(Opcodes.RETURN);
methodNode.visitEnd();
List<MethodNode> methodNodes = classNode.methods;
methodNodes.add(methodNode);
ClassLoader classLoader = new URLClassLoader(new URL[0], null);
Level level = Level.WARNING;
if (logEnabled) {
level = Level.INFO;
}
try (CaptureHandler captureHandler =
JDKLoggerTestUtil.configureJDKLogger(
IntrabandProxyUtil.class.getName(), level)) {
List<LogRecord> logRecords = captureHandler.getLogRecords();
IntrabandProxyUtil.toClass(classNode, classLoader);
if (proxyClassesDumpEnabled) {
StringBundler sb = new StringBundler(6);
sb.append(SystemProperties.get(SystemProperties.TMP_DIR));
sb.append(StringPool.SLASH);
sb.append(PropsValues.INTRABAND_PROXY_DUMP_CLASSES_DIR);
sb.append(StringPool.SLASH);
sb.append(classNode.name);
sb.append(".class");
String filePath = sb.toString();
File classFile = new File(filePath);
Assert.assertTrue(classFile.exists());
ClassNode reloadedClassNode = _loadClass(
new FileInputStream(classFile));
MethodNode clinitMethodNode = ASMUtil.findMethodNode(
reloadedClassNode.methods, "<clinit>", Type.VOID_TYPE);
InsnList insnList = clinitMethodNode.instructions;
Assert.assertEquals(1, insnList.size());
_assertInsnNode(insnList.getFirst(), Opcodes.RETURN);
if (logEnabled) {
Assert.assertEquals(
logRecords.toString(), 1, logRecords.size());
LogRecord logRecord = logRecords.get(0);
Assert.assertEquals(
logRecord.getMessage(),
"Dumpped class ".concat(filePath));
}
}
if (!proxyClassesDumpEnabled || !logEnabled) {
Assert.assertTrue(logRecords.isEmpty());
}
}
try {
IntrabandProxyUtil.toClass(classNode, classLoader);
Assert.fail();
}
catch (RuntimeException re) {
Throwable throwable = re.getCause();
Assert.assertSame(
InvocationTargetException.class, throwable.getClass());
throwable = throwable.getCause();
Assert.assertSame(LinkageError.class, throwable.getClass());
String message = throwable.getMessage();
Assert.assertTrue(
message.contains(
"duplicate class definition for name: \"" +
Type.getInternalName(TestClass.class) + "\""));
}
}
private void _doTestValidate(boolean skeletonOrStub) throws Exception {
try {
IntrabandProxyUtil.validate(_classLoader, Id.class, skeletonOrStub);
Assert.fail();
}
catch (IllegalArgumentException iae) {
Assert.assertEquals(
Id.class + " is an annotation", iae.getMessage());
}
try {
IntrabandProxyUtil.validate(
_classLoader, int[].class, skeletonOrStub);
Assert.fail();
}
catch (IllegalArgumentException iae) {
Assert.assertEquals(int[].class + " is an array", iae.getMessage());
}
try {
IntrabandProxyUtil.validate(
_classLoader, SystemDataType.class, skeletonOrStub);
Assert.fail();
}
catch (IllegalArgumentException iae) {
Assert.assertEquals(
SystemDataType.class + " is an enum", iae.getMessage());
}
try {
IntrabandProxyUtil.validate(
_classLoader, int.class, skeletonOrStub);
Assert.fail();
}
catch (IllegalArgumentException iae) {
Assert.assertEquals(
int.class + " is a primitive", iae.getMessage());
}
ClassLoader classLoader = new URLClassLoader(new URL[0], null);
try {
IntrabandProxyUtil.validate(
classLoader, IntrabandProxyUtilTest.class, skeletonOrStub);
Assert.fail();
}
catch (IllegalArgumentException iae) {
Assert.assertEquals(
IntrabandProxyUtilTest.class +
" is not visible from class loader " + classLoader,
iae.getMessage());
}
class TestValidateClass1 {
@SuppressWarnings("unused")
private String[] PROXY_METHOD_SIGNATURES;
}
try {
IntrabandProxyUtil.validate(
_classLoader, TestValidateClass1.class, skeletonOrStub);
Assert.fail();
}
catch (IllegalArgumentException iae) {
Field field = TestValidateClass1.class.getDeclaredField(
"PROXY_METHOD_SIGNATURES");
Assert.assertEquals(
"Field " + field + " is expected to be of type " +
String[].class + " and static",
iae.getMessage());
}
if (skeletonOrStub) {
class TestValidateClass2 {
@SuppressWarnings("unused")
private String _PROXY_METHODS_MAPPING;
}
try {
IntrabandProxyUtil.validate(
_classLoader, TestValidateClass2.class, true);
Assert.fail();
}
catch (IllegalArgumentException iae) {
Field field = TestValidateClass2.class.getDeclaredField(
"_PROXY_METHODS_MAPPING");
Assert.assertEquals(
"Field " + field + " is expected to be of type " +
String.class + " and static",
iae.getMessage());
}
class TestValidateClass3 {
@SuppressWarnings("unused")
private String _log;
}
try {
IntrabandProxyUtil.validate(
_classLoader, TestValidateClass3.class, true);
Assert.fail();
}
catch (IllegalArgumentException iae) {
Field field = TestValidateClass3.class.getDeclaredField("_log");
Assert.assertEquals(
"Field " + field + " is expected to be of type " +
Log.class + " and static",
iae.getMessage());
}
class TestValidateClass4 {
@SuppressWarnings("unused")
private Object _targetLocator;
}
try {
IntrabandProxyUtil.validate(
_classLoader, TestValidateClass4.class, true);
Assert.fail();
}
catch (IllegalArgumentException iae) {
Field field = TestValidateClass4.class.getDeclaredField(
"_targetLocator");
Assert.assertEquals(
"Field " + field + " is expected to be of type " +
TargetLocator.class + " and not static",
iae.getMessage());
}
}
else {
class TestValidateClass5 {
@SuppressWarnings("unused")
int _proxyType = 0;
}
try {
IntrabandProxyUtil.validate(
_classLoader, TestValidateClass5.class, false);
Assert.fail();
}
catch (IllegalArgumentException iae) {
Field field = TestValidateClass5.class.getDeclaredField(
"_proxyType");
Assert.assertEquals(
"Field " + field + " is expected to be of type " +
byte.class + " and static",
iae.getMessage());
}
class TestValidateClass6 {
@SuppressWarnings("unused")
private Object _id;
}
try {
IntrabandProxyUtil.validate(
_classLoader, TestValidateClass6.class, false);
Assert.fail();
}
catch (IllegalArgumentException iae) {
Field field = TestValidateClass6.class.getDeclaredField("_id");
Assert.assertEquals(
"Field " + field + " is expected to be of type " +
String.class + " and not static",
iae.getMessage());
}
class TestValidateClass7 {
@SuppressWarnings("unused")
private Object _intraband;
}
try {
IntrabandProxyUtil.validate(
_classLoader, TestValidateClass7.class, false);
Assert.fail();
}
catch (IllegalArgumentException iae) {
Field field = TestValidateClass7.class.getDeclaredField(
"_intraband");
Assert.assertEquals(
"Field " + field + " is expected to be of type " +
Intraband.class + " and not static",
iae.getMessage());
}
class TestValidateClass8 {
@SuppressWarnings("unused")
private Object _registrationReference;
}
try {
IntrabandProxyUtil.validate(
_classLoader, TestValidateClass8.class, false);
Assert.fail();
}
catch (IllegalArgumentException iae) {
Field field = TestValidateClass8.class.getDeclaredField(
"_registrationReference");
Assert.assertEquals(
"Field " + field + " is expected to be of type " +
RegistrationReference.class + " and not static",
iae.getMessage());
}
class TestValidateClass9 {
@SuppressWarnings("unused")
private Object _exceptionHandler;
}
try {
IntrabandProxyUtil.validate(
_classLoader, TestValidateClass9.class, false);
Assert.fail();
}
catch (IllegalArgumentException iae) {
Field field = TestValidateClass9.class.getDeclaredField(
"_exceptionHandler");
Assert.assertEquals(
"Field " + field + " is expected to be of type " +
ExceptionHandler.class + " and not static",
iae.getMessage());
}
}
IntrabandProxyUtil.validate(
_classLoader, TestValidateClass.class, skeletonOrStub);
}
private List<Method> _getCopiedMethods(Class<?> clazz) {
List<Method> emptyMethods = new ArrayList<>();
for (Method method : ReflectionUtil.getVisibleMethods(clazz)) {
String name = method.getName();
if (!Modifier.isAbstract(method.getModifiers()) &&
name.startsWith("copy") &&
(method.getAnnotation(Id.class) == null) &&
(method.getAnnotation(Proxy.class) == null)) {
emptyMethods.add(method);
}
}
return emptyMethods;
}
private List<Method> _getEmptyMethods(Class<?> clazz) {
List<Method> emptyMethods = new ArrayList<>();
for (Method method : ReflectionUtil.getVisibleMethods(clazz)) {
if (Modifier.isAbstract(method.getModifiers()) &&
(method.getAnnotation(Id.class) == null) &&
(method.getAnnotation(Proxy.class) == null)) {
emptyMethods.add(method);
}
}
return emptyMethods;
}
private List<Method> _getIdMethods(Class<?> clazz) {
List<Method> idMethods = new ArrayList<>();
for (Method method : ReflectionUtil.getVisibleMethods(clazz)) {
if (method.getAnnotation(Id.class) != null) {
idMethods.add(method);
}
}
return idMethods;
}
private List<Method> _getProxyMethods(Class<?> clazz) {
List<Method> proxyMethods = new ArrayList<>();
for (Method method : ReflectionUtil.getVisibleMethods(clazz)) {
if (method.getAnnotation(Proxy.class) != null) {
proxyMethods.add(method);
}
}
Collections.sort(proxyMethods, new MethodComparator());
return proxyMethods;
}
private ClassNode _loadClass(Class<?> clazz) {
ClassLoader classLoader = clazz.getClassLoader();
String name = clazz.getName();
name = name.replace(CharPool.PERIOD, CharPool.SLASH);
return _loadClass(
classLoader.getResourceAsStream(name.concat(".class")));
}
private ClassNode _loadClass(InputStream is) {
ClassReader classReader = null;
try {
classReader = new ClassReader(is);
}
catch (IOException ioe) {
throw new RuntimeException(ioe);
}
ClassNode classNode = new ClassNode();
classReader.accept(classNode, 0);
return classNode;
}
private static final Map<Class<?>, Class<?>> _autoboxingMap =
new HashMap<>();
private static final ClassLoader _classLoader =
IntrabandProxyUtilTest.class.getClassLoader();
private static final Map<Class<?>, Object> _defaultValueMap =
new HashMap<>();
private static final Map<Class<?>, Object> _sampleValueMap =
new HashMap<>();
private static final Type[] _types = {
Type.BOOLEAN_TYPE, Type.BYTE_TYPE, Type.CHAR_TYPE, Type.DOUBLE_TYPE,
Type.FLOAT_TYPE, Type.INT_TYPE, Type.LONG_TYPE, Type.SHORT_TYPE,
Type.getType(String.class), Type.getType(Object.class)
};
static {
_autoboxingMap.put(boolean.class, Boolean.class);
_autoboxingMap.put(byte.class, Number.class);
_autoboxingMap.put(char.class, Character.class);
_autoboxingMap.put(double.class, Number.class);
_autoboxingMap.put(float.class, Number.class);
_autoboxingMap.put(int.class, Number.class);
_autoboxingMap.put(long.class, Number.class);
_autoboxingMap.put(short.class, Number.class);
_defaultValueMap.put(boolean.class, Boolean.FALSE);
_defaultValueMap.put(byte.class, (byte)0);
_defaultValueMap.put(char.class, (char)0);
_defaultValueMap.put(double.class, (double)0);
_defaultValueMap.put(float.class, (float)0);
_defaultValueMap.put(int.class, 0);
_defaultValueMap.put(long.class, (long)0);
_defaultValueMap.put(short.class, (short)0);
_defaultValueMap.put(String.class, null);
_defaultValueMap.put(Date.class, null);
_defaultValueMap.put(Object.class, null);
_defaultValueMap.put(void.class, null);
_sampleValueMap.put(boolean.class, Boolean.TRUE);
_sampleValueMap.put(byte.class, (byte)11);
_sampleValueMap.put(char.class, 'X');
_sampleValueMap.put(double.class, 12.345);
_sampleValueMap.put(float.class, 5.325F);
_sampleValueMap.put(int.class, 127);
_sampleValueMap.put(long.class, (long)82465);
_sampleValueMap.put(short.class, (short)-35);
_sampleValueMap.put(String.class, "Hello");
_sampleValueMap.put(Date.class, new Date());
_sampleValueMap.put(Object.class, new Locale("en"));
_sampleValueMap.put(void.class, null);
}
private static class AutoReplyMockIntraband extends MockIntraband {
public AutoReplyMockIntraband(String skeletonId, String targetId) {
_skeletonId = skeletonId;
_targetId = targetId;
}
public void setInvocation(Method method, int index) {
_method = method;
_index = index;
}
@Override
protected Datagram processDatagram(Datagram datagram) {
Deserializer deserializer = new Deserializer(
datagram.getDataByteBuffer());
Assert.assertEquals(_skeletonId, deserializer.readString());
Assert.assertEquals(_targetId, deserializer.readString());
Assert.assertEquals(_index, deserializer.readInt());
for (Class<?> parameterType : _method.getParameterTypes()) {
Assert.assertEquals(
_sampleValueMap.get(parameterType),
_readFromDeserializer(deserializer, parameterType));
}
Class<?> returnType = _method.getReturnType();
if (returnType == void.class) {
return null;
}
Serializer serializer = new Serializer();
serializer.writeObject(
new RPCResponse((Serializable)_sampleValueMap.get(returnType)));
return Datagram.createResponseDatagram(
datagram, serializer.toByteBuffer());
}
private int _index;
private Method _method;
private final String _skeletonId;
private final String _targetId;
}
private static class TestExtractMethodsClass1 {
@Id
public static String getId() {
return null;
}
}
private static class TestExtractMethodsClass2 {
@Id
public String getId(Object obj) {
return null;
}
}
private static class TestExtractMethodsClass3 {
@Id
public Object getId() {
return null;
}
}
private static class TestExtractMethodsClass4 {
@Proxy
public static void doStuff() {
}
}
private static class TestGenerateStubFunction1 {
@SuppressWarnings("unused")
public TestGenerateStubFunction1() {
if (_log.isInfoEnabled()) {
_log.info(
TestGenerateStubFunction1.class.getName() + " in <init>");
}
}
private static final Log _log = LogFactoryUtil.getLog(
TestGenerateStubFunction1.class);
static {
if (_log.isInfoEnabled()) {
_log.info(
TestGenerateStubFunction1.class.getName() + " in <clinit>");
}
}
}
private static class TestGenerateTargetLocator implements TargetLocator {
public TestGenerateTargetLocator(Class<?> clazz) {
_clazz = clazz;
}
@Override
public boolean equals(Object obj) {
TestGenerateTargetLocator testGenerateTargetLocator =
(TestGenerateTargetLocator)obj;
return _clazz.equals(testGenerateTargetLocator._clazz);
}
@SuppressWarnings("unused")
public String getId() {
return _id;
}
@Override
public Object getTarget(String id) {
_id = id;
return ProxyUtil.newProxyInstance(
_classLoader, new Class<?>[] {_clazz},
new InvocationHandler() {
@Override
public Object invoke(
Object proxy, Method method, Object[] args) {
Class<?>[] parameterTypes = method.getParameterTypes();
for (int i = 0; i < args.length; i++) {
Assert.assertEquals(
_sampleValueMap.get(parameterTypes[i]),
args[i]);
}
return _sampleValueMap.get(method.getReturnType());
}
});
}
@Override
public int hashCode() {
return super.hashCode();
}
private final Class<?> _clazz;
private String _id;
}
private static class TestValidateClass {
@SuppressWarnings("unused")
private static String _PROXY_METHODS_MAPPING;
@SuppressWarnings("unused")
private static String[] PROXY_METHOD_SIGNATURES;
@SuppressWarnings("unused")
private static Log _log;
@SuppressWarnings("unused")
private static byte _proxyType;
@SuppressWarnings("unused")
private ExceptionHandler _exceptionHandler;
@SuppressWarnings("unused")
private String _id;
@SuppressWarnings("unused")
private Intraband _intraband;
@SuppressWarnings("unused")
private RegistrationReference _registrationReference;
@SuppressWarnings("unused")
private TargetLocator _targetLocator;
}
private interface TestEmptyMethodsInterface {
public boolean testBoolean();
public byte testByte();
public char testChar();
public double testDouble();
public float testFloat();
public int testInt();
public long testLong();
public Object testObject();
public short testShort();
public void testVoid();
}
private abstract static class TestExtractMethodsClass5 {
@Proxy
public void doStuff1() {
}
@Proxy(name = "doStuffX")
public void doStuff2() {
}
@SuppressWarnings("unused")
public void doStuff3() {
}
public abstract void doStuff4();
@Id
public String getId1() {
return null;
}
@Id
public String getId2() {
return null;
}
}
private abstract static class TestGenerateClass1
extends TestProxyMethodsClass implements TestGenerateInterface1 {
}
private abstract static class TestGenerateClass2
extends TestProxyMethodsClass implements TestGenerateInterface2 {
}
private interface TestGenerateInterface1
extends Comparable<String>, Callable<String>, Runnable,
TestEmptyMethodsInterface, TestProxyMethodsInterface {
}
private interface TestGenerateInterface2
extends TestIdMethodsInterface, TestGenerateInterface1 {
}
private abstract static class TestGenerateStubFunction2
extends TestProxyMethodsClass
implements TestEmptyMethodsInterface, TestIdMethodsInterface {
@SuppressWarnings("unused")
public void copyMethod1() {
if (_log.isInfoEnabled()) {
_log.info("copyMethod1");
}
}
@SuppressWarnings("unused")
protected void copyMethod2() {
if (_log.isInfoEnabled()) {
_log.info("copyMethod2");
}
}
@SuppressWarnings("unused")
void copyMethod3() {
if (_log.isInfoEnabled()) {
_log.info("copyMethod3");
}
}
@SuppressWarnings("unused")
private void copyMethod4() {
if (_log.isInfoEnabled()) {
_log.info("copyMethod4");
}
}
private static final Log _log = LogFactoryUtil.getLog(
TestGenerateStubFunction2.class);
}
private interface TestIdMethodsInterface {
@Id
public abstract String getId1();
@Id
public abstract String getId2();
}
private abstract static class TestProxyMethodsClass
implements TestProxyMethodsInterface {
@Proxy
protected abstract short syncCallShort(
boolean z, byte b, char c, double d, float f, int i, long j,
short s, String string, Date date, Object obj)
throws InterruptedException, IOException;
@Proxy
abstract Object syncCallObject(
boolean z, byte b, char c, double d, float f, int i, long j,
short s, String string, Date date, Object obj)
throws InterruptedException, IOException;
@Proxy
abstract String syncCallString(
boolean z, byte b, char c, double d, float f, int i, long j,
short s, String string, Date date, Object obj)
throws InterruptedException, IOException;
}
private interface TestProxyMethodsInterface {
@Proxy
public void asyncCall(
boolean z, byte b, char c, double d, float f, int i, long j,
short s, String string, Date date, Object obj)
throws InterruptedException, IOException;
@Proxy
public boolean syncCallBoolean(
boolean z, byte b, char c, double d, float f, int i, long j,
short s, String string, Date date, Object obj)
throws InterruptedException, IOException;
@Proxy
public byte syncCallByte(
boolean z, byte b, char c, double d, float f, int i, long j,
short s, String string, Date date, Object obj)
throws InterruptedException, IOException;
@Proxy
public char syncCallChar(
boolean z, byte b, char c, double d, float f, int i, long j,
short s, String string, Date date, Object obj)
throws InterruptedException, IOException;
@Proxy
public double syncCallDouble(
boolean z, byte b, char c, double d, float f, int i, long j,
short s, String string, Date date, Object obj)
throws InterruptedException, IOException;
@Proxy
public float syncCallFloat(
boolean z, byte b, char c, double d, float f, int i, long j,
short s, String string, Date date, Object obj)
throws InterruptedException, IOException;
@Proxy
public int syncCallInt(
boolean z, byte b, char c, double d, float f, int i, long j,
short s, String string, Date date, Object obj)
throws InterruptedException, IOException;
@Proxy
public long syncCallLong(
boolean z, byte b, char c, double d, float f, int i, long j,
short s, String string, Date date, Object obj)
throws InterruptedException, IOException;
}
}