alibaba / jvm-sandbox

Real - time non-invasive AOP framework container based on JVM
GNU Lesser General Public License v3.0
6.77k stars 1.56k forks source link

JDK >= 9的环境中,ClassStructureImplByAsm.getResourceAsStream会返回null #385

Closed DayJun closed 1 year ago

DayJun commented 1 year ago

原代码:

private InputStream getResourceAsStream(final String resourceName) {
        return isBootstrapClassLoader()
                ? Object.class.getResourceAsStream("/" + resourceName)
                : loader.getResourceAsStream(resourceName);
    }

    private ClassStructure newInstance(final String javaClassName) {
        ......
        final InputStream is = getResourceAsStream(internalClassNameToResourceName(SandboxStringUtils.toInternalClassName(javaClassName)));
        ......
    }

在JDK 》= 9的情况下,java自己的基础类并不是全部位于同一个包内,而是分为了java.base、java.desktop等好多个模块。使用java.base中的Object.class是无法得到java.desktop等其他模块中类的Resource的URL的。

修改方法:

private InputStream getResourceAsStream(final String javaClassName) {
        final String resourceName = internalClassNameToResourceName(SandboxStringUtils.toInternalClassName(javaClassName));
        InputStream ins = null;
        if(isBootstrapClassLoader()) {
            try {
                Class<?> clz = Class.forName(javaClassName, false, null);
                ins = clz.getResourceAsStream("/" + resourceName);
            } catch (ClassNotFoundException e) {
                // pass
            }
        } else {
            ins = loader.getResourceAsStream(resourceName);
        }
        return ins;
    }

    private ClassStructure newInstance(final String javaClassName) {
        ......
        final InputStream is = getResourceAsStream(SandboxStringUtils.toJavaClassName(javaClassName));
        ......
    }

如果是BootStrapClassLoader加载的类,就先获取到这个类,然后用这个类取get自己的resource

另外,如果getResourceAsStream返回null,会导致UnsupportedMatcher中的isJavaMainBehavior抛出空指针异常

原代码:

    private boolean isJavaMainBehavior(final BehaviorStructure behaviorStructure) {
        final Access access = behaviorStructure.getAccess();
        final List<ClassStructure> parameterTypeClassStructures = behaviorStructure.getParameterTypeClassStructures();
        return access.isPublic()
                && access.isStatic()
                && "void".equals(behaviorStructure.getReturnTypeClassStructure().getJavaClassName())
                && "main".equals(behaviorStructure.getName())
                && parameterTypeClassStructures.size() == 1
                && "java.lang.String[]".equals(parameterTypeClassStructures.get(0).getJavaClassName());
    }

修改后:

    private boolean isJavaMainBehavior(final BehaviorStructure behaviorStructure) {
        final Access access = behaviorStructure.getAccess();
        final List<ClassStructure> parameterTypeClassStructures = behaviorStructure.getParameterTypeClassStructures();
        return access.isPublic() && null != behaviorStructure.getReturnTypeClassStructure()
                && access.isStatic()
                && "void".equals(behaviorStructure.getReturnTypeClassStructure().getJavaClassName())
                && "main".equals(behaviorStructure.getName())
                && parameterTypeClassStructures.size() == 1
                && "java.lang.String[]".equals(parameterTypeClassStructures.get(0).getJavaClassName());
    }

添加一个null != behaviorStructure.getReturnTypeClassStructure()的检测会比较好

oldmanpushcart commented 1 year ago

嗯嗯,能否提交一个pull-request到develop-for-20220822的分支上来呢,这样能统计到你的贡献度。我每次copy你的代码过意不去

DayJun commented 1 year ago

嗯嗯,能否提交一个pull-request到develop-for-20220822的分支上来呢,这样能统计到你的贡献度。我每次copy你的代码过意不去

ok,随后我提交一下

oldmanpushcart commented 1 year ago

1.4.0已发布,多谢PR