偶然一天,运行eclipse单元测试,报错:
java.lang.IllegalStateException: Native library for Attach API not available in this JRE at mockit.internal.startup.JDK6AgentLoader.getVirtualMachineImplementationFromEmbeddedOnes(JDK6AgentLoader.java:81) at mockit.internal.startup.JDK6AgentLoader.loadAgent(JDK6AgentLoader.java:54) at mockit.internal.startup.AgentInitialization.initializeAccordingToJDKVersion(AgentInitialization.java:21) at mockit.internal.startup.Startup.initializeIfNeeded(Startup.java:208) java.lang.IllegalStateException: Native library for Attach API not available in this JRE at mockit.internal.startup.JDK6AgentLoader.getVirtualMachineImplementationFromEmbeddedOnes(JDK6AgentLoader.java:81) at mockit.internal.startup.JDK6AgentLoader.loadAgent(JDK6AgentLoader.java:54) at mockit.internal.startup.AgentInitialization.initializeAccordingToJDKVersion(AgentInitialization.java:21) at mockit.internal.startup.Startup.initializeIfNeeded(Startup.java:208)
重新跑单元测试,运行正常!问题解决;
这个出错有点奇怪,通过出错类,进行跟踪,发现最后的出错信息如下:
Class JDK6AgentLoader{ private VirtualMachine attachToThisVM() { try { return VirtualMachine.attach(pid); } catch (AttachNotSupportedException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } } private VirtualMachine getVirtualMachineImplementationFromEmbeddedOnes() { try { if (File.separatorChar == '\\') { return new WindowsVirtualMachine(ATTACH_PROVIDER, pid); } else { return new LinuxVirtualMachine(ATTACH_PROVIDER, pid); } } catch (AttachNotSupportedException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } catch (UnsatisfiedLinkError e) { throw new IllegalStateException("Native library for Attach API not available in this JRE", e); } }
通过文件路径判断是windwo,还是linux操作系统,从代码看catch并抛出异常的处理很常见;
WindowsVirtualMachine{ static /* */ { /* 167 */ System.loadLibrary("attach"); /* 168 */ init(); /* 169 */ stub = generateStub(); /* */ } }如果没有-javaagent,那么上面的代码就回出错,而这部分是虚拟机启动的装载初始化操作,所以javaagent设置的是虚拟机启动初始化类;
jmockit里面用到了jdk6.0的不少特性,jdk6.0的动态修改和装载还是挺强大的。