1 /** 2 * Copyright 2006-2013 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package org.objenesis.instantiator.perc; 17 18 import java.io.ObjectInputStream; 19 import java.io.Serializable; 20 import java.lang.reflect.InvocationTargetException; 21 import java.lang.reflect.Method; 22 23 import org.objenesis.ObjenesisException; 24 import org.objenesis.instantiator.ObjectInstantiator; 25 26 /** 27 * Instantiates a class by making a call to internal Perc private methods. It is only supposed to 28 * work on Perc JVMs. This instantiator will create classes in a way compatible with serialization, 29 * calling the first non-serializable superclass' no-arg constructor. <p/> Based on code provided by 30 * Aonix but <b>doesn't work right now</b> 31 * 32 * @author Henri Tremblay 33 * @see org.objenesis.instantiator.ObjectInstantiator 34 */ 35 public class PercSerializationInstantiator implements ObjectInstantiator { 36 37 private Object[] typeArgs; 38 39 private final java.lang.reflect.Method newInstanceMethod; 40 41 public PercSerializationInstantiator(Class type) { 42 43 // Find the first unserializable parent class 44 Class unserializableType = type; 45 46 while(Serializable.class.isAssignableFrom(unserializableType)) { 47 unserializableType = unserializableType.getSuperclass(); 48 } 49 50 try { 51 // Get the special Perc method to call 52 Class percMethodClass = Class.forName("COM.newmonics.PercClassLoader.Method"); 53 54 newInstanceMethod = ObjectInputStream.class.getDeclaredMethod("noArgConstruct", 55 new Class[] {Class.class, Object.class, percMethodClass}); 56 newInstanceMethod.setAccessible(true); 57 58 // Create invoke params 59 Class percClassClass = Class.forName("COM.newmonics.PercClassLoader.PercClass"); 60 Method getPercClassMethod = percClassClass.getDeclaredMethod("getPercClass", 61 new Class[] {Class.class}); 62 Object someObject = getPercClassMethod.invoke(null, new Object[] {unserializableType}); 63 Method findMethodMethod = someObject.getClass().getDeclaredMethod("findMethod", 64 new Class[] {String.class}); 65 Object percMethod = findMethodMethod.invoke(someObject, new Object[] {"<init>()V"}); 66 67 typeArgs = new Object[] {unserializableType, type, percMethod}; 68 69 } 70 catch(ClassNotFoundException e) { 71 throw new ObjenesisException(e); 72 } 73 catch(NoSuchMethodException e) { 74 throw new ObjenesisException(e); 75 } 76 catch(InvocationTargetException e) { 77 throw new ObjenesisException(e); 78 } 79 catch(IllegalAccessException e) { 80 throw new ObjenesisException(e); 81 } 82 } 83 84 public Object newInstance() { 85 try { 86 return newInstanceMethod.invoke(null, typeArgs); 87 } 88 catch(IllegalAccessException e) { 89 throw new ObjenesisException(e); 90 } 91 catch(InvocationTargetException e) { 92 throw new ObjenesisException(e); 93 } 94 } 95 96 } 97