diff --git a/fine-kryo/src/com/fr/third/org/objenesis/Objenesis.java b/fine-kryo/src/com/fr/third/org/objenesis/Objenesis.java index 7fdc4a503..15e166a1c 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/Objenesis.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/Objenesis.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. diff --git a/fine-kryo/src/com/fr/third/org/objenesis/ObjenesisBase.java b/fine-kryo/src/com/fr/third/org/objenesis/ObjenesisBase.java index 2d08272c3..85f4aee11 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/ObjenesisBase.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/ObjenesisBase.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -29,88 +29,88 @@ import java.util.concurrent.ConcurrentHashMap; */ public class ObjenesisBase implements Objenesis { - /** - * Strategy used by this Objenesi implementation to create classes - */ - protected final InstantiatorStrategy strategy; + /** + * Strategy used by this Objenesi implementation to create classes + */ + protected final InstantiatorStrategy strategy; - /** - * Strategy cache. Key = Class, Value = InstantiatorStrategy - */ - protected Map> cache; + /** + * Strategy cache. Key = Class, Value = InstantiatorStrategy + */ + protected Map> cache; - /** - * Constructor allowing to pick a strategy and using cache - * - * @param strategy Strategy to use - */ - public ObjenesisBase(InstantiatorStrategy strategy) { - this(strategy, true); - } + /** + * 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>() : null; - } + /** + * 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>() : null; + } - @Override - public String toString() { - return getClass().getName() + " using " + strategy.getClass().getName() - + (cache == null ? " without" : " with") + " caching"; - } + @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 newInstance(Class clazz) { - return getInstantiatorOf(clazz).newInstance(); - } + /** + * Will create a new object without any constructor being called + * + * @param clazz Class to instantiate + * @return New instance of clazz + */ + public T newInstance(Class 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 ObjectInstantiator getInstantiatorOf(Class 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); - if (instantiator == null) { - ObjectInstantiator newInstantiator = strategy.newInstantiatorOf(clazz); - instantiator = putIfAbsent(clazz, newInstantiator); - if (instantiator == null) { - instantiator = newInstantiator; - } - } - return (ObjectInstantiator) instantiator; - } + /** + * 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 ObjectInstantiator getInstantiatorOf(Class 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); + if (instantiator == null) { + ObjectInstantiator newInstantiator = strategy.newInstantiatorOf(clazz); + instantiator = putIfAbsent(clazz, newInstantiator); + if (instantiator == null) { + instantiator = newInstantiator; + } + } + return (ObjectInstantiator) instantiator; + } - private ObjectInstantiator putIfAbsent(Class key, ObjectInstantiator newInstantiator) { + private ObjectInstantiator putIfAbsent(Class key, ObjectInstantiator newInstantiator) { - ObjectInstantiator instantiator = cache.get(key); - if (instantiator == null) { - instantiator = cache.put(key, newInstantiator); - } - return instantiator; - } -} \ No newline at end of file + ObjectInstantiator instantiator = cache.get(key); + if (instantiator == null) { + instantiator = cache.put(key, newInstantiator); + } + return instantiator; + } +} diff --git a/fine-kryo/src/com/fr/third/org/objenesis/ObjenesisException.java b/fine-kryo/src/com/fr/third/org/objenesis/ObjenesisException.java index 84b64fa44..678131a2a 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/ObjenesisException.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/ObjenesisException.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. diff --git a/fine-kryo/src/com/fr/third/org/objenesis/ObjenesisHelper.java b/fine-kryo/src/com/fr/third/org/objenesis/ObjenesisHelper.java index 1a2b180bf..764b424ff 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/ObjenesisHelper.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/ObjenesisHelper.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -53,7 +53,7 @@ public final class ObjenesisHelper { * @return New instance of clazz */ public static T newSerializableInstance(Class clazz) { - return (T) OBJENESIS_SERIALIZER.newInstance(clazz); + return OBJENESIS_SERIALIZER.newInstance(clazz); } /** diff --git a/fine-kryo/src/com/fr/third/org/objenesis/ObjenesisSerializer.java b/fine-kryo/src/com/fr/third/org/objenesis/ObjenesisSerializer.java index 869af45a2..0eadfc057 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/ObjenesisSerializer.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/ObjenesisSerializer.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -15,7 +15,6 @@ */ package com.fr.third.org.objenesis; -import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import com.fr.third.org.objenesis.strategy.SerializingInstantiatorStrategy; /** @@ -26,17 +25,17 @@ import com.fr.third.org.objenesis.strategy.SerializingInstantiatorStrategy; public class ObjenesisSerializer extends ObjenesisBase { /** - * Default constructor using the {@link SerializingInstantiatorStrategy} + * Default constructor using the {@link com.fr.third.org.objenesis.strategy.SerializingInstantiatorStrategy} */ public ObjenesisSerializer() { super(new SerializingInstantiatorStrategy()); } /** - * Instance using the {@link SerializingInstantiatorStrategy} with or without caching - * {@link ObjectInstantiator}s + * Instance using the {@link com.fr.third.org.objenesis.strategy.SerializingInstantiatorStrategy} with or without caching + * {@link com.fr.third.org.objenesis.instantiator.ObjectInstantiator}s * - * @param useCache If {@link ObjectInstantiator}s should be cached + * @param useCache If {@link com.fr.third.org.objenesis.instantiator.ObjectInstantiator}s should be cached */ public ObjenesisSerializer(boolean useCache) { super(new SerializingInstantiatorStrategy(), useCache); diff --git a/fine-kryo/src/com/fr/third/org/objenesis/ObjenesisStd.java b/fine-kryo/src/com/fr/third/org/objenesis/ObjenesisStd.java index ce3a65bea..d8fe2602b 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/ObjenesisStd.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/ObjenesisStd.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -15,28 +15,27 @@ */ package com.fr.third.org.objenesis; -import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import com.fr.third.org.objenesis.strategy.StdInstantiatorStrategy; /** - * Objenesis implementation using the {@link StdInstantiatorStrategy}. + * Objenesis implementation using the {@link com.fr.third.org.objenesis.strategy.StdInstantiatorStrategy}. * * @author Henri Tremblay */ public class ObjenesisStd extends ObjenesisBase { /** - * Default constructor using the {@link StdInstantiatorStrategy} + * Default constructor using the {@link com.fr.third.org.objenesis.strategy.StdInstantiatorStrategy} */ public ObjenesisStd() { super(new StdInstantiatorStrategy()); } /** - * Instance using the {@link StdInstantiatorStrategy} with or without - * caching {@link ObjectInstantiator}s + * Instance using the {@link com.fr.third.org.objenesis.strategy.StdInstantiatorStrategy} with or without + * caching {@link com.fr.third.org.objenesis.instantiator.ObjectInstantiator}s * - * @param useCache If {@link ObjectInstantiator}s should be cached + * @param useCache If {@link com.fr.third.org.objenesis.instantiator.ObjectInstantiator}s should be cached */ public ObjenesisStd(boolean useCache) { super(new StdInstantiatorStrategy(), useCache); diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/ObjectInstantiator.java b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/ObjectInstantiator.java index 6878e49ae..4ecf2d9be 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/ObjectInstantiator.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/ObjectInstantiator.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/SerializationInstantiatorHelper.java b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/SerializationInstantiatorHelper.java index ba4277814..17bf3a470 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/SerializationInstantiatorHelper.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/SerializationInstantiatorHelper.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/android/Android10Instantiator.java b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/android/Android10Instantiator.java index 2b7bc703e..76c3942b0 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/android/Android10Instantiator.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/android/Android10Instantiator.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -18,10 +18,10 @@ package com.fr.third.org.objenesis.instantiator.android; import java.io.ObjectInputStream; import java.lang.reflect.Method; +import com.fr.third.org.objenesis.ObjenesisException; import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import com.fr.third.org.objenesis.instantiator.annotations.Instantiator; import com.fr.third.org.objenesis.instantiator.annotations.Typology; -import com.fr.third.org.objenesis.ObjenesisException; /** * Instantiator for Android API level 10 and lover which creates objects without driving their @@ -56,10 +56,7 @@ public class Android10Instantiator implements ObjectInstantiator { newStaticMethod.setAccessible(true); return newStaticMethod; } - catch(RuntimeException e) { - throw new ObjenesisException(e); - } - catch(NoSuchMethodException e) { + catch(Exception e) { throw new ObjenesisException(e); } } diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/android/Android17Instantiator.java b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/android/Android17Instantiator.java index de14f0319..1986696e7 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/android/Android17Instantiator.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/android/Android17Instantiator.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -19,10 +19,10 @@ import java.io.ObjectStreamClass; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import com.fr.third.org.objenesis.ObjenesisException; import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import com.fr.third.org.objenesis.instantiator.annotations.Instantiator; import com.fr.third.org.objenesis.instantiator.annotations.Typology; -import com.fr.third.org.objenesis.ObjenesisException; /** * Instantiator for Android API level 11 to 17 which creates objects without driving their @@ -58,10 +58,7 @@ public class Android17Instantiator implements ObjectInstantiator { newInstanceMethod.setAccessible(true); return newInstanceMethod; } - catch(RuntimeException e) { - throw new ObjenesisException(e); - } - catch(NoSuchMethodException e) { + catch(Exception e) { throw new ObjenesisException(e); } } @@ -74,16 +71,7 @@ public class Android17Instantiator implements ObjectInstantiator { 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) { + catch(Exception e) { throw new ObjenesisException(e); } } diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/android/Android18Instantiator.java b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/android/Android18Instantiator.java index 34bb5aa3d..dc9b23cf0 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/android/Android18Instantiator.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/android/Android18Instantiator.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -19,13 +19,13 @@ import java.io.ObjectStreamClass; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import com.fr.third.org.objenesis.ObjenesisException; import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import com.fr.third.org.objenesis.instantiator.annotations.Instantiator; import com.fr.third.org.objenesis.instantiator.annotations.Typology; -import com.fr.third.org.objenesis.ObjenesisException; /** - * Instantiator for Android API leve 18 and higher. Same as the version 17 but the + * Instantiator for Android API level 18 and higher. Same as the version 17 but the * newInstance now takes a long in parameter * * @author Henri Tremblay @@ -58,10 +58,7 @@ public class Android18Instantiator implements ObjectInstantiator { newInstanceMethod.setAccessible(true); return newInstanceMethod; } - catch(RuntimeException e) { - throw new ObjenesisException(e); - } - catch(NoSuchMethodException e) { + catch(Exception e) { throw new ObjenesisException(e); } } @@ -74,16 +71,7 @@ public class Android18Instantiator implements ObjectInstantiator { 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) { + catch(Exception e) { throw new ObjenesisException(e); } } diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/android/AndroidSerializationInstantiator.java b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/android/AndroidSerializationInstantiator.java index db054207d..9b2678901 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/android/AndroidSerializationInstantiator.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/android/AndroidSerializationInstantiator.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -19,10 +19,10 @@ import java.io.ObjectStreamClass; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import com.fr.third.org.objenesis.ObjenesisException; import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import com.fr.third.org.objenesis.instantiator.annotations.Instantiator; import com.fr.third.org.objenesis.instantiator.annotations.Typology; -import com.fr.third.org.objenesis.ObjenesisException; /** * {@link ObjectInstantiator} for Android which creates objects using the constructor from the first @@ -40,7 +40,7 @@ public class AndroidSerializationInstantiator implements ObjectInstantiator type) { this.type = type; newInstanceMethod = getNewInstanceMethod(); - Method m = null; + Method m; try { m = ObjectStreamClass.class.getMethod("lookupAny", Class.class); } catch (NoSuchMethodException e) { @@ -48,9 +48,7 @@ public class AndroidSerializationInstantiator implements ObjectInstantiator implements ObjectInstantiator implements ObjectInstantiator extends ConstructorInstantiator { diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/ConstructorInstantiator.java b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/ConstructorInstantiator.java index 90dc290ee..773f769ca 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/ConstructorInstantiator.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/ConstructorInstantiator.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -17,10 +17,10 @@ package com.fr.third.org.objenesis.instantiator.basic; import java.lang.reflect.Constructor; +import com.fr.third.org.objenesis.ObjenesisException; import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import com.fr.third.org.objenesis.instantiator.annotations.Instantiator; import com.fr.third.org.objenesis.instantiator.annotations.Typology; -import com.fr.third.org.objenesis.ObjenesisException; /** * Instantiates a class by grabbing the no args constructor and calling Constructor.newInstance(). diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/FailingInstantiator.java b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/FailingInstantiator.java index 1802b735b..3796dec05 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/FailingInstantiator.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/FailingInstantiator.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -15,10 +15,10 @@ */ package com.fr.third.org.objenesis.instantiator.basic; +import com.fr.third.org.objenesis.ObjenesisException; import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import com.fr.third.org.objenesis.instantiator.annotations.Instantiator; import com.fr.third.org.objenesis.instantiator.annotations.Typology; -import com.fr.third.org.objenesis.ObjenesisException; /** * The instantiator that always throws an exception. Mainly used for tests diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/NewInstanceInstantiator.java b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/NewInstanceInstantiator.java index 93f34cdf2..fc07813e2 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/NewInstanceInstantiator.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/NewInstanceInstantiator.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -18,7 +18,7 @@ package com.fr.third.org.objenesis.instantiator.basic; import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import com.fr.third.org.objenesis.instantiator.annotations.Instantiator; import com.fr.third.org.objenesis.instantiator.annotations.Typology; -import com.fr.third.org.objenesis.ObjenesisException; +import com.fr.third.org.objenesis.instantiator.util.ClassUtils; /** * The simplest instantiator - simply calls Class.newInstance(). This can deal with default public @@ -37,12 +37,7 @@ public class NewInstanceInstantiator implements ObjectInstantiator { } public T newInstance() { - try { - return type.newInstance(); - } - catch(Exception e) { - throw new ObjenesisException(e); - } + return ClassUtils.newInstance(type); } } diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/NullInstantiator.java b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/NullInstantiator.java index 26f7936b8..59f1318b9 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/NullInstantiator.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/NullInstantiator.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/ObjectInputStreamInstantiator.java b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/ObjectInputStreamInstantiator.java index 22d0262d2..83431c46e 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/ObjectInputStreamInstantiator.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/ObjectInputStreamInstantiator.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -25,10 +25,10 @@ import java.io.ObjectStreamClass; import java.io.ObjectStreamConstants; import java.io.Serializable; +import com.fr.third.org.objenesis.ObjenesisException; import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import com.fr.third.org.objenesis.instantiator.annotations.Instantiator; import com.fr.third.org.objenesis.instantiator.annotations.Typology; -import com.fr.third.org.objenesis.ObjenesisException; /** * Instantiates a class by using a dummy input stream that always feeds data for an empty object of @@ -38,7 +38,7 @@ import com.fr.third.org.objenesis.ObjenesisException; * completely different class. * * @author Leonardo Mesquita - * @see ObjectInstantiator + * @see com.fr.third.org.objenesis.instantiator.ObjectInstantiator */ @Instantiator(Typology.SERIALIZATION) public class ObjectInputStreamInstantiator implements ObjectInstantiator { @@ -120,7 +120,7 @@ public class ObjectInputStreamInstantiator implements ObjectInstantiator { } @Override - public int read() throws IOException { + public int read() { int result = data[pointer++]; if(pointer >= data.length) { advanceBuffer(); @@ -130,12 +130,12 @@ public class ObjectInputStreamInstantiator implements ObjectInstantiator { } @Override - public int available() throws IOException { + public int available() { return Integer.MAX_VALUE; } @Override - public int read(byte[] b, int off, int len) throws IOException { + public int read(byte[] b, int off, int len) { int left = len; int remaining = data.length - pointer; diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/ObjectStreamClassInstantiator.java b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/ObjectStreamClassInstantiator.java index 4e3e7d7e6..d6099faf8 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/ObjectStreamClassInstantiator.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/ObjectStreamClassInstantiator.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -18,10 +18,10 @@ package com.fr.third.org.objenesis.instantiator.basic; import java.io.ObjectStreamClass; import java.lang.reflect.Method; +import com.fr.third.org.objenesis.ObjenesisException; import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import com.fr.third.org.objenesis.instantiator.annotations.Instantiator; import com.fr.third.org.objenesis.instantiator.annotations.Typology; -import com.fr.third.org.objenesis.ObjenesisException; /** * Instantiates a class by using reflection to make a call to private method @@ -44,10 +44,7 @@ public class ObjectStreamClassInstantiator implements ObjectInstantiator { newInstanceMethod = ObjectStreamClass.class.getDeclaredMethod("newInstance"); newInstanceMethod.setAccessible(true); } - catch(RuntimeException e) { - throw new ObjenesisException(e); - } - catch(NoSuchMethodException e) { + catch(Exception e) { throw new ObjenesisException(e); } } diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/ProxyingInstantiator.java b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/ProxyingInstantiator.java index 025dcfc74..e4354c5b3 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/ProxyingInstantiator.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/ProxyingInstantiator.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -19,11 +19,14 @@ import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; +import com.fr.third.org.objenesis.ObjenesisException; import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import com.fr.third.org.objenesis.instantiator.annotations.Instantiator; import com.fr.third.org.objenesis.instantiator.annotations.Typology; import com.fr.third.org.objenesis.instantiator.util.ClassDefinitionUtils; -import com.fr.third.org.objenesis.ObjenesisException; +import com.fr.third.org.objenesis.instantiator.util.ClassUtils; + +import static com.fr.third.org.objenesis.instantiator.util.ClassDefinitionUtils.*; /** * This instantiator creates a class by dynamically extending it. It will skip the call to the parent constructor @@ -44,9 +47,9 @@ public class ProxyingInstantiator implements ObjectInstantiator { 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 int CONSTANT_POOL_COUNT = 9; - private static final byte[] CODE = { ClassDefinitionUtils.OPS_aload_0, ClassDefinitionUtils.OPS_return}; + 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"; @@ -54,28 +57,21 @@ public class ProxyingInstantiator implements ObjectInstantiator { private static final String CONSTRUCTOR_NAME = ""; private static final String CONSTRUCTOR_DESC = "()V"; - private final Class newType; + private final Class newType; public ProxyingInstantiator(Class type) { - byte[] classBytes = writeExtendingClass(type, SUFFIX); + byte[] classBytes = writeExtendingClass(type); try { - newType = ClassDefinitionUtils.defineClass(type.getName() + SUFFIX, classBytes, type.getClassLoader()); + newType = ClassDefinitionUtils.defineClass(type.getName() + SUFFIX, classBytes, type, 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); - } + return ClassUtils.newInstance(newType); } /** @@ -83,61 +79,58 @@ public class ProxyingInstantiator implements ObjectInstantiator { * 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 = ClassDefinitionUtils.classNameToInternalClassName(type.getName()); - String clazz = parentClazz + suffix; + private static byte[] writeExtendingClass(Class type) { + String parentClazz = ClassUtils.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(ClassDefinitionUtils.MAGIC); - in.write(ClassDefinitionUtils.VERSION); + try{ + DataOutputStream 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(ClassDefinitionUtils.CONSTANT_Class); + in.writeByte(CONSTANT_Class); in.writeShort(INDEX_UTF8_CLASS); // 2. super class - in.writeByte(ClassDefinitionUtils.CONSTANT_Class); + in.writeByte(CONSTANT_Class); in.writeShort(INDEX_UTF8_SUPERCLASS); // 3. default constructor name - in.writeByte(ClassDefinitionUtils.CONSTANT_Utf8); + in.writeByte(CONSTANT_Utf8); in.writeUTF(CONSTRUCTOR_NAME); // 4. default constructor description - in.writeByte(ClassDefinitionUtils.CONSTANT_Utf8); + in.writeByte(CONSTANT_Utf8); in.writeUTF(CONSTRUCTOR_DESC); // 5. Code - in.writeByte(ClassDefinitionUtils.CONSTANT_Utf8); + in.writeByte(CONSTANT_Utf8); in.writeUTF("Code"); // 6. Class name - in.writeByte(ClassDefinitionUtils.CONSTANT_Utf8); + in.writeByte(CONSTANT_Utf8); in.writeUTF("L" + clazz + ";"); // 7. Class name (again) - in.writeByte(ClassDefinitionUtils.CONSTANT_Utf8); + in.writeByte(CONSTANT_Utf8); in.writeUTF(clazz); // 8. Superclass name - in.writeByte(ClassDefinitionUtils.CONSTANT_Utf8); + in.writeByte(CONSTANT_Utf8); in.writeUTF(parentClazz); // end of constant pool // access flags: We want public, ACC_SUPER is always there - in.writeShort(ClassDefinitionUtils.ACC_PUBLIC | ClassDefinitionUtils.ACC_SUPER); + in.writeShort(ACC_PUBLIC | ACC_SUPER); // this class index in the constant pool in.writeShort(INDEX_CLASS_THIS); @@ -155,7 +148,7 @@ public class ProxyingInstantiator implements ObjectInstantiator { in.writeShort(1); // default constructor method_info - in.writeShort(ClassDefinitionUtils.ACC_PUBLIC); + in.writeShort(ACC_PUBLIC); in.writeShort(INDEX_UTF8_CONSTRUCTOR_NAME); // index of the method name () in.writeShort(INDEX_UTF8_CONSTRUCTOR_DESC); // index of the description in.writeShort(1); // number of attributes: only one, the code @@ -176,14 +169,6 @@ public class ProxyingInstantiator implements ObjectInstantiator { } catch (IOException e) { throw new ObjenesisException(e); - } finally { - if(in != null) { - try { - in.close(); - } catch (IOException e) { - throw new ObjenesisException(e); - } - } } return bIn.toByteArray(); diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/gcj/GCJInstantiator.java b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/gcj/GCJInstantiator.java index 793d2f21f..c232579a8 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/gcj/GCJInstantiator.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/gcj/GCJInstantiator.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -17,7 +17,6 @@ package com.fr.third.org.objenesis.instantiator.gcj; import java.lang.reflect.InvocationTargetException; -import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import com.fr.third.org.objenesis.ObjenesisException; import com.fr.third.org.objenesis.instantiator.annotations.Instantiator; import com.fr.third.org.objenesis.instantiator.annotations.Typology; @@ -27,7 +26,7 @@ import com.fr.third.org.objenesis.instantiator.annotations.Typology; * work on GCJ JVMs. This instantiator will not call any constructors. * * @author Leonardo Mesquita - * @see ObjectInstantiator + * @see com.fr.third.org.objenesis.instantiator.ObjectInstantiator */ @Instantiator(Typology.STANDARD) public class GCJInstantiator extends GCJInstantiatorBase { @@ -40,13 +39,7 @@ public class GCJInstantiator extends GCJInstantiatorBase { 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) { + catch(Exception e) { throw new ObjenesisException(e); } } diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/gcj/GCJInstantiatorBase.java b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/gcj/GCJInstantiatorBase.java index 733869919..25ea93f0e 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/gcj/GCJInstantiatorBase.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/gcj/GCJInstantiatorBase.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -19,8 +19,8 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.lang.reflect.Method; -import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import com.fr.third.org.objenesis.ObjenesisException; +import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; /** * Base class for GCJ-based instantiators. It initializes reflection access to method @@ -41,18 +41,11 @@ public abstract class GCJInstantiatorBase implements ObjectInstantiator { private static void initialize() { if(newObjectMethod == null) { try { - newObjectMethod = ObjectInputStream.class.getDeclaredMethod("newObject", new Class[] { - Class.class, Class.class}); + newObjectMethod = ObjectInputStream.class.getDeclaredMethod("newObject", 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) { + catch(Exception e) { throw new ObjenesisException(e); } } diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/gcj/GCJSerializationInstantiator.java b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/gcj/GCJSerializationInstantiator.java index 5a52513f4..956c20fa0 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/gcj/GCJSerializationInstantiator.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/gcj/GCJSerializationInstantiator.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -15,7 +15,6 @@ */ package com.fr.third.org.objenesis.instantiator.gcj; -import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import com.fr.third.org.objenesis.ObjenesisException; import com.fr.third.org.objenesis.instantiator.SerializationInstantiatorHelper; import com.fr.third.org.objenesis.instantiator.annotations.Instantiator; @@ -27,11 +26,11 @@ import com.fr.third.org.objenesis.instantiator.annotations.Typology; * calling the first non-serializable superclass' no-arg constructor. * * @author Leonardo Mesquita - * @see ObjectInstantiator + * @see com.fr.third.org.objenesis.instantiator.ObjectInstantiator */ @Instantiator(Typology.SERIALIZATION) public class GCJSerializationInstantiator extends GCJInstantiatorBase { - private Class superType; + private final Class superType; public GCJSerializationInstantiator(Class type) { super(type); diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/perc/PercInstantiator.java b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/perc/PercInstantiator.java index 0334d9704..875a1768e 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/perc/PercInstantiator.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/perc/PercInstantiator.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -18,8 +18,8 @@ package com.fr.third.org.objenesis.instantiator.perc; import java.io.ObjectInputStream; import java.lang.reflect.Method; -import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import com.fr.third.org.objenesis.ObjenesisException; +import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import com.fr.third.org.objenesis.instantiator.annotations.Instantiator; import com.fr.third.org.objenesis.instantiator.annotations.Typology; @@ -29,7 +29,7 @@ import com.fr.third.org.objenesis.instantiator.annotations.Typology; * Aonix Perc support team. * * @author Henri Tremblay - * @see ObjectInstantiator + * @see com.fr.third.org.objenesis.instantiator.ObjectInstantiator */ @Instantiator(Typology.STANDARD) public class PercInstantiator implements ObjectInstantiator { @@ -47,13 +47,10 @@ public class PercInstantiator implements ObjectInstantiator { Boolean.TYPE); newInstanceMethod.setAccessible(true); } - catch(RuntimeException e) { + catch(Exception e) { throw new ObjenesisException(e); } - catch(NoSuchMethodException e) { - throw new ObjenesisException(e); - } - } + } @SuppressWarnings("unchecked") public T newInstance() { diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/perc/PercSerializationInstantiator.java b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/perc/PercSerializationInstantiator.java index e2be57461..c3a9f4a76 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/perc/PercSerializationInstantiator.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/perc/PercSerializationInstantiator.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -20,8 +20,8 @@ import java.io.Serializable; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import com.fr.third.org.objenesis.ObjenesisException; +import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import com.fr.third.org.objenesis.instantiator.annotations.Instantiator; import com.fr.third.org.objenesis.instantiator.annotations.Typology; @@ -33,7 +33,7 @@ import com.fr.third.org.objenesis.instantiator.annotations.Typology; * Based on code provided by Aonix but doesn't work right now * * @author Henri Tremblay - * @see ObjectInstantiator + * @see com.fr.third.org.objenesis.instantiator.ObjectInstantiator */ @Instantiator(Typology.SERIALIZATION) public class PercSerializationInstantiator implements ObjectInstantiator { @@ -56,7 +56,7 @@ public class PercSerializationInstantiator implements ObjectInstantiator { Class percMethodClass = Class.forName("COM.newmonics.PercClassLoader.Method"); newInstanceMethod = ObjectInputStream.class.getDeclaredMethod("noArgConstruct", - new Class[] {Class.class, Object.class, percMethodClass}); + Class.class, Object.class, percMethodClass); newInstanceMethod.setAccessible(true); // Create invoke params @@ -64,22 +64,13 @@ public class PercSerializationInstantiator implements ObjectInstantiator { Method getPercClassMethod = percClassClass.getDeclaredMethod("getPercClass", Class.class); Object someObject = getPercClassMethod.invoke(null, unserializableType); Method findMethodMethod = someObject.getClass().getDeclaredMethod("findMethod", - new Class[] {String.class}); + String.class); Object percMethod = findMethodMethod.invoke(someObject, "()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) { + catch(Exception e) { throw new ObjenesisException(e); } } @@ -89,10 +80,7 @@ public class PercSerializationInstantiator implements ObjectInstantiator { try { return (T) newInstanceMethod.invoke(null, typeArgs); } - catch(IllegalAccessException e) { - throw new ObjenesisException(e); - } - catch(InvocationTargetException e) { + catch(Exception e) { throw new ObjenesisException(e); } } diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/MagicInstantiator.java b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/MagicInstantiator.java index 33a9dec8a..c865333a6 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/MagicInstantiator.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/MagicInstantiator.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -19,11 +19,14 @@ import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; -import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; -import com.fr.third.org.objenesis.instantiator.util.ClassDefinitionUtils; import com.fr.third.org.objenesis.ObjenesisException; +import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import com.fr.third.org.objenesis.instantiator.annotations.Instantiator; import com.fr.third.org.objenesis.instantiator.annotations.Typology; +import com.fr.third.org.objenesis.instantiator.util.ClassDefinitionUtils; +import com.fr.third.org.objenesis.instantiator.util.ClassUtils; + +import static com.fr.third.org.objenesis.instantiator.util.ClassDefinitionUtils.*; /** * This instantiator will correctly bypass the constructors by instantiating the class using the default @@ -55,18 +58,18 @@ public class MagicInstantiator implements ObjectInstantiator { 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 int CONSTANT_POOL_COUNT = 19; - private static final byte[] CONSTRUCTOR_CODE = { ClassDefinitionUtils.OPS_aload_0, ClassDefinitionUtils.OPS_invokespecial, 0, INDEX_METHODREF_OBJECT_CONSTRUCTOR, ClassDefinitionUtils.OPS_return}; + 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 = { ClassDefinitionUtils.OPS_new, 0, INDEX_CLASS_TYPE, ClassDefinitionUtils.OPS_dup, ClassDefinitionUtils.OPS_invokespecial, 0, INDEX_METHODREF_OBJECT_CONSTRUCTOR, ClassDefinitionUtils.OPS_areturn}; + 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 = ""; private static final String CONSTRUCTOR_DESC = "()V"; - private ObjectInstantiator instantiator; + private final ObjectInstantiator instantiator; public MagicInstantiator(Class type) { instantiator = newInstantiatorOf(type); @@ -85,29 +88,23 @@ public class MagicInstantiator implements ObjectInstantiator { return instantiator; } - private ObjectInstantiator newInstantiatorOf(Class type) { + private ObjectInstantiator newInstantiatorOf(Class type) { String suffix = type.getSimpleName(); String className = getClass().getName() + "$$$" + suffix; - Class> clazz = ClassDefinitionUtils.getExistingClass(getClass().getClassLoader(), className); + Class> clazz = ClassUtils.getExistingClass(getClass().getClassLoader(), className); if(clazz == null) { byte[] classBytes = writeExtendingClass(type, className); try { - clazz = ClassDefinitionUtils.defineClass(className, classBytes, getClass().getClassLoader()); + clazz = ClassDefinitionUtils.defineClass(className, classBytes, type, 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); - } + return ClassUtils.newInstance(clazz); } /** @@ -120,98 +117,96 @@ public class MagicInstantiator implements ObjectInstantiator { * @throws ObjenesisException is something goes wrong */ private byte[] writeExtendingClass(Class type, String className) { - String clazz = ClassDefinitionUtils.classNameToInternalClassName(className); + String clazz = ClassUtils.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(ClassDefinitionUtils.MAGIC); - in.write(ClassDefinitionUtils.VERSION); + ByteArrayOutputStream bIn = new ByteArrayOutputStream(1000); // 1000 should be large enough to fit the entire class + try{ + DataOutputStream 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(ClassDefinitionUtils.CONSTANT_Class); + in.writeByte(CONSTANT_Class); in.writeShort(INDEX_UTF8_INSTANTIATOR_CLASS); // 2. super class - in.writeByte(ClassDefinitionUtils.CONSTANT_Class); + in.writeByte(CONSTANT_Class); in.writeShort(INDEX_UTF8_SUPERCLASS); // 3. default constructor name - in.writeByte(ClassDefinitionUtils.CONSTANT_Utf8); + in.writeByte(CONSTANT_Utf8); in.writeUTF(CONSTRUCTOR_NAME); // 4. default constructor description - in.writeByte(ClassDefinitionUtils.CONSTANT_Utf8); + in.writeByte(CONSTANT_Utf8); in.writeUTF(CONSTRUCTOR_DESC); // 5. Code - in.writeByte(ClassDefinitionUtils.CONSTANT_Utf8); + in.writeByte(CONSTANT_Utf8); in.writeUTF("Code"); // 6. Class name - in.writeByte(ClassDefinitionUtils.CONSTANT_Utf8); + in.writeByte(CONSTANT_Utf8); in.writeUTF("L" + clazz + ";"); // 7. Class name (again) - in.writeByte(ClassDefinitionUtils.CONSTANT_Utf8); + in.writeByte(CONSTANT_Utf8); in.writeUTF(clazz); // 8. Superclass name - in.writeByte(ClassDefinitionUtils.CONSTANT_Utf8); + in.writeByte(CONSTANT_Utf8); // in.writeUTF("java/lang/Object"); in.writeUTF(MAGIC_ACCESSOR); // 9. ObjectInstantiator interface - in.writeByte(ClassDefinitionUtils.CONSTANT_Class); + in.writeByte(CONSTANT_Class); in.writeShort(INDEX_UTF8_INTERFACE); // 10. ObjectInstantiator name - in.writeByte(ClassDefinitionUtils.CONSTANT_Utf8); + in.writeByte(CONSTANT_Utf8); in.writeUTF(ObjectInstantiator.class.getName().replace('.', '/')); // 11. newInstance name - in.writeByte(ClassDefinitionUtils.CONSTANT_Utf8); + in.writeByte(CONSTANT_Utf8); in.writeUTF("newInstance"); // 12. newInstance desc - in.writeByte(ClassDefinitionUtils.CONSTANT_Utf8); + in.writeByte(CONSTANT_Utf8); in.writeUTF("()Ljava/lang/Object;"); // 13. Methodref to the Object constructor - in.writeByte(ClassDefinitionUtils.CONSTANT_Methodref); + in.writeByte(CONSTANT_Methodref); in.writeShort(INDEX_CLASS_OBJECT); in.writeShort(INDEX_NAMEANDTYPE_DEFAULT_CONSTRUCTOR); // 14. Object class - in.writeByte(ClassDefinitionUtils.CONSTANT_Class); + in.writeByte(CONSTANT_Class); in.writeShort(INDEX_UTF8_OBJECT); // 15. Object class name - in.writeByte(ClassDefinitionUtils.CONSTANT_Utf8); + in.writeByte(CONSTANT_Utf8); in.writeUTF("java/lang/Object"); // 16. Default constructor name and type - in.writeByte(ClassDefinitionUtils.CONSTANT_NameAndType); + in.writeByte(CONSTANT_NameAndType); in.writeShort(INDEX_UTF8_CONSTRUCTOR_NAME); in.writeShort(INDEX_UTF8_CONSTRUCTOR_DESC); // 17. Type to instantiate class - in.writeByte(ClassDefinitionUtils.CONSTANT_Class); + in.writeByte(CONSTANT_Class); in.writeShort(INDEX_UTF8_TYPE); // 18. Type to instantiate name - in.writeByte(ClassDefinitionUtils.CONSTANT_Utf8); - in.writeUTF(ClassDefinitionUtils.classNameToInternalClassName(type.getName())); + in.writeByte(CONSTANT_Utf8); + in.writeUTF(ClassUtils.classNameToInternalClassName(type.getName())); // end of constant pool // access flags: We want public, ACC_SUPER is always there - in.writeShort(ClassDefinitionUtils.ACC_PUBLIC | ClassDefinitionUtils.ACC_SUPER | ClassDefinitionUtils.ACC_FINAL); + in.writeShort(ACC_PUBLIC | ACC_SUPER | ACC_FINAL); // this class index in the constant pool in.writeShort(INDEX_CLASS_THIS); @@ -230,7 +225,7 @@ public class MagicInstantiator implements ObjectInstantiator { in.writeShort(2); // default constructor method_info - in.writeShort(ClassDefinitionUtils.ACC_PUBLIC); + in.writeShort(ACC_PUBLIC); in.writeShort(INDEX_UTF8_CONSTRUCTOR_NAME); // index of the method name () in.writeShort(INDEX_UTF8_CONSTRUCTOR_DESC); // index of the description in.writeShort(1); // number of attributes: only one, the code @@ -246,7 +241,7 @@ public class MagicInstantiator implements ObjectInstantiator { in.writeShort(0); // attributes count = 0, no need to have LineNumberTable and LocalVariableTable // newInstance method_info - in.writeShort(ClassDefinitionUtils.ACC_PUBLIC); + 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 @@ -266,14 +261,6 @@ public class MagicInstantiator implements ObjectInstantiator { } catch (IOException e) { throw new ObjenesisException(e); - } finally { - if(in != null) { - try { - in.close(); - } catch (IOException e) { - throw new ObjenesisException(e); - } - } } return bIn.toByteArray(); diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/SunReflectionFactoryHelper.java b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/SunReflectionFactoryHelper.java index 40e9df661..b40215c83 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/SunReflectionFactoryHelper.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/SunReflectionFactoryHelper.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -18,8 +18,8 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import com.fr.third.org.objenesis.ObjenesisException; +import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; /** @@ -44,13 +44,7 @@ class SunReflectionFactoryHelper { return (Constructor) newConstructorForSerializationMethod.invoke( reflectionFactory, type, constructor); } - catch(IllegalArgumentException e) { - throw new ObjenesisException(e); - } - catch(IllegalAccessException e) { - throw new ObjenesisException(e); - } - catch(InvocationTargetException e) { + catch(Exception e) { throw new ObjenesisException(e); } } @@ -70,16 +64,7 @@ class SunReflectionFactoryHelper { "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) { + catch(Exception e) { throw new ObjenesisException(e); } } diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.java b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.java index a732fe0ff..0ea6d3300 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -17,8 +17,8 @@ package com.fr.third.org.objenesis.instantiator.sun; import java.lang.reflect.Constructor; -import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import com.fr.third.org.objenesis.ObjenesisException; +import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import com.fr.third.org.objenesis.instantiator.annotations.Instantiator; import com.fr.third.org.objenesis.instantiator.annotations.Typology; diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/SunReflectionFactorySerializationInstantiator.java b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/SunReflectionFactorySerializationInstantiator.java index ef7574674..fdfd120cf 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/SunReflectionFactorySerializationInstantiator.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/SunReflectionFactorySerializationInstantiator.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -18,8 +18,8 @@ package com.fr.third.org.objenesis.instantiator.sun; import java.io.NotSerializableException; import java.lang.reflect.Constructor; -import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import com.fr.third.org.objenesis.ObjenesisException; +import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import com.fr.third.org.objenesis.instantiator.SerializationInstantiatorHelper; import com.fr.third.org.objenesis.instantiator.annotations.Instantiator; import com.fr.third.org.objenesis.instantiator.annotations.Typology; diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/UnsafeFactoryInstantiator.java b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/UnsafeFactoryInstantiator.java index 709276a29..d351bdaf6 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/UnsafeFactoryInstantiator.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/UnsafeFactoryInstantiator.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -15,12 +15,12 @@ */ package com.fr.third.org.objenesis.instantiator.sun; -import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; -import com.fr.third.org.objenesis.instantiator.util.UnsafeUtils; import sun.misc.Unsafe; import com.fr.third.org.objenesis.ObjenesisException; +import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import com.fr.third.org.objenesis.instantiator.annotations.Instantiator; import com.fr.third.org.objenesis.instantiator.annotations.Typology; +import com.fr.third.org.objenesis.instantiator.util.UnsafeUtils; /** * Instantiates an object, WITHOUT calling it's constructor, using diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/util/ClassDefinitionUtils.java b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/util/ClassDefinitionUtils.java index d7fdb79ce..d44afcdb4 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/util/ClassDefinitionUtils.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/util/ClassDefinitionUtils.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -67,15 +67,11 @@ public final class ClassDefinitionUtils { private ClassDefinitionUtils() { } -// private static Method DEFINE_CLASS; private static final ProtectionDomain PROTECTION_DOMAIN; static { - PROTECTION_DOMAIN = AccessController.doPrivileged(new PrivilegedAction() { - public ProtectionDomain run() { - return ClassDefinitionUtils.class.getProtectionDomain(); - } - }); + + PROTECTION_DOMAIN = AccessController.doPrivileged((PrivilegedAction) ClassDefinitionUtils.class.getProtectionDomain()); } /** @@ -83,16 +79,17 @@ public final class ClassDefinitionUtils { * ReflectUtils.defineClass * * @param type of the class returned - * @param className class name in the format org.objenesis.MyClass + * @param className class name in the format com.fr.third.org.objenesis.MyClass * @param b bytes representing the class + * @param neighbor a class in the same package as the loaded 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 Class defineClass(String className, byte[] b, ClassLoader loader) + public static Class defineClass(String className, byte[] b, Class neighbor, ClassLoader loader) throws Exception { - Class c = (Class) UnsafeUtils.getUnsafe().defineClass(className, b, 0, b.length, loader, PROTECTION_DOMAIN); + Class c = (Class) DefineClassHelper.defineClass(className, b, 0, b.length, neighbor, loader, PROTECTION_DOMAIN); // Force static initializers to run. Class.forName(className, true, loader); return c; @@ -108,18 +105,17 @@ public final class ClassDefinitionUtils { */ public static byte[] readClass(String className) throws IOException { // convert to a resource - className = classNameToResource(className); + className = ClassUtils.classNameToResource(className); byte[] b = new byte[2500]; // I'm assuming that I'm reading class that are not too big - int length; + int length=0; - InputStream in = ClassDefinitionUtils.class.getClassLoader().getResourceAsStream(className); try { + InputStream in = ClassDefinitionUtils.class.getClassLoader().getResourceAsStream(className); length = in.read(b); - } - finally { - in.close(); + } catch (Exception e) { + } if(length >= 2500) { @@ -139,52 +135,12 @@ public final class ClassDefinitionUtils { * @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 { + BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(fileName)); out.write(bytes); - } - finally { - out.close(); - } - } - - /** - * Will convert a class name to its name in the class definition format (e.g {@code org.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('.', '/'); - } + } catch (Throwable e) { - /** - * Will convert a class name to its class loader resource name (e.g {@code org.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 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 Class getExistingClass(ClassLoader classLoader, String className) { - try { - return (Class) Class.forName(className, true, classLoader); - } - catch (ClassNotFoundException e) { - return null; } } } diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/util/ClassUtils.java b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/util/ClassUtils.java new file mode 100644 index 000000000..56df360b0 --- /dev/null +++ b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/util/ClassUtils.java @@ -0,0 +1,78 @@ +/* + * Copyright 2006-2018 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.org.objenesis.instantiator.util; + +import com.fr.third.org.objenesis.ObjenesisException; + +/** + * Helper class for to play with classes. It contains everything needed to play with a class + * except the dodgy (Java 8) code you will find in {@link ClassDefinitionUtils}. + * + * @author Henri Tremblay + */ +public final class ClassUtils { + + private ClassUtils() { } + + /** + * Will convert a class name to its name in the class definition format (e.g {@code com.fr.third.org.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.org.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 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 Class getExistingClass(ClassLoader classLoader, String className) { + try { + return (Class) Class.forName(className, true, classLoader); + } + catch (ClassNotFoundException e) { + return null; + } + } + + @SuppressWarnings("deprecation") + public static T newInstance(Class clazz) { + try { + return clazz.newInstance(); + } catch (Exception e) { + throw new ObjenesisException(e); + } + } +} diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/util/DefineClassHelper.java b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/util/DefineClassHelper.java new file mode 100644 index 000000000..bc26ed0ec --- /dev/null +++ b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/util/DefineClassHelper.java @@ -0,0 +1,147 @@ +/* + * Copyright 2006-2018 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.org.objenesis.instantiator.util; + +import sun.misc.Unsafe; +import com.fr.third.org.objenesis.ObjenesisException; +import com.fr.third.org.objenesis.strategy.PlatformDescription; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.security.ProtectionDomain; + +/** + * Java 11+ removed sun.misc.Unsafe.defineClass. This class bridges the gap to work from Java 1.8 up to 11. + *

+ * It was inspired from javassist. + * + * @author Henri Tremblay + */ +public final class DefineClassHelper { + + private static abstract class Helper { + abstract Class defineClass(String name, byte[] b, int off, int len, Class neighbor, + ClassLoader loader, ProtectionDomain protectionDomain); + } + + private static class Java8 extends Helper { + + private final MethodHandle defineClass = defineClass(); + + private MethodHandle defineClass() { + MethodType mt = MethodType.methodType(Class.class, String.class, byte[].class, int.class, int.class, ClassLoader.class, ProtectionDomain.class); + MethodHandle m; + try { + m = MethodHandles.publicLookup().findVirtual(Unsafe.class, "defineClass", mt); + } catch(Exception e) { + throw new ObjenesisException(e); + } + Unsafe unsafe = UnsafeUtils.getUnsafe(); + return m.bindTo(unsafe); + } + + @Override + Class defineClass(String className, byte[] b, int off, int len, Class neighbor, ClassLoader loader, ProtectionDomain protectionDomain) { + try { + return (Class) defineClass.invokeExact(className, b, off, len, loader, protectionDomain); + } catch (Throwable e) { + if(e instanceof Error) { + throw (Error) e; + } + if(e instanceof RuntimeException) { + throw (RuntimeException) e; + } + throw new ObjenesisException(e); + } + } + } + + private static class Java11 extends Helper { + + private final Class module = module(); + private final MethodHandles.Lookup lookup = MethodHandles.lookup(); + private final MethodHandle getModule = getModule(); + private final MethodHandle addReads = addReads(); + private final MethodHandle privateLookupIn = privateLookupIn(); + private final MethodHandle defineClass = defineClass(); + + private Class module() { + try { + return Class.forName("java.lang.Module"); + } catch (ClassNotFoundException e) { + throw new ObjenesisException(e); + } + } + + private MethodHandle getModule() { + try { + return lookup.findVirtual(Class.class, "getModule", MethodType.methodType(module)); + } catch (Exception e) { + throw new ObjenesisException(e); + } + } + + private MethodHandle addReads() { + try { + return lookup.findVirtual(module, "addReads", MethodType.methodType(module, module)); + } catch (Exception e) { + throw new ObjenesisException(e); + } + } + + private MethodHandle privateLookupIn() { + try { + return lookup.findStatic(MethodHandles.class, "privateLookupIn", MethodType.methodType(MethodHandles.Lookup.class, Class.class, MethodHandles.Lookup.class)); + } catch (Exception e) { + throw new ObjenesisException(e); + } + } + + private MethodHandle defineClass() { + try { + return lookup.findVirtual(MethodHandles.Lookup.class, "defineClass", MethodType.methodType(Class.class, byte[].class)); + } catch (Exception e) { + throw new ObjenesisException(e); + } + } + + @Override + Class defineClass(String className, byte[] b, int off, int len, Class neighbor, ClassLoader loader, ProtectionDomain protectionDomain) { + try { + Object module = getModule.invokeWithArguments(DefineClassHelper.class); + Object neighborModule = getModule.invokeWithArguments(neighbor); + addReads.invokeWithArguments(module, neighborModule); + MethodHandles.Lookup prvlookup = (MethodHandles.Lookup) privateLookupIn.invokeExact(neighbor, lookup); + return (Class) defineClass.invokeExact(prvlookup, b); + } catch (Throwable e) { + throw new ObjenesisException(neighbor.getName() + " has no permission to define the class", e); + } + } + } + + // Java 11+ removed sun.misc.Unsafe.defineClass, so we fallback to invoking defineClass on + // ClassLoader until we have an implementation that uses MethodHandles.Lookup.defineClass + private static final Helper privileged = PlatformDescription.isAfterJava11() ? + new Java11() : new Java8(); + + public static Class defineClass(String name, byte[] b, int off, int len, Class neighbor, + ClassLoader loader, ProtectionDomain protectionDomain) { + return privileged.defineClass(name, b, off, len, neighbor, loader, protectionDomain); + } + + private DefineClassHelper() {} +} diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/util/UnsafeUtils.java b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/util/UnsafeUtils.java index 150c87627..b793af373 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/util/UnsafeUtils.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/instantiator/util/UnsafeUtils.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. diff --git a/fine-kryo/src/com/fr/third/org/objenesis/strategy/BaseInstantiatorStrategy.java b/fine-kryo/src/com/fr/third/org/objenesis/strategy/BaseInstantiatorStrategy.java index 20f445d9e..31ef3809e 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/strategy/BaseInstantiatorStrategy.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/strategy/BaseInstantiatorStrategy.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. diff --git a/fine-kryo/src/com/fr/third/org/objenesis/strategy/InstantiatorStrategy.java b/fine-kryo/src/com/fr/third/org/objenesis/strategy/InstantiatorStrategy.java index 3a7e697f1..95e6fce57 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/strategy/InstantiatorStrategy.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/strategy/InstantiatorStrategy.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. diff --git a/fine-kryo/src/com/fr/third/org/objenesis/strategy/PlatformDescription.java b/fine-kryo/src/com/fr/third/org/objenesis/strategy/PlatformDescription.java index a401fc320..1706834cc 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/strategy/PlatformDescription.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/strategy/PlatformDescription.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -15,10 +15,10 @@ */ package com.fr.third.org.objenesis.strategy; -import com.fr.third.org.objenesis.ObjenesisException; - import java.lang.reflect.Field; +import com.fr.third.org.objenesis.ObjenesisException; + /** * List of constants describing the currently used platform. * @@ -26,9 +26,6 @@ import java.lang.reflect.Field; */ 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"; @@ -93,9 +90,8 @@ public final class PlatformDescription { + "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) { + // Add the API level if it's an Android platform + if(ANDROID_VERSION != 0) { desc += ", API level=" + ANDROID_VERSION; } desc += ")"; @@ -134,6 +130,29 @@ public final class PlatformDescription { return bootClasspath != null && bootClasspath.toLowerCase().contains("core-oj.jar"); } + /** + * Tells if the current JVM is running Java 9 or above + * + * @return if the current JVM is Java 9 or above + */ + public static boolean isAfterJigsaw() { + String version = PlatformDescription.SPECIFICATION_VERSION; + return version.indexOf('.') < 0; // No dot means the version is 9, 10, 11, ... not 1.6, 1.7, 1.8 + } + + /** + * Tells if the current JVM is running Java 11 or above + * + * @return if the current JVM is Java 11 or above + */ + public static boolean isAfterJava11() { + if(!isAfterJigsaw()) { + return false; + } + int version = Integer.parseInt(PlatformDescription.SPECIFICATION_VERSION); + return version >= 11; + } + public static boolean isGoogleAppEngine() { return GAE_VERSION != null; } diff --git a/fine-kryo/src/com/fr/third/org/objenesis/strategy/SerializingInstantiatorStrategy.java b/fine-kryo/src/com/fr/third/org/objenesis/strategy/SerializingInstantiatorStrategy.java index 3aa9e3a98..fcaddc17f 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/strategy/SerializingInstantiatorStrategy.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/strategy/SerializingInstantiatorStrategy.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -60,24 +60,24 @@ public class SerializingInstantiatorStrategy extends BaseInstantiatorStrategy { 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(type); + return new ObjectInputStreamInstantiator(type); } - return new SunReflectionFactorySerializationInstantiator(type); + return new SunReflectionFactorySerializationInstantiator(type); } else if(JVM_NAME.startsWith(DALVIK)) { if(PlatformDescription.isAndroidOpenJDK()) { - return new ObjectStreamClassInstantiator(type); + return new ObjectStreamClassInstantiator(type); } - return new AndroidSerializationInstantiator(type); + return new AndroidSerializationInstantiator(type); } else if(JVM_NAME.startsWith(GNU)) { - return new GCJSerializationInstantiator(type); + return new GCJSerializationInstantiator(type); } else if(JVM_NAME.startsWith(PERC)) { - return new PercSerializationInstantiator(type); + return new PercSerializationInstantiator(type); } - return new SunReflectionFactorySerializationInstantiator(type); + return new SunReflectionFactorySerializationInstantiator(type); } } diff --git a/fine-kryo/src/com/fr/third/org/objenesis/strategy/SingleInstantiatorStrategy.java b/fine-kryo/src/com/fr/third/org/objenesis/strategy/SingleInstantiatorStrategy.java index 6e0a55eba..cda717e4b 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/strategy/SingleInstantiatorStrategy.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/strategy/SingleInstantiatorStrategy.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -15,8 +15,8 @@ */ package com.fr.third.org.objenesis.strategy; -import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import com.fr.third.org.objenesis.ObjenesisException; +import com.fr.third.org.objenesis.instantiator.ObjectInstantiator; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; @@ -59,11 +59,7 @@ public class SingleInstantiatorStrategy implements InstantiatorStrategy { public ObjectInstantiator newInstantiatorOf(Class type) { try { return (ObjectInstantiator) constructor.newInstance(type); - } catch (InstantiationException e) { - throw new ObjenesisException(e); - } catch (IllegalAccessException e) { - throw new ObjenesisException(e); - } catch (InvocationTargetException e) { + } catch (Exception e) { throw new ObjenesisException(e); } } diff --git a/fine-kryo/src/com/fr/third/org/objenesis/strategy/StdInstantiatorStrategy.java b/fine-kryo/src/com/fr/third/org/objenesis/strategy/StdInstantiatorStrategy.java index e62d66591..3026dc207 100644 --- a/fine-kryo/src/com/fr/third/org/objenesis/strategy/StdInstantiatorStrategy.java +++ b/fine-kryo/src/com/fr/third/org/objenesis/strategy/StdInstantiatorStrategy.java @@ -1,5 +1,5 @@ -/** - * Copyright 2006-2017 the original author or authors. +/* + * Copyright 2006-2018 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. @@ -53,49 +53,46 @@ public class StdInstantiatorStrategy extends BaseInstantiatorStrategy { * @param type Class to instantiate * @return The ObjectInstantiator for the class */ + @Override public ObjectInstantiator newInstantiatorOf(Class 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(type); + return new ObjectInputStreamInstantiator(type); } - return new AccessibleInstantiator(type); + return new AccessibleInstantiator(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(type); + return new SunReflectionFactoryInstantiator(type); } else if(PlatformDescription.isThisJVM(DALVIK)) { if(PlatformDescription.isAndroidOpenJDK()) { // Starting at Android N which is based on OpenJDK - return new UnsafeFactoryInstantiator(type); + return new UnsafeFactoryInstantiator(type); } if(ANDROID_VERSION <= 10) { // Android 2.3 Gingerbread and lower - return new Android10Instantiator(type); + return new Android10Instantiator(type); } if(ANDROID_VERSION <= 17) { // Android 3.0 Honeycomb to 4.2 Jelly Bean - return new Android17Instantiator(type); + return new Android17Instantiator(type); } // Android 4.3 until Android N - return new Android18Instantiator(type); - } - else if(PlatformDescription.isThisJVM(JROCKIT)) { - // JRockit is compliant with HotSpot - return new SunReflectionFactoryInstantiator(type); + return new Android18Instantiator(type); } else if(PlatformDescription.isThisJVM(GNU)) { - return new GCJInstantiator(type); + return new GCJInstantiator(type); } else if(PlatformDescription.isThisJVM(PERC)) { - return new PercInstantiator(type); + return new PercInstantiator(type); } // Fallback instantiator, should work with most modern JVM - return new UnsafeFactoryInstantiator(type); + return new UnsafeFactoryInstantiator(type); } }