Dynamic Linking and Java

I’m working with my friend on a Java side project (Typestream) and trying to get a dev environment working on my Nix machine:

Current shell.nix:

{ pkgs ? import <nixpkgs> {} }:
let
  javaDevEnv = pkgs.buildFHSUserEnv {
    name = "java-dev-env";
    targetPkgs = pkgs: with pkgs; [
      jdk17
      gradle
      protobuf
      git
      bashInteractive
      coreutils
      protoc-gen-grpc-web
    ];
    multiPkgs = pkgs: with pkgs; [
      bashInteractive
      git
    ];
    runScript = "bash";
  };
in pkgs.stdenv.mkDerivation {
  name = "java-dev-env-shell";
  nativeBuildInputs = [ javaDevEnv ];
  shellHook = "exec ${javaDevEnv}/bin/bash";
}

I started with a very simple devenv, then flake.nix but I still always get the same error:

Starting a Gradle Daemon (subsequent builds will be faster)
> Task :stub:generateProto FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':stub:generateProto'.
> protoc: stdout: . stderr: Could not start dynamically linked executable: /home/jevin/.gradle/caches/modules-2/files-2.1/io.grpc/protoc-gen-grpc-java/1.57.2/d3f50bdc45086ae0d90f95e362fb506221940c2e/protoc-gen-grpc-java-1.57.2-linux-x86_64.exe
  NixOS cannot run dynamically linked executables intended for generic
  linux environments out of the box. For more information, see:
  https://nix.dev/permalink/stub-ld
  --grpc_out: protoc-gen-grpc: Plugin failed with status code 127.


* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.

Any help would be appreciated. I’m trying to avoid having to run a VM :stuck_out_tongue:

1 Like

Run ldd on the protoc-gen-grpc-java-1.57.2-linux-x86_64.exe to see which libraries it needs. Then ensure those libraries are in your buildFHSEnv.

1 Like

I not sure if these map to particular packages.

Could the issue be related to the gradle plugin dynamically compiling the protobuf code and generating a java package from that?

ldd /home/jevin/.gradle/caches/modules-2/files-2.1/io.grpc/protoc-gen-grpc-java/1.57.2/d3f50bdc45086ae0d90f95e362fb506221940c2e/protoc-gen-grpc-java-1.57.2-linux-x86_64.exe
	linux-vdso.so.1 (0x00007ffc221d4000)
	libpthread.so.0 => /nix/store/1rm6sr6ixxzipv5358x0cmaw8rs84g2j-glibc-2.38-44/lib/libpthread.so.0 (0x00007ff564b54000)
	libm.so.6 => /nix/store/1rm6sr6ixxzipv5358x0cmaw8rs84g2j-glibc-2.38-44/lib/libm.so.6 (0x00007ff564a72000)
	libc.so.6 => /nix/store/1rm6sr6ixxzipv5358x0cmaw8rs84g2j-glibc-2.38-44/lib/libc.so.6 (0x00007ff564889000)
	/lib64/ld-linux-x86-64.so.2 => /nix/store/1rm6sr6ixxzipv5358x0cmaw8rs84g2j-glibc-2.38-44/lib64/ld-linux-x86-64.so.2 (0x00007ff564b5b000)

Yes, it’s quite likely that the gradle plugin is trying to compile something.

The error is “Could not start dynamically linked executable…”, which suggests that the linker (ld) could not load the executable. Quite often the cause for this is missing libraries.

Your ldd output shows that your Nix store has all of the necessary libraries, but that doesn’t mean those libraries are accessible within your buildFHSUserEnv.

There may also be additional libraries which are accessed dynamically. Such libraries would not be reflected in the ldd output.

The library linux-vdso.so.1 should be taken care of automatically, so you can just add the glibc package to your buildFHSUserEnv, as a starting point.

You do not appear to be running the build inside the fhsenv. Its LD.so should override stub-ld, so you should never see it print its message.

If you run ls -l /lib64/ld-linux-x86-64.so.2 inside the devenv, what is the output of that?

I haven’t had a chance to keep playing with it, but I’m posting a bounty to get it done if anyone here is interested: $100 Bounty: Help me get my dev environment working