Skip to content

Commit

Permalink
Merge branch 'develop-for-20190410' of https://github.com/alibaba/jvm…
Browse files Browse the repository at this point in the history
…-sandbox into develop-for-20190410

� Conflicts:
�	sandbox-core/src/main/java/com/alibaba/jvm/sandbox/core/enhance/weaver/asm/EventWeaver.java
  • Loading branch information
dongchenxu committed Sep 18, 2019
2 parents d600604 + 5e61357 commit aae5882
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 50 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.alibaba.jvm.sandbox.api.listener.ext;

import com.alibaba.jvm.sandbox.api.event.BeforeEvent;
import com.alibaba.jvm.sandbox.api.event.Event;
import com.alibaba.jvm.sandbox.api.event.InvokeEvent;

Expand All @@ -18,11 +19,12 @@ public class Advice implements Attachment {

private final int processId;
private final int invokeId;
private final Behavior behavior;
private Behavior behavior;

private final ClassLoader loader;
private final Object[] parameterArray;
private final Object target;
private final AdviceAdapterListener listener;

private Object returnObj;
private Throwable throwable;
Expand All @@ -34,28 +36,28 @@ public class Advice implements Attachment {
private Advice parent = this;
private Event.Type state = Event.Type.BEFORE;

private BeforeEvent beforeEvent;


/**
* 构造通知
*
* @param processId {@link InvokeEvent#processId}
* @param invokeId {@link InvokeEvent#invokeId}
* @param behavior 触发事件的行为
* @param loader 触发事件的行为所在ClassLoader
* @param parameterArray 触发事件的行为入参
* @param target 触发事件所归属的对象实例
* @param listener 触发事件的处理监听器
*/
Advice(final int processId,
final int invokeId,
final Behavior behavior,
final ClassLoader loader,
final Object[] parameterArray,
final Object target) {
final Object target,
final AdviceAdapterListener listener) {
this.processId = processId;
this.invokeId = invokeId;
this.behavior = behavior;
this.loader = loader;
this.parameterArray = parameterArray;
this.target = target;
this.listener = listener;
}

/**
Expand Down Expand Up @@ -140,6 +142,31 @@ public int getInvokeId() {
* @return 触发事件的行为
*/
public Behavior getBehavior() {

try {
return internalGetBehavior();
} catch (NoSuchMethodException e) {
return null;
} catch (ClassNotFoundException e) {
return null;
}
}

private Behavior internalGetBehavior() throws NoSuchMethodException, ClassNotFoundException {
if (behavior == null) {
synchronized (this) {
if (behavior == null) {
final ClassLoader loader = listener.toClassLoader(beforeEvent.javaClassLoader);
final Class<?> targetClass = listener.toClass(loader, beforeEvent.javaClassName);
behavior = listener.toBehavior(
targetClass,
beforeEvent.javaMethodName,
beforeEvent.javaMethodDesc
);
}
}
}

return behavior;
}

Expand Down Expand Up @@ -295,4 +322,7 @@ public List<Advice> listHasMarkOnChain(final String exceptMark) {
return advices;
}

public void setBeforeEvent(BeforeEvent beforeEvent) {
this.beforeEvent = beforeEvent;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,12 @@ private void switchEvent(final OpStack opStack,
switch (event.type) {
case BEFORE: {
final BeforeEvent bEvent = (BeforeEvent) event;
final ClassLoader loader = toClassLoader(bEvent.javaClassLoader);
final Class<?> targetClass = toClass(loader, bEvent.javaClassName);
final Advice advice = new Advice(
bEvent.processId,
bEvent.invokeId,
toBehavior(
targetClass,
bEvent.javaMethodName,
bEvent.javaMethodDesc
),
bEvent.javaClassLoader,
bEvent.argumentArray,
bEvent.target
bEvent.target,
this
);

final Advice top;
Expand All @@ -86,6 +79,7 @@ private void switchEvent(final OpStack opStack,

opStackRef.get().pushForBegin(advice);
adviceListener.before(advice);
advice.setBeforeEvent(bEvent);
break;
}

Expand Down Expand Up @@ -289,20 +283,20 @@ private String toJavaClassName(final String internalClassName) {
if (GaStringUtils.isEmpty(internalClassName)) {
return internalClassName;
} else {
return internalClassName.replaceAll("/", ".");
return internalClassName.replace('/', '.');
}
}

// 提取ClassLoader,从BeforeEvent中获取到的ClassLoader
private ClassLoader toClassLoader(ClassLoader loader) {
ClassLoader toClassLoader(ClassLoader loader) {
return null == loader
// 如果此处为null,则说明遇到了来自Bootstrap的类,
? AdviceAdapterListener.class.getClassLoader()
: loader;
}

// 根据JavaClassName从ClassLoader中提取出Class<?>对象
private Class<?> toClass(ClassLoader loader, String javaClassName) throws ClassNotFoundException {
Class<?> toClass(ClassLoader loader, String javaClassName) throws ClassNotFoundException {
return toClassLoader(loader).loadClass(javaClassName);
}

Expand Down Expand Up @@ -417,7 +411,7 @@ public <T> T attachment() {
* @return 匹配的行为
* @throws NoSuchMethodException 如果匹配不到行为,则抛出该异常
*/
private Behavior toBehavior(final Class<?> clazz,
Behavior toBehavior(final Class<?> clazz,
final String javaMethodName,
final String javaMethodDesc) throws NoSuchMethodException {
final Behavior behavior = toBehaviorCacheGet.getFromCache(new BehaviorCacheKey(clazz, javaMethodName, javaMethodDesc));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ public interface IBuildingForBehavior {

IBuildingForWatching onWatching();

EventWatcher onWatch(AdviceListener adviceListener);
EventWatcher onWatch(AdviceListener adviceListener, Event.Type... eventTypeArray);

EventWatcher onWatch(EventListener eventListener, Event.Type... eventTypeArray);

Expand Down Expand Up @@ -629,8 +629,11 @@ public IBuildingForWatching onWatching() {
}

@Override
public EventWatcher onWatch(final AdviceListener adviceListener) {
return build(new AdviceAdapterListener(adviceListener), null, BEFORE, RETURN, THROWS, IMMEDIATELY_RETURN, IMMEDIATELY_THROWS);
public EventWatcher onWatch(final AdviceListener adviceListener, Event.Type... eventTypeArray) {
if (eventTypeArray == null) {
return build(new AdviceAdapterListener(adviceListener), null, BEFORE, RETURN, THROWS, IMMEDIATELY_RETURN, IMMEDIATELY_THROWS);
}
return build(new AdviceAdapterListener(adviceListener), null, eventTypeArray);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ class CallAsmCodeLock extends AsmCodeLock {
*/
class AsmTryCatchBlock {

final Label start;
final Label end;
final Label handler;
final String type;
protected final Label start;
protected final Label end;
protected final Label handler;
protected final String type;

AsmTryCatchBlock(Label start, Label end, Label handler, String type) {
this.start = start;
Expand Down Expand Up @@ -109,12 +109,17 @@ private boolean isMatchedBehavior(final String signCode) {

private String getBehaviorSignCode(final String name,
final String desc) {
final Type methodType = Type.getMethodType(desc);
final Collection<String> parameterClassNameArray = new ArrayList<String>();
for (final Type parameterType : methodType.getArgumentTypes()) {
parameterClassNameArray.add(parameterType.getClassName());
final StringBuilder sb = new StringBuilder(256).append(targetJavaClassName).append("#").append(name).append("(");

final Type[] methodTypes = Type.getMethodType(desc).getArgumentTypes();
if (methodTypes.length != 0) {
sb.append(methodTypes[0].getClassName());
for (int i = 1; i < methodTypes.length; i++) {
sb.append(",").append(methodTypes[i].getClassName());
}
}
return targetJavaClassName + "#" + name + "(" + join(parameterClassNameArray, ",") + ")";

return sb.append(")").toString();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ public class SandboxStringUtils {
* @return internal's classname
*/
public static String toInternalClassName(String javaClassName) {
return StringUtils.replace(javaClassName, ".", "/");
}
if (StringUtils.isEmpty(javaClassName)) {
return javaClassName;
}
return javaClassName.replace('.', '/'); }

/**
* internal's classname to java's classname
Expand All @@ -31,8 +33,10 @@ public static String toInternalClassName(String javaClassName) {
* @return java's classname
*/
public static String toJavaClassName(String internalClassName) {
return StringUtils.replace(internalClassName, "/", ".");
}
if (StringUtils.isEmpty(internalClassName)) {
return internalClassName;
}
return internalClassName.replace('/', '.'); }

public static String[] toJavaClassNameArray(String[] internalClassNameArray) {
if (null == internalClassNameArray) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,14 @@ private Collection<String> takeJavaClassNames(final Collection<ClassStructure> c
private final LazyGet<String> signCodeLazyGet = new LazyGet<String>() {
@Override
protected String initialValue() {
return String.format("%s#%s(%s)",
getDeclaringClassStructure().getJavaClassName(),
getName(),
join(takeJavaClassNames(getParameterTypeClassStructures()), ",")
);
return new StringBuilder(256)
.append(getDeclaringClassStructure().getJavaClassName())
.append("#")
.append(getName())
.append("(")
.append(join(takeJavaClassNames(getParameterTypeClassStructures()), ","))
.append(")")
.toString();
}
};

Expand All @@ -113,12 +116,15 @@ public String getSignCode() {
private final LazyGet<String> toStringLazyGet = new LazyGet<String>() {
@Override
protected String initialValue() {
return String.format("%s:[%s]:%s:%s",
getReturnTypeClassStructure().getJavaClassName(),
join(takeJavaClassNames(getAnnotationTypeClassStructures()), ","),
getSignCode(),
join(takeJavaClassNames(getExceptionTypeClassStructures()), ",")
);
return new StringBuilder(256)
.append(getReturnTypeClassStructure().getJavaClassName())
.append(":[")
.append(join(takeJavaClassNames(getAnnotationTypeClassStructures()), ","))
.append("]:")
.append(getSignCode())
.append(":")
.append(join(takeJavaClassNames(getExceptionTypeClassStructures()), ","))
.toString();
}
};

Expand All @@ -138,8 +144,7 @@ public int hashCode() {

@Override
public boolean equals(Object obj) {
return null != obj
&& (obj instanceof BehaviorStructure)
return (obj instanceof BehaviorStructure)
&& getSignCode().equals(((BehaviorStructure) obj).getSignCode());
}
}

0 comments on commit aae5882

Please sign in to comment.