Skip to content

Commit 34683de

Browse files
committed
fix: native-image jit linkage errors in cli
- fix: missing `log4j` classes, via `slf4j` bridge - fix: allow conditional language inclusion in `cli` build - fix: drop JRT flag to `native-image` - fix: swap to `NONE` runtime for Micronaut - fix: missing `initialize-at-build-time` netty types - fix: missing Netty, NPN, ALPN dependencies - chore: ability to dynamically load/detect languages in cli Fixes and closes #394. Relates-To: oracle/graal#7110 Relates-To: micronaut-projects/micronaut-core#9664 Relates-To: #394 Signed-off-by: Sam Gammon <[email protected]>
1 parent 16614a4 commit 34683de

File tree

3 files changed

+65
-51
lines changed

3 files changed

+65
-51
lines changed

gradle/elide.versions.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ closure_stylesheets = "1.5.0"
6767
picocli = "4.7.5"
6868
picocli_jansi_graalvm = "1.2.0"
6969
slf4j = "2.0.9"
70-
slf4j_jul = "2.0.9"
7170
jakarta = "2.0.1"
7271
jakarta_persistence = "3.1.0"
7372
jakarta_annotation_api = "2.1.1"
@@ -367,7 +366,8 @@ picocli_jline3 = { group = "info.picocli", name = "picocli-shell-jline3", versio
367366
picocli_jansi_graalvm = { group = "info.picocli", name = "picocli-jansi-graalvm", version.ref = "picocli_jansi_graalvm" }
368367
slf4j = { group = "org.slf4j", name = "slf4j-api", version.ref = "slf4j" }
369368
slf4j_jdk14 = { group = "org.slf4j", name = "slf4j-jdk14", version.ref = "slf4j" }
370-
slf4j_jul = { group = "org.slf4j", name = "jul-to-slf4j", version.ref = "slf4j_jul" }
369+
slf4j_jul = { group = "org.slf4j", name = "jul-to-slf4j", version.ref = "slf4j" }
370+
slf4j_log4j_bridge = { group = "org.slf4j", name = "log4j-over-slf4j", version.ref = "slf4j" }
371371
jakarta_annotation_api = { group = "jakarta.annotation", name = "jakarta.annotation-api", version.ref = "jakarta_annotation_api" }
372372
jakarta_inject = { group = "jakarta.inject", name = "jakarta.inject-api", version.ref = "jakarta" }
373373
jakarta_persistence = { group = "jakarta.persistence", name = "jakarta.persistence-api", version.ref = "jakarta_persistence" }

packages/cli/build.gradle.kts

+55-42
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ val enableProguard = false
6767
val enableDashboard = false
6868
val encloseSdk = false
6969
val oracleGvm = false
70+
val enableEdge = true
7071

7172
buildscript {
7273
repositories {
@@ -83,7 +84,7 @@ buildscript {
8384
if (enableMosaic) apply(plugin = "com.jakewharton.mosaic")
8485

8586
val jvmCompileArgs = listOf(
86-
// "--enable-preview",
87+
"--enable-preview",
8788
"--add-exports=java.base/jdk.internal.module=elide.cli",
8889
"--add-exports=jdk.internal.vm.compiler/org.graalvm.compiler.options=elide.cli",
8990
"--add-exports=jdk.internal.vm.compiler/org.graalvm.compiler.options=ALL-UNNAMED",
@@ -147,8 +148,8 @@ kotlin {
147148
}
148149

149150
// use consistent compose plugin version
150-
//the<com.jakewharton.mosaic.gradle.MosaicExtension>().kotlinCompilerPlugin =
151-
// libs.versions.compose.get()
151+
the<com.jakewharton.mosaic.gradle.MosaicExtension>().kotlinCompilerPlugin =
152+
libs.versions.compose.get()
152153

153154
kapt {
154155
useBuildCache = true
@@ -188,17 +189,19 @@ dependencies {
188189

189190
// GraalVM: Engines
190191
implementation(projects.packages.graalvm)
191-
implementation(projects.packages.graalvmJvm)
192-
implementation(projects.packages.graalvmLlvm)
193-
implementation(projects.packages.graalvmPy)
194-
implementation(projects.packages.graalvmRb)
195-
implementation(projects.packages.graalvmKt)
196-
implementation(projects.packages.graalvmWasm)
192+
if (enableEspresso) implementation(projects.packages.graalvmJvm)
193+
if (enableLlvm) implementation(projects.packages.graalvmLlvm)
194+
if (enablePython) implementation(projects.packages.graalvmPy)
195+
if (enableRuby) implementation(projects.packages.graalvmRb)
196+
if (enableEspresso) implementation(projects.packages.graalvmKt)
197+
if (enableWasm) implementation(projects.packages.graalvmWasm)
197198

198199
api(libs.picocli)
200+
api(libs.slf4j)
201+
api(libs.slf4j.jul)
202+
api(libs.slf4j.log4j.bridge)
203+
199204
implementation(libs.picocli.jansi.graalvm)
200-
implementation(libs.slf4j)
201-
implementation(libs.slf4j.jul)
202205
implementation(libs.jline.reader)
203206
implementation(libs.jline.console)
204207
implementation(libs.jline.terminal.core)
@@ -212,6 +215,18 @@ dependencies {
212215

213216
api(mn.micronaut.inject)
214217
implementation(mn.micronaut.picocli)
218+
implementation(mn.micronaut.http)
219+
implementation(mn.micronaut.http.netty)
220+
implementation(mn.micronaut.http.client)
221+
implementation(mn.micronaut.http.server)
222+
implementation(mn.netty.handler)
223+
implementation(mn.netty.handler.proxy)
224+
implementation(mn.netty.codec.http)
225+
implementation(mn.netty.codec.http2)
226+
implementation(mn.netty.buffer)
227+
implementation(mn.netty.incubator.codec.http3)
228+
implementation(mn.micronaut.websocket)
229+
215230
runtimeOnly(mn.micronaut.context)
216231
runtimeOnly(mn.micronaut.kotlin.runtime)
217232

@@ -220,6 +235,10 @@ dependencies {
220235
runtimeOnly(projects.packages.proto.protoKotlinx)
221236

222237
runtimeOnly(mn.micronaut.graal)
238+
implementation("org.eclipse.jetty.npn:npn-api:8.1.2.v20120308")
239+
implementation("org.eclipse.jetty.alpn:alpn-api:1.1.3.v20160715")
240+
241+
implementation(libs.netty.tcnative)
223242

224243
val arch = when (System.getProperty("os.arch")) {
225244
"amd64", "x86_64" -> "x86_64"
@@ -235,10 +254,9 @@ dependencies {
235254
when {
236255
Os.isFamily(Os.FAMILY_MAC) -> {
237256
implementation(libs.netty.transport.native.kqueue)
238-
implementation(libs.netty.transport.native.kqueue)
239-
implementation(variantOf(libs.netty.transport.native.kqueue) { classifier("osx-$arch") })
240257
implementation(variantOf(libs.netty.transport.native.kqueue) { classifier("osx-$arch") })
241258
implementation(libs.netty.resolver.dns.native.macos)
259+
implementation(variantOf(libs.netty.tcnative.boringssl.static) { classifier("osx-$arch") })
242260
}
243261

244262
else -> {
@@ -443,15 +461,16 @@ val commonNativeArgs = listOf(
443461
"--language:icu4j",
444462
"--language:regex",
445463
"--no-fallback",
446-
// "--enable-preview",
464+
"--enable-preview",
447465
"--enable-http",
448466
"--enable-https",
467+
"--enable-all-security-services",
449468
"--install-exit-handlers",
450469
"-H:CStandard=C11",
451470
"-H:DefaultCharset=UTF-8",
452471
"-H:+UseContainerSupport",
453472
"-H:+ReportExceptionStackTraces",
454-
"-H:-EnableAllSecurityServices",
473+
"-H:+EnableAllSecurityServices",
455474
"-R:MaxDirectMemorySize=256M",
456475
"-Dpolyglot.image-build-time.PreinitializeContexts=js",
457476
"--trace-object-instantiation=elide.tool.cli.PropertySourceLoaderFactory",
@@ -462,19 +481,13 @@ val commonNativeArgs = listOf(
462481
if (enableLlvm) "--language:llvm" else null,
463482
if (enablePython) "--language:python" else null,
464483
if (enableRuby) "--language:ruby" else null,
465-
)).plus(
466-
if (enableTools) listOf(
484+
)).plus(if (enableTools) listOf(
467485
"--tool:chromeinspector",
468486
"--tool:coverage",
469487
"--tool:profiler",
470-
) else emptyList()
471-
).plus(
472-
if (enableTruffleJson) listOf(
473-
"--language:truffle-json",
474-
) else emptyList()
475-
).plus(
476-
jvmModuleArgs
477-
).plus(if (oracleGvm) commonGvmArgs else emptyList())
488+
) else emptyList()).plus(if (enableEdge) listOfNotNull(
489+
if (!enableTruffleJson) null else "--language:truffle-json",
490+
) else emptyList()).plus(if (oracleGvm) commonGvmArgs else emptyList())
478491

479492
val dashboardFlags: List<String> = listOf(
480493
"-H:DashboardDump=elide-tool",
@@ -525,8 +538,8 @@ val experimentalFlags = listOf(
525538

526539
// CFlags for release mode.
527540
val releaseCFlags: List<String> = listOf(
528-
// "-O3",
529-
// "-flto",
541+
"-O3",
542+
"-flto",
530543
)
531544

532545
// PGO profiles to specify in release mode.
@@ -588,29 +601,32 @@ val initializeAtBuildTime = listOf(
588601
"com.google.common.jimfs.Feature",
589602
"com.google.common.jimfs.SystemJimfsFileSystemProvider",
590603
"ch.qos.logback",
604+
"org.slf4j.MarkerFactory",
591605
"org.slf4j.simple.SimpleLogger",
592606
"org.slf4j.impl.StaticLoggerBinder",
593-
// "org.codehaus.stax2.typed.Base64Variants",
594-
// "org.bouncycastle.util.Properties",
595-
// "org.bouncycastle.util.Strings",
596-
// "org.bouncycastle.crypto.macs.HMac",
597-
// "org.bouncycastle.crypto.prng.drbg.Utils",
598-
// "org.bouncycastle.jcajce.provider.drbg.DRBG",
599-
// "org.bouncycastle.jcajce.provider.drbg.DRBG$${'$'}Default",
600-
// "com.sun.tools.doclint",
601-
// "jdk.jshell.Snippet${'$'}SubKind",
602-
// "com.sun.tools.javac.parser.Tokens${'$'}TokenKind",
607+
"org.codehaus.stax2.typed.Base64Variants",
608+
"org.bouncycastle.util.Properties",
609+
"org.bouncycastle.util.Strings",
610+
"org.bouncycastle.crypto.macs.HMac",
611+
"org.bouncycastle.crypto.prng.drbg.Utils",
612+
"org.bouncycastle.jcajce.provider.drbg.DRBG",
613+
"org.bouncycastle.jcajce.provider.drbg.DRBG$${'$'}Default",
614+
"com.sun.tools.doclint",
615+
"jdk.jshell.Snippet${'$'}SubKind",
616+
"com.sun.tools.javac.parser.Tokens${'$'}TokenKind",
603617
"org.xml.sax.helpers.LocatorImpl",
604618
"org.xml.sax.helpers.AttributesImpl",
605619
"org.sqlite.util.ProcessRunner",
606620
"io.netty.handler.codec.http.cookie.ServerCookieEncoder",
621+
"io.micronaut.http.util.HttpTypeInformationProvider",
622+
"io.micronaut.inject.provider.ProviderTypeInformationProvider",
623+
"io.micronaut.core.async.ReactiveStreamsTypeInformationProvider",
607624
"com.google.common.collect.MapMakerInternalMap",
608625
"com.google.common.collect.MapMakerInternalMap${'$'}StrongKeyWeakValueSegment",
609626
"com.google.common.collect.MapMakerInternalMap${'$'}EntrySet",
610627
"com.google.common.collect.MapMakerInternalMap${'$'}StrongKeyWeakValueEntry${'$'}Helper",
611628
"com.google.common.collect.MapMakerInternalMap${'$'}1",
612629
"com.google.common.base.Equivalence${'$'}Equals",
613-
614630
//
615631
// "elide.tool.cli.HttpRequestFactoryFactory",
616632
// "elide.tool.cli.HttpResponseFactoryFactory",
@@ -626,12 +642,11 @@ val initializeAtBuildTimeTest: List<String> = listOf(
626642
)
627643

628644
val initializeAtRuntime: List<String> = listOf(
629-
"io.netty.channel.ChannelInitializer",
645+
// "io.netty.channel.ChannelInitializer",
630646
"ch.qos.logback.core.AsyncAppenderBase${'$'}Worker",
631647
"io.micronaut.core.util.KotlinUtils",
632648
"io.micrometer.common.util.internal.logging.Slf4JLoggerFactory",
633649
"com.sun.tools.javac.file.Locations",
634-
// "org.bouncycastle.jcajce.provider.drbg.DRBG${'$'}NonceAndIV",
635650
)
636651

637652
val initializeAtRuntimeTest: List<String> = emptyList()
@@ -660,7 +675,6 @@ val darwinOnlyArgs = defaultPlatformArgs.plus(listOf(
660675
"-march=native",
661676
"--gc=serial",
662677
"-Delide.vm.engine.preinitialize=true",
663-
"-H:+AllowJRTFileSystem",
664678
"-H:InitialCollectionPolicy=Adaptive",
665679
"-R:MaximumHeapSizePercent=80",
666680
).plus(if (project.properties["elide.ci"] == "true") listOf(
@@ -678,7 +692,6 @@ val linuxOnlyArgs = defaultPlatformArgs.plus(listOf(
678692
"-march=native",
679693
"-H:RuntimeCheckedCPUFeatures=AVX,AVX2",
680694
"-H:+StaticExecutableWithDynamicLibC",
681-
"-H:+AllowJRTFileSystem",
682695
)).plus(
683696
if (enableG1) listOf(
684697
"--gc=G1",

packages/cli/src/main/kotlin/elide/tool/cli/cmd/repl/ToolShellCommand.kt

+8-7
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ import org.graalvm.polyglot.Engine as VMEngine
111111
private const val CONFIG_PATH_APP = "/etc/elide"
112112
private const val CONFIG_PATH_USR = "~/.elide"
113113
private val initialized: AtomicBoolean = AtomicBoolean(false)
114+
private val engine: VMEngine = VMEngine.create()
114115
private val logging: Logger by lazy {
115116
Logging.of(ToolShellCommand::class)
116117
}
@@ -142,49 +143,49 @@ import org.graalvm.polyglot.Engine as VMEngine
142143
names = ["--js", "--javascript", "-js"],
143144
description = ["Equivalent to passing '--language=JS'."],
144145
)
145-
internal var javascript: Boolean = true
146+
internal var javascript: Boolean = engine.languages.containsKey("js")
146147

147148
/** Flag for JVM support. */
148149
@Option(
149150
names = ["--jvm", "--java", "-java"],
150151
description = ["Equivalent to passing '--language=JVM'."],
151152
)
152-
internal var jvm: Boolean = false // not yet implemented (experimental)
153+
internal var jvm: Boolean = engine.languages.containsKey("java")
153154

154155
/** Flag for Kotlin support. */
155156
@Option(
156157
names = ["--kotlin", "--kt", "-kt"],
157158
description = ["Equivalent to passing '--language=KOTLIN'."],
158159
)
159-
internal var kotlin: Boolean = false
160+
internal var kotlin: Boolean = jvm
160161

161162
/** Flag for Ruby support. */
162163
@Option(
163164
names = ["--ruby", "--rb", "-rb"],
164165
description = ["Equivalent to passing '--language=RUBY'."],
165166
)
166-
internal var ruby: Boolean = true
167+
internal var ruby: Boolean = engine.languages.containsKey("ruby")
167168

168169
/** Flag for Python support. */
169170
@Option(
170171
names = ["--python", "--py", "-py"],
171172
description = ["Equivalent to passing '--language=PYTHON'."],
172173
)
173-
internal var python: Boolean = true
174+
internal var python: Boolean = engine.languages.containsKey("python")
174175

175176
/** Flag for WebAssembly support. */
176177
@Option(
177178
names = ["--wasm"],
178179
description = ["Equivalent to passing '--language=WASM'."],
179180
)
180-
internal var wasm: Boolean = true
181+
internal var wasm: Boolean = engine.languages.containsKey("wasm")
181182

182183
/** Flag for LLVM support. */
183184
@Option(
184185
names = ["--llvm"],
185186
description = ["Equivalent to passing '--language=LLVM'."],
186187
)
187-
internal var llvm: Boolean = true
188+
internal var llvm: Boolean = engine.languages.containsKey("llvm")
188189

189190
// Calculated and cached suite of supported languages loaded into the VM space.
190191
private val langs: EnumSet<GuestLanguage> by lazy {

0 commit comments

Comments
 (0)