Skip to content

Commit 3f989b5

Browse files
committed
Handle continuable Java and CGLib proxies
1 parent 6b97856 commit 3f989b5

File tree

17 files changed

+472
-169
lines changed

17 files changed

+472
-169
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* Copyright 2013-2019 Valery Silaev (http://vsilaev.com)
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.apache.commons.javaflow.core;
17+
18+
import java.lang.reflect.Proxy;
19+
20+
/**
21+
* Marker interface for dynamic proxy classes like standard Java {@link Proxy} or CGLib Proxy.
22+
* Run-time instrumentation agent is capable to correctly decorate such proxies so continuable methods works correctly
23+
*
24+
* @author vsilaev
25+
*
26+
*/
27+
public interface ContinuableProxy {}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* Copyright 2013-2019 Valery Silaev (http://vsilaev.com)
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.apache.commons.javaflow.core;
17+
18+
import java.lang.reflect.Proxy;
19+
20+
/**
21+
* Generic interface for continuable dynamic proxy classes.
22+
* Unlike standard Java {@link Proxy} or CGLib Proxy where it's possible to resolve proxy -> handler
23+
* dependency via API, custom continuable proxies should provide implementation of this interface to get
24+
* corresponding "handler" from the proxied object, in the same manner as {@link Proxy#getInvocationHandler(Object)}.
25+
*
26+
* @author vsilaev
27+
*
28+
*/
29+
public interface CustomContinuableProxy {
30+
/**
31+
* Get a real continuable invocation handler for the proxy method descrived via <code>methodName</code>
32+
* and <code>methodDescription</code>.
33+
*
34+
* @param methodName name of the continuable method that is proxied
35+
* @param methodDescription arguments/return type of the method in internal JVM format
36+
* @return the continuable handler that processed invocation
37+
*/
38+
public Object getInvocationHandler(String methodName, String methodDescription);
39+
}

net.tascalate.javaflow.api/src/main/java/org/apache/commons/javaflow/core/ReflectionUtils.java

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import java.io.ObjectInputStream;
2323
import java.io.ObjectOutputStream;
2424
import java.lang.reflect.Field;
25-
import java.lang.reflect.InvocationTargetException;
2625
import java.lang.reflect.Method;
2726
import java.util.HashMap;
2827
import java.util.Map;
@@ -168,33 +167,4 @@ public static final String descriptionOfObject(Object o) {
168167
public static final String descriptionOfClass(Object o) {
169168
return getClassName(o) + "/" + getClassLoaderName(o);
170169
}
171-
172-
173-
public static Class<?> defineClass(ClassLoader cl, byte[] b) {
174-
try {
175-
return (Class<?>) defineClassMethod.invoke(cl, null, b, 0, b.length);
176-
} catch (InvocationTargetException ex) {
177-
log.error("Could not define class", ex.getTargetException());
178-
throw new RuntimeException(ex.getTargetException());
179-
} catch (Exception ex) {
180-
log.error("Could not invoke method \"defineClass\"", ex);
181-
throw new RuntimeException(ex);
182-
}
183-
}
184-
185-
private static final Method defineClassMethod;
186-
187-
static {
188-
// defineClass(String name, byte[] b, int off, int len)
189-
try {
190-
defineClassMethod = ClassLoader.class.getDeclaredMethod("defineClass", String.class, byte[].class,
191-
int.class, int.class);
192-
defineClassMethod.setAccessible(true);
193-
} catch (NoSuchMethodException ex) {
194-
throw new IllegalStateException("Could not find method \"defineClass\"", ex);
195-
} catch (SecurityException ex) {
196-
throw new IllegalStateException("Could not find method \"defineClass\"", ex);
197-
}
198-
}
199-
200170
}

net.tascalate.javaflow.providers.asm3/src/main/java/org/apache/commons/javaflow/providers/asm3/InheritanceLookup.java

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,20 +49,26 @@
4949
* @author Eric Bruneton
5050
* @author vsilaev
5151
*/
52-
class InheritanceLookup {
52+
public class InheritanceLookup {
5353

5454
private final ResourceLoader loader;
5555
private final Map<Key, String> lookupCache = new HashMap<Key, String>();
5656

57-
InheritanceLookup(ResourceLoader loader) {
57+
public InheritanceLookup(ResourceLoader loader) {
5858
this.loader = loader;
5959
}
6060

61-
Type getCommonSuperType(Type type1, Type type2) {
62-
return Type.getObjectType(getCommonSuperClass(type1.getInternalName(), type2.getInternalName()));
61+
public boolean isSuperClass(String type1, String type2) {
62+
String commonSuperClass = getCommonSuperClass(type1, type2);
63+
return type1.equals(commonSuperClass);
6364
}
6465

65-
String getCommonSuperClass(String type1, String type2) {
66+
public boolean isSubClass(String type1, String type2) {
67+
String commonSuperClass = getCommonSuperClass(type1, type2);
68+
return type2.equals(commonSuperClass);
69+
}
70+
71+
public String getCommonSuperClass(String type1, String type2) {
6672
Key key = new Key(type1, type2);
6773
String result;
6874
synchronized (lookupCache) {
@@ -75,6 +81,20 @@ String getCommonSuperClass(String type1, String type2) {
7581
return result;
7682
}
7783

84+
public boolean isClassAvailable(String type) {
85+
try {
86+
InputStream in = loader.getResourceAsStream(type + ".class");
87+
try { in.close(); } catch (IOException ex) {}
88+
return true;
89+
} catch (IOException ex) {
90+
return false;
91+
}
92+
}
93+
94+
Type getCommonSuperType(Type type1, Type type2) {
95+
return Type.getObjectType(getCommonSuperClass(type1.getInternalName(), type2.getInternalName()));
96+
}
97+
7898
private String calculateCommonSuperClass(final String type1, final String type2) {
7999
try {
80100
ClassReader info1 = typeInfo(type1);

net.tascalate.javaflow.providers.asm4/src/main/java/org/apache/commons/javaflow/providers/asm4/InheritanceLookup.java

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,20 +49,26 @@
4949
* @author Eric Bruneton
5050
* @author vsilaev
5151
*/
52-
class InheritanceLookup {
52+
public class InheritanceLookup {
5353

5454
private final ResourceLoader loader;
5555
private final Map<Key, String> lookupCache = new HashMap<Key, String>();
5656

57-
InheritanceLookup(ResourceLoader loader) {
57+
public InheritanceLookup(ResourceLoader loader) {
5858
this.loader = loader;
5959
}
6060

61-
Type getCommonSuperType(Type type1, Type type2) {
62-
return Type.getObjectType(getCommonSuperClass(type1.getInternalName(), type2.getInternalName()));
61+
public boolean isSuperClass(String type1, String type2) {
62+
String commonSuperClass = getCommonSuperClass(type1, type2);
63+
return type1.equals(commonSuperClass);
6364
}
6465

65-
String getCommonSuperClass(String type1, String type2) {
66+
public boolean isSubClass(String type1, String type2) {
67+
String commonSuperClass = getCommonSuperClass(type1, type2);
68+
return type2.equals(commonSuperClass);
69+
}
70+
71+
public String getCommonSuperClass(String type1, String type2) {
6672
Key key = new Key(type1, type2);
6773
String result;
6874
synchronized (lookupCache) {
@@ -75,6 +81,20 @@ String getCommonSuperClass(String type1, String type2) {
7581
return result;
7682
}
7783

84+
public boolean isClassAvailable(String type) {
85+
try {
86+
InputStream in = loader.getResourceAsStream(type + ".class");
87+
try { in.close(); } catch (IOException ex) {}
88+
return true;
89+
} catch (IOException ex) {
90+
return false;
91+
}
92+
}
93+
94+
Type getCommonSuperType(Type type1, Type type2) {
95+
return Type.getObjectType(getCommonSuperClass(type1.getInternalName(), type2.getInternalName()));
96+
}
97+
7898
private String calculateCommonSuperClass(final String type1, final String type2) {
7999
try {
80100
ClassReader info1 = typeInfo(type1);

net.tascalate.javaflow.providers.asm5/src/main/java/org/apache/commons/javaflow/providers/asm5/InheritanceLookup.java

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,20 +49,26 @@
4949
* @author Eric Bruneton
5050
* @author vsilaev
5151
*/
52-
class InheritanceLookup {
52+
public class InheritanceLookup {
5353

5454
private final ResourceLoader loader;
5555
private final Map<Key, String> lookupCache = new HashMap<Key, String>();
5656

57-
InheritanceLookup(ResourceLoader loader) {
57+
public InheritanceLookup(ResourceLoader loader) {
5858
this.loader = loader;
5959
}
6060

61-
Type getCommonSuperType(Type type1, Type type2) {
62-
return Type.getObjectType(getCommonSuperClass(type1.getInternalName(), type2.getInternalName()));
61+
public boolean isSuperClass(String type1, String type2) {
62+
String commonSuperClass = getCommonSuperClass(type1, type2);
63+
return type1.equals(commonSuperClass);
6364
}
6465

65-
String getCommonSuperClass(String type1, String type2) {
66+
public boolean isSubClass(String type1, String type2) {
67+
String commonSuperClass = getCommonSuperClass(type1, type2);
68+
return type2.equals(commonSuperClass);
69+
}
70+
71+
public String getCommonSuperClass(String type1, String type2) {
6672
Key key = new Key(type1, type2);
6773
String result;
6874
synchronized (lookupCache) {
@@ -75,6 +81,20 @@ String getCommonSuperClass(String type1, String type2) {
7581
return result;
7682
}
7783

84+
public boolean isClassAvailable(String type) {
85+
try {
86+
InputStream in = loader.getResourceAsStream(type + ".class");
87+
try { in.close(); } catch (IOException ex) {}
88+
return true;
89+
} catch (IOException ex) {
90+
return false;
91+
}
92+
}
93+
94+
Type getCommonSuperType(Type type1, Type type2) {
95+
return Type.getObjectType(getCommonSuperClass(type1.getInternalName(), type2.getInternalName()));
96+
}
97+
7898
private String calculateCommonSuperClass(final String type1, final String type2) {
7999
try {
80100
ClassReader info1 = typeInfo(type1);

net.tascalate.javaflow.providers.asmx/src/main/java/org/apache/commons/javaflow/providers/asmx/InheritanceLookup.java

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,20 +49,26 @@
4949
* @author Eric Bruneton
5050
* @author vsilaev
5151
*/
52-
class InheritanceLookup {
52+
public class InheritanceLookup {
5353

5454
private final ResourceLoader loader;
5555
private final Map<Key, String> lookupCache = new HashMap<Key, String>();
5656

57-
InheritanceLookup(ResourceLoader loader) {
57+
public InheritanceLookup(ResourceLoader loader) {
5858
this.loader = loader;
5959
}
6060

61-
Type getCommonSuperType(Type type1, Type type2) {
62-
return Type.getObjectType(getCommonSuperClass(type1.getInternalName(), type2.getInternalName()));
61+
public boolean isSuperClass(String type1, String type2) {
62+
String commonSuperClass = getCommonSuperClass(type1, type2);
63+
return type1.equals(commonSuperClass);
6364
}
6465

65-
String getCommonSuperClass(String type1, String type2) {
66+
public boolean isSubClass(String type1, String type2) {
67+
String commonSuperClass = getCommonSuperClass(type1, type2);
68+
return type2.equals(commonSuperClass);
69+
}
70+
71+
public String getCommonSuperClass(String type1, String type2) {
6672
Key key = new Key(type1, type2);
6773
String result;
6874
synchronized (lookupCache) {
@@ -75,6 +81,20 @@ String getCommonSuperClass(String type1, String type2) {
7581
return result;
7682
}
7783

84+
public boolean isClassAvailable(String type) {
85+
try {
86+
InputStream in = loader.getResourceAsStream(type + ".class");
87+
try { in.close(); } catch (IOException ex) {}
88+
return true;
89+
} catch (IOException ex) {
90+
return false;
91+
}
92+
}
93+
94+
Type getCommonSuperType(Type type1, Type type2) {
95+
return Type.getObjectType(getCommonSuperClass(type1.getInternalName(), type2.getInternalName()));
96+
}
97+
7898
private String calculateCommonSuperClass(final String type1, final String type2) {
7999
try {
80100
ClassReader info1 = typeInfo(type1);
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package net.tascalate.javaflow.providers.asmx;
2+
3+
import static org.junit.Assert.assertTrue;
4+
5+
import org.apache.commons.javaflow.providers.asmx.InheritanceLookup;
6+
import org.apache.commons.javaflow.spi.ClasspathResourceLoader;
7+
import org.junit.Test;
8+
9+
public class InheritanceLookupTest {
10+
11+
@Test
12+
public void testInheritance() {
13+
InheritanceLookup lookup = new InheritanceLookup(new ClasspathResourceLoader(ClassLoader.getSystemClassLoader()));
14+
String sAbstractCollection = lookup.getCommonSuperClass("java/util/ArrayList", "java/util/HashSet");
15+
assertTrue("java/util/AbstractCollection".equals(sAbstractCollection));
16+
17+
String sIterable1 = lookup.getCommonSuperClass("java/util/List", "java/lang/Iterable");
18+
assertTrue("java/lang/Iterable".equals(sIterable1));
19+
20+
String sIterable2 = lookup.getCommonSuperClass("java/util/LinkedList", "java/lang/Iterable");
21+
assertTrue("java/lang/Iterable".equals(sIterable2));
22+
23+
}
24+
25+
}

0 commit comments

Comments
 (0)