#kotlin #plugins #jar #runtime #classloader
#котлин #Плагины #jar #время выполнения #загрузчик классов
Вопрос:
У меня есть foo.jar
то, что содержит Foo
:
class Foo: Bar { ... }
bar.jar
который содержит Бар:
abstract class Bar { ... }
Тогда у меня есть baz.jar
то, что загружается Foo
динамически:
val jarFile = JarFile("./foo.jar")
val e: Enumeration<JarEntry> = jarFile.entries()
val urls = arrayOf(URL("jar:file:foo.jar!/"))
val cl = URLClassLoader.newInstance(urls)
Thread.currentThread().contextClassLoader = cl // With or without same result.
val list = mutableListOf<Class<*>>()
while (e.hasMoreElements()) {
val je: JarEntry = e.nextElement()
...
cl.loadClass(className)
И запустите его следующим образом:
java -cp ./bar.jar -jar ./baz.jar
Во-первых, меня смущает, что я получаю «ClassNotFoundException», хотя bar.jar
он находится в пути к классу.
Я решаю эту проблему, загружая динамически ./bar.jar
, ./foo.jar
как в приведенном выше коде.
Тогда теперь я получаю NoClassDefFoundError: kotlin/jvm/internal/markers/KMappedMarker
Среда выполнения kotlin уже упакована в foo.jar
.
jar -xvf foo/build/libs/foo-1.0.jar | grep std
extracted: BOOT-INF/lib/kotlin-stdlib-1.4.10.jar
Я также создал fat-jar для bar.jar
so, чтобы он содержал kotlin-stdlib
и kotlin-reflect
, но я все еще получаю ту же ошибку.
Кто-нибудь может объяснить мне, что происходит?
Ответ №1:
Для всех, кому интересно, я, наконец, заставляю его работать, изменив:
val cl = URLClassLoader.newInstance(urls)
для этого:
val cl = URLClassLoader.newInstance(urls, this::class.java.classLoader)
Нет необходимости в fat-jar или дополнительных -cp
опциях.