Исключение в потоке "main" java .lang.VerifyError: Неверный тип в стеке операндов Java 8 121, но не в Java 11 - PullRequest
2 голосов
/ 04 апреля 2020

Я знаю, что было исправлено Java 8 Build 75 https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8006684, и я не могу воспроизвести ту же проблему с кодом, который ломается в версии до 75 Но этот код вызывает исключение на 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
Exception Details:
  Location:
    projectname/issues/JavaBug$SupplierElementWithMapper.lambda$new$1(Ljava/lang/String;Lprojectname/issues/JavaBug;)Lprojectname/issues/Element; @1: getfield
  Reason:
    Type 'java/lang/String' (current frame, stack[0]) is not assignable to 'projectname/issues/JavaBug$SupplierElementWithMapper'
  Current Frame:
    bci: @1
    flags: { }
    locals: { 'java/lang/String', 'projectname/issues/JavaBug' }
    stack: { 'java/lang/String' }
  Bytecode:
    0x0000000: 2ab4 0005 b400 102a b600 11b0          

    at projectname.issues.JavaBug.<init>(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

Проблема заключается в этой строке в поставщике.

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);/*ADDING IN THE CODE THE 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

FULL PRODUCT VERSION :
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


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 голос
/ 06 апреля 2020

Ваша проблема - экземпляр JDK-8184989 :

Исправление для JDK-8129740 является неполным. Он не работает в тех случаях, когда внешний класс является подклассом, а сущности его [sic] суперкласса упоминаются в лямбда-выражении.

Эта ошибка была закрыта с помощью «Fix Version / s: 10» и Я действительно могу воспроизвести вашу проблему с JDK-9.0.4, но не с JDK-10.0.2.

Ссылочная JDK-8129740 - это сообщение об ошибке, связанное в в этих вопросах и ответах Вы уже перешли по ссылке через комментарий.

...