VerifyError

Bekommt man nicht alle Tage zu sehen, da habe ich wohl den Kotlin-Compiler überfordert…

2018-11-19 22:49:37 [offers-consumer] runir.server.game.OffersConsumer.run()
ERROR: java.lang.VerifyError: Illegal type at constant pool entry 76 in class runir.server.game.GameConductor$gameStarted$$inlined$schedule$1
Exception Details:
  Location:
    runir/server/game/GameConductor$gameStarted$$inlined$schedule$1.run()V @93: invokestatic
  Reason:
    Constant pool index 76 is invalid
  Bytecode:
    0x0000000: 2ac0 0004 4c2a b400 0fb6 001b b600 214d
    0x0000010: 2cc1 0023 9900 b02c c000 23b2 0029 b600
    0x0000020: 2db9 0033 0100 3e2c c000 23b2 0036 b600
    0x0000030: 2db9 0033 0100 3604 1db8 003c 1504 b800
    0x0000040: 3cb8 0042 3a05 1905 03b8 003c 03b8 003c
    0x0000050: b800 42b8 0048 9900 192a b400 0fb8 004c
    0x0000060: 5912 4eb8 0052 b200 58b6 005c a700 5819
    0x0000070: 0504 b800 3c03 b800 3cb8 0042 b800 4899
    0x0000080: 001c 2ab4 000f b200 29b8 0060 5912 62b8
    0x0000090: 0052 b200 58b6 005c a700 2c19 0503 b800
    0x00000a0: 3c04 b800 3cb8 0042 b800 4899 0019 2ab4
    0x00000b0: 000f b200 36b8 0060 5912 64b8 0052 b200
    0x00000c0: 58b6 005c 00b1                         
  Stackmap Table:
    full_frame(@111,{Object[#2],Object[#4],Object[#111],Integer,Integer,Object[#113]},{})
    same_frame(@155)
    chop_frame(@196,3)

Keine Idee, wie ich da rangehe, also rumfriemeln bis es geht :stuck_out_tongue:

Code or it didn’t happen :stuck_out_tongue:

Hier ist die Klasse, der Thread in init verursacht den Crash:

package runir.server.game

import io.vavr.kotlin.option
import org.pmw.tinylog.Logger
import runir.model.gson
import runir.server.game.opponent.BotOpponent
import runir.server.game.opponent.HeinzBot
import runir.server.game.opponent.KlausBot
import runir.server.user.User
import java.util.concurrent.ConcurrentLinkedDeque
import java.util.function.Predicate
import io.vavr.collection.List as VList

object OffersConsumer {

    val bots: VList<BotOpponent> = VList.of(HeinzBot, KlausBot)

    private val ops = ConcurrentLinkedDeque<Ops>()

    private val offers = ConcurrentLinkedDeque<Offer>().apply {
        addAll(bots.map(::BotOffer))
    }

    init {
        Thread {
            Logger.info("Starting offers consumer thread")
            while (true) {
                try {
                    while (!ops.isEmpty()) {
                        val op = ops.pop()
                        when (op) {
                            is Ops.Remove -> offers.removeIf(op.test::test)
                            is Ops.MatchOrAdd -> matchOrAddOp(op)
                        }
                    }
                } catch (ex: Throwable) {
                    Logger.error(ex)
                }
                Thread.sleep(50)
            }
        }.start()
    }

    private fun matchOrAddOp(op: Ops.MatchOrAdd) {
        offers
                .firstOrNull {
                    it.matches(op.offer)
                }.option()
                .peek { storedOffer ->
                    val storedOpponent = storedOffer.opponent()
                    val incomingOpponent = op.offer.opponent()
                    if (!storedOffer.canPlayMany()) {
                        offers.remove(storedOffer)
                    }
                    GameConductor(storedOpponent, incomingOpponent)
                }.onEmpty {
                    if (op.offer is MatchOffer) {
                        offers.add(op.offer)
                    }
                }
    }

    sealed class Ops {
        data class Remove(val test: Predicate<Offer>) : Ops()
        data class MatchOrAdd(val offer: Offer) : Ops()
    }

    fun remove(user: User) {
        ops.push(Ops.Remove(Predicate { it is MatchOffer && it.user == user }))
    }

    fun matchOrAdd(offer: Offer) {
        ops.push(Ops.MatchOrAdd(offer))
    }

}

Aber ich werde meine Strategie sowieso mal überdenken müssen - zu viele Threads.

Der generierte ByteCode scheint erst einmal kaputt zu sein.