/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.harmony.tests.java.lang.reflect;
import tests.support.Support_Proxy_I1;
import tests.support.Support_Proxy_I2;
import tests.support.Support_Proxy_ParentException;
import tests.support.Support_Proxy_SubException;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import java.security.AllPermission;
import java.security.ProtectionDomain;
import java.util.ArrayList;
public class ProxyTest extends junit.framework.TestCase {
/*
* When multiple interfaces define the same method, the list of thrown
* exceptions are those which can be mapped to another exception in the
* other method:
*
* String foo(String s) throws SubException, LinkageError;
*
* UndeclaredThrowableException wrappers any checked exception which is not
* in the merged list. So ParentException would be wrapped, BUT LinkageError
* would not be since its not an Error/RuntimeException.
*
* interface I1 { String foo(String s) throws ParentException, LinkageError; }
* interface I2 { String foo(String s) throws SubException, Error; }
*/
interface Broken1 {
public float method(float _number0, float _number1);
}
class Broken1Invoke implements InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return args[1];
}
}
class ProxyCoonstructorTest extends Proxy {
protected ProxyCoonstructorTest(InvocationHandler h) {
super(h);
}
}
/**
* java.lang.reflect.Proxy#getProxyClass(java.lang.ClassLoader,
* java.lang.Class[])
*/
public void test_getProxyClassLjava_lang_ClassLoader$Ljava_lang_Class() {
Class proxy = Proxy.getProxyClass(Support_Proxy_I1.class
.getClassLoader(), new Class[] { Support_Proxy_I1.class });
assertTrue("Did not create a Proxy subclass ",
proxy.getSuperclass() == Proxy.class);
assertTrue("Does not believe its a Proxy class ", Proxy
.isProxyClass(proxy));
assertTrue("Does not believe it's a Proxy class ", Proxy
.isProxyClass(Proxy.getProxyClass(null,
new Class[] { Comparable.class })));
try {
Proxy.getProxyClass(Support_Proxy_I1.class.getClassLoader(),
(Class<?>[]) null);
fail("NPE expected");
} catch (NullPointerException expected) {
}
try {
Proxy.getProxyClass(Support_Proxy_I1.class.getClassLoader(),
new Class<?>[] {Support_Proxy_I1.class, null});
fail("NPE expected");
} catch (NullPointerException expected) {
}
}
/**
* java.lang.reflect.Proxy#Proxy(java.lang.reflect.InvocationHandler)
*/
public void test_ProxyLjava_lang_reflect_InvocationHandler() {
assertNotNull(new ProxyCoonstructorTest(new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}
}));
}
/**
* java.lang.reflect.Proxy#newProxyInstance(java.lang.ClassLoader,
* java.lang.Class[], java.lang.reflect.InvocationHandler)
*/
public void test_newProxyInstanceLjava_lang_ClassLoader$Ljava_lang_ClassLjava_lang_reflect_InvocationHandler()
throws Exception {
Object p = Proxy.newProxyInstance(Support_Proxy_I1.class
.getClassLoader(), new Class[] { Support_Proxy_I1.class,
Support_Proxy_I2.class }, new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if (method.getName().equals("equals"))
return new Boolean(proxy == args[0]);
if (method.getName().equals("array"))
return new int[] { (int) ((long[]) args[0])[1], -1 };
if (method.getName().equals("string")) {
if ("".equals(args[0]))
throw new Support_Proxy_SubException();
if ("clone".equals(args[0]))
throw new Support_Proxy_ParentException();
if ("error".equals(args[0]))
throw new ArrayStoreException();
if ("any".equals(args[0]))
throw new IllegalAccessException();
}
return null;
}
});
Support_Proxy_I1 proxy = (Support_Proxy_I1) p;
assertTrue("Failed identity test ", proxy.equals(proxy));
assertTrue("Failed not equals test ", !proxy.equals(""));
int[] result = (int[]) proxy.array(new long[] { 100L, -200L });
assertEquals("Failed primitive type conversion test ", -200, result[0]);
try {
proxy.string("");
fail("Problem converting exception");
} catch (Support_Proxy_SubException e) {
}
try {
proxy.string("clone");
fail("Problem converting exception");
} catch (UndeclaredThrowableException e) {
assertSame(Support_Proxy_ParentException.class, e.getCause().getClass());
}
try {
proxy.string("error");
fail("Problem converting exception");
} catch (ArrayStoreException e) {
}
try {
proxy.string("any");
fail("Problem converting exception");
} catch (UndeclaredThrowableException e) {
assertSame(IllegalAccessException.class, e.getCause().getClass());
}
Broken1 proxyObject = (Broken1) Proxy.newProxyInstance(Broken1.class
.getClassLoader(), new Class[] { Broken1.class },
new Broken1Invoke());
float brokenResult = proxyObject.method(2.1f, 5.8f);
assertTrue("Invalid invoke result", brokenResult == 5.8f);
}
/**
* java.lang.reflect.Proxy#isProxyClass(java.lang.Class)
*/
public void test_isProxyClassLjava_lang_Class() {
Class proxy = Proxy.getProxyClass(Support_Proxy_I1.class
.getClassLoader(), new Class[] { Support_Proxy_I1.class });
class Fake extends Proxy {
Fake() {
super(null);
}
}
Proxy fake = new Proxy(new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}
}) {
};
assertTrue("Does not believe its a Proxy class ", Proxy
.isProxyClass(proxy));
assertTrue("Proxy subclasses do not count ", !Proxy
.isProxyClass(Fake.class));
assertTrue("Is not a runtime generated Proxy class ", !Proxy
.isProxyClass(fake.getClass()));
try{
Proxy.isProxyClass(null);
fail("NPE was not thrown");
} catch (NullPointerException expected){
}
}
/**
* java.lang.reflect.Proxy#getInvocationHandler(java.lang.Object)
*/
public void test_getInvocationHandlerLjava_lang_Object() {
InvocationHandler handler = new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}
};
Object p = Proxy.newProxyInstance(Support_Proxy_I1.class
.getClassLoader(), new Class[] { Support_Proxy_I1.class },
handler);
assertTrue("Did not return invocation handler ", Proxy
.getInvocationHandler(p) == handler);
try {
Proxy.getInvocationHandler("");
fail("Did not detect non proxy object");
} catch (IllegalArgumentException e) {
}
}
//Regression Test for HARMONY-2355
public void test_newProxyInstance_withCompatibleReturnTypes() {
Object o = Proxy
.newProxyInstance(this.getClass().getClassLoader(),
new Class[] { ITestReturnObject.class,
ITestReturnString.class },
new TestProxyHandler(new TestProxyImpl()));
assertNotNull(o);
}
public void test_newProxyInstance_withNonCompatibleReturnTypes() {
try {
Proxy.newProxyInstance(this.getClass().getClassLoader(),
new Class[] { ITestReturnInteger.class,
ITestReturnString.class }, new TestProxyHandler(
new TestProxyImpl()));
fail("should throw IllegalArgumentException");
} catch (IllegalArgumentException e) {
// expected
}
}
@SuppressWarnings("unchecked")
public void test_ProxyClass_withParentAndSubInThrowList() throws SecurityException, NoSuchMethodException {
TestParentIntf myImpl = new MyImplWithParentAndSubInThrowList();
Class<?> c = Proxy.getProxyClass(myImpl.getClass().getClassLoader(), myImpl.getClass().getInterfaces());
Method m = c.getMethod("test", (Class<?>[]) null);
Class<?>[] exceptions = m.getExceptionTypes();
ArrayList<Class> exps = new ArrayList<Class>();
for (Class<?> exp : exceptions) {
exps.add(exp);
}
assertTrue(exps.contains(Exception.class));
}
public static interface ITestReturnObject {
Object f();
}
public static interface ITestReturnString {
String f();
}
public static interface ITestReturnInteger {
Integer f();
}
public static class TestProxyImpl implements ITestReturnObject,
ITestReturnString {
public String f() {
// do nothing
return null;
}
}
public static class TestProxyHandler implements InvocationHandler {
private Object proxied;
public TestProxyHandler(Object object) {
proxied = object;
}
public Object invoke(Object object, Method method, Object[] args)
throws Throwable {
// do nothing
return method.invoke(proxied, args);
}
}
class MyImplWithParentAndSubInThrowList implements TestSubIntf {
public void test() throws Exception {
throw new Exception();
}
}
protected void setUp() {
}
protected void tearDown() {
}
}
interface PkgIntf {
}
interface TestParentIntf {
//IOException is a subclass of Exception
public void test() throws IOException, Exception;
}
interface TestSubIntf extends TestParentIntf {
}