Using `patchelf` on `java` executable to make it work on nixos

This is part of a larger problem, compiling truffleruby on nixos, which uses a tool called mx.

The tool downloads openjdk-21, which has jdk binaries. I would like to make all of them run so I can continue with a truffleruby build.

This is the error I get when running java:

$ ~/.mx/jdks/labsjdk-ce-21-jvmci-23.1-b15/bin/java
bash: /home/razetime/.mx/jdks/labsjdk-ce-21-jvmci-23.1-b15/bin/java: cannot execute: required file not found

As an attempt to make sure it recognizes my system libraries, I have nixos-rebuild config set LD_LIBRARY_PATH every build:

$ ~/.mx/jdks/labsjdk-ce-21-jvmci-23.1-b15/bin/java
bash: /home/razetime/.mx/jdks/labsjdk-ce-21-jvmci-23.1-b15/bin/java: cannot execute: required file not found

I am attempting to figure out a way to patch the file(s) for jdk with patchelf, but I am unsure of what fields to patch with the given output. I am also open to knowing what other methods i can use to run it.

$ readelf -d java

Dynamic section at offset 0x1d08 contains 33 entries:
  Tag        Type                         Name/Value
 0x0000000000000003 (PLTGOT)             0x2f88
 0x0000000000000002 (PLTRELSZ)           288 (bytes)
 0x0000000000000017 (JMPREL)             0x7c0
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000007 (RELA)               0x718
 0x0000000000000008 (RELASZ)             168 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000006ffffff9 (RELACOUNT)          3
 0x0000000000000015 (DEBUG)              0x0
 0x0000000000000006 (SYMTAB)             0x278
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000005 (STRTAB)             0x470
 0x000000000000000a (STRSZ)              381 (bytes)
 0x000000006ffffef5 (GNU_HASH)           0x5f0
 0x0000000000000004 (HASH)               0x628
 0x0000000000000001 (NEEDED)             Shared library: [libz.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libjli.so]
 0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libdl.so.2]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000c (INIT)               0x8e0
 0x000000000000000d (FINI)               0xd0c
 0x000000000000001a (FINI_ARRAY)         0x2cf8
 0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
 0x0000000000000019 (INIT_ARRAY)         0x2d00
 0x000000000000001b (INIT_ARRAYSZ)       8 (bytes)
 0x000000000000001d (RUNPATH)            Library runpath: [$ORIGIN:$ORIGIN/../lib]
 0x000000000000001e (FLAGS)              BIND_NOW
 0x000000006ffffffb (FLAGS_1)            Flags: NOW PIE
 0x000000006ffffff0 (VERSYM)             0x6c8
 0x000000006ffffffe (VERNEED)            0x6f4
 0x000000006fffffff (VERNEEDNUM)         1
 0x0000000000000000 (NULL)               0x0

I suggest you look at how AdoptOpenJDK or jetbrains.jdk are packaged and first package the special GitHub - graalvm/labs-openjdk-21: JDK 21 fork for building GraalVM CE..
Once that works, mx can be patched to use the local JDK instead of downloading one.

Note that if your final goal is to package truffelruby all builds must work in a sandbox, so all dependencies have to be downloaded ahead of building.

2 Likes