Error when running enonic sandbox start, no such file or directory

Enonic version: enonic CLI version 1.5.1, linux sdk 7.6.0
OS: NixOS 20.09

Hi,

I’m struggling a bit with getting started and following the guides provided. I have a sneaking suspicion that this is due to NixOS and the way it handles things, but I’m not entirely sure, so I thought I’d post here to see if anyone knows anything about it.

The issue is that when running enonic sandbox start, I get an error message saying:

Could not start process: /home/thomas/.enonic/distributions/enonic-xp-linux-sdk-7.6.0/bin/server.sh fork/exec /home/thomas/.enonic/distributions/enonic-xp-linux-sdk-7.6.0/bin/server.sh: no such file or directory

Turns out it’s trying to use /bin/bash, which should work on most Linux distros. However, on NixOS, the path is different. In fact, it’s /nix/store/vnyfysaya7sblgdyvqjkrjbrb0cy11jf-bash-4.4-p23/bin/bash on my current system, though /run/current-system/sw/bin/bash should work.

So I rewrote the shebang lines in the scripts in the directory to use the latter. Now it complains that:

./enonic-xp-linux-sdk-7.6.0/bin/server.sh: line 91: /home/thomas/.enonic/distributions/enonic-xp-linux-sdk-7.6.0/jdk/bin/java: No such file or directory

That line is the run command, which looks like this:

exec "$JAVACMD" $JAVA_OPTS -Dxp.install="$XP_INSTALL" -Dfile.encoding=UTF8 -Dnashorn.args="--no-deprecation-warning" $XP_OPTS -Dmapper.allow_dots_in_name=true --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.xml/com.sun.org.apache.xerces.internal.util=ALL-UNNAMED --add-modules java.se --add-exports java.base/jdk.internal.ref=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.management/sun.management=ALL-UNNAMED --add-opens jdk.management/com.sun.management.internal=ALL-UNNAMED -classpath "$XP_INSTALL/lib/*" com.enonic.xp.launcher.LauncherMain "${ARGS[@]}"

Now, I’ve checked that the file .../bin/java is definitely there, but there is this interesting thing where if I try and run it I get an error message:

In the jdk/bin dir

$ ./java
Failed to execute process './java'. Reason:
The file './java' does not exist or could not be executed.

The file is definitely there and the permissions say it’s executable for all groups, so I don’t really know what’s going on. Again, I suspect this is related to how NixOS handles software and packages, but I’m not 100% certain, so I thought I’d come here for advice first.

Oh, and for the record: I downloaded the binary from https://repo.enonic.com/public/com/enonic/cli/enonic/1.5.1/enonic_1.5.1_Linux_64-bit.tar.gz and not through my regular package manager (nix). Nix does not yet support snaps.

Any thoughts and insights are much appreciated. I’m also happy to provide any other information you may need; just ask.

Cheers!

The issue with the shebang line is a bug. I filed an issue in XP to fix this issue: https://github.com/enonic/xp/issues/8652

The second problem is related to NixOS specifically. It seems to be a linking issue between the java binary and some dynamic libraries. Here are some resources to help you out with that:

If you find a solution to this problem please post it. I am curious how to fix this.

It’s definitely related to how NixOS handles things: the interpreter and libraries are not in the place the binary expects them.

For Java, I think it would be interesting to know why enonic is shipping with a jdk. Is it a somehow-patched JDK, or is it just there for convenience so that everything is in one package and there is no chance of version mismatches? In the latter case, which is pretty common, it might be a fine strategy to just use a nix-packaged jdk.

I’m not entirely sure whether the JDK is patched in some way or not, though I suspect it isn’t and that it’s included to make the environment as controlled as possible. @gbi, can you speak to that?

I also tried using a nix-packaged JDK, but it still didn’t work. However, it is definitely possible that I didn’t do it correctly.

Side note: I also created a post on the NixOS discourse forums about this issue, and have gotten some good pointers so far. The gradle2nix tool looks particularly promising and might be just what I need in this case.

I think it’d be interesting in what way that failed :).

Yeah, that’s where I found out about this thread, but I figured the ‘why ship a jdk’ question would be more likely to be answered here than there :wink: .

It’s definitely neat and a good learning experience to create a derivation to build from source, but it might not be the easiest route. Hard to predict though: sometimes it actually is the easiest route :wink: .

JVM is bundled inside XP to ensure consistency of version across deployments and upgrades, but also to simplify installation and use of the platform. It is a standard Java distro.

Thanks for picking up on this. I thought I’d try again, but decided to go with a different approach this time and changed the $JAVACMD variable in the server.sh to just use the java in my path (from the adoptopenjdk-bin package in nixpkgs). Doing it this way, it starts up just fine, which is great!

To be clear, I changed this:

locateJava() {
    if [ -n "$JAVA_HOME" ] ; then
        if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
            JAVACMD="$JAVA_HOME/jre/sh/java"
        else
            JAVACMD="$JAVA_HOME/bin/java"
        fi
        if [ ! -x "$JAVACMD" ] ; then
            die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME."
        fi
    else
        JAVACMD="java"
        which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH."
    fi
}

to this:

locateJava() {
  JAVACMD="java"
  which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH."
}

Obviously, if it means manually modifying the files, then it’s not much of a permanent solution, but at least it works for now. I’ll try and find a better way to handle this. Any ideas?

Interesting. If I make available adoptopenjdk-bin in nix-shell, JAVA_HOME is set:

$  nix-shell -p adoptopenjdk-bin
$ export | grep JAVA_HOME
declare -x JAVA_HOME="/nix/store/8cgax4522yhc05y4f3cgdagp7py5rac7-adoptopenjdk-hotspot-bin-11.0.9"
$ ls /nix/store/8cgax4522yhc05y4f3cgdagp7py5rac7-adoptopenjdk-hotspot-bin-11.0.9/bin/java
/nix/store/8cgax4522yhc05y4f3cgdagp7py5rac7-adoptopenjdk-hotspot-bin-11.0.9/bin/java

… so that looks like it should actually work with the script? How are you installing adoptopenjdk-bin?

Interesting. I’ve just created a nix shell with adoptopenjdk: nix-shell -p adoptopenjdk-bin and tried to launch things from there.

When I try to run it with the original function definition, I get this message:

server.sh: ERROR: JAVA_HOME is set to an invalid directory: /home/thomas/.enonic/distributions/enonic-xp-linux-sdk-7.6.0/jdk.

However, if echo $JAVA_HOME from the same shell that launches the ./server.sh script, I get this path:

/nix/store/xy2r5kdxz6j3drqbsh72nyn5pzy6i0h4-adoptopenjdk-hotspot-bin-11.0.7

I don’t know whether it gets overridden somehow or whether the nix shell just doesn’t export the variable, though. There’s no assignment to JAVA_HOME in the script.

Ah, no, I figured out what’s up: At the start of the script, it calls setenv.sh, which contains this:

# Set JAVA_HOME pointing to the embedded JDK
export JAVA_HOME=$(cd "$(dirname "$0")/../jdk"; pwd)
export PATH="$JAVA_HOME/bin:$PATH"

If I don’t run that script, it works as expected.

Hmm, now that I’ve made it work:

I wonder if there’s an elegant way to avoid having to fiddle with files on disk and still make it compatible with NixOS.

If the primary means of distribution (and user interface) is the Enonic CLI, it’d be nice to be able to make that available as a nix package, and then have everything else just work. At the same time, special casing something for NixOS feels a bit much. And even if the script detected whether you were on NixOS, it’d still require a JDK to be available.

What’s a good path forward here?