简体   繁体   English

java.lang.NoClassDefFoundError-javassist

[英]java.lang.NoClassDefFoundError - javassist

I am performing instrumentation on all classes in the class path. 我在类路径中的所有类上执行检测。 This includes the JDK classes as well. 这也包括JDK类。

Instrumentation code works very well if I instrument my class (HelloWorld for example). 如果我对我的类(例如,HelloWorld)进行检测,则检测代码的效果很好。 Other than that, I receive the below ugly error. 除此之外,我收到以下难看的错误。

java.lang.NoClassDefFoundError - klass: 'java/lang/NoClassDefFoundError' java.lang.NoClassDefFoundError-klass:'java / lang / NoClassDefFoundError'

A fatal error has been detected by the Java Runtime Environment: Java运行时环境检测到致命错误:

Internal Error (exceptions.cpp:427), pid=35008, tid=0x00007f8db6892700 fatal error: ExceptionMark destructor expects no pending exceptions 内部错误(exceptions.cpp:427),pid = 35008,tid = 0x00007f8db6892700致命错误:ExceptionMark析构函数不希望任何未决异常

JRE version: Java(TM) SE Runtime Environment (8.0_171-b11) (build 1.8.0_171-b11) Java VM: Java HotSpot(TM) 64-Bit Server VM (25.171-b11 mixed mode linux-amd64 compressed oops) Failed to write core dump. JRE版本:Java(TM)SE运行时环境(8.0_171-b11)(内部版本1.8.0_171-b11)Java VM:Java HotSpot(TM)64位服务器VM(25.171-b11混合模式linux-amd64压缩oops)失败写核心转储。 Core dumps have been disabled. 核心转储已被禁用。 To enable core dumping, try "ulimit -c unlimited" before starting Java again 要启用核心转储,请在再次启动Java之前尝试“ ulimit -c unlimited”

An error report file with more information is saved as: /home/user/yield_instrumentation/hs_err_pid35008.log 包含更多信息的错误报告文件将另存为:/home/user/yield_instrumentation/hs_err_pid35008.log

If you would like to submit a bug report, please visit: http://bugreport.java.com/bugreport/crash.jsp ./run_agent.sh: line 1: 35008 Aborted java -javaagent:yield_point.jar HelloWorld 如果您想提交错误报告,请访问: http ://bugreport.java.com/bugreport/crash.jsp ./run_agent.sh:第1行:35008中止了java -javaagent:yield_point.jar HelloWorld

The error log files contains the following: 错误日志文件包含以下内容:

--------------- THREAD --------------- ---------------线迹---------------

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

Stack: [0x00007f5794434000,0x00007f5794535000], sp=0x00007f5794533a00, free space=1022k Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) 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] Threads::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 堆栈:[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_ 0xc4

--------------- PROCESS --------------- ---------------过程---------------

Java Threads: ( => current thread ) 0x00007f578c4de000 JavaThread "C1 CompilerThread14" daemon [_thread_blocked, id=34901, stack(0x00007f574b6f7000,0x00007f574b7f8000)] 0x00007f578c4dc000 JavaThread "C1 CompilerThread13" daemon [_thread_blocked, id=34900, stack(0x00007f574b7f8000,0x00007f574b8f9000)] 0x00007f578c4da000 JavaThread "C1 CompilerThread12" daemon [_thread_blocked, id=34899, stack(0x00007f574b8f9000,0x00007f574b9fa000)] "hs_err_pid34853.log" 1609L, 80820C Java线程:(=>当前线程)0x00007f578c4de000 JavaThread“ C1 CompilerThread14”守护程序[_thread_blocked,id = 34901,stack(0x00007f574b6f7000,0x00007f574b7f8000)] 0x00007f578c4dc000Java0000“ 7xff7f7b,ed(0x00007f578b6f7000) ] 0x00007f578c4da000 JavaThread“ C1 CompilerThread12”守护程序[_thread_blocked,id = 34899,stack(0x00007f574b8f9000,0x00007f574b9fa000)]“ hs_err_pid34853.log” 1609L,80820C

Below is my instrumentation Code 以下是我的检测代码

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;
}

Here is little bit detailed answer to the question. 这里是问题的详细解答。 It is related to class loaders. 它与类加载器有关。 In Java, there multiple class loader including the following: 在Java中,有多个类加载器,包括以下内容:

  1. The boot class loader that loads all of the JDK related classes. 引导类加载器,用于加载所有与JDK相关的类。 It has certain paths to look for such the path to rt.jar. 它具有某些路径来寻找rt.jar的路径。

  2. Classpath class loader that loads everything in the class path. Classpath类加载器,用于加载类路径中的所有内容。

Classes are resolved at run-time when needed. 在需要时在运行时解析类。 The code I am injecting contains references to other code outside of the JDK (that is loaded by the boot class loader). 我要注入的代码包含对JDK之外的其他代码的引用(由引导类加载器加载)。 At runtime, JDK will ask the boot class loader to load classes, which of course does not have them. 在运行时,JDK将要求引导类加载器加载类,而这些类当然没有。 They are loaded by the classpath class loader. 它们由类路径类加载器加载。

To solve this, Java allows to add additional paths to be loaded by the default class loader. 为解决此问题,Java允许添加其他路径,以由默认类加载器加载。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM