当前位置:   article > 正文

类加载机制与JVM -Xverify参数关系_-xverify:none

-xverify:none

问题引申

使用javassist 动态生成了一个类,通过IDEA运行没有任何问题,但是通过IDEA JUnit运行则报VerifyError异常。

案发现场

代码如下:

  1. //模拟代码0
  2. public interface SharpHelper {
  3. Object run(String group, String name,int timeout, Callable callable);
  4. Object run(String group,int timeout,Callable callable);
  5. }
  6. //模拟代码1
  7. public interface AppleService {
  8. String get(String value);
  9. }
  10. //模拟代码2
  11. public class C1 implements Callable{
  12. private AppleService target;
  13. public Object call() throws Exception {
  14. java.lang.String result = null;
  15. result = target.get(this.args0);
  16. return result;
  17. }
  18. public void setTarget(AppleService target) {
  19. this.target = target;
  20. }
  21. public void setParam(java.lang.String args0) {
  22. this.args0 = args0;
  23. }
  24. }
  25. //模拟代码3
  26. public class C2 implements AppleService {
  27. private AppleService target;
  28. @Autowired
  29. private SharpHelper sharp;
  30. public java.lang.String get(String args0){
  31. try {
  32. C1 callable = new C1();
  33. callable.setTarget(this.target);
  34. callable.setParam(args0);
  35. //return (java.lang.String)sharp.run("goods","",10000,callable);
  36. //在使用 javassist 3.27.0-GA 编译可以通过,并且正常运行,当然这样的代码是不对的
  37. //但是也正常运行了,
  38. return sharp.run("goods","",10000,callable);
  39. } catch (Exception e) {
  40. throw e;
  41. }
  42. }
  43. }

但是使用JUnit运行,则无法启动,提示VerifyError异常。

通过类加载机制,原因是触发了类加载机制中的校验 原文链接:类加载机制-深入理解jvm - 简书,错误的源代码无法校验通过。 原文链接:类加载机制-深入理解jvm - 简书

图片来自原文内

  

通过查阅IDEA 启动项目后的JVM参数(通过jdk工具 jps)

执行命令:jps -v

16580 ProductApplication

-XX:TieredStopAtLevel=1

-Xverify:none

-Dspring.output.ansi.enabled=always

-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2021.1.3\lib\idea_rt.jar=49400:C:\P
rogram Files\JetBrains\IntelliJ IDEA 2021.1.3\bin

-Dcom.sun.management.jmxremote

-Dspring.jmx.enabled=true

-Dspring.liveBeansView.mbeanDomain

-Dspring.application.admin.enabled=true

-Dfile.encoding=UTF-8

参数释义

-Xverify[:<option>]

如果不使用任何参数,那么将启用验证器,这是缺省值。 因此,如果单独使用而不带任何参数,如 -Xverify,那么此选项将不执行任何操作。可选参数如下所示:

  • all - 启用最完整的验证
  • none - 禁用验证器
  • remote - 对远程装入的类启用严格的类装入检查

缺省情况下,验证器处于开启状态,必须针对所有生产服务器启用验证器。不支持在关闭验证器的情况下运行。 如果遇到问题,并且使用 -Xverify:none 关闭了验证器,那么请除去此选项并尝试重现问题。

查阅JUnit下的JVM 参数

5840 JUnitStarter

-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:50452,suspend=y,server=n

-ea

-Didea.test.cyclic.buffer.size=1048576

-javaagent:C:\Users\jiangj\AppData\Local\JetBra
ins\IntelliJIdea2021.1\captureAgent\debugger-agent.jar

-Dfile.encoding=UTF-8 

没有发现-Xverify参数的定义,那么默认将启用检验,所以错误的源代码无法运行,会抛出VerifyError异常。

解决方案

1.Junit 下增加 JVM 参数 -noverify(强烈建议加最后) 关闭类的校验

2.书写正确的源代码(这个坑其实是BUG产生的)

疑惑

为什么错误的源代码在-Xverify:none下依然可以运行?

本人猜测:因为java关闭了类的校验,所以代码不严谨(例如类型不严谨)的问题就被略去了,JAVA本身实现一些特性靠的就是剑走偏锋(例如泛型)。只要运行时是能过关的,很多问题人们可能就也不会去追究了。

之前本人还遇到过,声明的变量为List<Student> 的集合。内部实际装载的是List<JSONObject>

运行也没问题,因为泛型擦除后所有List 内部都是Object。

当然这样的异常效果都是运行时才能得到(通过javassist骚操作),这个例子似乎好像可以解释,为什么源代码都有误,但是不影响运行,姑且这样信下去,直到有一天,产生新的认知。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/一键难忘520/article/detail/941236
推荐阅读
相关标签
  

闽ICP备14008679号