Я не использую Undertow, но я использую Weld SE в настройке сервлета на Jetty и столкнулся с той же проблемой, что и вы, похоже. Мне посчастливилось исключить kotlin-пакеты из сканирования обнаружения бина в моем beans.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="all"
version="1.1">
<scan>
...
<exclude name="kotlin.**" />
<exclude name="kotlinx.**" />
</scan>
</beans>
Я попытался отладить проблему, и для меня java.lang.InternalError: Malformed class name
произошел от Java Class.getSimpleBinaryName
, вызванного на некоторой лямбде в теле kotlin.coroutines.CoroutineContext.plus
, названном kotlin.coroutines.CoroutineContext$plus$1
, который, очевидно, имеет включающий класс kotlin.coroutines.CoroutineContext$DefaultImpls
, который на 6 символов длиннее, чем имя класса лямбда, вызывая IndexOutOfBoundsException
при попытке подстановки лямбда-имени в длину с именем включающего класса, чтобы получить простое имя лямбда-выражения. Это можно рассматривать как ошибку в том, как Котлин называет / печатает лямбды. Наименьший по отношению к отражению.
Я также попытался воспроизвести проблему, создав этот интерфейс:
interface Foo {
fun fooBar(operation: (Foo) -> Foo): Foo
fun plus(foo: Foo): Foo = fooBar { f -> f.plus(f) }
}
И это вызывает ту же проблему (с или без operator
до fun
). Создание Foo
класса и реализация fooBar
устраняет проблему. Не знаю почему.
Использование, например, let
в теле Foo.plus
не вызвало никаких проблем. Вероятно, потому что let
встроено. Так что, если вы можете избежать использования не встроенных лямбд в телах интерфейсных функций, вы можете быть в порядке. И вы всегда можете поместить интерфейс, вызывающий проблемы, в отдельный пакет и исключить его из сканирования, если вы не собираетесь его внедрять. Надеюсь, эта проблема не получила широкого распространения.
Надеюсь, это помогло, несмотря на то, что он не был ответом для Undertow!
РЕДАКТИРОВАТЬ: Вы можете добавить аннотацию @JvmDefault
(https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-jvm-default/index.html)) к реализованной функции в интерфейсе для создания байт-кода, совместимого с методом по умолчанию (функция Java 8), и, следовательно, устранить проблему описано выше. Обратите внимание, что затем вам нужно указать аргумент компилятора -Xjvm-default=enable
или -Xjvm-default=compatibility
. В этой статье больше информации о @JvmDefault
будет рассказано: https://realjenius.com/2018/06/29/jvm-default/.