Skip to content

Commit 3c9cb54

Browse files
Henri TremblayHenri Tremblay
authored andcommitted
Bridge to exotic instantiator to keep compatibility
1 parent eb17cf8 commit 3c9cb54

6 files changed

Lines changed: 163 additions & 9 deletions

File tree

exotic/src/test/java/org/objenesis/instantiator/exotic/MagicInstantiatorTest.java renamed to exotic/src/test/java/org/objenesis/instantiator/exotic/test/MagicInstantiatorTest.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
package org.objenesis.instantiator.exotic;
16+
package org.objenesis.instantiator.exotic.test;
1717

1818
import org.junit.Before;
1919
import org.junit.Test;
20+
import org.objenesis.instantiator.sun.MagicInstantiator;
2021
import org.objenesis.test.EmptyClass;
2122
import org.objenesis.instantiator.ObjectInstantiator;
2223
import org.objenesis.strategy.PlatformDescription;
@@ -25,6 +26,8 @@
2526
import static org.junit.Assume.*;
2627

2728
/**
29+
* This test is using the original sun.ProxyInstantiator do make sure the bridging to the new class is working.
30+
*
2831
* @author Henri Tremblay
2932
*/
3033
public class MagicInstantiatorTest {
@@ -46,9 +49,4 @@ public void testNewInstance() {
4649
assertEquals(EmptyClass.class, o2.newInstance().getClass());
4750
}
4851

49-
@Test
50-
public void testInternalInstantiator() {
51-
ObjectInstantiator<EmptyClass> o1 = new MagicInstantiator<>(EmptyClass.class).getInstantiator();
52-
assertEquals(EmptyClass.class, o1.newInstance().getClass());
53-
}
5452
}

exotic/src/test/java/org/objenesis/instantiator/exotic/ProxyingInstantiatorTest.java renamed to exotic/src/test/java/org/objenesis/instantiator/exotic/test/ProxyingInstantiatorTest.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,19 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
package org.objenesis.instantiator.exotic;
16+
package org.objenesis.instantiator.exotic.test;
1717

1818
import org.junit.Ignore;
1919
import org.junit.Test;
20+
import org.objenesis.instantiator.basic.ProxyingInstantiator;
2021
import org.objenesis.test.EmptyClass;
2122
import org.objenesis.instantiator.ObjectInstantiator;
2223

2324
import static org.junit.Assert.*;
2425

2526
/**
27+
* This test is using the original basic.ProxyInstantiator do make sure the bridging to the new class is working.
28+
*
2629
* @author Henri Tremblay
2730
*/
2831
@Ignore("Because it doesn't work without -Xverify:none")
@@ -32,7 +35,7 @@ public class ProxyingInstantiatorTest {
3235
public void testNewInstance() {
3336
ObjectInstantiator<EmptyClass> inst = new ProxyingInstantiator<>(EmptyClass.class);
3437
EmptyClass c = inst.newInstance();
35-
assertEquals("org.objenesis.EmptyClass$$$Objenesis", c.getClass().getName());
38+
assertEquals("org.objenesis.test.EmptyClass$$$Objenesis", c.getClass().getName());
3639
}
3740

3841
@Test
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright 2006-2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
/*
17+
* Copyright 2006-2021 the original author or authors.
18+
*
19+
* Licensed under the Apache License, Version 2.0 (the "License");
20+
* you may not use this file except in compliance with the License.
21+
* You may obtain a copy of the License at
22+
*
23+
* http://www.apache.org/licenses/LICENSE-2.0
24+
*
25+
* Unless required by applicable law or agreed to in writing, software
26+
* distributed under the License is distributed on an "AS IS" BASIS,
27+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
28+
* See the License for the specific language governing permissions and
29+
* limitations under the License.
30+
*/
31+
package org.objenesis.instantiator.basic;
32+
33+
import org.objenesis.ObjenesisException;
34+
import org.objenesis.instantiator.ObjectInstantiator;
35+
36+
import java.lang.reflect.Constructor;
37+
import java.lang.reflect.InvocationTargetException;
38+
39+
/**
40+
* Helper class extended by instantiators for which the implementation was moved to the exotic project.
41+
*
42+
* @param <T> type of the class instantiated
43+
* @author Henri Tremblay
44+
*/
45+
public abstract class DelegatingToExoticInstantiator<T> implements ObjectInstantiator<T> {
46+
47+
private final ObjectInstantiator<T> wrapped;
48+
49+
protected DelegatingToExoticInstantiator(String className, Class<T> type) {
50+
Class<ObjectInstantiator<T>> clazz = instantiatorClass(className);
51+
Constructor<ObjectInstantiator<T>> constructor = instantiatorConstructor(className, clazz);
52+
wrapped = instantiator(className, type, constructor);
53+
}
54+
55+
private ObjectInstantiator<T> instantiator(String className, Class<T> type, Constructor<ObjectInstantiator<T>> constructor) {
56+
try {
57+
return constructor.newInstance(type);
58+
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
59+
throw new RuntimeException("Failed to call constructor of " + className, e);
60+
}
61+
}
62+
63+
private Class<ObjectInstantiator<T>> instantiatorClass(String className) {
64+
try {
65+
@SuppressWarnings("unchecked")
66+
Class<ObjectInstantiator<T>> clazz = (Class<ObjectInstantiator<T>>) Class.forName(className);
67+
return clazz;
68+
} catch (ClassNotFoundException e) {
69+
throw new ObjenesisException(getClass().getSimpleName() + " now requires objenesis-exotic to be in the classpath", e);
70+
}
71+
}
72+
73+
private Constructor<ObjectInstantiator<T>> instantiatorConstructor(String className, Class<ObjectInstantiator<T>> clazz) {
74+
try {
75+
return clazz.getConstructor(Class.class);
76+
} catch (NoSuchMethodException e) {
77+
throw new ObjenesisException("Try to find constructor taking a Class<T> in parameter on " + className + " but can't find it", e);
78+
}
79+
}
80+
81+
@Override
82+
public T newInstance() {
83+
return wrapped.newInstance();
84+
}
85+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright 2006-2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.objenesis.instantiator.basic;
17+
18+
import org.objenesis.instantiator.annotations.Instantiator;
19+
import org.objenesis.instantiator.annotations.Typology;
20+
21+
/**
22+
* Shell keeping compatibility but delegating to objenesis-exotic which contains the real implementation.
23+
*
24+
* @param <T> type of the class instantiated
25+
*/
26+
@Instantiator(Typology.STANDARD)
27+
public class ProxyingInstantiator<T> extends DelegatingToExoticInstantiator<T> {
28+
29+
public ProxyingInstantiator(Class<T> type) {
30+
super("org.objenesis.instantiator.exotic.ProxyingInstantiator", type);
31+
}
32+
33+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright 2006-2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.objenesis.instantiator.sun;
17+
18+
import org.objenesis.instantiator.annotations.Instantiator;
19+
import org.objenesis.instantiator.annotations.Typology;
20+
import org.objenesis.instantiator.basic.DelegatingToExoticInstantiator;
21+
22+
/**
23+
* Shell keeping compatibility but delegating to objenesis-exotic which contains the real implementation.
24+
*
25+
* @param <T> type of the class instantiated
26+
*/
27+
@Instantiator(Typology.STANDARD)
28+
public class MagicInstantiator<T> extends DelegatingToExoticInstantiator<T> {
29+
30+
public MagicInstantiator(Class<T> type) {
31+
super("org.objenesis.instantiator.exotic.MagicInstantiator", type);
32+
}
33+
34+
}

tck/src/main/java/org/objenesis/tck/search/SearchWorkingInstantiator.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.io.Serializable;
2323
import java.lang.reflect.Constructor;
2424
import java.lang.reflect.InvocationTargetException;
25+
import java.lang.reflect.Modifier;
2526
import java.util.SortedSet;
2627

2728
/**
@@ -63,7 +64,7 @@ public void searchForInstantiator(Class<?> toInstantiate) {
6364
continue;
6465
}
6566

66-
if (c.isInterface() || !ObjectInstantiator.class.isAssignableFrom(c)) {
67+
if (c.isInterface() || Modifier.isAbstract(c.getModifiers()) || !ObjectInstantiator.class.isAssignableFrom(c)) {
6768
continue;
6869
}
6970

0 commit comments

Comments
 (0)