Path: blob/master/test/jdk/sun/reflect/ReflectionFactory/ReflectionFactoryTest.java
41149 views
/*1* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.io.ByteArrayInputStream;24import java.io.ByteArrayOutputStream;25import java.io.Externalizable;26import java.io.IOException;27import java.io.ObjectInput;28import java.io.ObjectInputStream;29import java.io.ObjectOutput;30import java.io.ObjectOutputStream;31import java.io.OptionalDataException;32import java.io.Serializable;33import java.lang.invoke.MethodHandle;34import java.lang.reflect.Constructor;35import java.lang.reflect.InvocationTargetException;3637import sun.reflect.ReflectionFactory;3839import org.testng.Assert;40import org.testng.annotations.BeforeClass;41import org.testng.annotations.Test;42import org.testng.annotations.DataProvider;43import org.testng.TestNG;4445/*46* @test47* @bug 8137058 8164908 816898048* @run testng ReflectionFactoryTest49* @run testng/othervm/policy=security.policy ReflectionFactoryTest50* @summary Basic test for the unsupported ReflectionFactory51* @modules jdk.unsupported52*/5354public class ReflectionFactoryTest {5556// Initialized by init()57static ReflectionFactory factory;5859@DataProvider(name = "ClassConstructors")60static Object[][] classConstructors() {61return new Object[][] {62{Object.class},63{Foo.class},64{Bar.class},65};66}6768@BeforeClass69static void init() {70factory = ReflectionFactory.getReflectionFactory();71}7273/**74* Test that the correct Constructor is selected and run.75* @param type type of object to create76* @throws NoSuchMethodException - error77* @throws InstantiationException - error78* @throws IllegalAccessException - error79* @throws InvocationTargetException - error80*/81@Test(dataProvider="ClassConstructors")82static void testConstructor(Class<?> type)83throws NoSuchMethodException, InstantiationException,84IllegalAccessException, InvocationTargetException85{86@SuppressWarnings("unchecked")87Constructor<?> c = factory.newConstructorForSerialization(type);8889Object o = c.newInstance();90Assert.assertEquals(o.getClass(), type, "Instance is wrong type");91if (o instanceof Foo) {92Foo foo = (Foo)o;93foo.check();94}95}9697@DataProvider(name = "NonSerialConstructors")98static Object[][] constructors() throws NoSuchMethodException {99return new Object[][] {100{Foo.class, Object.class.getDeclaredConstructor()},101{Foo.class, Foo.class.getDeclaredConstructor()},102{Baz.class, Object.class.getDeclaredConstructor()},103{Baz.class, Foo.class.getDeclaredConstructor()},104{Baz.class, Baz.class.getDeclaredConstructor()}105};106}107108/**109* Tests that the given Constructor, in the hierarchy, is run.110*/111@Test(dataProvider="NonSerialConstructors")112static void testNonSerializableConstructor(Class<?> cl,113Constructor<?> constructorToCall)114throws ReflectiveOperationException115{116@SuppressWarnings("unchecked")117Constructor<?> c = factory.newConstructorForSerialization(cl,118constructorToCall);119120Object o = c.newInstance();121Assert.assertEquals(o.getClass(), cl, "Instance is wrong type");122123int expectedFoo = 0;124int expectedBaz = 0;125if (constructorToCall.getName().equals("ReflectionFactoryTest$Foo")) {126expectedFoo = 1;127} else if (constructorToCall.getName().equals("ReflectionFactoryTest$Baz")) {128expectedFoo = 1;129expectedBaz = 4;130}131132Assert.assertEquals(((Foo)o).foo(), expectedFoo);133if (o instanceof Baz) {134Assert.assertEquals(((Baz)o).baz(), expectedBaz);135}136}137138static class Foo {139private int foo;140public Foo() {141this.foo = 1;142}143144public String toString() {145return "foo: " + foo;146}147148public void check() {149int expectedFoo = 1;150Assert.assertEquals(foo, expectedFoo, "foo() constructor not run");151}152153public int foo() { return foo; }154}155156static class Bar extends Foo implements Serializable {157private int bar;158public Bar() {159this.bar = 1;160}161162public String toString() {163return super.toString() + ", bar: " + bar;164}165166public void check() {167super.check();168int expectedBar = 0;169Assert.assertEquals(bar, expectedBar, "bar() constructor not run");170}171}172173static class Baz extends Foo {174private final int baz;175public Baz() { this.baz = 4; }176public int baz() { return baz; }177}178179/**180* Test newConstructorForExternalization returns the constructor and it can be called.181* @throws NoSuchMethodException - error182* @throws InstantiationException - error183* @throws IllegalAccessException - error184* @throws InvocationTargetException - error185*/186@Test187static void newConstructorForExternalization()188throws NoSuchMethodException, InstantiationException,189IllegalAccessException, InvocationTargetException {190Constructor<?> cons = factory.newConstructorForExternalization(Ext.class);191Ext ext = (Ext)cons.newInstance();192Assert.assertEquals(ext.ext, 1, "Constructor not run");193}194195static class Ext implements Externalizable {196private static final long serialVersionUID = 1L;197198int ext;199200public Ext() {201ext = 1;202}203204@Override205public void writeExternal(ObjectOutput out) throws IOException {}206207@Override208public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {}209}210211@Test212static void testReadWriteObjectForSerialization() throws Throwable {213MethodHandle readObjectMethod = factory.readObjectForSerialization(Ser.class);214Assert.assertNotNull(readObjectMethod, "readObjectMethod not found");215216MethodHandle readObjectNoDataMethod = factory.readObjectNoDataForSerialization(Ser.class);217Assert.assertNotNull(readObjectNoDataMethod, "readObjectNoDataMethod not found");218219MethodHandle writeObjectMethod = factory.writeObjectForSerialization(Ser.class);220Assert.assertNotNull(writeObjectMethod, "writeObjectMethod not found");221222MethodHandle readResolveMethod = factory.readResolveForSerialization(Ser.class);223Assert.assertNotNull(readResolveMethod, "readResolveMethod not found");224225MethodHandle writeReplaceMethod = factory.writeReplaceForSerialization(Ser.class);226Assert.assertNotNull(writeReplaceMethod, "writeReplaceMethod not found");227228byte[] data = null;229try (ByteArrayOutputStream baos = new ByteArrayOutputStream();230ObjectOutputStream oos = new ObjectOutputStream(baos)) {231Ser ser = new Ser();232233writeReplaceMethod.invoke(ser);234Assert.assertTrue(ser.writeReplaceCalled, "writeReplace not called");235Assert.assertFalse(ser.writeObjectCalled, "writeObject should not have been called");236237writeObjectMethod.invoke(ser, oos);238Assert.assertTrue(ser.writeReplaceCalled, "writeReplace should have been called");239Assert.assertTrue(ser.writeObjectCalled, "writeObject not called");240oos.flush();241data = baos.toByteArray();242}243244try (ByteArrayInputStream bais = new ByteArrayInputStream(data);245ObjectInputStream ois = new ObjectInputStream(bais)) {246Ser ser2 = new Ser();247248readObjectMethod.invoke(ser2, ois);249Assert.assertTrue(ser2.readObjectCalled, "readObject not called");250Assert.assertFalse(ser2.readObjectNoDataCalled, "readObjectNoData should not be called");251Assert.assertFalse(ser2.readResolveCalled, "readResolve should not be called");252253readObjectNoDataMethod.invoke(ser2, ois);254Assert.assertTrue(ser2.readObjectCalled, "readObject should have been called");255Assert.assertTrue(ser2.readObjectNoDataCalled, "readObjectNoData not called");256Assert.assertFalse(ser2.readResolveCalled, "readResolve should not be called");257258readResolveMethod.invoke(ser2);259Assert.assertTrue(ser2.readObjectCalled, "readObject should have been called");260Assert.assertTrue(ser2.readObjectNoDataCalled, "readObjectNoData not called");261Assert.assertTrue(ser2.readResolveCalled, "readResolve not called");262}263}264265@Test266static void hasStaticInitializer() {267boolean actual = factory.hasStaticInitializerForSerialization(Ser.class);268Assert.assertTrue(actual, "hasStaticInitializerForSerialization is wrong");269}270271static class Ser implements Serializable {272private static final long serialVersionUID = 2L;273static {274// Define a static class initialization method275}276277boolean readObjectCalled = false;278boolean readObjectNoDataCalled = false;279boolean writeObjectCalled = false;280boolean readResolveCalled = false;281boolean writeReplaceCalled = false;282283public Ser() {}284285private void readObject(ObjectInputStream ois) throws IOException {286Assert.assertFalse(writeObjectCalled, "readObject called too many times");287readObjectCalled = ois.readBoolean();288}289290private void readObjectNoData(ObjectInputStream ois) throws IOException {291Assert.assertFalse(readObjectNoDataCalled, "readObjectNoData called too many times");292readObjectNoDataCalled = true;293}294295private void writeObject(ObjectOutputStream oos) throws IOException {296Assert.assertFalse(writeObjectCalled, "writeObject called too many times");297writeObjectCalled = true;298oos.writeBoolean(writeObjectCalled);299}300301private Object writeReplace() {302Assert.assertFalse(writeReplaceCalled, "writeReplace called too many times");303writeReplaceCalled = true;304return this;305}306307private Object readResolve() {308Assert.assertFalse(readResolveCalled, "readResolve called too many times");309readResolveCalled = true;310return this;311}312}313314/**315* Test the constructor of OptionalDataExceptions.316*/317@Test318static void newOptionalDataException() {319OptionalDataException ode = factory.newOptionalDataExceptionForSerialization(true);320Assert.assertTrue(ode.eof, "eof wrong");321ode = factory.newOptionalDataExceptionForSerialization(false);322Assert.assertFalse(ode.eof, "eof wrong");323324}325326327328// Main can be used to run the tests from the command line with only testng.jar.329@SuppressWarnings("raw_types")330@Test(enabled = false)331public static void main(String[] args) {332Class<?>[] testclass = {ReflectionFactoryTest.class};333TestNG testng = new TestNG();334testng.setTestClasses(testclass);335testng.run();336}337}338339340