Сбой Akka Actors, VerifyError: несогласованные кадры карты стека в целевой ветви

У меня есть приложение Java, в котором я использую Akka типизированные актеры. В коде нет ошибок в Eclipse, но когда я запускаю приложение, оно вылетает и печатает эту ошибку:

Exception in thread "main" java.lang.VerifyError: Inconsistent stackmap frames at branch target 266 in method com.example.actors.DBActor.getItems(Lorg/joda/time/DateTime;Lorg/joda/time/DateTime;)I at offset 170
    at com.example.ui.Main$1.create(Main.java:31)
    at akka.actor.TypedActor$$anonfun$newInstance$3.apply(TypedActor.scala:677)
    at akka.actor.TypedActor$$anonfun$newInstance$3.apply(TypedActor.scala:677)
    at akka.actor.TypedActor$.newTypedActor(TypedActor.scala:847)
    at akka.actor.TypedActor$$anonfun$newInstance$1.apply(TypedActor.scala:601)
    at akka.actor.TypedActor$$anonfun$newInstance$1.apply(TypedActor.scala:601)
    at akka.actor.LocalActorRef.akka$actor$LocalActorRef$$newActor(ActorRef.scala:1084)
    at akka.actor.LocalActorRef$$anonfun$2.apply(ActorRef.scala:628)
    at akka.actor.LocalActorRef$$anonfun$2.apply(ActorRef.scala:628)
    at akka.util.ReentrantGuard.withGuard(LockUtil.scala:20)
    at akka.actor.LocalActorRef.<init>(ActorRef.scala:628)
    at akka.actor.Actor$.actorOf(Actor.scala:249)
    at akka.actor.TypedActor$.newInstance(TypedActor.scala:677)
    at akka.actor.TypedActor.newInstance(TypedActor.scala)
    at com.example.ui.Main.main(Main.java:29)

Я не понимаю, что может быть не так. Я проверил свой com.example.actors.DBActor.getItems(), но в нем нет ошибки. Что может быть не так?


ОБНОВЛЕНИЕ

Ниже приведен пример кода, в котором я получаю эту ошибку. У меня есть эти jar-файлы на «Пути сборки» в Eclipse:

  • derby.jar (из JDK7) (в этом примере используется только база данных в памяти)
  • akka-actor-1.2.jar
  • akka-typed-actor-1.2.jar
  • aspectwerkz-2.2.3.jar
  • scala-library.jar

Вот код:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import akka.actor.TypedActor;
import akka.actor.TypedActorFactory;


public class App {

    public App() {
        TypedActor.newInstance(Backend.class, new TypedActorFactory() {
            public TypedActor create() {
                return new DataActor();
            }
        });
    }

    class DataActor extends TypedActor implements Backend {

        @Override
        public void insertData(String msg) {
            final String sqlSelect = "SELECT msg FROM SESSION.messages "+
                                     "WHERE to_user_id = ? AND from_user_id = ?";
            final String connectionURL = "jdbc:derby:memory:memdatabase;create=true";

            /* if this declaration is moved to where the string is used 
               in the conditional, the conditional can be used */
            String result;

            try(Connection conn = DriverManager.getConnection(connectionURL);) {

                try(PreparedStatement ps = conn.prepareStatement(sqlSelect);
                    ResultSet rs = new QueryHelper(ps)
                                    .integer(13).integer(26).executeQuery();) {

                    /* this doesn't work */

                    result = (rs.next()) ? rs.getString("text")
                                         : null;

                    /* but this work:

                     String result = (rs.next()) ? rs.getString("text")
                                                 : null;
                     */

                    /* this works fine 

                    while(rs.next()) {
                        result = rs.getString("msg");
                    }                                   */
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    class QueryHelper {
        private final PreparedStatement ps;
        private int index = 1;

        public QueryHelper(PreparedStatement ps) {
            this.ps = ps;
        }

        public QueryHelper integer(int param) throws SQLException {
            ps.setInt(index++, param);
            return this;
        }

        public ResultSet executeQuery() throws SQLException {
            return ps.executeQuery();
        }
    }

    public interface Backend {
        public void insertData(String text);
    }

    public static void main(String[] args) {
        new App();
    }
}

person Jonas    schedule 10.11.2011    source источник
comment
Это может произойти, когда код, сгенерированный байтовым кодом, построен неправильно. Я бы попробовал более раннюю версию (или более позднюю версию)   -  person Peter Lawrey    schedule 10.11.2011
comment
@Peter: Раньше у меня была более ранняя версия, но я получил ту же ошибку, но другим методом.   -  person Jonas    schedule 10.11.2011
comment
TypedActors в Akka ‹ 2.0 использует плетение байт-кода AspektWerkz, я понятия не имею, что может быть причиной вашей проблемы, но если вы сможете свести к минимуму проблему и отправить заявку, кто-нибудь может взглянуть на нее.   -  person Viktor Klang    schedule 10.11.2011
comment
@ViktorKlang: Может быть, я использую Java 7? Я постараюсь создать минимальную программу.   -  person Jonas    schedule 10.11.2011
comment
Я видел ошибку с другим усилителем/модификациями байт-кода при работе на Java 7. Решение заключалось в том, чтобы явно скомпилировать код для Java 6: -target 1.6 в javac.   -  person Gamlor    schedule 11.11.2011
comment
@ViktorKlang: я минимизировал проблему и опубликовал код сейчас. Я посмотрю, как я могу отправить билет сейчас.   -  person Jonas    schedule 11.11.2011
comment
попробуйте параметр jvm -XX:-UseSplitVerifier. у меня была та же ошибка, и это помогло (хотя и с совершенно другим фрагментом кода)   -  person awx    schedule 17.11.2011


Ответы (2)


Я обнаружил, что эта ошибка возникает в тех местах, где я использую несколько ресурсов в одном операторе try-with-resources Java 7.

Например. этот код будет иметь ошибку:

try (Connection conn = DriverManager.getConnection(connURL);
     PreparedStatement ps = conn.prepareStatement(sql);) {

    // do something

} catch (SQLException e) {
    e.printStackTrace();
}

и обходной путь будет выглядеть так:

try (Connection conn = DriverManager.getConnection(connURL);) {
    try (PreparedStatement ps = conn.prepareStatement(sql);) {

        // do something

    }
} catch (SQLException e) {
    e.printStackTrace();
}
person Jonas    schedule 11.11.2011
comment
Я никогда не видел try с параметрами () - person ZiglioUK; 18.10.2013

запустить java с параметром -XX:-UseSplitVerifier

person Alejadro Xalabarder    schedule 21.09.2014
comment
Предупреждение виртуальной машины 64-разрядного сервера OpenJDK: игнорирование параметра UseSplitVerifier; поддержка была удалена в 8.0 - person Paul Draper; 06.08.2015