Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

springboot下Module中使用宿主应用类报错ClassNotFoundException #444

Open
fawen18 opened this issue Oct 11, 2023 · 8 comments
Open
Assignees

Comments

@fawen18
Copy link

fawen18 commented Oct 11, 2023

背景:
对MySQL driver进行增强,监控执行sql耗时

启动脚本:
java -jar -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8003 -javaagent:${HOME}/sandbox/lib/sandbox-agent.jar uniqueauth.jar
这里是关键,使用的是springboot的fatjar,由于springboot有自己的classloader,所以导致下面的问题(我的猜测)。

代码如下:
`@MetaInfServices(Module.class)
@InFormation(id = "MySQLMonitorModule", version = "0.0.1", author = "")
public class MySQLMonitorModule implements Module, LoadCompleted {
@resource
private ModuleEventWatcher moduleEventWatcher;

@Override
public void loadCompleted() {
    new EventWatchBuilder(moduleEventWatcher)
            .onClass("com.mysql.jdbc.MySQLConnection")
            .includeSubClasses()
            .includeBootstrap()
            .onBehavior("execSQL")
            .onWatch(new AdviceListener() {
                @Override
                protected void before(Advice advice) throws Throwable {
                    long start = System.currentTimeMillis();
                    advice.attach(start);
                }

                @Override
                protected void afterReturning(Advice advice) throws Throwable {
                    StatementImpl callingStatement = (StatementImpl) advice.getParameterArray()[0];
           
                }

                @Override
                protected void afterThrowing(Advice advice) throws Throwable {
                }
            });
}

}`

报错如下:
image
其中com.mysql.jdbc.StatementImpl该类为宿主应用类

@oldmanpushcart @dongchenxu 求大神帮助

@lemon0029
Copy link

是用的 jvm-sandbox v1.4.0 吗?我也遇到的同样的问题,排查发现 v1.3.3 是没有问题的,因为存在 BusinessClassLoaderHolder 的缘故,ModuleJarClassLoader 在加载不到类时会自动去通过 BusinessClassLoader 加载,不过这部分内容在 v1.4.0 中删除了...现在也没有什么好办法解决这个问题。

@fawen18
Copy link
Author

fawen18 commented Oct 17, 2023

是jvm-sandbox v1.4.0,不能使用宿主类编程特别不方便,现在只能使用反射来处理!!!

@lemon0029
Copy link

是jvm-sandbox v1.4.0,不能使用宿主类编程特别不方便,现在只能使用反射来处理!!!

模块中 AdviceListener 数量比较少还好哦,我们这几十上百个,都要这么改的话实在太麻烦了。打算实现一个 ClassLoader 然后再实现一个 EventListener 来包装现有的代码了,可行性感觉没问题,但是这样子相当于就是把 jvm-sandbox-api 再包了一层,非常怪异...折腾下来给我的感觉就是 jvm-sandbox 这个所谓的 “小版本” 升级真不靠谱,明明 1.3.3 还好好的,升级到 1.4.0 就不行了,但是不升级吧,现在已经遇到了性能瓶颈,测试 1.4.0 又能提升 50% 左右到性能,不升级也说不过去...

@Aresxue
Copy link

Aresxue commented Oct 23, 2023

盲猜一下估计是为了实现比较严谨的类加载器隔离,像淘宝的Pandora那样,不隔离的后果到后期真的会很坑爹。但是这一点该在release note中提一下,可以扩展下AdviceListener——自己找到类加载器然后swap一下。

@z529192557
Copy link
Collaborator

BusinessClassLoaderHolder 的设计是不够严谨的,只能解决部分类加载关系比较简单的场景

@z529192557
Copy link
Collaborator

如果 BusinessClassLoaderHolder 对各位的帮助确实很大,可以拉个分支,把1.3.3版本之前 BusinessClassLoaderHolder 的逻辑重新合并回去,打一个适应自己业务的sandbox包

@oldmanpushcart
Copy link
Collaborator

纠结啊,要不要保留BusinessClassLoaderHolder呢,好纠结啊啊啊。但如果有,真的会出非常不可预期的Cast异常。不严谨。
@z529192557 我也想在主干上继续保留这个功能,但必须更精简、更可控。

@z529192557
Copy link
Collaborator

z529192557 commented Jun 17, 2024

纠结啊,要不要保留BusinessClassLoaderHolder呢,好纠结啊啊啊。但如果有,真的会出非常不可预期的Cast异常。不严谨。 @z529192557 我也想在主干上继续保留这个功能,但必须更精简、更可控。

@oldmanpushcart
要不然在1.4.1中折中保留吧,默认不开启,在properties中提供开关来帮助大家开启这个小小的特性,在完美方案想好之前过度一下?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants