Exception in thread "main" java.lang.VerifyError: Bad type on operand stack Java 8 121 but not on Java 11

huangapple go评论87阅读模式
英文:

Exception in thread "main" java.lang.VerifyError: Bad type on operand stack Java 8 121 but not on Java 11

问题

我知道在Java 8 Build 75上进行了修复 https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8006684 ,我无法再Java 8-121上重新现有同样的问题,但此代码在Java 8-121上抛出异常,但在Java 11上不会。在哪个版本的JDK中解决了这个问题?

这段代码的一个示例在75之前的版本上会出现问题,但之后不会。

public static void main(String[] args) {
    xxx();
}
static void xxx() {
    Functional1 f  = () -> {
        Object o = new Object() { };
        return new A();
    };
}
static class A { }
static interface Functional1 { A func(); }

但我的代码在Java 8-121上抛出异常,但在Java 11上不会。

这段代码只是一个代表真实代码的示例,但仍然是单一的方式。

class Element{
    private final String data;
    public Element(final String data) {
        this.data = data;
    }    
    public String getData() {
        return data;
    }    
}

class Html{
    protected Element doSomething(final String data){
        return new Element(data);
    }
}

class A{
    protected final Html html = new Html();
}
class B extends A{}
class C extends B{}
class D extends C{}
class E extends D{}

public final class JavaBug extends E{
    private final List<SupplierElementWithMapper> data = Arrays.asList(new SupplierElementWithMapper(""));
    public static void main(String[] args)throws Exception{
        System.out.println("JavaVersion: "+System.getProperty("java.version"));
        final JavaBug clazz = new JavaBug();        
    }

    private final class SupplierElementWithMapper{
        private final Supplier<Element> supplier;
        private final Function<Element,String> mapper;
        private UnaryOperator<String> unaryOperator = UnaryOperator.identity();

        public SupplierElementWithMapper(final String selector) {
            this(()->html.doSomething(selector),Element::getData);
        }
        public SupplierElementWithMapper(final Supplier<Element> supplier,final Function<Element, String> mapper) {
            this.supplier = supplier;
            this.mapper = mapper;
        }

        private SupplierElementWithMapper addUnaryOperator(final UnaryOperator<String> unaryOperator){
            this.unaryOperator = unaryOperator;
            return this;
        }    
    }    
}

控制台输出:

JavaVersion: 1.8.0_121
Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
...

问题出现在供应商的这一行。

this(() -> html.doSomething(selector), Element::getData);

调用了一个受保护成员,我尝试过没有成功。

this(() -> { return html.doSomething(selector); }, Element::getData);
this(() -> JavaBug.super.html.doSomething(selector), Element::getData);
this(() -> getHtml().doSomething(selector), Element::getData); /*将GETTER添加到代码中*/

但这个可以工作。

this(() -> JavaBug.this.html.doSomething(selector), Element::getData);

我如何找到此修复是在哪个版本中进行的?我需要通知我的团队。

在IntelliJ IDEA的提示中,显示“源代码与字节码不匹配”。

在121版本上也有相同的问题 https://discuss.newrelic.com/t/verifyerror-bad-type-on-operand-stack/50700

我认为解决方法可能是这个。

https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8178444

完整的产品版本:

java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
javac 1.8.0_121

附加的操作系统版本信息:

OSX 10.12.4 (16E195)
16.5.0 Darwin Kernel Version 16.5.0: Fri Mar  3 16:52:33 PST 2017; root:xnu-3789.51.2~3/RELEASE_X86_64 x86_64
英文:

I know that a fix was made on Java 8 Build 75 https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8006684 and I cannot reproduce the same problem with the code that break on version before 75. But this code is throwing the exception on Java 8-121 but not on Java 11. In which version of the JDK was this problem solved?

A example this code was generating the problem on versions before 75 but not afterwards.

public static void main(String[] args) {
xxx();
}
static void xxx() {
Functional1 f  = () -&gt; {
Object o = new Object() { };
return new A();
};
}
static class A { }
static interface Functional1 { A func(); }

But my code is throwing the exception on Java 8-121 but not on Java 11.

The code is just a example of the real code to be able to represent it but still in a single way.

class Element{
private final String data;
public Element(final String data) {
this.data = data;
}    
public String getData() {
return data;
}    
}
class Html{
protected Element doSomething(final String data){
return new Element(data);
}
}
class A{
protected final Html html = new Html();
}
class B extends A{}
class C extends B{}
class D extends C{}
class E extends D{}
public final class JavaBug extends E{
private final List&lt;SupplierElementWithMapper&gt;data = Arrays.asList(new SupplierElementWithMapper(&quot;&quot;));
public static void main(String[] args)throws Exception{
System.out.println(&quot;JavaVersion: &quot;+System.getProperty(&quot;java.version&quot;));
final JavaBug clazz = new JavaBug();        
}
private final class SupplierElementWithMapper{
private final Supplier&lt;Element&gt; supplier;
private final Function&lt;Element,String&gt; mapper;
private UnaryOperator&lt;String&gt; unaryOperator = UnaryOperator.identity();
public SupplierElementWithMapper(final String selector) {
this(()-&gt;html.doSomething(selector),Element::getData);
}
public SupplierElementWithMapper(final Supplier&lt;Element&gt; supplier,final Function&lt;Element, String&gt; mapper) {
this.supplier = supplier;
this.mapper = mapper;
}
private SupplierElementWithMapper addUnaryOperator(final UnaryOperator&lt;String&gt;unaryOperator){
this.unaryOperator = unaryOperator;
return this;
}    
}    
}

The console

JavaVersion: 1.8.0_121
Exception in thread &quot;main&quot; java.lang.VerifyError: Bad type on operand stack
Exception Details:
Location:
projectname/issues/JavaBug$SupplierElementWithMapper.lambda$new$1(Ljava/lang/String;Lprojectname/issues/JavaBug;)Lprojectname/issues/Element; @1: getfield
Reason:
Type &#39;java/lang/String&#39; (current frame, stack[0]) is not assignable to &#39;projectname/issues/JavaBug$SupplierElementWithMapper&#39;
Current Frame:
bci: @1
flags: { }
locals: { &#39;java/lang/String&#39;, &#39;projectname/issues/JavaBug&#39; }
stack: { &#39;java/lang/String&#39; }
Bytecode:
0x0000000: 2ab4 0005 b400 102a b600 11b0          
at projectname.issues.JavaBug.&lt;init&gt;(JavaBug.java:34)
at projectname.issues.JavaBug.main(JavaBug.java:37)
C:\Users\JavIut\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53: Java returned: 1

The problem is this line in the supplier.

this(()-&gt;html.doSomething(selector),Element::getData);

Is calling a protected member i have try with no success.

this(()-&gt;{return html.doSomething(selector);},Element::getData);
this(()-&gt;JavaBug.super.html.doSomething(selector),Element::getData);
this(()-&gt;getHtml().doSomething(selector),Element::getData);/*ADDING IN THE CODE THE GETTER*/

But this works.

this(()-&gt;JavaBug.this.html.doSomething(selector),Element::getData);

How can I find in which version this fix was made? I need to inform into my team.

In the IntelliJ idea prompt states that Source code don't match bytecode

Same problem with 121 https://discuss.newrelic.com/t/verifyerror-bad-type-on-operand-stack/50700

I think the solution might be this.

https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8178444

FULL PRODUCT VERSION :
java version &quot;1.8.0_121&quot;
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
javac 1.8.0_121
ADDITIONAL OS VERSION INFORMATION :
OSX 10.12.4 (16E195)
16.5.0 Darwin Kernel Version 16.5.0: Fri Mar  3 16:52:33 PST 2017; root:xnu-3789.51.2~3/RELEASE_X86_64 x86_64
A DESCRIPTION OF THE PROBLEM :
See code snippet below.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the provided code.

答案1

得分: 1

你的问题是JDK-8184989的一个实例:

JDK-8129740的修复是不完整的。在外部类是子类且其超类的实体在lambda表达式中被引用的情况下,它会失败。

这个错误已经在“修复版本:10”中关闭,我确实可以在JDK-9.0.4中复现你的问题,但在JDK-10.0.2中却不能。

所提到的JDK-8129740是在这个问答中链接的错误报告,你已经通过评论回链到了它。

英文:

Your problem is an instance of JDK-8184989:

> The fix for <strike>JDK-8129740</strike> is incomplete. It fails on cases when outer class is a subclass and the entities of it's [sic] superclass are referred to in lambda expression.

This bug has been close with “Fix Version/s: 10” and I can indeed reproduce your problem with JDK-9.0.4 but not with JDK-10.0.2.

The referenced JDK-8129740 is the bug report linked in this Q&A you already backlinked via a comment.

huangapple
  • 本文由 发表于 2020年4月4日 07:37:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/61021950.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定