Skip to content

同时拦截嵌套调用的两个方法出现ClassCastException,子方法中抛出的异常无法触发上级调用者的afterThrowing事件 #123

@zengguoyu

Description

@zengguoyu

操作环境

... ...
操作系统 macOS Mojave 版本10.14.1
JVM版本 1.8.0_181
沙箱容器版本 1.1.2
沙箱API版本 1.1.2

问题描述

如果Sandbox同时拦截ServiceA.sayHello和ServiceB.sayHello方法,并在ServiceB.sayHello的Before事件中抛出 ProcessController.throwsImmediately(new RuntimeException());会导致ClassCastException。

image

另外ServiceB.sayHello的before事件中抛出的异常无法触发ServiceA.sayHello的afterThrowing事件。

重现步骤

  1. 两个服务,在服务A中调用了服务B
package com.demo.app1.service.impl;

import com.demo.app1.service.ServiceA;
import com.demo.app1.service.ServiceB;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class ServceAImpl implements ServiceA {
    @Autowired
    private ServiceB serviceB;
    @Override
    public String sayHello(String name) {
        return this.serviceB.sayHello(name);
    }
}
package com.demo.app1.service.impl;

import com.demo.app1.service.ServiceB;
import org.springframework.stereotype.Service;

@Service
public class ServceBImpl implements ServiceB {
    @Override
    public String sayHello(String name) {
        return "hello," + name;
    }
}
  1. 第二步
  eventWatcher = new EventWatchBuilder(this.moduleEventWatcher)
                .onClass("com.demo.app1.service.impl.Servce*")
                .onBehavior("sayHello")
                .onWatch(new AdviceListener() {
                    @Override
                    protected void before(Advice advice) throws Throwable {
                        logger.error("before:" + advice.getTarget().getClass().getName());
                        if ("com.demo.app1.service.impl.ServceBImpl".equals(advice.getTarget().getClass().getName())) {
                            ProcessController.throwsImmediately(new RuntimeException("---------------------------"));
                        }
                    }
                    @Override
                    protected void afterReturning(Advice advice) throws Throwable {
                        logger.error("afterReturning:" + advice.getTarget().getClass().getName());
                    }

                    @Override
                    protected void afterThrowing(Advice advice) throws Throwable {
                        logger.error("afterThrowing:" + advice.getTarget().getClass().getName());
                    }
                });

打印的日志
image

sandbox.log日志
image

  1. 第三步
  2. ...

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions