Skip to content

Commit d195796

Browse files
author
vsilaev
committed
Spring AOP support in cdi-instrumentation agent
1 parent 3b3940b commit d195796

File tree

8 files changed

+122
-41
lines changed

8 files changed

+122
-41
lines changed

net.tascalate.javaflow.tools.cdi-javaagent/src/main/java/org/apache/commons/javaflow/instrumentation/cdi/AroundCdiProxyInvocationAdvice.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2013-2017 Valery Silaev (http://vsilaev.com)
2+
* Copyright 2013-2018 Valery Silaev (http://vsilaev.com)
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

net.tascalate.javaflow.tools.cdi-javaagent/src/main/java/org/apache/commons/javaflow/instrumentation/cdi/AroundOwbInterceptorProxyAdvice.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2013-2017 Valery Silaev (http://vsilaev.com)
2+
* Copyright 2013-2018 Valery Silaev (http://vsilaev.com)
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

net.tascalate.javaflow.tools.cdi-javaagent/src/main/java/org/apache/commons/javaflow/instrumentation/cdi/AroundOwbScopeProxyAdvice.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2013-2017 Valery Silaev (http://vsilaev.com)
2+
* Copyright 2013-2018 Valery Silaev (http://vsilaev.com)
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* Copyright 2013-2018 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.instrumentation.cdi;
17+
18+
import org.objectweb.asm.MethodVisitor;
19+
import org.objectweb.asm.Type;
20+
import org.objectweb.asm.commons.Method;
21+
22+
class AroundSpringProxyInvocationAdvice extends AroundCdiProxyInvocationAdvice {
23+
protected AroundSpringProxyInvocationAdvice(int api, MethodVisitor mv, int acc, String className, String methodName, String desc) {
24+
super(api, mv, acc, className, methodName, desc);
25+
}
26+
27+
@Override
28+
protected void loadProxiedInstance() {
29+
loadThis();
30+
invokeVirtual(Type.getType(className), GET_TARGET_SOURCE);
31+
/*
32+
* May be used instead of above
33+
invokeInterface(Type.getType("org/springframework/aop/framework/Advised"), GET_TARGET_SOURCE);
34+
*/
35+
invokeInterface(Type.getType("org/springframework/aop/TargetSource"), GET_TARGET);
36+
}
37+
38+
private static final Method GET_TARGET_SOURCE = Method.getMethod("org.springframework.aop.TargetSource getTargetSource()");
39+
private static final Method GET_TARGET = Method.getMethod("java.lang.Object getTarget()");
40+
41+
}

net.tascalate.javaflow.tools.cdi-javaagent/src/main/java/org/apache/commons/javaflow/instrumentation/cdi/AroundWeldProxyInvocationAdvice.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2013-2017 Valery Silaev (http://vsilaev.com)
2+
* Copyright 2013-2018 Valery Silaev (http://vsilaev.com)
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

net.tascalate.javaflow.tools.cdi-javaagent/src/main/java/org/apache/commons/javaflow/instrumentation/cdi/CdiProxyClassAdapter.java

Lines changed: 75 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2013-2017 Valery Silaev (http://vsilaev.com)
2+
* Copyright 2013-2018 Valery Silaev (http://vsilaev.com)
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
1717

1818
import java.io.IOException;
1919
import java.util.Arrays;
20+
import java.util.Collections;
2021
import java.util.HashSet;
2122
import java.util.Set;
2223

@@ -31,10 +32,64 @@
3132

3233
class CdiProxyClassAdapter extends ClassVisitor {
3334

34-
private String className;
35-
private Type owbProxiedInstanceType;
36-
private Type owbProxiedInstanceProviderType;
37-
private boolean isWeldProxy;
35+
static enum CdiEnvironmentType {
36+
WELD("org/jboss/weld/bean/proxy/ProxyObject") {
37+
38+
@Override
39+
boolean accept(String className, String interfaceName) {
40+
// *$$_WeldSubclass is not a scope/interceptor proxy
41+
// Otherwise it's indeed a proxy
42+
return super.accept(className, interfaceName) && !className.endsWith("$$_WeldSubclass");
43+
}
44+
45+
@Override
46+
MethodVisitor createAdviceAdapter(CdiProxyClassAdapter ca, MethodVisitor mv, int acc, String name, String desc) {
47+
return new AroundWeldProxyInvocationAdvice(ca.api, mv, acc, ca.className, name, desc);
48+
}
49+
},
50+
SPRING("org/springframework/aop/framework/Advised") {
51+
52+
@Override
53+
MethodVisitor createAdviceAdapter(CdiProxyClassAdapter ca, MethodVisitor mv, int acc, String name, String desc) {
54+
return new AroundWeldProxyInvocationAdvice(ca.api, mv, acc, ca.className, name, desc);
55+
}
56+
},
57+
OWB(
58+
"org/apache/webbeans/proxy/OwbInterceptorProxy",
59+
"org/apache/webbeans/proxy/OwbNormalScopeProxy"
60+
) {
61+
62+
@Override
63+
MethodVisitor createAdviceAdapter(CdiProxyClassAdapter ca, MethodVisitor mv, int acc, String name, String desc) {
64+
if (null != ca.owbProxiedInstanceType) {
65+
return new AroundOwbInterceptorProxyAdvice(ca.api, mv, acc, ca.className, name, desc, ca.owbProxiedInstanceType);
66+
} else if (null != ca.owbProxiedInstanceProviderType) {
67+
return new AroundOwbScopeProxyAdvice(ca.api, mv, acc, ca.className, name, desc, ca.owbProxiedInstanceProviderType);
68+
} else {
69+
return mv;
70+
}
71+
}
72+
}
73+
;
74+
75+
private Set<String> markerInterfaces;
76+
77+
private CdiEnvironmentType(String... markerInterfaces) {
78+
this.markerInterfaces =
79+
Collections.unmodifiableSet( new HashSet<String>(Arrays.asList(markerInterfaces)) );
80+
}
81+
82+
abstract MethodVisitor createAdviceAdapter(CdiProxyClassAdapter ca, MethodVisitor mv, int acc, String name, String desc);
83+
boolean accept(String className, String interfaceName) {
84+
return markerInterfaces.contains(interfaceName);
85+
}
86+
}
87+
88+
String className;
89+
Type owbProxiedInstanceType;
90+
Type owbProxiedInstanceProviderType;
91+
92+
private CdiEnvironmentType cdiEnvironmentType;
3893
private ContinuableClassInfo classInfo;
3994

4095
private final ContinuableClassInfoResolver cciResolver;
@@ -48,27 +103,26 @@ class CdiProxyClassAdapter extends ClassVisitor {
48103
@Override
49104
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
50105
className = name;
51-
boolean hasMarker = false;
106+
CdiEnvironmentType selectedType = null;
107+
CdiEnvironmentType[] cdiEnvironmentTypes = CdiEnvironmentType.values();
108+
outerLoop:
52109
for (final String interfaze : interfaces) {
53-
if (MARKER_INTERFACES.contains(interfaze)) {
54-
if (WELD_PROXY_OBJECT.equals(interfaze)) {
55-
if (!className.endsWith("$$_WeldSubclass")) {
56-
// *$$_WeldSubclass is not a scope/interceptor proxy
57-
// Otherwise it's indeed a proxy
58-
isWeldProxy = true;
59-
hasMarker = true;
60-
}
110+
for (int i = cdiEnvironmentTypes.length - 1; i >= 0; i--) {
111+
selectedType = cdiEnvironmentTypes[i];
112+
if (selectedType.accept(name, interfaze)) {
113+
// Exclusive, may exit early
114+
break outerLoop;
61115
} else {
62-
hasMarker = true;
116+
selectedType = null;
63117
}
64-
// Exclusive, may exit early
65-
break;
66118
}
67119
}
68120

69-
if (!hasMarker) {
121+
if (null == selectedType) {
70122
throw StopException.INSTANCE;
71123
}
124+
125+
cdiEnvironmentType = selectedType;
72126

73127
try {
74128
classInfo = cciResolver.resolve(superName);
@@ -95,31 +149,17 @@ public FieldVisitor visitField(int access, String name, String desc, String sign
95149
@Override
96150
public MethodVisitor visitMethod(int acc, String name, String desc, String signature, String[] exceptions) {
97151
MethodVisitor mv = cv.visitMethod(acc, name, desc, signature, exceptions);
98-
if (isContinuableMethodProxy(acc, name, desc, signature, exceptions)) {
99-
if (isWeldProxy) {
100-
mv = new AroundWeldProxyInvocationAdvice(api, mv, acc, className, name, desc);
101-
} else if (null != owbProxiedInstanceType) {
102-
mv = new AroundOwbInterceptorProxyAdvice(api, mv, acc, className, name, desc, owbProxiedInstanceType);
103-
} else if (null != owbProxiedInstanceProviderType) {
104-
mv = new AroundOwbScopeProxyAdvice(api, mv, acc, className, name, desc, owbProxiedInstanceProviderType);
105-
}
152+
if (isContinuableMethodProxy(acc, name, desc, signature, exceptions) && null != cdiEnvironmentType) {
153+
mv = cdiEnvironmentType.createAdviceAdapter(this, mv, acc, name, desc);
106154
}
107155
return mv;
108156
}
109157

110-
protected boolean isContinuableMethodProxy(int acc, String name, String desc, String signature, String[] exceptions) {
158+
private boolean isContinuableMethodProxy(int acc, String name, String desc, String signature, String[] exceptions) {
111159
int idx = name.lastIndexOf("$$super");
112160
if (idx > 0) {
113161
name = name.substring(0, idx);
114162
}
115163
return ! "<init>".equals(name) && classInfo.isContinuableMethod(acc, name, desc, signature);
116164
}
117-
118-
private static final String OWB_INTERCEPTOR_PROXY = "org/apache/webbeans/proxy/OwbInterceptorProxy";
119-
private static final String OWB_NORMAL_SCOPE_PROXY = "org/apache/webbeans/proxy/OwbNormalScopeProxy";
120-
private static final String WELD_PROXY_OBJECT = "org/jboss/weld/bean/proxy/ProxyObject";
121-
122-
private static final Set<String> MARKER_INTERFACES = new HashSet<String>(Arrays.asList(
123-
OWB_INTERCEPTOR_PROXY, OWB_NORMAL_SCOPE_PROXY, WELD_PROXY_OBJECT
124-
));
125165
}

net.tascalate.javaflow.tools.cdi-javaagent/src/main/java/org/apache/commons/javaflow/instrumentation/cdi/CdiProxyClassTransformer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2013-2017 Valery Silaev (http://vsilaev.com)
2+
* Copyright 2013-2018 Valery Silaev (http://vsilaev.com)
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

net.tascalate.javaflow.tools.cdi-javaagent/src/main/java/org/apache/commons/javaflow/instrumentation/cdi/CdiProxyInstrumentationAgent.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2013-2017 Valery Silaev (http://vsilaev.com)
2+
* Copyright 2013-2018 Valery Silaev (http://vsilaev.com)
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

0 commit comments

Comments
 (0)