# Kotlin Multiplatform native executable using dlopen+dlsym

**URL:** <https://discuss.kotlinlang.org/t/kotlin-multiplatform-native-executable-using-dlopen-dlsym/27756>\
**Category:** Support\
**Created:** [December 4, 2023, 5:39pm UTC](https://discuss.kotlinlang.org/t/kotlin-multiplatform-native-executable-using-dlopen-dlsym/27756 "2023-12-04T17:39:22Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![ctrue](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/ctrue/32/10648_2.png) [@ctrue](https://discuss.kotlinlang.org/u/ctrue)\
**Post date:** [December 4, 2023, 5:39pm UTC](https://discuss.kotlinlang.org/t/kotlin-multiplatform-native-executable-using-dlopen-dlsym/27756/1 "2023-12-04T17:39:22Z")

</div>

I have [a native launcher written in C](https://github.com/imagej/imagej-launcher) for my Java application. I am trying to rewrite the launcher in Kotlin Native. I found [this nice example code](https://github.com/hfhbd/jniTest) that links to `libjvm` so that you can call the JNI invocation API from Kotlin. However, the generated native executable then ends up with a `libjvm` dependency baked in, which my current native launcher does not have; rather, it has various heuristics to discover and select the best available libjvm, and then load it via `dlopen` and access it dynamically via `dlsym`.

I was not able to find a Kotlin Multiplatform example that uses `dlopen`+`dlsym` in this way, to avoid baking in a shared library dependency into the compiled binary. Could someone point me in the right direction? I know Java well but I’m rather new to Kotlin, and pretty bad at C. 😅

My first attempt can be found here: [GitHub - ctrueden/java-launcher: [EXPERIMENTAL] Native executable to launch Java in the same process](https://github.com/ctrueden/java-launcher)

---

<div class="post-metadata">

**Author:** ![ctrue](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/ctrue/32/10648_2.png) [@ctrue](https://discuss.kotlinlang.org/u/ctrue)\
**Post date:** [December 9, 2023, 1:49am UTC](https://discuss.kotlinlang.org/t/kotlin-multiplatform-native-executable-using-dlopen-dlsym/27756/2 "2023-12-09T01:49:28Z")

</div>

I decided to make the Kotlin/C interop interface much simpler by building a tiny shared library in C that uses `dlopen`/`dlsym` to work with `libjvm`, exposing only a single function `launch_java(char *libjvm_path, int jvm_argc, char *jvm_argv[], char *main_class_name, int main_argc, char *main_argv[])`, then wrap that C library to KMP using C interop. What I have so far can be [found here](https://github.com/ctrueden/java-launcher). It almost works on my Linux system, but I’m seeing errors at link time:

```auto
./libjaunch.so: error: undefined reference to 'dlerror', version 'GLIBC_2.34'
./libjaunch.so: error: undefined reference to 'dlclose', version 'GLIBC_2.34'
./libjaunch.so: error: undefined reference to 'dlopen', version 'GLIBC_2.34'
./libjaunch.so: error: undefined reference to 'dlsym', version 'GLIBC_2.34'

```

I know that the libdl stuff (`dlopen` et al.) moved intoi glibc core as of 2.34, so I don’t understand why these errors are happening. But this is maybe becoming more of a C question than a Kotlin one I suppose. Still, if anyone has any insight, I would appreciate any thoughts and ideas.

---

<div class="post-metadata">

**Author:** ![ctrue](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/ctrue/32/10648_2.png) [@ctrue](https://discuss.kotlinlang.org/u/ctrue)\
**Post date:** [December 13, 2023, 2:48pm UTC](https://discuss.kotlinlang.org/t/kotlin-multiplatform-native-executable-using-dlopen-dlsym/27756/3 "2023-12-13T14:48:15Z")

</div>

I gave up on making Kotlin Native use `libdl` functions in their intended fashion. I switched instead to the following design:

1. A small (~300 line) C program with functions:

2. A configurator program written using Kotlin Native, with no dependencies, and no custom use of cInterop—only built-in `platform.posix`, `platform.windows`, etc. This configurator can do most of the launcher’s heavy lifting, including discovery of installed JVMs, reasoning about which flags passed should be passed to the JVM vs the main method, implementation of any custom arguments that shouldn’t be passed directly to the main method, and anything else that needs to happen before launching the JVM (e.g. moving updated JAR files into place).

In this way, I can replicate the design of the project’s previous 5000-line C-only program, using Kotlin for most of it, and suffering the pain of C as minimally as possible.

If anyone has a better design, or knows of an existing project meeting these requirements in a better way, I would be very interested. Otherwise, I believe I can move forward well enough for now.

For anyone curious, the repo is at:

> **[GitHub - ctrueden/jaunch: \[EXPERIMENTAL\] Native executable to launch Java in...](https://github.com/ctrueden/jaunch)**
>
> \[EXPERIMENTAL\] Native executable to launch Java in the same process - GitHub - ctrueden/jaunch: \[EXPERIMENTAL\] Native executable to launch Java in the same process

P.S. The reason for the `undefined reference` errors in the second design iteration above was discovered by @elect: it is due to Kotlin Native using a different, older version of glibc compared to the system one. A workaround is to call the Konan compiler directly, something like:

```shell
~/.konan/kotlin-native-prebuilt-linux-x86_64-1.9.20/bin/run_konan clang clang linux_x64 @/path/to/jaunch/args

```

But TBH I did not try this solution myself…
