java.lang.NoClassDefFoundError-javassist

时间:2018-07-07 23:17:09

标签: java instrumentation javassist

我正在对类路径中的所有类执行检测。这也包括JDK类。

如果我对我的班级(例如,HelloWorld)进行检测,则仪器代码会很好地工作。除此之外,我还会收到以下难看的错误。

  

java.lang.NoClassDefFoundError    -klass:“ java / lang / NoClassDefFoundError”

     

Java运行时环境检测到致命错误:

     

内部错误(exceptions.cpp:427),pid = 35008,tid = 0x00007f8db6892700    致命错误:ExceptionMark析构函数不希望有任何待处理的异常

     

JRE版本:Java(TM)SE运行时环境(8.0_171-b11)(内部版本1.8.0_171-b11)   Java虚拟机:Java HotSpot(TM)64位服务器虚拟机(25.171-b11混合模式linux-amd64压缩的oops)   无法写入核心转储。核心转储已被禁用。要启用核心转储,请在再次启动Java之前尝试“ ulimit -c unlimited”

     

包含更多信息的错误报告文件另存为:   /home/user/yield_instrumentation/hs_err_pid35008.log

     

如果您要提交错误报告,请访问:     http://bugreport.java.com/bugreport/crash.jsp   ./run_agent.sh:第1行:35008中止了java -javaagent:yield_point.jar HelloWorld

错误日志文件包含以下内容:

  

----------------- T H R E A D ---------------

     

当前线程(0x00007f578c00b000):JavaThread“ main”   [_thread_in_vm,id = 34854,   堆栈(0x00007f5794434000,0x00007f5794535000)]

     

堆栈:[0x00007f5794434000,0x00007f5794535000],   sp = 0x00007f5794533a00,可用空间= 1022k本机帧:(J =已编译   Java代码,j =解释后的代码,Vv = VM代码,C =本机代码)V   [libjvm.so + 0xacfffa] VMError :: report_and_die()+ 0x2ba V   [libjvm.so + 0x500189] report_fatal(char const *,int,char const *)+ 0x59   V [libjvm.so + 0x582bd0] ExceptionMark ::〜ExceptionMark()+ 0xb0 V   [libjvm.so + 0xa7cea6]线程:: create_vm(JavaVMInitArgs *,bool *)+ 0x396   V [libjvm.so + 0x6d6e44] JNI_CreateJavaVM + 0x74 C [libjli.so + 0x797e]   JavaMain + 0x9e C [libpthread.so.0 + 0x7494] start_thread + 0xc4

     

--------------- P R O C E S S S ---------------

     

Java线程:(=>当前线程)0x00007f578c4de000 JavaThread   “ C1 CompilerThread14”守护程序[_thread_blocked,id = 34901,   堆栈(0x00007f574b6f7000,0x00007f574b7f8000)] 0x00007f578c4dc000   JavaThread“ C1 CompilerThread13”守护程序[_thread_blocked,id = 34900,   堆栈(0x00007f574b7f8000,0x00007f574b8f9000)] 0x00007f578c4da000   JavaThread“ C1 CompilerThread12”守护程序[_thread_blocked,id = 34899,   stack(0x00007f574b8f9000,0x00007f574b9fa000)]“ hs_err_pid34853.log”   1609L,80820C

下面是我的检测代码

public byte[] transform(ClassLoader loader, String className,
        Class classBeingRedefined, ProtectionDomain protectionDomain,
        byte[] classfileBuffer) throws IllegalClassFormatException {

    byte[] byteCode = classfileBuffer;

    try {
        ClassPool classPool = ClassPool.getDefault();
            CtClass ctClass = classPool.makeClass(new ByteArrayInputStream(classfileBuffer));
        CtClass greeting_ct = classPool.get("whatever.GreetingFactory");

        /*if(!ctClass.getSimpleName().equalsIgnoreCase("HelloWorld")) {
            return byteCode; 
        }*/

        //The below returns all methods including constructors
        CtBehavior[] all_methods =  ctClass.getDeclaredBehaviors();
        for (CtBehavior method : all_methods) {
            MethodInfo methodInfo = method.getMethodInfo();
            CodeAttribute code = methodInfo.getCodeAttribute();
            CodeIterator instruction_iterator = code.iterator();                    
            int instruction_loc=0;          
            Bytecode invoke_hi = new Bytecode(methodInfo.getConstPool());
            invoke_hi.addInvokestatic(greeting_ct,"hello", void_non());
            int pos = instruction_iterator.insertEx(invoke_hi.get());
            instruction_iterator.insert(code.getExceptionTable(), pos);             
        }

    ctClass.detatch(); //Without or without this statement ... result is the same
    return ctClass.toBytecode();    
    } catch (Throwable ex) {
        ex.printStackTrace();
    }

    return byteCode;
}

    public static String void_non() {
     String desc = Descriptor.ofMethod(CtClass.voidType, null);
     return desc;
}

1 个答案:

答案 0 :(得分:0)

这里是对该问题的详细解答。它与类加载器有关。在Java中,有多个类加载器,包括以下内容:

  1. 引导类加载器,用于加载所有与JDK相关的类。它具有某些路径来寻找到rt.jar的路径。

  2. Classpath类加载器,用于加载类路径中的所有内容。

在需要时在运行时解析类。我要注入的代码包含对JDK之外的其他代码的引用(由引导类加载器加载)。在运行时,JDK将要求引导类加载器加载类,而这些类当然没有。它们是由classpath类加载器加载的。

为解决此问题,Java允许添加其他路径,以由默认的类加载器加载。

java -Xbootclasspath / p:javassist.jar:whatever.jar