Browse Source
* commit '97411af6382b940ab356f0b2876f45ce18580872': KERNEL-1334 fine-spring支持JDK11research/11.0
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