zhouping
5 years ago
43 changed files with 7 additions and 3217 deletions
@ -1,46 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator; |
|
||||||
|
|
||||||
/** |
|
||||||
* Common interface to all kind of Objenesis objects |
|
||||||
* |
|
||||||
* @author Henri Tremblay |
|
||||||
*/ |
|
||||||
public interface Objenesis { |
|
||||||
|
|
||||||
/** |
|
||||||
* Will create a new object without any constructor being called |
|
||||||
* |
|
||||||
* @param <T> Type instantiated |
|
||||||
* @param clazz Class to instantiate |
|
||||||
* @return New instance of clazz |
|
||||||
*/ |
|
||||||
<T> T newInstance(Class<T> clazz); |
|
||||||
|
|
||||||
/** |
|
||||||
* Will pick the best instantiator for the provided class. If you need to create a lot of |
|
||||||
* instances from the same class, it is way more efficient to create them from the same |
|
||||||
* ObjectInstantiator than calling {@link #newInstance(Class)}. |
|
||||||
* |
|
||||||
* @param <T> Type to instantiate |
|
||||||
* @param clazz Class to instantiate |
|
||||||
* @return Instantiator dedicated to the class
|
|
||||||
*/ |
|
||||||
<T> ObjectInstantiator<T> getInstantiatorOf(Class<T> clazz); |
|
||||||
} |
|
@ -1,102 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.strategy.InstantiatorStrategy; |
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentHashMap; |
|
||||||
|
|
||||||
/** |
|
||||||
* Base class to extend if you want to have a class providing your own default strategy. Can also be |
|
||||||
* instantiated directly. |
|
||||||
* |
|
||||||
* @author Henri Tremblay |
|
||||||
*/ |
|
||||||
public class ObjenesisBase implements Objenesis { |
|
||||||
|
|
||||||
/** Strategy used by this Objenesi implementation to create classes */ |
|
||||||
protected final InstantiatorStrategy strategy; |
|
||||||
|
|
||||||
/** Strategy cache. Key = Class, Value = InstantiatorStrategy */ |
|
||||||
protected ConcurrentHashMap<String, ObjectInstantiator<?>> cache; |
|
||||||
|
|
||||||
/** |
|
||||||
* Constructor allowing to pick a strategy and using cache |
|
||||||
* |
|
||||||
* @param strategy Strategy to use |
|
||||||
*/ |
|
||||||
public ObjenesisBase(InstantiatorStrategy strategy) { |
|
||||||
this(strategy, true); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Flexible constructor allowing to pick the strategy and if caching should be used |
|
||||||
* |
|
||||||
* @param strategy Strategy to use |
|
||||||
* @param useCache If {@link ObjectInstantiator}s should be cached |
|
||||||
*/ |
|
||||||
public ObjenesisBase(InstantiatorStrategy strategy, boolean useCache) { |
|
||||||
if(strategy == null) { |
|
||||||
throw new IllegalArgumentException("A strategy can't be null"); |
|
||||||
} |
|
||||||
this.strategy = strategy; |
|
||||||
this.cache = useCache ? new ConcurrentHashMap<String, ObjectInstantiator<?>>() : null; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public String toString() { |
|
||||||
return getClass().getName() + " using " + strategy.getClass().getName() |
|
||||||
+ (cache == null ? " without" : " with") + " caching"; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Will create a new object without any constructor being called |
|
||||||
* |
|
||||||
* @param clazz Class to instantiate |
|
||||||
* @return New instance of clazz |
|
||||||
*/ |
|
||||||
public <T> T newInstance(Class<T> clazz) { |
|
||||||
return getInstantiatorOf(clazz).newInstance(); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Will pick the best instantiator for the provided class. If you need to create a lot of |
|
||||||
* instances from the same class, it is way more efficient to create them from the same |
|
||||||
* ObjectInstantiator than calling {@link #newInstance(Class)}. |
|
||||||
* |
|
||||||
* @param clazz Class to instantiate |
|
||||||
* @return Instantiator dedicated to the class
|
|
||||||
*/ |
|
||||||
@SuppressWarnings("unchecked") |
|
||||||
public <T> ObjectInstantiator<T> getInstantiatorOf(Class<T> clazz) { |
|
||||||
if(clazz.isPrimitive()) { |
|
||||||
throw new IllegalArgumentException("Primitive types can't be instantiated in Java"); |
|
||||||
} |
|
||||||
if(cache == null) { |
|
||||||
return strategy.newInstantiatorOf(clazz); |
|
||||||
} |
|
||||||
ObjectInstantiator<?> instantiator = cache.get(clazz.getName()); |
|
||||||
if(instantiator == null) { |
|
||||||
ObjectInstantiator<?> newInstantiator = strategy.newInstantiatorOf(clazz); |
|
||||||
instantiator = cache.putIfAbsent(clazz.getName(), newInstantiator); |
|
||||||
if(instantiator == null) { |
|
||||||
instantiator = newInstantiator; |
|
||||||
} |
|
||||||
} |
|
||||||
return (ObjectInstantiator<T>) instantiator; |
|
||||||
} |
|
||||||
} |
|
@ -1,49 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis; |
|
||||||
|
|
||||||
/** |
|
||||||
* Exception thrown by Objenesis. It wraps any instantiation exceptions. Note that this exception is |
|
||||||
* runtime to prevent having to catch it. |
|
||||||
* |
|
||||||
* @author Henri Tremblay |
|
||||||
*/ |
|
||||||
public class ObjenesisException extends RuntimeException { |
|
||||||
|
|
||||||
private static final long serialVersionUID = -2677230016262426968L; |
|
||||||
|
|
||||||
/** |
|
||||||
* @param msg Error message |
|
||||||
*/ |
|
||||||
public ObjenesisException(String msg) { |
|
||||||
super(msg); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* @param cause Wrapped exception. The message will be the one of the cause. |
|
||||||
*/ |
|
||||||
public ObjenesisException(Throwable cause) { |
|
||||||
super(cause); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* @param msg Error message |
|
||||||
* @param cause Wrapped exception |
|
||||||
*/ |
|
||||||
public ObjenesisException(String msg, Throwable cause) { |
|
||||||
super(msg, cause); |
|
||||||
} |
|
||||||
} |
|
@ -1,84 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis; |
|
||||||
|
|
||||||
import java.io.Serializable; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator; |
|
||||||
|
|
||||||
/** |
|
||||||
* Use Objenesis in a static way. <strong>It is strongly not recommended to use this class.</strong> |
|
||||||
* |
|
||||||
* @author Henri Tremblay |
|
||||||
*/ |
|
||||||
public final class ObjenesisHelper { |
|
||||||
|
|
||||||
private static final Objenesis OBJENESIS_STD = new ObjenesisStd(); |
|
||||||
|
|
||||||
private static final Objenesis OBJENESIS_SERIALIZER = new ObjenesisSerializer(); |
|
||||||
|
|
||||||
private ObjenesisHelper() { |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Will create a new object without any constructor being called |
|
||||||
* |
|
||||||
* @param <T> Type instantiated |
|
||||||
* @param clazz Class to instantiate |
|
||||||
* @return New instance of clazz |
|
||||||
*/ |
|
||||||
public static <T> T newInstance(Class<T> clazz) { |
|
||||||
return OBJENESIS_STD.newInstance(clazz); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Will create an object just like it's done by ObjectInputStream.readObject (the default |
|
||||||
* constructor of the first non serializable class will be called) |
|
||||||
* |
|
||||||
* @param <T> Type instantiated |
|
||||||
* @param clazz Class to instantiate |
|
||||||
* @return New instance of clazz |
|
||||||
*/ |
|
||||||
public static <T extends Serializable> T newSerializableInstance(Class<T> clazz) { |
|
||||||
return (T) OBJENESIS_SERIALIZER.newInstance(clazz); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Will pick the best instantiator for the provided class. If you need to create a lot of |
|
||||||
* instances from the same class, it is way more efficient to create them from the same |
|
||||||
* ObjectInstantiator than calling {@link #newInstance(Class)}. |
|
||||||
* |
|
||||||
* @param <T> Type to instantiate |
|
||||||
* @param clazz Class to instantiate |
|
||||||
* @return Instantiator dedicated to the class
|
|
||||||
*/ |
|
||||||
public static <T> ObjectInstantiator<T> getInstantiatorOf(Class<T> clazz) { |
|
||||||
return OBJENESIS_STD.getInstantiatorOf(clazz); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Same as {@link #getInstantiatorOf(Class)} but providing an instantiator emulating |
|
||||||
* ObjectInputStream.readObject behavior. |
|
||||||
* |
|
||||||
* @see #newSerializableInstance(Class) |
|
||||||
* @param <T> Type to instantiate |
|
||||||
* @param clazz Class to instantiate |
|
||||||
* @return Instantiator dedicated to the class
|
|
||||||
*/ |
|
||||||
public static <T extends Serializable> ObjectInstantiator<T> getSerializableObjectInstantiatorOf(Class<T> clazz) { |
|
||||||
return OBJENESIS_SERIALIZER.getInstantiatorOf(clazz); |
|
||||||
} |
|
||||||
} |
|
@ -1,43 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.strategy.SerializingInstantiatorStrategy; |
|
||||||
|
|
||||||
/** |
|
||||||
* Objenesis implementation using the {@link SerializingInstantiatorStrategy}. |
|
||||||
* |
|
||||||
* @author Henri Tremblay |
|
||||||
*/ |
|
||||||
public class ObjenesisSerializer extends ObjenesisBase { |
|
||||||
|
|
||||||
/** |
|
||||||
* Default constructor using the {@link com.fr.third.springframework.aop.objenesis.strategy.SerializingInstantiatorStrategy} |
|
||||||
*/ |
|
||||||
public ObjenesisSerializer() { |
|
||||||
super(new SerializingInstantiatorStrategy()); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Instance using the {@link com.fr.third.springframework.aop.objenesis.strategy.SerializingInstantiatorStrategy} with or without caching |
|
||||||
* {@link com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator}s |
|
||||||
* |
|
||||||
* @param useCache If {@link com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator}s should be cached |
|
||||||
*/ |
|
||||||
public ObjenesisSerializer(boolean useCache) { |
|
||||||
super(new SerializingInstantiatorStrategy(), useCache); |
|
||||||
} |
|
||||||
} |
|
@ -1,43 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.strategy.StdInstantiatorStrategy; |
|
||||||
|
|
||||||
/** |
|
||||||
* Objenesis implementation using the {@link com.fr.third.springframework.aop.objenesis.strategy.StdInstantiatorStrategy}. |
|
||||||
* |
|
||||||
* @author Henri Tremblay |
|
||||||
*/ |
|
||||||
public class ObjenesisStd extends ObjenesisBase { |
|
||||||
|
|
||||||
/** |
|
||||||
* Default constructor using the {@link com.fr.third.springframework.aop.objenesis.strategy.StdInstantiatorStrategy} |
|
||||||
*/ |
|
||||||
public ObjenesisStd() { |
|
||||||
super(new StdInstantiatorStrategy()); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Instance using the {@link com.fr.third.springframework.aop.objenesis.strategy.StdInstantiatorStrategy} with or without |
|
||||||
* caching {@link com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator}s |
|
||||||
* |
|
||||||
* @param useCache If {@link com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator}s should be cached |
|
||||||
*/ |
|
||||||
public ObjenesisStd(boolean useCache) { |
|
||||||
super(new StdInstantiatorStrategy(), useCache); |
|
||||||
} |
|
||||||
} |
|
@ -1,33 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator; |
|
||||||
|
|
||||||
/** |
|
||||||
* Instantiates a new object. |
|
||||||
* |
|
||||||
* @author Leonardo Mesquita |
|
||||||
*/ |
|
||||||
public interface ObjectInstantiator<T> { |
|
||||||
|
|
||||||
/** |
|
||||||
* Returns a new instance of an object. The returned object's class is defined by the |
|
||||||
* implementation. |
|
||||||
* |
|
||||||
* @return A new instance of an object. |
|
||||||
*/ |
|
||||||
T newInstance(); |
|
||||||
|
|
||||||
} |
|
@ -1,49 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator; |
|
||||||
|
|
||||||
import java.io.Serializable; |
|
||||||
|
|
||||||
/** |
|
||||||
* Helper for common serialization-compatible instantiation functions |
|
||||||
* |
|
||||||
* @author Leonardo Mesquita |
|
||||||
*/ |
|
||||||
public class SerializationInstantiatorHelper { |
|
||||||
|
|
||||||
/** |
|
||||||
* Returns the first non-serializable superclass of a given class. According to Java Object |
|
||||||
* Serialization Specification, objects read from a stream are initialized by calling an |
|
||||||
* accessible no-arg constructor from the first non-serializable superclass in the object's |
|
||||||
* hierarchy, allowing the state of non-serializable fields to be correctly initialized. |
|
||||||
* |
|
||||||
* @param <T> Type to instantiate |
|
||||||
* @param type Serializable class for which the first non-serializable superclass is to be found |
|
||||||
* @return The first non-serializable superclass of 'type'. |
|
||||||
* @see Serializable |
|
||||||
*/ |
|
||||||
public static <T> Class<? super T> getNonSerializableSuperClass(Class<T> type) { |
|
||||||
Class<? super T> result = type; |
|
||||||
while(Serializable.class.isAssignableFrom(result)) { |
|
||||||
result = result.getSuperclass(); |
|
||||||
if(result == null) { |
|
||||||
throw new Error("Bad class hierarchy: No non-serializable parents"); |
|
||||||
} |
|
||||||
} |
|
||||||
return result; |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
@ -1,67 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator.android; |
|
||||||
|
|
||||||
import java.io.ObjectInputStream; |
|
||||||
import java.lang.reflect.Method; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.ObjenesisException; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology; |
|
||||||
|
|
||||||
/** |
|
||||||
* Instantiator for Android API level 10 and lover which creates objects without driving their |
|
||||||
* constructors, using internal methods on the Dalvik implementation of |
|
||||||
* {@link ObjectInputStream}. |
|
||||||
* |
|
||||||
* @author Piotr 'Qertoip' Włodarek |
|
||||||
*/ |
|
||||||
@Instantiator(Typology.STANDARD) |
|
||||||
public class Android10Instantiator<T> implements ObjectInstantiator<T> { |
|
||||||
private final Class<T> type; |
|
||||||
private final Method newStaticMethod; |
|
||||||
|
|
||||||
public Android10Instantiator(Class<T> type) { |
|
||||||
this.type = type; |
|
||||||
newStaticMethod = getNewStaticMethod(); |
|
||||||
} |
|
||||||
|
|
||||||
public T newInstance() { |
|
||||||
try { |
|
||||||
return type.cast(newStaticMethod.invoke(null, type, Object.class)); |
|
||||||
} |
|
||||||
catch(Exception e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private static Method getNewStaticMethod() { |
|
||||||
try { |
|
||||||
Method newStaticMethod = ObjectInputStream.class.getDeclaredMethod( |
|
||||||
"newInstance", Class.class, Class.class); |
|
||||||
newStaticMethod.setAccessible(true); |
|
||||||
return newStaticMethod; |
|
||||||
} |
|
||||||
catch(RuntimeException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
catch(NoSuchMethodException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,90 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator.android; |
|
||||||
|
|
||||||
import java.io.ObjectStreamClass; |
|
||||||
import java.lang.reflect.InvocationTargetException; |
|
||||||
import java.lang.reflect.Method; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.ObjenesisException; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology; |
|
||||||
|
|
||||||
/** |
|
||||||
* Instantiator for Android API level 11 to 17 which creates objects without driving their |
|
||||||
* constructors, using internal methods on the Dalvik implementation of {@link ObjectStreamClass}. |
|
||||||
* |
|
||||||
* @author Ian Parkinson (Google Inc.) |
|
||||||
*/ |
|
||||||
@Instantiator(Typology.STANDARD) |
|
||||||
public class Android17Instantiator<T> implements ObjectInstantiator<T> { |
|
||||||
private final Class<T> type; |
|
||||||
private final Method newInstanceMethod; |
|
||||||
private final Integer objectConstructorId; |
|
||||||
|
|
||||||
public Android17Instantiator(Class<T> type) { |
|
||||||
this.type = type; |
|
||||||
newInstanceMethod = getNewInstanceMethod(); |
|
||||||
objectConstructorId = findConstructorIdForJavaLangObjectConstructor(); |
|
||||||
} |
|
||||||
|
|
||||||
public T newInstance() { |
|
||||||
try { |
|
||||||
return type.cast(newInstanceMethod.invoke(null, type, objectConstructorId)); |
|
||||||
} |
|
||||||
catch(Exception e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private static Method getNewInstanceMethod() { |
|
||||||
try { |
|
||||||
Method newInstanceMethod = ObjectStreamClass.class.getDeclaredMethod( |
|
||||||
"newInstance", Class.class, Integer.TYPE); |
|
||||||
newInstanceMethod.setAccessible(true); |
|
||||||
return newInstanceMethod; |
|
||||||
} |
|
||||||
catch(RuntimeException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
catch(NoSuchMethodException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private static Integer findConstructorIdForJavaLangObjectConstructor() { |
|
||||||
try { |
|
||||||
Method newInstanceMethod = ObjectStreamClass.class.getDeclaredMethod( |
|
||||||
"getConstructorId", Class.class); |
|
||||||
newInstanceMethod.setAccessible(true); |
|
||||||
|
|
||||||
return (Integer) newInstanceMethod.invoke(null, Object.class); |
|
||||||
} |
|
||||||
catch(RuntimeException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
catch(NoSuchMethodException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
catch(IllegalAccessException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
catch(InvocationTargetException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,90 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator.android; |
|
||||||
|
|
||||||
import java.io.ObjectStreamClass; |
|
||||||
import java.lang.reflect.InvocationTargetException; |
|
||||||
import java.lang.reflect.Method; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.ObjenesisException; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology; |
|
||||||
|
|
||||||
/** |
|
||||||
* Instantiator for Android API leve 18 and higher. Same as the version 17 but the |
|
||||||
* <code>newInstance</code> now takes a long in parameter |
|
||||||
* |
|
||||||
* @author Henri Tremblay |
|
||||||
*/ |
|
||||||
@Instantiator(Typology.STANDARD) |
|
||||||
public class Android18Instantiator<T> implements ObjectInstantiator<T> { |
|
||||||
private final Class<T> type; |
|
||||||
private final Method newInstanceMethod; |
|
||||||
private final Long objectConstructorId; |
|
||||||
|
|
||||||
public Android18Instantiator(Class<T> type) { |
|
||||||
this.type = type; |
|
||||||
newInstanceMethod = getNewInstanceMethod(); |
|
||||||
objectConstructorId = findConstructorIdForJavaLangObjectConstructor(); |
|
||||||
} |
|
||||||
|
|
||||||
public T newInstance() { |
|
||||||
try { |
|
||||||
return type.cast(newInstanceMethod.invoke(null, type, objectConstructorId)); |
|
||||||
} |
|
||||||
catch(Exception e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private static Method getNewInstanceMethod() { |
|
||||||
try { |
|
||||||
Method newInstanceMethod = ObjectStreamClass.class.getDeclaredMethod("newInstance", |
|
||||||
Class.class, Long.TYPE); |
|
||||||
newInstanceMethod.setAccessible(true); |
|
||||||
return newInstanceMethod; |
|
||||||
} |
|
||||||
catch(RuntimeException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
catch(NoSuchMethodException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private static Long findConstructorIdForJavaLangObjectConstructor() { |
|
||||||
try { |
|
||||||
Method newInstanceMethod = ObjectStreamClass.class.getDeclaredMethod("getConstructorId", |
|
||||||
Class.class); |
|
||||||
newInstanceMethod.setAccessible(true); |
|
||||||
|
|
||||||
return (Long) newInstanceMethod.invoke(null, Object.class); |
|
||||||
} |
|
||||||
catch(RuntimeException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
catch(NoSuchMethodException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
catch(IllegalAccessException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
catch(InvocationTargetException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,87 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator.android; |
|
||||||
|
|
||||||
import java.io.ObjectStreamClass; |
|
||||||
import java.lang.reflect.InvocationTargetException; |
|
||||||
import java.lang.reflect.Method; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.ObjenesisException; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology; |
|
||||||
|
|
||||||
/** |
|
||||||
* {@link ObjectInstantiator} for Android which creates objects using the constructor from the first |
|
||||||
* non-serializable parent class constructor, using internal methods on the Dalvik implementation of |
|
||||||
* {@link ObjectStreamClass}. |
|
||||||
* |
|
||||||
* @author Ian Parkinson (Google Inc.) |
|
||||||
*/ |
|
||||||
@Instantiator(Typology.SERIALIZATION) |
|
||||||
public class AndroidSerializationInstantiator<T> implements ObjectInstantiator<T> { |
|
||||||
private final Class<T> type; |
|
||||||
private final ObjectStreamClass objectStreamClass; |
|
||||||
private final Method newInstanceMethod; |
|
||||||
|
|
||||||
public AndroidSerializationInstantiator(Class<T> type) { |
|
||||||
this.type = type; |
|
||||||
newInstanceMethod = getNewInstanceMethod(); |
|
||||||
Method m = null; |
|
||||||
try { |
|
||||||
m = ObjectStreamClass.class.getMethod("lookupAny", Class.class); |
|
||||||
} catch (NoSuchMethodException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
try { |
|
||||||
objectStreamClass = (ObjectStreamClass) m.invoke(null, type); |
|
||||||
} catch (IllegalAccessException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} catch (InvocationTargetException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public T newInstance() { |
|
||||||
try { |
|
||||||
return type.cast(newInstanceMethod.invoke(objectStreamClass, type)); |
|
||||||
} |
|
||||||
catch(IllegalAccessException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
catch(IllegalArgumentException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
catch(InvocationTargetException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private static Method getNewInstanceMethod() { |
|
||||||
try { |
|
||||||
Method newInstanceMethod = ObjectStreamClass.class.getDeclaredMethod( |
|
||||||
"newInstance", Class.class); |
|
||||||
newInstanceMethod.setAccessible(true); |
|
||||||
return newInstanceMethod; |
|
||||||
} |
|
||||||
catch(RuntimeException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
catch(NoSuchMethodException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,38 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator.annotations; |
|
||||||
|
|
||||||
import java.lang.annotation.Documented; |
|
||||||
import java.lang.annotation.ElementType; |
|
||||||
import java.lang.annotation.Retention; |
|
||||||
import java.lang.annotation.RetentionPolicy; |
|
||||||
import java.lang.annotation.Target; |
|
||||||
|
|
||||||
/** |
|
||||||
* Denote that the class in an instantiator of a given type |
|
||||||
* |
|
||||||
* @author Henri Tremblay |
|
||||||
*/ |
|
||||||
@Documented |
|
||||||
@Retention(RetentionPolicy.RUNTIME) |
|
||||||
@Target(ElementType.TYPE) |
|
||||||
public @interface Instantiator { |
|
||||||
|
|
||||||
/** |
|
||||||
* @return type of instantiator |
|
||||||
*/ |
|
||||||
Typology value(); |
|
||||||
} |
|
@ -1,43 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator.annotations; |
|
||||||
|
|
||||||
/** |
|
||||||
* Possible types of instantiator |
|
||||||
* @author Henri Tremblay |
|
||||||
*/ |
|
||||||
public enum Typology { |
|
||||||
/** |
|
||||||
* Mark an instantiator used for standard instantiation (not calling a constructor). |
|
||||||
*/ |
|
||||||
STANDARD, |
|
||||||
|
|
||||||
/** |
|
||||||
* Mark an instantiator used for serialization. |
|
||||||
*/ |
|
||||||
SERIALIZATION, |
|
||||||
|
|
||||||
/** |
|
||||||
* Mark an instantiator that doesn't behave like a {@link #STANDARD} nor a {@link #SERIALIZATION} (e.g. calls a constructor, fails |
|
||||||
* all the time, etc.) |
|
||||||
*/ |
|
||||||
NOT_COMPLIANT, |
|
||||||
|
|
||||||
/** |
|
||||||
* No type specified on the instantiator class
|
|
||||||
*/ |
|
||||||
UNKNOWN |
|
||||||
} |
|
@ -1,38 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator.basic; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology; |
|
||||||
|
|
||||||
/** |
|
||||||
* Instantiates a class by grabbing the no-args constructor, making it accessible and then calling |
|
||||||
* Constructor.newInstance(). Although this still requires no-arg constructors, it can call |
|
||||||
* non-public constructors (if the security manager allows it). |
|
||||||
* |
|
||||||
* @author Joe Walnes |
|
||||||
* @see com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator |
|
||||||
*/ |
|
||||||
@Instantiator(Typology.NOT_COMPLIANT) |
|
||||||
public class AccessibleInstantiator<T> extends ConstructorInstantiator<T> { |
|
||||||
|
|
||||||
public AccessibleInstantiator(Class<T> type) { |
|
||||||
super(type); |
|
||||||
if(constructor != null) { |
|
||||||
constructor.setAccessible(true); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,56 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator.basic; |
|
||||||
|
|
||||||
import java.lang.reflect.Constructor; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.ObjenesisException; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology; |
|
||||||
|
|
||||||
/** |
|
||||||
* Instantiates a class by grabbing the no args constructor and calling Constructor.newInstance(). |
|
||||||
* This can deal with default public constructors, but that's about it. |
|
||||||
* |
|
||||||
* @author Joe Walnes |
|
||||||
* @param <T> Type instantiated |
|
||||||
* @see ObjectInstantiator |
|
||||||
*/ |
|
||||||
@Instantiator(Typology.NOT_COMPLIANT) |
|
||||||
public class ConstructorInstantiator<T> implements ObjectInstantiator<T> { |
|
||||||
|
|
||||||
protected Constructor<T> constructor; |
|
||||||
|
|
||||||
public ConstructorInstantiator(Class<T> type) { |
|
||||||
try { |
|
||||||
constructor = type.getDeclaredConstructor((Class[]) null); |
|
||||||
} |
|
||||||
catch(Exception e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public T newInstance() { |
|
||||||
try { |
|
||||||
return constructor.newInstance((Object[]) null); |
|
||||||
} |
|
||||||
catch(Exception e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,40 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator.basic; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.ObjenesisException; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology; |
|
||||||
|
|
||||||
/** |
|
||||||
* The instantiator that always throws an exception. Mainly used for tests |
|
||||||
* |
|
||||||
* @author Henri Tremblay |
|
||||||
*/ |
|
||||||
@Instantiator(Typology.NOT_COMPLIANT) |
|
||||||
public class FailingInstantiator<T> implements ObjectInstantiator<T> { |
|
||||||
|
|
||||||
public FailingInstantiator(Class<T> type) { |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* @return Always throwing an exception |
|
||||||
*/ |
|
||||||
public T newInstance() { |
|
||||||
throw new ObjenesisException("Always failing"); |
|
||||||
} |
|
||||||
} |
|
@ -1,48 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator.basic; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.ObjenesisException; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology; |
|
||||||
|
|
||||||
/** |
|
||||||
* The simplest instantiator - simply calls Class.newInstance(). This can deal with default public |
|
||||||
* constructors, but that's about it. |
|
||||||
* |
|
||||||
* @author Joe Walnes |
|
||||||
* @see ObjectInstantiator |
|
||||||
*/ |
|
||||||
@Instantiator(Typology.NOT_COMPLIANT) |
|
||||||
public class NewInstanceInstantiator<T> implements ObjectInstantiator<T> { |
|
||||||
|
|
||||||
private final Class<T> type; |
|
||||||
|
|
||||||
public NewInstanceInstantiator(Class<T> type) { |
|
||||||
this.type = type; |
|
||||||
} |
|
||||||
|
|
||||||
public T newInstance() { |
|
||||||
try { |
|
||||||
return type.newInstance(); |
|
||||||
} |
|
||||||
catch(Exception e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,39 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator.basic; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology; |
|
||||||
|
|
||||||
/** |
|
||||||
* The instantiator that always return a null instance |
|
||||||
* |
|
||||||
* @author Henri Tremblay |
|
||||||
*/ |
|
||||||
@Instantiator(Typology.NOT_COMPLIANT) |
|
||||||
public class NullInstantiator<T> implements ObjectInstantiator<T> { |
|
||||||
|
|
||||||
public NullInstantiator(Class<T> type) { |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* @return Always null |
|
||||||
*/ |
|
||||||
public T newInstance() { |
|
||||||
return null; |
|
||||||
} |
|
||||||
} |
|
@ -1,186 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator.basic; |
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream; |
|
||||||
import java.io.DataOutputStream; |
|
||||||
import java.io.IOException; |
|
||||||
import java.io.InputStream; |
|
||||||
import java.io.NotSerializableException; |
|
||||||
import java.io.ObjectInputStream; |
|
||||||
import java.io.ObjectStreamClass; |
|
||||||
import java.io.ObjectStreamConstants; |
|
||||||
import java.io.Serializable; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.ObjenesisException; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology; |
|
||||||
|
|
||||||
/** |
|
||||||
* Instantiates a class by using a dummy input stream that always feeds data for an empty object of |
|
||||||
* the same kind. NOTE: This instantiator may not work properly if the class being instantiated |
|
||||||
* defines a "readResolve" method, since it may return objects that have been returned previously |
|
||||||
* (i.e., there's no guarantee that the returned object is a new one), or even objects from a |
|
||||||
* completely different class. |
|
||||||
* |
|
||||||
* @author Leonardo Mesquita |
|
||||||
* @see com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator |
|
||||||
*/ |
|
||||||
@Instantiator(Typology.SERIALIZATION) |
|
||||||
public class ObjectInputStreamInstantiator<T> implements ObjectInstantiator<T> { |
|
||||||
private static class MockStream extends InputStream { |
|
||||||
|
|
||||||
private int pointer; |
|
||||||
private byte[] data; |
|
||||||
private int sequence; |
|
||||||
private static final int[] NEXT = new int[] {1, 2, 2}; |
|
||||||
private byte[][] buffers; |
|
||||||
|
|
||||||
private final byte[] FIRST_DATA; |
|
||||||
private static byte[] HEADER; |
|
||||||
private static byte[] REPEATING_DATA; |
|
||||||
|
|
||||||
static { |
|
||||||
initialize(); |
|
||||||
} |
|
||||||
|
|
||||||
private static void initialize() { |
|
||||||
try { |
|
||||||
ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); |
|
||||||
DataOutputStream dout = new DataOutputStream(byteOut); |
|
||||||
dout.writeShort(ObjectStreamConstants.STREAM_MAGIC); |
|
||||||
dout.writeShort(ObjectStreamConstants.STREAM_VERSION); |
|
||||||
HEADER = byteOut.toByteArray(); |
|
||||||
|
|
||||||
byteOut = new ByteArrayOutputStream(); |
|
||||||
dout = new DataOutputStream(byteOut); |
|
||||||
|
|
||||||
dout.writeByte(ObjectStreamConstants.TC_OBJECT); |
|
||||||
dout.writeByte(ObjectStreamConstants.TC_REFERENCE); |
|
||||||
dout.writeInt(ObjectStreamConstants.baseWireHandle); |
|
||||||
REPEATING_DATA = byteOut.toByteArray(); |
|
||||||
} |
|
||||||
catch(IOException e) { |
|
||||||
throw new Error("IOException: " + e.getMessage()); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
public MockStream(Class<?> clazz) { |
|
||||||
this.pointer = 0; |
|
||||||
this.sequence = 0; |
|
||||||
this.data = HEADER; |
|
||||||
|
|
||||||
// (byte) TC_OBJECT
|
|
||||||
// (byte) TC_CLASSDESC
|
|
||||||
// (short length)
|
|
||||||
// (byte * className.length)
|
|
||||||
// (long)serialVersionUID
|
|
||||||
// (byte) SC_SERIALIZABLE
|
|
||||||
// (short)0 <fields>
|
|
||||||
// TC_ENDBLOCKDATA
|
|
||||||
// TC_NULL
|
|
||||||
ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); |
|
||||||
DataOutputStream dout = new DataOutputStream(byteOut); |
|
||||||
try { |
|
||||||
dout.writeByte(ObjectStreamConstants.TC_OBJECT); |
|
||||||
dout.writeByte(ObjectStreamConstants.TC_CLASSDESC); |
|
||||||
dout.writeUTF(clazz.getName()); |
|
||||||
dout.writeLong(ObjectStreamClass.lookup(clazz).getSerialVersionUID()); |
|
||||||
dout.writeByte(ObjectStreamConstants.SC_SERIALIZABLE); |
|
||||||
dout.writeShort((short) 0); // Zero fields
|
|
||||||
dout.writeByte(ObjectStreamConstants.TC_ENDBLOCKDATA); |
|
||||||
dout.writeByte(ObjectStreamConstants.TC_NULL); |
|
||||||
} |
|
||||||
catch(IOException e) { |
|
||||||
throw new Error("IOException: " + e.getMessage()); |
|
||||||
} |
|
||||||
this.FIRST_DATA = byteOut.toByteArray(); |
|
||||||
buffers = new byte[][] {HEADER, FIRST_DATA, REPEATING_DATA}; |
|
||||||
} |
|
||||||
|
|
||||||
private void advanceBuffer() { |
|
||||||
pointer = 0; |
|
||||||
sequence = NEXT[sequence]; |
|
||||||
data = buffers[sequence]; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int read() throws IOException { |
|
||||||
int result = data[pointer++]; |
|
||||||
if(pointer >= data.length) { |
|
||||||
advanceBuffer(); |
|
||||||
} |
|
||||||
|
|
||||||
return result; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int available() throws IOException { |
|
||||||
return Integer.MAX_VALUE; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int read(byte[] b, int off, int len) throws IOException { |
|
||||||
int left = len; |
|
||||||
int remaining = data.length - pointer; |
|
||||||
|
|
||||||
while(remaining <= left) { |
|
||||||
System.arraycopy(data, pointer, b, off, remaining); |
|
||||||
off += remaining; |
|
||||||
left -= remaining; |
|
||||||
advanceBuffer(); |
|
||||||
remaining = data.length - pointer; |
|
||||||
} |
|
||||||
if(left > 0) { |
|
||||||
System.arraycopy(data, pointer, b, off, left); |
|
||||||
pointer += left; |
|
||||||
} |
|
||||||
|
|
||||||
return len; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private ObjectInputStream inputStream; |
|
||||||
|
|
||||||
public ObjectInputStreamInstantiator(Class<T> clazz) { |
|
||||||
if(Serializable.class.isAssignableFrom(clazz)) { |
|
||||||
try { |
|
||||||
this.inputStream = new ObjectInputStream(new MockStream(clazz)); |
|
||||||
} |
|
||||||
catch(IOException e) { |
|
||||||
throw new Error("IOException: " + e.getMessage()); |
|
||||||
} |
|
||||||
} |
|
||||||
else { |
|
||||||
throw new ObjenesisException(new NotSerializableException(clazz + " not serializable")); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@SuppressWarnings("unchecked") |
|
||||||
public T newInstance() { |
|
||||||
try { |
|
||||||
return (T) inputStream.readObject(); |
|
||||||
} |
|
||||||
catch(ClassNotFoundException e) { |
|
||||||
throw new Error("ClassNotFoundException: " + e.getMessage()); |
|
||||||
} |
|
||||||
catch(Exception e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,75 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator.basic; |
|
||||||
|
|
||||||
import java.io.ObjectStreamClass; |
|
||||||
import java.lang.reflect.Method; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.ObjenesisException; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology; |
|
||||||
|
|
||||||
/** |
|
||||||
* Instantiates a class by using reflection to make a call to private method |
|
||||||
* ObjectStreamClass.newInstance, present in many JVM implementations. This instantiator will create |
|
||||||
* classes in a way compatible with serialization, calling the first non-serializable superclass' |
|
||||||
* no-arg constructor. |
|
||||||
* |
|
||||||
* @author Leonardo Mesquita |
|
||||||
* @see ObjectInstantiator |
|
||||||
* @see java.io.Serializable |
|
||||||
*/ |
|
||||||
@Instantiator(Typology.SERIALIZATION) |
|
||||||
public class ObjectStreamClassInstantiator<T> implements ObjectInstantiator<T> { |
|
||||||
|
|
||||||
private static Method newInstanceMethod; |
|
||||||
|
|
||||||
private static void initialize() { |
|
||||||
if(newInstanceMethod == null) { |
|
||||||
try { |
|
||||||
newInstanceMethod = ObjectStreamClass.class.getDeclaredMethod("newInstance"); |
|
||||||
newInstanceMethod.setAccessible(true); |
|
||||||
} |
|
||||||
catch(RuntimeException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
catch(NoSuchMethodException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private final ObjectStreamClass objStreamClass; |
|
||||||
|
|
||||||
public ObjectStreamClassInstantiator(Class<T> type) { |
|
||||||
initialize(); |
|
||||||
objStreamClass = ObjectStreamClass.lookup(type); |
|
||||||
} |
|
||||||
|
|
||||||
@SuppressWarnings("unchecked") |
|
||||||
public T newInstance() { |
|
||||||
|
|
||||||
try { |
|
||||||
return (T) newInstanceMethod.invoke(objStreamClass); |
|
||||||
} |
|
||||||
catch(Exception e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,193 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator.basic; |
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream; |
|
||||||
import java.io.DataOutputStream; |
|
||||||
import java.io.IOException; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.ObjenesisException; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.util.ClassDefinitionUtils; |
|
||||||
|
|
||||||
import static com.fr.third.springframework.aop.objenesis.instantiator.util.ClassDefinitionUtils.*; |
|
||||||
|
|
||||||
/** |
|
||||||
* This instantiator creates a class by dynamically extending it. It will skip the call to the parent constructor |
|
||||||
* in the bytecode. So that the constructor is indeed not called but you however instantiate a child class, not |
|
||||||
* the actual class. The class loader will normally throw a {@code VerifyError} is you do that. However, using |
|
||||||
* {@code -Xverify:none} should make it work |
|
||||||
* |
|
||||||
* @author Henri Tremblay |
|
||||||
*/ |
|
||||||
@Instantiator(Typology.STANDARD) |
|
||||||
public class ProxyingInstantiator<T> implements ObjectInstantiator<T> { |
|
||||||
|
|
||||||
private static final int INDEX_CLASS_THIS = 1; |
|
||||||
private static final int INDEX_CLASS_SUPERCLASS = 2; |
|
||||||
private static final int INDEX_UTF8_CONSTRUCTOR_NAME = 3; |
|
||||||
private static final int INDEX_UTF8_CONSTRUCTOR_DESC = 4; |
|
||||||
private static final int INDEX_UTF8_CODE_ATTRIBUTE = 5; |
|
||||||
private static final int INDEX_UTF8_CLASS = 7; |
|
||||||
private static final int INDEX_UTF8_SUPERCLASS = 8; |
|
||||||
|
|
||||||
private static int CONSTANT_POOL_COUNT = 9; |
|
||||||
|
|
||||||
private static final byte[] CODE = { OPS_aload_0, OPS_return}; |
|
||||||
private static final int CODE_ATTRIBUTE_LENGTH = 12 + CODE.length; |
|
||||||
|
|
||||||
private static final String SUFFIX = "$$$Objenesis"; |
|
||||||
|
|
||||||
private static final String CONSTRUCTOR_NAME = "<init>"; |
|
||||||
private static final String CONSTRUCTOR_DESC = "()V"; |
|
||||||
|
|
||||||
private final Class<?> newType; |
|
||||||
|
|
||||||
public ProxyingInstantiator(Class<T> type) { |
|
||||||
|
|
||||||
byte[] classBytes = writeExtendingClass(type, SUFFIX); |
|
||||||
|
|
||||||
try { |
|
||||||
newType = ClassDefinitionUtils.defineClass(type.getName() + SUFFIX, classBytes, type.getClassLoader()); |
|
||||||
} catch (Exception e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@SuppressWarnings("unchecked") |
|
||||||
public T newInstance() { |
|
||||||
try { |
|
||||||
return (T) newType.newInstance(); |
|
||||||
} catch (InstantiationException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} catch (IllegalAccessException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Will generate the bytes for a class extending the type passed in parameter. This class will |
|
||||||
* only have an empty default constructor |
|
||||||
* |
|
||||||
* @param type type to extend |
|
||||||
* @param suffix the suffix appended to the class name to create the next extending class name |
|
||||||
* @return the byte for the class
|
|
||||||
* @throws ObjenesisException is something goes wrong |
|
||||||
*/ |
|
||||||
private static byte[] writeExtendingClass(Class<?> type, String suffix) { |
|
||||||
String parentClazz = classNameToInternalClassName(type.getName()); |
|
||||||
String clazz = parentClazz + suffix; |
|
||||||
|
|
||||||
DataOutputStream in = null; |
|
||||||
ByteArrayOutputStream bIn = new ByteArrayOutputStream(1000); // 1000 should be large enough to fit the entire class
|
|
||||||
try { |
|
||||||
in = new DataOutputStream(bIn); |
|
||||||
|
|
||||||
in.write(MAGIC); |
|
||||||
in.write(VERSION); |
|
||||||
in.writeShort(CONSTANT_POOL_COUNT); |
|
||||||
|
|
||||||
// set all the constant pool here
|
|
||||||
|
|
||||||
// 1. class
|
|
||||||
in.writeByte(CONSTANT_Class); |
|
||||||
in.writeShort(INDEX_UTF8_CLASS); |
|
||||||
|
|
||||||
// 2. super class
|
|
||||||
in.writeByte(CONSTANT_Class); |
|
||||||
in.writeShort(INDEX_UTF8_SUPERCLASS); |
|
||||||
|
|
||||||
// 3. default constructor name
|
|
||||||
in.writeByte(CONSTANT_Utf8); |
|
||||||
in.writeUTF(CONSTRUCTOR_NAME); |
|
||||||
|
|
||||||
// 4. default constructor description
|
|
||||||
in.writeByte(CONSTANT_Utf8); |
|
||||||
in.writeUTF(CONSTRUCTOR_DESC); |
|
||||||
|
|
||||||
// 5. Code
|
|
||||||
in.writeByte(CONSTANT_Utf8); |
|
||||||
in.writeUTF("Code"); |
|
||||||
|
|
||||||
// 6. Class name
|
|
||||||
in.writeByte(CONSTANT_Utf8); |
|
||||||
in.writeUTF("L" + clazz + ";"); |
|
||||||
|
|
||||||
// 7. Class name (again)
|
|
||||||
in.writeByte(CONSTANT_Utf8); |
|
||||||
in.writeUTF(clazz); |
|
||||||
|
|
||||||
// 8. Superclass name
|
|
||||||
in.writeByte(CONSTANT_Utf8); |
|
||||||
in.writeUTF(parentClazz); |
|
||||||
|
|
||||||
// end of constant pool
|
|
||||||
|
|
||||||
// access flags: We want public, ACC_SUPER is always there
|
|
||||||
in.writeShort(ACC_PUBLIC | ACC_SUPER); |
|
||||||
|
|
||||||
// this class index in the constant pool
|
|
||||||
in.writeShort(INDEX_CLASS_THIS); |
|
||||||
|
|
||||||
// super class index in the constant pool
|
|
||||||
in.writeShort(INDEX_CLASS_SUPERCLASS); |
|
||||||
|
|
||||||
// interfaces implemented count (we have none)
|
|
||||||
in.writeShort(0); |
|
||||||
|
|
||||||
// fields count (we have none)
|
|
||||||
in.writeShort(0); |
|
||||||
|
|
||||||
// methods count (we have one: the default constructor)
|
|
||||||
in.writeShort(1); |
|
||||||
|
|
||||||
// default constructor method_info
|
|
||||||
in.writeShort(ACC_PUBLIC); |
|
||||||
in.writeShort(INDEX_UTF8_CONSTRUCTOR_NAME); // index of the method name (<init>)
|
|
||||||
in.writeShort(INDEX_UTF8_CONSTRUCTOR_DESC); // index of the description
|
|
||||||
in.writeShort(1); // number of attributes: only one, the code
|
|
||||||
|
|
||||||
// code attribute of the default constructor
|
|
||||||
in.writeShort(INDEX_UTF8_CODE_ATTRIBUTE); |
|
||||||
in.writeInt(CODE_ATTRIBUTE_LENGTH); // attribute length
|
|
||||||
in.writeShort(1); // max_stack
|
|
||||||
in.writeShort(1); // max_locals
|
|
||||||
in.writeInt(CODE.length); // code length
|
|
||||||
in.write(CODE); |
|
||||||
in.writeShort(0); // exception_table_length = 0
|
|
||||||
in.writeShort(0); // attributes count = 0, no need to have LineNumberTable and LocalVariableTable
|
|
||||||
|
|
||||||
// class attributes
|
|
||||||
in.writeShort(0); // none. No need to have a source file attribute
|
|
||||||
|
|
||||||
|
|
||||||
} catch (IOException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} finally { |
|
||||||
if(in != null) { |
|
||||||
try { |
|
||||||
in.close(); |
|
||||||
} catch (IOException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return bIn.toByteArray(); |
|
||||||
} |
|
||||||
} |
|
@ -1,52 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator.gcj; |
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.ObjenesisException; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology; |
|
||||||
|
|
||||||
/** |
|
||||||
* Instantiates a class by making a call to internal GCJ private methods. It is only supposed to |
|
||||||
* work on GCJ JVMs. This instantiator will not call any constructors. |
|
||||||
* |
|
||||||
* @author Leonardo Mesquita |
|
||||||
* @see com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator |
|
||||||
*/ |
|
||||||
@Instantiator(Typology.STANDARD) |
|
||||||
public class GCJInstantiator<T> extends GCJInstantiatorBase<T> { |
|
||||||
public GCJInstantiator(Class<T> type) { |
|
||||||
super(type); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public T newInstance() { |
|
||||||
try { |
|
||||||
return type.cast(newObjectMethod.invoke(dummyStream, type, Object.class)); |
|
||||||
} |
|
||||||
catch(RuntimeException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
catch(IllegalAccessException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
catch(InvocationTargetException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,69 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator.gcj; |
|
||||||
|
|
||||||
import java.io.IOException; |
|
||||||
import java.io.ObjectInputStream; |
|
||||||
import java.lang.reflect.Method; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.ObjenesisException; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator; |
|
||||||
|
|
||||||
/** |
|
||||||
* Base class for GCJ-based instantiators. It initializes reflection access to method |
|
||||||
* ObjectInputStream.newObject, as well as creating a dummy ObjectInputStream to be used as the |
|
||||||
* "this" argument for the method. |
|
||||||
* |
|
||||||
* @author Leonardo Mesquita |
|
||||||
*/ |
|
||||||
public abstract class GCJInstantiatorBase<T> implements ObjectInstantiator<T> { |
|
||||||
static Method newObjectMethod = null; |
|
||||||
static ObjectInputStream dummyStream; |
|
||||||
|
|
||||||
private static class DummyStream extends ObjectInputStream { |
|
||||||
public DummyStream() throws IOException { |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private static void initialize() { |
|
||||||
if(newObjectMethod == null) { |
|
||||||
try { |
|
||||||
newObjectMethod = ObjectInputStream.class.getDeclaredMethod("newObject", new Class[] { |
|
||||||
Class.class, Class.class}); |
|
||||||
newObjectMethod.setAccessible(true); |
|
||||||
dummyStream = new DummyStream(); |
|
||||||
} |
|
||||||
catch(RuntimeException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
catch(NoSuchMethodException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
catch(IOException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
protected final Class<T> type; |
|
||||||
|
|
||||||
public GCJInstantiatorBase(Class<T> type) { |
|
||||||
this.type = type; |
|
||||||
initialize(); |
|
||||||
} |
|
||||||
|
|
||||||
public abstract T newInstance(); |
|
||||||
} |
|
@ -1,50 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator.gcj; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.ObjenesisException; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.SerializationInstantiatorHelper; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology; |
|
||||||
|
|
||||||
/** |
|
||||||
* Instantiates a class by making a call to internal GCJ private methods. It is only supposed to |
|
||||||
* work on GCJ JVMs. This instantiator will create classes in a way compatible with serialization, |
|
||||||
* calling the first non-serializable superclass' no-arg constructor. |
|
||||||
* |
|
||||||
* @author Leonardo Mesquita |
|
||||||
* @see com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator |
|
||||||
*/ |
|
||||||
@Instantiator(Typology.SERIALIZATION) |
|
||||||
public class GCJSerializationInstantiator<T> extends GCJInstantiatorBase<T> { |
|
||||||
private Class<? super T> superType; |
|
||||||
|
|
||||||
public GCJSerializationInstantiator(Class<T> type) { |
|
||||||
super(type); |
|
||||||
this.superType = SerializationInstantiatorHelper.getNonSerializableSuperClass(type); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public T newInstance() { |
|
||||||
try { |
|
||||||
return type.cast(newObjectMethod.invoke(dummyStream, type, superType)); |
|
||||||
} |
|
||||||
catch(Exception e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,67 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator.perc; |
|
||||||
|
|
||||||
import java.io.ObjectInputStream; |
|
||||||
import java.lang.reflect.Method; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.ObjenesisException; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology; |
|
||||||
|
|
||||||
/** |
|
||||||
* Instantiates a class by making a call to internal Perc private methods. It is only supposed to |
|
||||||
* work on Perc JVMs. This instantiator will not call any constructors. The code was provided by |
|
||||||
* Aonix Perc support team. |
|
||||||
* |
|
||||||
* @author Henri Tremblay |
|
||||||
* @see com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator |
|
||||||
*/ |
|
||||||
@Instantiator(Typology.STANDARD) |
|
||||||
public class PercInstantiator<T> implements ObjectInstantiator<T> { |
|
||||||
|
|
||||||
private final Method newInstanceMethod; |
|
||||||
|
|
||||||
private final Object[] typeArgs = new Object[] { null, Boolean.FALSE }; |
|
||||||
|
|
||||||
public PercInstantiator(Class<T> type) { |
|
||||||
|
|
||||||
typeArgs[0] = type; |
|
||||||
|
|
||||||
try { |
|
||||||
newInstanceMethod = ObjectInputStream.class.getDeclaredMethod("newInstance", Class.class, |
|
||||||
Boolean.TYPE); |
|
||||||
newInstanceMethod.setAccessible(true); |
|
||||||
} |
|
||||||
catch(RuntimeException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
catch(NoSuchMethodException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@SuppressWarnings("unchecked") |
|
||||||
public T newInstance() { |
|
||||||
try { |
|
||||||
return (T) newInstanceMethod.invoke(null, typeArgs); |
|
||||||
} catch (Exception e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,100 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator.perc; |
|
||||||
|
|
||||||
import java.io.ObjectInputStream; |
|
||||||
import java.io.Serializable; |
|
||||||
import java.lang.reflect.InvocationTargetException; |
|
||||||
import java.lang.reflect.Method; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.ObjenesisException; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology; |
|
||||||
|
|
||||||
/** |
|
||||||
* Instantiates a class by making a call to internal Perc private methods. It is only supposed to |
|
||||||
* work on Perc JVMs. This instantiator will create classes in a way compatible with serialization, |
|
||||||
* calling the first non-serializable superclass' no-arg constructor. |
|
||||||
* <p> |
|
||||||
* Based on code provided by Aonix but <b>doesn't work right now</b> |
|
||||||
* |
|
||||||
* @author Henri Tremblay |
|
||||||
* @see com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator |
|
||||||
*/ |
|
||||||
@Instantiator(Typology.SERIALIZATION) |
|
||||||
public class PercSerializationInstantiator<T> implements ObjectInstantiator<T> { |
|
||||||
|
|
||||||
private Object[] typeArgs; |
|
||||||
|
|
||||||
private final Method newInstanceMethod; |
|
||||||
|
|
||||||
public PercSerializationInstantiator(Class<T> type) { |
|
||||||
|
|
||||||
// Find the first unserializable parent class
|
|
||||||
Class<? super T> unserializableType = type; |
|
||||||
|
|
||||||
while(Serializable.class.isAssignableFrom(unserializableType)) { |
|
||||||
unserializableType = unserializableType.getSuperclass(); |
|
||||||
} |
|
||||||
|
|
||||||
try { |
|
||||||
// Get the special Perc method to call
|
|
||||||
Class<?> percMethodClass = Class.forName("COM.newmonics.PercClassLoader.Method"); |
|
||||||
|
|
||||||
newInstanceMethod = ObjectInputStream.class.getDeclaredMethod("noArgConstruct", |
|
||||||
new Class[] {Class.class, Object.class, percMethodClass}); |
|
||||||
newInstanceMethod.setAccessible(true); |
|
||||||
|
|
||||||
// Create invoke params
|
|
||||||
Class<?> percClassClass = Class.forName("COM.newmonics.PercClassLoader.PercClass"); |
|
||||||
Method getPercClassMethod = percClassClass.getDeclaredMethod("getPercClass", Class.class); |
|
||||||
Object someObject = getPercClassMethod.invoke(null, unserializableType); |
|
||||||
Method findMethodMethod = someObject.getClass().getDeclaredMethod("findMethod", |
|
||||||
new Class[] {String.class}); |
|
||||||
Object percMethod = findMethodMethod.invoke(someObject, "<init>()V"); |
|
||||||
|
|
||||||
typeArgs = new Object[] {unserializableType, type, percMethod}; |
|
||||||
|
|
||||||
} |
|
||||||
catch(ClassNotFoundException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
catch(NoSuchMethodException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
catch(InvocationTargetException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
catch(IllegalAccessException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@SuppressWarnings("unchecked") |
|
||||||
public T newInstance() { |
|
||||||
try { |
|
||||||
return (T) newInstanceMethod.invoke(null, typeArgs); |
|
||||||
} |
|
||||||
catch(IllegalAccessException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
catch(InvocationTargetException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,296 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator.sun; |
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream; |
|
||||||
import java.io.DataOutputStream; |
|
||||||
import java.io.IOException; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.ObjenesisException; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.util.ClassDefinitionUtils; |
|
||||||
|
|
||||||
import static com.fr.third.springframework.aop.objenesis.instantiator.util.ClassDefinitionUtils.*; |
|
||||||
|
|
||||||
/** |
|
||||||
* This instantiator will correctly bypass the constructors by instantiating the class using the default |
|
||||||
* constructor from Object. It will be allowed to do so by extending {@code MagicAccessorImpl} which prevents |
|
||||||
* its children to be verified by the class loader |
|
||||||
* |
|
||||||
* @author Henri Tremblay |
|
||||||
*/ |
|
||||||
@Instantiator(Typology.STANDARD) |
|
||||||
public class MagicInstantiator<T> implements ObjectInstantiator<T> { |
|
||||||
|
|
||||||
private static final String MAGIC_ACCESSOR = getMagicClass(); |
|
||||||
|
|
||||||
private static final int INDEX_CLASS_THIS = 1; |
|
||||||
private static final int INDEX_CLASS_SUPERCLASS = 2; |
|
||||||
private static final int INDEX_UTF8_CONSTRUCTOR_NAME = 3; |
|
||||||
private static final int INDEX_UTF8_CONSTRUCTOR_DESC = 4; |
|
||||||
private static final int INDEX_UTF8_CODE_ATTRIBUTE = 5; |
|
||||||
private static final int INDEX_UTF8_INSTANTIATOR_CLASS = 7; |
|
||||||
private static final int INDEX_UTF8_SUPERCLASS = 8; |
|
||||||
private static final int INDEX_CLASS_INTERFACE = 9; |
|
||||||
private static final int INDEX_UTF8_INTERFACE = 10; |
|
||||||
private static final int INDEX_UTF8_NEWINSTANCE_NAME = 11; |
|
||||||
private static final int INDEX_UTF8_NEWINSTANCE_DESC = 12; |
|
||||||
private static final int INDEX_METHODREF_OBJECT_CONSTRUCTOR = 13; |
|
||||||
private static final int INDEX_CLASS_OBJECT = 14; |
|
||||||
private static final int INDEX_UTF8_OBJECT = 15; |
|
||||||
private static final int INDEX_NAMEANDTYPE_DEFAULT_CONSTRUCTOR = 16; |
|
||||||
private static final int INDEX_CLASS_TYPE = 17; |
|
||||||
private static final int INDEX_UTF8_TYPE = 18; |
|
||||||
|
|
||||||
private static int CONSTANT_POOL_COUNT = 19; |
|
||||||
|
|
||||||
private static final byte[] CONSTRUCTOR_CODE = { OPS_aload_0, OPS_invokespecial, 0, INDEX_METHODREF_OBJECT_CONSTRUCTOR, OPS_return}; |
|
||||||
private static final int CONSTRUCTOR_CODE_ATTRIBUTE_LENGTH = 12 + CONSTRUCTOR_CODE.length; |
|
||||||
|
|
||||||
private static final byte[] NEWINSTANCE_CODE = { OPS_new, 0, INDEX_CLASS_TYPE, OPS_dup, OPS_invokespecial, 0, INDEX_METHODREF_OBJECT_CONSTRUCTOR, OPS_areturn}; |
|
||||||
private static final int NEWINSTANCE_CODE_ATTRIBUTE_LENGTH = 12 + NEWINSTANCE_CODE.length; |
|
||||||
|
|
||||||
private static final String CONSTRUCTOR_NAME = "<init>"; |
|
||||||
private static final String CONSTRUCTOR_DESC = "()V"; |
|
||||||
|
|
||||||
private ObjectInstantiator<T> instantiator; |
|
||||||
|
|
||||||
public MagicInstantiator(Class<T> type) { |
|
||||||
instantiator = newInstantiatorOf(type); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Get the underlying instantiator. |
|
||||||
* |
|
||||||
* {@link MagicInstantiator} is a wrapper around another object |
|
||||||
* which implements {@link ObjectInstantiator} interface. |
|
||||||
* This method exposes that instantiator. |
|
||||||
* |
|
||||||
* @return the underlying instantiator |
|
||||||
*/ |
|
||||||
public ObjectInstantiator<T> getInstantiator() { |
|
||||||
return instantiator; |
|
||||||
} |
|
||||||
|
|
||||||
private <T> ObjectInstantiator<T> newInstantiatorOf(Class<T> type) { |
|
||||||
String suffix = type.getSimpleName(); |
|
||||||
String className = getClass().getName() + "$$$" + suffix; |
|
||||||
|
|
||||||
Class<ObjectInstantiator<T>> clazz = getExistingClass(getClass().getClassLoader(), className); |
|
||||||
|
|
||||||
if(clazz == null) { |
|
||||||
byte[] classBytes = writeExtendingClass(type, className); |
|
||||||
|
|
||||||
try { |
|
||||||
clazz = ClassDefinitionUtils.defineClass(className, classBytes, getClass().getClassLoader()); |
|
||||||
} catch (Exception e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
try { |
|
||||||
return clazz.newInstance(); |
|
||||||
} catch (InstantiationException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} catch (IllegalAccessException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Will generate the bytes for a class extending the type passed in parameter. This class will |
|
||||||
* only have an empty default constructor |
|
||||||
* |
|
||||||
* @param type type to extend |
|
||||||
* @param className name of the wrapped instantiator class
|
|
||||||
* @return the byte for the class
|
|
||||||
* @throws ObjenesisException is something goes wrong |
|
||||||
*/ |
|
||||||
private byte[] writeExtendingClass(Class<?> type, String className) { |
|
||||||
String clazz = classNameToInternalClassName(className); |
|
||||||
|
|
||||||
DataOutputStream in = null; |
|
||||||
ByteArrayOutputStream bIn = new ByteArrayOutputStream(1000); // 1000 should be large enough to fit the entire class
|
|
||||||
try { |
|
||||||
in = new DataOutputStream(bIn); |
|
||||||
|
|
||||||
in.write(MAGIC); |
|
||||||
in.write(VERSION); |
|
||||||
in.writeShort(CONSTANT_POOL_COUNT); |
|
||||||
|
|
||||||
// set all the constant pool here
|
|
||||||
|
|
||||||
// 1. class
|
|
||||||
in.writeByte(CONSTANT_Class); |
|
||||||
in.writeShort(INDEX_UTF8_INSTANTIATOR_CLASS); |
|
||||||
|
|
||||||
// 2. super class
|
|
||||||
in.writeByte(CONSTANT_Class); |
|
||||||
in.writeShort(INDEX_UTF8_SUPERCLASS); |
|
||||||
|
|
||||||
// 3. default constructor name
|
|
||||||
in.writeByte(CONSTANT_Utf8); |
|
||||||
in.writeUTF(CONSTRUCTOR_NAME); |
|
||||||
|
|
||||||
// 4. default constructor description
|
|
||||||
in.writeByte(CONSTANT_Utf8); |
|
||||||
in.writeUTF(CONSTRUCTOR_DESC); |
|
||||||
|
|
||||||
// 5. Code
|
|
||||||
in.writeByte(CONSTANT_Utf8); |
|
||||||
in.writeUTF("Code"); |
|
||||||
|
|
||||||
// 6. Class name
|
|
||||||
in.writeByte(CONSTANT_Utf8); |
|
||||||
in.writeUTF("L" + clazz + ";"); |
|
||||||
|
|
||||||
// 7. Class name (again)
|
|
||||||
in.writeByte(CONSTANT_Utf8); |
|
||||||
in.writeUTF(clazz); |
|
||||||
|
|
||||||
// 8. Superclass name
|
|
||||||
in.writeByte(CONSTANT_Utf8); |
|
||||||
// in.writeUTF("java/lang/Object");
|
|
||||||
in.writeUTF(MAGIC_ACCESSOR); |
|
||||||
|
|
||||||
// 9. ObjectInstantiator interface
|
|
||||||
in.writeByte(CONSTANT_Class); |
|
||||||
in.writeShort(INDEX_UTF8_INTERFACE); |
|
||||||
|
|
||||||
// 10. ObjectInstantiator name
|
|
||||||
in.writeByte(CONSTANT_Utf8); |
|
||||||
in.writeUTF(ObjectInstantiator.class.getName().replace('.', '/')); |
|
||||||
|
|
||||||
// 11. newInstance name
|
|
||||||
in.writeByte(CONSTANT_Utf8); |
|
||||||
in.writeUTF("newInstance"); |
|
||||||
|
|
||||||
// 12. newInstance desc
|
|
||||||
in.writeByte(CONSTANT_Utf8); |
|
||||||
in.writeUTF("()Ljava/lang/Object;"); |
|
||||||
|
|
||||||
// 13. Methodref to the Object constructor
|
|
||||||
in.writeByte(CONSTANT_Methodref); |
|
||||||
in.writeShort(INDEX_CLASS_OBJECT); |
|
||||||
in.writeShort(INDEX_NAMEANDTYPE_DEFAULT_CONSTRUCTOR); |
|
||||||
|
|
||||||
// 14. Object class
|
|
||||||
in.writeByte(CONSTANT_Class); |
|
||||||
in.writeShort(INDEX_UTF8_OBJECT); |
|
||||||
|
|
||||||
// 15. Object class name
|
|
||||||
in.writeByte(CONSTANT_Utf8); |
|
||||||
in.writeUTF("java/lang/Object"); |
|
||||||
|
|
||||||
// 16. Default constructor name and type
|
|
||||||
in.writeByte(CONSTANT_NameAndType); |
|
||||||
in.writeShort(INDEX_UTF8_CONSTRUCTOR_NAME); |
|
||||||
in.writeShort(INDEX_UTF8_CONSTRUCTOR_DESC); |
|
||||||
|
|
||||||
// 17. Type to instantiate class
|
|
||||||
in.writeByte(CONSTANT_Class); |
|
||||||
in.writeShort(INDEX_UTF8_TYPE); |
|
||||||
|
|
||||||
// 18. Type to instantiate name
|
|
||||||
in.writeByte(CONSTANT_Utf8); |
|
||||||
in.writeUTF(classNameToInternalClassName(type.getName())); |
|
||||||
|
|
||||||
// end of constant pool
|
|
||||||
|
|
||||||
// access flags: We want public, ACC_SUPER is always there
|
|
||||||
in.writeShort(ACC_PUBLIC | ACC_SUPER | ACC_FINAL); |
|
||||||
|
|
||||||
// this class index in the constant pool
|
|
||||||
in.writeShort(INDEX_CLASS_THIS); |
|
||||||
|
|
||||||
// super class index in the constant pool
|
|
||||||
in.writeShort(INDEX_CLASS_SUPERCLASS); |
|
||||||
|
|
||||||
// interfaces implemented count (we have none)
|
|
||||||
in.writeShort(1); |
|
||||||
in.writeShort(INDEX_CLASS_INTERFACE); |
|
||||||
|
|
||||||
// fields count (we have none)
|
|
||||||
in.writeShort(0); |
|
||||||
|
|
||||||
// method count (we have two: the default constructor and newInstance)
|
|
||||||
in.writeShort(2); |
|
||||||
|
|
||||||
// default constructor method_info
|
|
||||||
in.writeShort(ACC_PUBLIC); |
|
||||||
in.writeShort(INDEX_UTF8_CONSTRUCTOR_NAME); // index of the method name (<init>)
|
|
||||||
in.writeShort(INDEX_UTF8_CONSTRUCTOR_DESC); // index of the description
|
|
||||||
in.writeShort(1); // number of attributes: only one, the code
|
|
||||||
|
|
||||||
// code attribute of the default constructor
|
|
||||||
in.writeShort(INDEX_UTF8_CODE_ATTRIBUTE); |
|
||||||
in.writeInt(CONSTRUCTOR_CODE_ATTRIBUTE_LENGTH); // attribute length
|
|
||||||
in.writeShort(0); // max_stack
|
|
||||||
in.writeShort(1); // max_locals
|
|
||||||
in.writeInt(CONSTRUCTOR_CODE.length); // code length
|
|
||||||
in.write(CONSTRUCTOR_CODE); |
|
||||||
in.writeShort(0); // exception_table_length = 0
|
|
||||||
in.writeShort(0); // attributes count = 0, no need to have LineNumberTable and LocalVariableTable
|
|
||||||
|
|
||||||
// newInstance method_info
|
|
||||||
in.writeShort(ACC_PUBLIC); |
|
||||||
in.writeShort(INDEX_UTF8_NEWINSTANCE_NAME); // index of the method name (newInstance)
|
|
||||||
in.writeShort(INDEX_UTF8_NEWINSTANCE_DESC); // index of the description
|
|
||||||
in.writeShort(1); // number of attributes: only one, the code
|
|
||||||
|
|
||||||
// code attribute of newInstance
|
|
||||||
in.writeShort(INDEX_UTF8_CODE_ATTRIBUTE); |
|
||||||
in.writeInt(NEWINSTANCE_CODE_ATTRIBUTE_LENGTH); // attribute length
|
|
||||||
in.writeShort(2); // max_stack
|
|
||||||
in.writeShort(1); // max_locals
|
|
||||||
in.writeInt(NEWINSTANCE_CODE.length); // code length
|
|
||||||
in.write(NEWINSTANCE_CODE); |
|
||||||
in.writeShort(0); // exception_table_length = 0
|
|
||||||
in.writeShort(0); // attributes count = 0, no need to have LineNumberTable and LocalVariableTable
|
|
||||||
|
|
||||||
// class attributes
|
|
||||||
in.writeShort(0); // none. No need to have a source file attribute
|
|
||||||
|
|
||||||
} catch (IOException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} finally { |
|
||||||
if(in != null) { |
|
||||||
try { |
|
||||||
in.close(); |
|
||||||
} catch (IOException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return bIn.toByteArray(); |
|
||||||
} |
|
||||||
|
|
||||||
public T newInstance() { |
|
||||||
return instantiator.newInstance(); |
|
||||||
} |
|
||||||
|
|
||||||
private static String getMagicClass() { |
|
||||||
try { |
|
||||||
Class.forName("sun.reflect.MagicAccessorImpl", false, MagicInstantiator.class.getClassLoader()); |
|
||||||
return "sun/reflect/MagicAccessorImpl"; |
|
||||||
} catch (ClassNotFoundException e) { |
|
||||||
return "jdk/internal/reflect/MagicAccessorImpl"; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,96 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator.sun; |
|
||||||
import java.lang.reflect.Constructor; |
|
||||||
import java.lang.reflect.InvocationTargetException; |
|
||||||
import java.lang.reflect.Method; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.ObjenesisException; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator; |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* Helper methods providing access to {@link sun.reflect.ReflectionFactory} via reflection, for use |
|
||||||
* by the {@link ObjectInstantiator}s that use it. |
|
||||||
* |
|
||||||
* @author Henri Tremblay |
|
||||||
*/ |
|
||||||
@SuppressWarnings("restriction") |
|
||||||
class SunReflectionFactoryHelper { |
|
||||||
|
|
||||||
@SuppressWarnings("unchecked") |
|
||||||
public static <T> Constructor<T> newConstructorForSerialization(Class<T> type, |
|
||||||
Constructor<?> constructor) { |
|
||||||
Class<?> reflectionFactoryClass = getReflectionFactoryClass(); |
|
||||||
Object reflectionFactory = createReflectionFactory(reflectionFactoryClass); |
|
||||||
|
|
||||||
Method newConstructorForSerializationMethod = getNewConstructorForSerializationMethod( |
|
||||||
reflectionFactoryClass); |
|
||||||
|
|
||||||
try { |
|
||||||
return (Constructor<T>) newConstructorForSerializationMethod.invoke( |
|
||||||
reflectionFactory, type, constructor); |
|
||||||
} |
|
||||||
catch(IllegalArgumentException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
catch(IllegalAccessException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
catch(InvocationTargetException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private static Class<?> getReflectionFactoryClass() { |
|
||||||
try { |
|
||||||
return Class.forName("sun.reflect.ReflectionFactory"); |
|
||||||
} |
|
||||||
catch(ClassNotFoundException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private static Object createReflectionFactory(Class<?> reflectionFactoryClass) { |
|
||||||
try { |
|
||||||
Method method = reflectionFactoryClass.getDeclaredMethod( |
|
||||||
"getReflectionFactory"); |
|
||||||
return method.invoke(null); |
|
||||||
} |
|
||||||
catch(NoSuchMethodException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
catch(IllegalAccessException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
catch(IllegalArgumentException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
catch(InvocationTargetException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private static Method getNewConstructorForSerializationMethod(Class<?> reflectionFactoryClass) { |
|
||||||
try { |
|
||||||
return reflectionFactoryClass.getDeclaredMethod( |
|
||||||
"newConstructorForSerialization", Class.class, Constructor.class); |
|
||||||
} |
|
||||||
catch(NoSuchMethodException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,63 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator.sun; |
|
||||||
|
|
||||||
import java.lang.reflect.Constructor; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.ObjenesisException; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology; |
|
||||||
|
|
||||||
/** |
|
||||||
* Instantiates an object, WITHOUT calling it's constructor, using internal |
|
||||||
* sun.reflect.ReflectionFactory - a class only available on JDK's that use Sun's 1.4 (or later) |
|
||||||
* Java implementation. This is the best way to instantiate an object without any side effects |
|
||||||
* caused by the constructor - however it is not available on every platform. |
|
||||||
* |
|
||||||
* @author Joe Walnes |
|
||||||
* @see ObjectInstantiator |
|
||||||
*/ |
|
||||||
@Instantiator(Typology.STANDARD) |
|
||||||
public class SunReflectionFactoryInstantiator<T> implements ObjectInstantiator<T> { |
|
||||||
|
|
||||||
private final Constructor<T> mungedConstructor; |
|
||||||
|
|
||||||
public SunReflectionFactoryInstantiator(Class<T> type) { |
|
||||||
Constructor<Object> javaLangObjectConstructor = getJavaLangObjectConstructor(); |
|
||||||
mungedConstructor = SunReflectionFactoryHelper.newConstructorForSerialization( |
|
||||||
type, javaLangObjectConstructor); |
|
||||||
mungedConstructor.setAccessible(true); |
|
||||||
} |
|
||||||
|
|
||||||
public T newInstance() { |
|
||||||
try { |
|
||||||
return mungedConstructor.newInstance((Object[]) null); |
|
||||||
} |
|
||||||
catch(Exception e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private static Constructor<Object> getJavaLangObjectConstructor() { |
|
||||||
try { |
|
||||||
return Object.class.getConstructor((Class[]) null); |
|
||||||
} |
|
||||||
catch(NoSuchMethodException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,68 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator.sun; |
|
||||||
|
|
||||||
import java.io.NotSerializableException; |
|
||||||
import java.lang.reflect.Constructor; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.ObjenesisException; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.SerializationInstantiatorHelper; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology; |
|
||||||
|
|
||||||
/** |
|
||||||
* Instantiates an object using internal sun.reflect.ReflectionFactory - a class only available on |
|
||||||
* JDK's that use Sun's 1.4 (or later) Java implementation. This instantiator will create classes in |
|
||||||
* a way compatible with serialization, calling the first non-serializable superclass' no-arg |
|
||||||
* constructor. This is the best way to instantiate an object without any side effects caused by the |
|
||||||
* constructor - however it is not available on every platform. |
|
||||||
* |
|
||||||
* @author Leonardo Mesquita |
|
||||||
* @see ObjectInstantiator |
|
||||||
*/ |
|
||||||
@Instantiator(Typology.SERIALIZATION) |
|
||||||
public class SunReflectionFactorySerializationInstantiator<T> implements ObjectInstantiator<T> { |
|
||||||
|
|
||||||
private final Constructor<T> mungedConstructor; |
|
||||||
|
|
||||||
public SunReflectionFactorySerializationInstantiator(Class<T> type) { |
|
||||||
Class<? super T> nonSerializableAncestor = SerializationInstantiatorHelper |
|
||||||
.getNonSerializableSuperClass(type); |
|
||||||
|
|
||||||
Constructor<? super T> nonSerializableAncestorConstructor; |
|
||||||
try { |
|
||||||
nonSerializableAncestorConstructor = nonSerializableAncestor |
|
||||||
.getDeclaredConstructor((Class[]) null); |
|
||||||
} |
|
||||||
catch(NoSuchMethodException e) { |
|
||||||
throw new ObjenesisException(new NotSerializableException(type+" has no suitable superclass constructor")); |
|
||||||
} |
|
||||||
|
|
||||||
mungedConstructor = SunReflectionFactoryHelper.newConstructorForSerialization( |
|
||||||
type, nonSerializableAncestorConstructor); |
|
||||||
mungedConstructor.setAccessible(true); |
|
||||||
} |
|
||||||
|
|
||||||
public T newInstance() { |
|
||||||
try { |
|
||||||
return mungedConstructor.newInstance((Object[]) null); |
|
||||||
} |
|
||||||
catch(Exception e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,54 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator.sun; |
|
||||||
|
|
||||||
import sun.misc.Unsafe; |
|
||||||
import com.fr.third.springframework.aop.objenesis.ObjenesisException; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.util.UnsafeUtils; |
|
||||||
|
|
||||||
import java.lang.reflect.Field; |
|
||||||
|
|
||||||
/** |
|
||||||
* Instantiates an object, WITHOUT calling it's constructor, using |
|
||||||
* {@code sun.misc.Unsafe.allocateInstance()}. Unsafe and its methods are implemented by most |
|
||||||
* modern JVMs. |
|
||||||
* |
|
||||||
* @author Henri Tremblay |
|
||||||
* @see ObjectInstantiator |
|
||||||
*/ |
|
||||||
@SuppressWarnings("restriction") |
|
||||||
@Instantiator(Typology.STANDARD) |
|
||||||
public class UnsafeFactoryInstantiator<T> implements ObjectInstantiator<T> { |
|
||||||
|
|
||||||
private final Unsafe unsafe; |
|
||||||
private final Class<T> type; |
|
||||||
|
|
||||||
public UnsafeFactoryInstantiator(Class<T> type) { |
|
||||||
this.unsafe = UnsafeUtils.getUnsafe(); // retrieve it to fail right away at instantiator creation if not there
|
|
||||||
this.type = type; |
|
||||||
} |
|
||||||
|
|
||||||
public T newInstance() { |
|
||||||
try { |
|
||||||
return type.cast(unsafe.allocateInstance(type)); |
|
||||||
} catch (InstantiationException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,195 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator.util; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.ObjenesisException; |
|
||||||
|
|
||||||
import java.io.BufferedOutputStream; |
|
||||||
import java.io.FileOutputStream; |
|
||||||
import java.io.IOException; |
|
||||||
import java.io.InputStream; |
|
||||||
import java.lang.reflect.Field; |
|
||||||
import java.security.AccessController; |
|
||||||
import java.security.PrivilegedAction; |
|
||||||
import java.security.ProtectionDomain; |
|
||||||
|
|
||||||
import sun.misc.Unsafe; |
|
||||||
|
|
||||||
/** |
|
||||||
* Helper class for ProxyObjectInstantiator. We can see the details of a class specification |
|
||||||
* <a href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html">here</a> |
|
||||||
* |
|
||||||
* @author Henri Tremblay |
|
||||||
*/ |
|
||||||
public final class ClassDefinitionUtils { |
|
||||||
|
|
||||||
public static final byte OPS_aload_0 = 42; |
|
||||||
public static final byte OPS_invokespecial = -73; // has two bytes parameters
|
|
||||||
public static final byte OPS_return = -79; |
|
||||||
public static final byte OPS_new = -69; |
|
||||||
public static final byte OPS_dup = 89; |
|
||||||
public static final byte OPS_areturn = -80; |
|
||||||
|
|
||||||
public static final int CONSTANT_Utf8 = 1; |
|
||||||
public static final int CONSTANT_Integer = 3; |
|
||||||
public static final int CONSTANT_Float = 4; |
|
||||||
public static final int CONSTANT_Long = 5; |
|
||||||
public static final int CONSTANT_Double = 6; |
|
||||||
public static final int CONSTANT_Class = 7; |
|
||||||
public static final int CONSTANT_String = 8; |
|
||||||
public static final int CONSTANT_Fieldref = 9; |
|
||||||
public static final int CONSTANT_Methodref = 10; |
|
||||||
public static final int CONSTANT_InterfaceMethodref = 11; |
|
||||||
public static final int CONSTANT_NameAndType = 12; |
|
||||||
public static final int CONSTANT_MethodHandle = 15; |
|
||||||
public static final int CONSTANT_MethodType = 16; |
|
||||||
public static final int CONSTANT_InvokeDynamic = 18; |
|
||||||
|
|
||||||
public static final int ACC_PUBLIC = 0x0001; // Declared public; may be accessed from outside its package.
|
|
||||||
public static final int ACC_FINAL = 0x0010; // Declared final; no subclasses allowed.
|
|
||||||
public static final int ACC_SUPER = 0x0020; // Treat superclass methods specially when invoked by the invokespecial instruction.
|
|
||||||
public static final int ACC_INTERFACE = 0x0200; // Is an interface, not a class.
|
|
||||||
public static final int ACC_ABSTRACT = 0x0400; // Declared abstract; must not be instantiated.
|
|
||||||
public static final int ACC_SYNTHETIC = 0x1000; // Declared synthetic; not present in the source code.
|
|
||||||
public static final int ACC_ANNOTATION = 0x2000; // Declared as an annotation type.
|
|
||||||
public static final int ACC_ENUM = 0x4000; // Declared as an enum type.
|
|
||||||
|
|
||||||
public static final byte[] MAGIC = { (byte) 0xca, (byte) 0xfe, (byte) 0xba, (byte) 0xbe }; |
|
||||||
public static final byte[] VERSION = { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x31 }; // minor_version, major_version (Java 5)
|
|
||||||
|
|
||||||
private ClassDefinitionUtils() { } |
|
||||||
|
|
||||||
// private static Method DEFINE_CLASS;
|
|
||||||
private static final ProtectionDomain PROTECTION_DOMAIN; |
|
||||||
|
|
||||||
static { |
|
||||||
PROTECTION_DOMAIN = AccessController.doPrivileged(new PrivilegedAction<ProtectionDomain>() { |
|
||||||
public ProtectionDomain run() { |
|
||||||
return ClassDefinitionUtils.class.getProtectionDomain(); |
|
||||||
} |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Define a class in the provided class loader from the array of bytes. Inspired by cglib |
|
||||||
* <code>ReflectUtils.defineClass</code> |
|
||||||
* |
|
||||||
* @param <T> type of the class returned |
|
||||||
* @param className class name in the format <code>com.fr.third.springframework.aop.objenesis.MyClass</code> |
|
||||||
* @param b bytes representing the class
|
|
||||||
* @param loader the class loader where the class will be loaded |
|
||||||
* @return the newly loaded class
|
|
||||||
* @throws Exception whenever something goes wrong |
|
||||||
*/ |
|
||||||
@SuppressWarnings("unchecked") |
|
||||||
public static <T> Class<T> defineClass(String className, byte[] b, ClassLoader loader) |
|
||||||
throws Exception { |
|
||||||
Class<T> c = (Class<T>) UnsafeUtils.getUnsafe().defineClass(className, b, 0, b.length, loader, PROTECTION_DOMAIN); |
|
||||||
// Force static initializers to run.
|
|
||||||
Class.forName(className, true, loader); |
|
||||||
return c; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Read the bytes of a class from the classpath |
|
||||||
* |
|
||||||
* @param className full class name including the package
|
|
||||||
* @return the bytes representing the class
|
|
||||||
* @throws IllegalArgumentException if the class is longer than 2500 bytes |
|
||||||
* @throws IOException if we fail to read the class
|
|
||||||
*/ |
|
||||||
public static byte[] readClass(String className) throws IOException { |
|
||||||
// convert to a resource
|
|
||||||
className = classNameToResource(className); |
|
||||||
|
|
||||||
byte[] b = new byte[2500]; // I'm assuming that I'm reading class that are not too big
|
|
||||||
|
|
||||||
int length; |
|
||||||
|
|
||||||
InputStream in = ClassDefinitionUtils.class.getClassLoader().getResourceAsStream(className); |
|
||||||
try { |
|
||||||
length = in.read(b); |
|
||||||
} |
|
||||||
finally { |
|
||||||
in.close(); |
|
||||||
} |
|
||||||
|
|
||||||
if(length >= 2500) { |
|
||||||
throw new IllegalArgumentException("The class is longer that 2500 bytes which is currently unsupported"); |
|
||||||
} |
|
||||||
|
|
||||||
byte[] copy = new byte[length]; |
|
||||||
System.arraycopy(b, 0, copy, 0, length); |
|
||||||
return copy; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Write all class bytes to a file. |
|
||||||
* |
|
||||||
* @param fileName file where the bytes will be written |
|
||||||
* @param bytes bytes representing the class
|
|
||||||
* @throws IOException if we fail to write the class
|
|
||||||
*/ |
|
||||||
public static void writeClass(String fileName, byte[] bytes) throws IOException { |
|
||||||
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(fileName)); |
|
||||||
try { |
|
||||||
out.write(bytes); |
|
||||||
} |
|
||||||
finally { |
|
||||||
out.close(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Will convert a class name to its name in the class definition format (e.g {@code com.fr.third.springframework.aop.objenesis.EmptyClass} |
|
||||||
* becomes {@code org/objenesis/EmptyClass}) |
|
||||||
* |
|
||||||
* @param className full class name including the package
|
|
||||||
* @return the internal name |
|
||||||
*/ |
|
||||||
public static String classNameToInternalClassName(String className) { |
|
||||||
return className.replace('.', '/'); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Will convert a class name to its class loader resource name (e.g {@code com.fr.third.springframework.aop.objenesis.EmptyClass} |
|
||||||
* becomes {@code org/objenesis/EmptyClass.class}) |
|
||||||
* |
|
||||||
* @param className full class name including the package
|
|
||||||
* @return the resource name |
|
||||||
*/ |
|
||||||
public static String classNameToResource(String className) { |
|
||||||
return classNameToInternalClassName(className) + ".class"; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Check if this class already exists in the class loader and return it if it does |
|
||||||
* |
|
||||||
* @param <T> type of the class returned |
|
||||||
* @param classLoader Class loader where to search the class
|
|
||||||
* @param className Class name with full path |
|
||||||
* @return the class if it already exists or null |
|
||||||
*/ |
|
||||||
@SuppressWarnings("unchecked") |
|
||||||
public static <T> Class<T> getExistingClass(ClassLoader classLoader, String className) { |
|
||||||
try { |
|
||||||
return (Class<T>) Class.forName(className, true, classLoader); |
|
||||||
} |
|
||||||
catch (ClassNotFoundException e) { |
|
||||||
return null; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,53 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.instantiator.util; |
|
||||||
|
|
||||||
import java.lang.reflect.Field; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.ObjenesisException; |
|
||||||
|
|
||||||
import sun.misc.Unsafe; |
|
||||||
|
|
||||||
/** |
|
||||||
* Helper class basically allowing to get access to {@code sun.misc.Unsafe} |
|
||||||
* |
|
||||||
* @author Henri Tremblay |
|
||||||
*/ |
|
||||||
public final class UnsafeUtils { |
|
||||||
|
|
||||||
private static final Unsafe unsafe; |
|
||||||
|
|
||||||
static { |
|
||||||
Field f; |
|
||||||
try { |
|
||||||
f = Unsafe.class.getDeclaredField("theUnsafe"); |
|
||||||
} catch (NoSuchFieldException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
f.setAccessible(true); |
|
||||||
try { |
|
||||||
unsafe = (Unsafe) f.get(null); |
|
||||||
} catch (IllegalAccessException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private UnsafeUtils() {} |
|
||||||
|
|
||||||
public static Unsafe getUnsafe() { |
|
||||||
return unsafe; |
|
||||||
} |
|
||||||
} |
|
@ -1,25 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.strategy; |
|
||||||
|
|
||||||
/** |
|
||||||
* Base {@link InstantiatorStrategy} class basically. Only implements {@link InstantiatorStrategy} |
|
||||||
* |
|
||||||
* @author Henri Tremblay |
|
||||||
*/ |
|
||||||
public abstract class BaseInstantiatorStrategy implements InstantiatorStrategy { |
|
||||||
|
|
||||||
} |
|
@ -1,35 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.strategy; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator; |
|
||||||
|
|
||||||
/** |
|
||||||
* Defines a strategy to determine the best instantiator for a class. |
|
||||||
* |
|
||||||
* @author Henri Tremblay |
|
||||||
*/ |
|
||||||
public interface InstantiatorStrategy { |
|
||||||
|
|
||||||
/** |
|
||||||
* Create a dedicated instantiator for the given class
|
|
||||||
* |
|
||||||
* @param <T> Type to instantiate |
|
||||||
* @param type Class that will be instantiated |
|
||||||
* @return Dedicated instantiator |
|
||||||
*/ |
|
||||||
<T> ObjectInstantiator<T> newInstantiatorOf(Class<T> type); |
|
||||||
} |
|
@ -1,198 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.strategy; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.ObjenesisException; |
|
||||||
|
|
||||||
import java.lang.reflect.Field; |
|
||||||
|
|
||||||
/** |
|
||||||
* List of constants describing the currently used platform. |
|
||||||
* |
|
||||||
* @author Henri Tremblay |
|
||||||
*/ |
|
||||||
public final class PlatformDescription { |
|
||||||
|
|
||||||
/** JVM_NAME prefix for JRockit */ |
|
||||||
public static final String JROCKIT = "BEA"; |
|
||||||
|
|
||||||
/** JVM_NAME prefix for GCJ */ |
|
||||||
public static final String GNU = "GNU libgcj"; |
|
||||||
|
|
||||||
/** JVM_NAME prefix for Java HotSpot */ |
|
||||||
public static final String HOTSPOT = "Java HotSpot"; |
|
||||||
|
|
||||||
/** |
|
||||||
* JVM_NAME prefix for Java HotSpot |
|
||||||
* |
|
||||||
* @deprecated Use {@link #HOTSPOT} instead |
|
||||||
*/ |
|
||||||
@Deprecated |
|
||||||
public static final String SUN = HOTSPOT; |
|
||||||
|
|
||||||
/** JVM_NAME prefix for the OpenJDK */ |
|
||||||
public static final String OPENJDK = "OpenJDK"; |
|
||||||
|
|
||||||
/** JVM_NAME prefix for Aonix PERC */ |
|
||||||
public static final String PERC = "PERC"; |
|
||||||
|
|
||||||
/** JVM_NAME prefix for Dalvik/Android */ |
|
||||||
public static final String DALVIK = "Dalvik"; |
|
||||||
|
|
||||||
/** Java specification version */ |
|
||||||
public static final String SPECIFICATION_VERSION = System |
|
||||||
.getProperty("java.specification.version"); |
|
||||||
|
|
||||||
/** JVM version */ |
|
||||||
public static final String VM_VERSION = System.getProperty("java.runtime.version"); |
|
||||||
|
|
||||||
/** JVM version */ |
|
||||||
public static final String VM_INFO = System.getProperty("java.vm.info"); |
|
||||||
|
|
||||||
/** VM vendor version */ |
|
||||||
public static final String VENDOR_VERSION = System.getProperty("java.vm.version"); |
|
||||||
|
|
||||||
/** VM vendor name */ |
|
||||||
public static final String VENDOR = System.getProperty("java.vm.vendor"); |
|
||||||
|
|
||||||
/** JVM name */ |
|
||||||
public static final String JVM_NAME = System.getProperty("java.vm.name"); |
|
||||||
|
|
||||||
/** Android version. Will be 0 for none android platform */ |
|
||||||
public static final int ANDROID_VERSION = getAndroidVersion(); |
|
||||||
|
|
||||||
/** Flag telling if this version of Android is based on the OpenJDK */ |
|
||||||
public static final boolean IS_ANDROID_OPENJDK = getIsAndroidOpenJDK(); |
|
||||||
|
|
||||||
/** Google App Engine version or null is we are not on GAE */ |
|
||||||
public static final String GAE_VERSION = getGaeRuntimeVersion(); |
|
||||||
|
|
||||||
/** |
|
||||||
* Describes the platform. Outputs Java version and vendor. |
|
||||||
* |
|
||||||
* @return Description of the current platform |
|
||||||
*/ |
|
||||||
public static String describePlatform() { |
|
||||||
String desc = "Java " + SPECIFICATION_VERSION + " (" |
|
||||||
+ "VM vendor name=\"" + VENDOR + "\", " |
|
||||||
+ "VM vendor version=" + VENDOR_VERSION + ", " |
|
||||||
+ "JVM name=\"" + JVM_NAME + "\", " |
|
||||||
+ "JVM version=" + VM_VERSION + ", " |
|
||||||
+ "JVM info=" + VM_INFO; |
|
||||||
|
|
||||||
// Add the API level is it's an Android platform
|
|
||||||
int androidVersion = ANDROID_VERSION; |
|
||||||
if(androidVersion != 0) { |
|
||||||
desc += ", API level=" + ANDROID_VERSION; |
|
||||||
} |
|
||||||
desc += ")"; |
|
||||||
|
|
||||||
return desc; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Check if the current JVM is of the type passed in parameter. Normally, this will be a constant |
|
||||||
* from this class. We basically do |
|
||||||
* <code>System.getProperty("java.vm.name").startWith(name)</code>. |
|
||||||
* |
|
||||||
* @param name jvm name we are looking for |
|
||||||
* @return if it's the requested JVM |
|
||||||
*/ |
|
||||||
public static boolean isThisJVM(String name) { |
|
||||||
return JVM_NAME.startsWith(name); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Check if this JVM is an Android JVM based on OpenJDK. |
|
||||||
* |
|
||||||
* @return if it's an Android version based on the OpenJDK. Will return false if this JVM isn't an Android JVM at all |
|
||||||
*/ |
|
||||||
public static boolean isAndroidOpenJDK() { |
|
||||||
return IS_ANDROID_OPENJDK; |
|
||||||
} |
|
||||||
|
|
||||||
private static boolean getIsAndroidOpenJDK() { |
|
||||||
if(getAndroidVersion() == 0) { |
|
||||||
return false; // Not android at all
|
|
||||||
} |
|
||||||
// Sadly, Android N is still API 23. So we can't base ourselves on the API level to know if it is an OpenJDK
|
|
||||||
// version or not
|
|
||||||
String bootClasspath = System.getProperty("java.boot.class.path"); |
|
||||||
return bootClasspath != null && bootClasspath.toLowerCase().contains("core-oj.jar"); |
|
||||||
} |
|
||||||
|
|
||||||
public static boolean isGoogleAppEngine() { |
|
||||||
return GAE_VERSION != null; |
|
||||||
} |
|
||||||
|
|
||||||
private static String getGaeRuntimeVersion() { |
|
||||||
return System.getProperty("com.google.appengine.runtime.version"); |
|
||||||
} |
|
||||||
|
|
||||||
private static int getAndroidVersion() { |
|
||||||
if(!isThisJVM(DALVIK)) { |
|
||||||
return 0; |
|
||||||
} |
|
||||||
return getAndroidVersion0(); |
|
||||||
} |
|
||||||
|
|
||||||
private static int getAndroidVersion0() { |
|
||||||
Class<?> clazz; |
|
||||||
try { |
|
||||||
clazz = Class.forName("android.os.Build$VERSION"); |
|
||||||
} |
|
||||||
catch(ClassNotFoundException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
Field field; |
|
||||||
try { |
|
||||||
field = clazz.getField("SDK_INT"); |
|
||||||
} |
|
||||||
catch(NoSuchFieldException e) { |
|
||||||
// Might be a really old API (before 4), go for SDK
|
|
||||||
return getOldAndroidVersion(clazz); |
|
||||||
} |
|
||||||
int version; |
|
||||||
try { |
|
||||||
version = (Integer) field.get(null); |
|
||||||
} |
|
||||||
catch(IllegalAccessException e) { |
|
||||||
throw new RuntimeException(e); |
|
||||||
} |
|
||||||
return version; |
|
||||||
} |
|
||||||
|
|
||||||
private static int getOldAndroidVersion(Class<?> versionClass) { |
|
||||||
Field field; |
|
||||||
try { |
|
||||||
field = versionClass.getField("SDK"); |
|
||||||
} |
|
||||||
catch(NoSuchFieldException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
String version; |
|
||||||
try { |
|
||||||
version = (String) field.get(null); |
|
||||||
} |
|
||||||
catch(IllegalAccessException e) { |
|
||||||
throw new RuntimeException(e); |
|
||||||
} |
|
||||||
return Integer.parseInt(version); |
|
||||||
} |
|
||||||
|
|
||||||
private PlatformDescription() { |
|
||||||
} |
|
||||||
} |
|
@ -1,83 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.strategy; |
|
||||||
|
|
||||||
import java.io.NotSerializableException; |
|
||||||
import java.io.Serializable; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.ObjenesisException; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.android.AndroidSerializationInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.basic.ObjectInputStreamInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.basic.ObjectStreamClassInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.gcj.GCJSerializationInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.perc.PercSerializationInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.sun.SunReflectionFactorySerializationInstantiator; |
|
||||||
|
|
||||||
import static com.fr.third.springframework.aop.objenesis.strategy.PlatformDescription.*; |
|
||||||
|
|
||||||
/** |
|
||||||
* Guess the best serializing instantiator for a given class. The returned instantiator will |
|
||||||
* instantiate classes like the genuine java serialization framework (the constructor of the first |
|
||||||
* not serializable class will be called). Currently, the selection doesn't depend on the class. It |
|
||||||
* relies on the |
|
||||||
* <ul> |
|
||||||
* <li>JVM version</li> |
|
||||||
* <li>JVM vendor</li> |
|
||||||
* <li>JVM vendor version</li> |
|
||||||
* </ul> |
|
||||||
* However, instantiators are stateful and so dedicated to their class. |
|
||||||
* |
|
||||||
* @author Henri Tremblay |
|
||||||
* @see ObjectInstantiator |
|
||||||
*/ |
|
||||||
public class SerializingInstantiatorStrategy extends BaseInstantiatorStrategy { |
|
||||||
|
|
||||||
/** |
|
||||||
* Return an {@link ObjectInstantiator} allowing to create instance following the java |
|
||||||
* serialization framework specifications. |
|
||||||
* |
|
||||||
* @param type Class to instantiate |
|
||||||
* @return The ObjectInstantiator for the class
|
|
||||||
*/ |
|
||||||
public <T> ObjectInstantiator<T> newInstantiatorOf(Class<T> type) { |
|
||||||
if(!Serializable.class.isAssignableFrom(type)) { |
|
||||||
throw new ObjenesisException(new NotSerializableException(type+" not serializable")); |
|
||||||
} |
|
||||||
if(JVM_NAME.startsWith(HOTSPOT) || PlatformDescription.isThisJVM(OPENJDK)) { |
|
||||||
// Java 7 GAE was under a security manager so we use a degraded system
|
|
||||||
if(isGoogleAppEngine() && PlatformDescription.SPECIFICATION_VERSION.equals("1.7")) { |
|
||||||
return new ObjectInputStreamInstantiator<T>(type); |
|
||||||
} |
|
||||||
return new SunReflectionFactorySerializationInstantiator<T>(type); |
|
||||||
} |
|
||||||
else if(JVM_NAME.startsWith(DALVIK)) { |
|
||||||
if(PlatformDescription.isAndroidOpenJDK()) { |
|
||||||
return new ObjectStreamClassInstantiator<T>(type); |
|
||||||
} |
|
||||||
return new AndroidSerializationInstantiator<T>(type); |
|
||||||
} |
|
||||||
else if(JVM_NAME.startsWith(GNU)) { |
|
||||||
return new GCJSerializationInstantiator<T>(type); |
|
||||||
} |
|
||||||
else if(JVM_NAME.startsWith(PERC)) { |
|
||||||
return new PercSerializationInstantiator<T>(type); |
|
||||||
} |
|
||||||
|
|
||||||
return new SunReflectionFactorySerializationInstantiator<T>(type); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,70 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.strategy; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.ObjenesisException; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator; |
|
||||||
|
|
||||||
import java.lang.reflect.Constructor; |
|
||||||
import java.lang.reflect.InvocationTargetException; |
|
||||||
|
|
||||||
/** |
|
||||||
* Strategy returning only one instantiator type. Useful if you know on which JVM Objenesis |
|
||||||
* will be used and want to specify it explicitly. |
|
||||||
* |
|
||||||
* @author Henri Tremblay |
|
||||||
*/ |
|
||||||
public class SingleInstantiatorStrategy implements InstantiatorStrategy { |
|
||||||
|
|
||||||
private Constructor<?> constructor; |
|
||||||
|
|
||||||
/** |
|
||||||
* Create a strategy that will return always the same instantiator type. We assume this instantiator |
|
||||||
* has one constructor taking the class to instantiate in parameter. |
|
||||||
* |
|
||||||
* @param <T> the type we want to instantiate |
|
||||||
* @param instantiator the instantiator type |
|
||||||
*/ |
|
||||||
public <T extends ObjectInstantiator<?>> SingleInstantiatorStrategy(Class<T> instantiator) { |
|
||||||
try { |
|
||||||
constructor = instantiator.getConstructor(Class.class); |
|
||||||
} |
|
||||||
catch(NoSuchMethodException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Return an instantiator for the wanted type and of the one and only type of instantiator returned by this |
|
||||||
* class. |
|
||||||
* |
|
||||||
* @param <T> the type we want to instantiate |
|
||||||
* @param type Class to instantiate |
|
||||||
* @return The ObjectInstantiator for the class
|
|
||||||
*/ |
|
||||||
@SuppressWarnings("unchecked") |
|
||||||
public <T> ObjectInstantiator<T> newInstantiatorOf(Class<T> type) { |
|
||||||
try { |
|
||||||
return (ObjectInstantiator<T>) constructor.newInstance(type); |
|
||||||
} catch (InstantiationException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} catch (IllegalAccessException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} catch (InvocationTargetException e) { |
|
||||||
throw new ObjenesisException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,101 +0,0 @@ |
|||||||
/** |
|
||||||
* Copyright 2006-2017 the original author or authors. |
|
||||||
* |
|
||||||
* Licensed 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 com.fr.third.springframework.aop.objenesis.strategy; |
|
||||||
|
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.android.Android10Instantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.android.Android17Instantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.android.Android18Instantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.basic.AccessibleInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.basic.ObjectInputStreamInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.gcj.GCJInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.perc.PercInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.sun.SunReflectionFactoryInstantiator; |
|
||||||
import com.fr.third.springframework.aop.objenesis.instantiator.sun.UnsafeFactoryInstantiator; |
|
||||||
|
|
||||||
import java.io.Serializable; |
|
||||||
|
|
||||||
import static com.fr.third.springframework.aop.objenesis.strategy.PlatformDescription.*; |
|
||||||
|
|
||||||
/** |
|
||||||
* Guess the best instantiator for a given class. The instantiator will instantiate the class
|
|
||||||
* without calling any constructor. Currently, the selection doesn't depend on the class. It relies |
|
||||||
* on the |
|
||||||
* <ul> |
|
||||||
* <li>JVM version</li> |
|
||||||
* <li>JVM vendor</li> |
|
||||||
* <li>JVM vendor version</li> |
|
||||||
* </ul> |
|
||||||
* However, instantiators are stateful and so dedicated to their class. |
|
||||||
* |
|
||||||
* @author Henri Tremblay |
|
||||||
* @see ObjectInstantiator |
|
||||||
*/ |
|
||||||
public class StdInstantiatorStrategy extends BaseInstantiatorStrategy { |
|
||||||
|
|
||||||
/** |
|
||||||
* Return an {@link ObjectInstantiator} allowing to create instance without any constructor being |
|
||||||
* called. |
|
||||||
* |
|
||||||
* @param type Class to instantiate |
|
||||||
* @return The ObjectInstantiator for the class
|
|
||||||
*/ |
|
||||||
public <T> ObjectInstantiator<T> newInstantiatorOf(Class<T> type) { |
|
||||||
|
|
||||||
if(PlatformDescription.isThisJVM(HOTSPOT) || PlatformDescription.isThisJVM(OPENJDK)) { |
|
||||||
// Java 7 GAE was under a security manager so we use a degraded system
|
|
||||||
if(PlatformDescription.isGoogleAppEngine() && PlatformDescription.SPECIFICATION_VERSION.equals("1.7")) { |
|
||||||
if(Serializable.class.isAssignableFrom(type)) { |
|
||||||
return new ObjectInputStreamInstantiator<T>(type); |
|
||||||
} |
|
||||||
return new AccessibleInstantiator<T>(type); |
|
||||||
} |
|
||||||
// The UnsafeFactoryInstantiator would also work. But according to benchmarks, it is 2.5
|
|
||||||
// times slower. So I prefer to use this one
|
|
||||||
return new SunReflectionFactoryInstantiator<T>(type); |
|
||||||
} |
|
||||||
else if(PlatformDescription.isThisJVM(DALVIK)) { |
|
||||||
if(PlatformDescription.isAndroidOpenJDK()) { |
|
||||||
// Starting at Android N which is based on OpenJDK
|
|
||||||
return new UnsafeFactoryInstantiator<T>(type); |
|
||||||
} |
|
||||||
if(ANDROID_VERSION <= 10) { |
|
||||||
// Android 2.3 Gingerbread and lower
|
|
||||||
return new Android10Instantiator<T>(type); |
|
||||||
} |
|
||||||
if(ANDROID_VERSION <= 17) { |
|
||||||
// Android 3.0 Honeycomb to 4.2 Jelly Bean
|
|
||||||
return new Android17Instantiator<T>(type); |
|
||||||
} |
|
||||||
// Android 4.3 until Android N
|
|
||||||
return new Android18Instantiator<T>(type); |
|
||||||
} |
|
||||||
else if(PlatformDescription.isThisJVM(JROCKIT)) { |
|
||||||
// JRockit is compliant with HotSpot
|
|
||||||
return new SunReflectionFactoryInstantiator<T>(type); |
|
||||||
} |
|
||||||
else if(PlatformDescription.isThisJVM(GNU)) { |
|
||||||
return new GCJInstantiator<T>(type); |
|
||||||
} |
|
||||||
else if(PlatformDescription.isThisJVM(PERC)) { |
|
||||||
return new PercInstantiator<T>(type); |
|
||||||
} |
|
||||||
|
|
||||||
// Fallback instantiator, should work with most modern JVM
|
|
||||||
return new UnsafeFactoryInstantiator<T>(type); |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
Loading…
Reference in new issue