Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

singlejar is not runnable on Alpine Linux #12961

Closed
kigero opened this issue Feb 4, 2021 · 10 comments
Closed

singlejar is not runnable on Alpine Linux #12961

kigero opened this issue Feb 4, 2021 · 10 comments

Comments

@kigero
Copy link

kigero commented Feb 4, 2021

Description of the problem / feature request:

singlejar_local is not executable on alpine linux.

Feature requests: what underlying problem are you trying to solve with this feature?

Building a jar with resources.

Bugs: what's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

Given the following four files (note that WORKSPACE is empty):

## WORKSPACE

## BUILD
load("@rules_java//java:defs.bzl", "java_binary")

java_binary(
    name = "test-bin",
    srcs = glob(["src/main/java/**/*"]),
    main_class = "com.test.Test",
    resources = glob(["src/main/resources/**/*"]),
)

## src/main/java/com/test/Test.java
package com.test;

public class Test
{
    public static void main(String[] args)
    {
        System.out.println("hello world");
    }
}

## src/main/resources/test.txt
Some content.

Running the test-bin target gives me the following:

$ bazel run //:test-bin --verbose_failures --sandbox_debug
INFO: Analyzed target //:test-bin (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
ERROR: /dist/test/BUILD:3:12: Building Java resource jar failed: (Exit 1): process-wrapper failed: error executing command
  (cd /home/docker/.cache/bazel/_bazel_docker/092469a9fc0d27c21edffa3ec0dba937/sandbox/processwrapper-sandbox/13/execroot/__main__ && \
  exec env - \
    PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
    TMPDIR=/tmp \
  /home/docker/.cache/bazel/_bazel_docker/install/819f0bd2c978e86aebb402b68670e31f/process-wrapper '--timeout=0' '--kill_delay=15' external/remote_java_tools_linux/java_tools/src/tools/singlejar/singlejar_local --normalize --dont_change_compression --exclude_build_data --output bazel-out/k8-fastbuild/bin/test-bin.jar --sources bazel-out/k8-fastbuild/bin/test-bin-class.jar --resources src/main/resources/test.txt:test.txt) process-wrapper failed: error executing command
  (cd /home/docker/.cache/bazel/_bazel_docker/092469a9fc0d27c21edffa3ec0dba937/sandbox/processwrapper-sandbox/13/execroot/__main__ && \
  exec env - \
    PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
    TMPDIR=/tmp \
  /home/docker/.cache/bazel/_bazel_docker/install/819f0bd2c978e86aebb402b68670e31f/process-wrapper '--timeout=0' '--kill_delay=15' external/remote_java_tools_linux/java_tools/src/tools/singlejar/singlejar_local --normalize --dont_change_compression --exclude_build_data --output bazel-out/k8-fastbuild/bin/test-bin.jar --sources bazel-out/k8-fastbuild/bin/test-bin-class.jar --resources src/main/resources/test.txt:test.txt)
src/main/tools/process-wrapper-legacy.cc:80: "execvp(external/remote_java_tools_linux/java_tools/src/tools/singlejar/singlejar_local, ...)": No such file or directory
Target //:test-bin failed to build
INFO: Elapsed time: 0.114s, Critical Path: 0.01s
INFO: 2 processes: 2 internal.
FAILED: Build did NOT complete successfully
FAILED: Build did NOT complete successfully

If I comment out the resources line in the test-bin target, I can succesfuly run the target.

$ bazel run //:test-bin --verbose_failures --sandbox_debug
INFO: Analyzed target //:test-bin (1 packages loaded, 2 targets configured).
INFO: Found 1 target...
Target //:test-bin up-to-date:
  bazel-bin/test-bin.jar
  bazel-bin/test-bin
INFO: Elapsed time: 0.216s, Critical Path: 0.07s
INFO: 2 processes: 1 internal, 1 worker.
INFO: Build completed successfully, 2 total actions
INFO: Build completed successfully, 2 total actions
hello world

What operating system are you running Bazel on?

Alpine 3.9

What's the output of bazel info release?

$ bazel info release
release 4.0.0- (@non-git)

If bazel info release returns "development version" or "(@Non-Git)", tell us how you built Bazel.

I built bazel directly on Alpine from source in a docker container; here's the relevant section:

RUN mkdir bazel-build
RUN cd bazel-build && wget https://github.com/bazelbuild/bazel/releases/download/4.0.0/bazel-4.0.0-dist.zip && unzip bazel-4.0.0-dist.zip
# Add a macro definition to allow Bazel to compile on Alpine; OOTB compilation complains about a missing TEMP_FAILURE_RETRY macro, this line adds that macro to the one file that needs it.
# This macro definition came from https://stackoverflow.com/a/41446972/1322
# See https://github.com/bazelbuild/bazel/issues/12460
RUN sed -i '57i\#ifndef TEMP_FAILURE_RETRY\n#define TEMP_FAILURE_RETRY(exp) \\\n  ({ \\\n    decltype(exp) _rc; \\\n    do { \\\n      _rc = (exp); \\\n    } while (_rc == -1 && errno == EINTR); \\\n    _rc; \\\n  })\n#endif\n' bazel-build/src/main/tools/linux-sandbox-pid1.cc
RUN cd bazel-build && env EXTRA_BAZEL_ARGS="--host_javabase=@local_jdk//:jdk" bash ./compile.sh

Have you found anything relevant by searching the web?

The only thing I've found is that singlejar used to be a java version, and got moved to a C++ version. Not sure how long this has been a problem though, so whether anything there is relevant I'm not sure.

Any other information, logs, or outputs that you want to share?

$ cat /etc/os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.9.3
PRETTY_NAME="Alpine Linux v3.9"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"

The binary is created, it's just not executable.

$ ls -al /home/docker/.cache/bazel/_bazel_docker/092469a9fc0d27c21edffa3ec0dba937/external/remote_java_tools_linux/java_tools/src/tools/singlejar/singlejar_local
-r-xr-xr-x    1 docker   nogroup    4866096 Dec  7 11:37 /home/docker/.cache/bazel/_bazel_docker/092469a9fc0d27c21edffa3ec0dba937/external/remote_java_tools_linux/java_tools/src/tools/singlejar/singlejar_local
$ /home/docker/.cache/bazel/_bazel_docker/092469a9fc0d27c21edffa3ec0dba937/external/remote_java_tools_linux/java_tools/src/tools/singlejar/singlejar_local
sh: /home/docker/.cache/bazel/_bazel_docker/092469a9fc0d27c21edffa3ec0dba937/external/remote_java_tools_linux/java_tools/src/tools/singlejar/singlejar_local: not found
@kigero
Copy link
Author

kigero commented Feb 5, 2021

Interestingly, I checked out the source code and tried building singlejar directly in that alpine environment and it worked, so I'm not sure what's going on with the one that gets used as part of my build. Maybe it's not actually built locally and just downloaded - and if that is the case, is there a way I can build it separately and tell bazel to use that version?

$ bazel build //src/tools/singlejar:singlejar_local
DEBUG: /home/docker/.cache/bazel/_bazel_docker/4caa791091d21d23e63637080226f370/external/bazel_toolchains/rules/rbe_repo/version_check.bzl:68:14:
Current running Bazel is ahead of bazel-toolchains repo. Please update your pin to bazel-toolchains repo in your WORKSPACE file.
DEBUG: /home/docker/.cache/bazel/_bazel_docker/4caa791091d21d23e63637080226f370/external/bazel_toolchains/rules/rbe_repo/checked_in.bzl:103:14: rbe_ubuntu1804_java11 not using checked in configs as detect_java_home was set to True
DEBUG: /home/docker/.cache/bazel/_bazel_docker/4caa791091d21d23e63637080226f370/external/bazel_toolchains/rules/rbe_repo/version_check.bzl:68:14:
Current running Bazel is ahead of bazel-toolchains repo. Please update your pin to bazel-toolchains repo in your WORKSPACE file.
DEBUG: /home/docker/.cache/bazel/_bazel_docker/4caa791091d21d23e63637080226f370/external/bazel_toolchains/rules/rbe_repo/checked_in.bzl:103:14: rbe_ubuntu1604_java8 not using checked in configs as detect_java_home was set to True
INFO: Analyzed target //src/tools/singlejar:singlejar_local (26 packages loaded, 666 targets configured).
INFO: Found 1 target...
Target //src/tools/singlejar:singlejar_local up-to-date:
  bazel-bin/src/tools/singlejar/singlejar_local
INFO: Elapsed time: 57.249s, Critical Path: 20.18s
INFO: 340 processes: 28 internal, 312 processwrapper-sandbox.
INFO: Build completed successfully, 340 total actions
$ ./bazel-bin/src/tools/singlejar/singlejar_local
singlejar_local: Use --output <output_jar> to specify the output file name

@comius
Copy link
Contributor

comius commented Mar 3, 2021

The error is "execvp(external/remote_java_tools_linux/java_tools/src/tools/singlejar/singlejar_local, ...)": No such file or directory.

I don't understand how this file got removed. It is distributed with java_tools, it has an executable bit set.

With Bazel@HEAD you have an option to disable using prebuilt tools. More information on https://docs.bazel.build/versions/master/bazel-and-java.html

@benjaminp
Copy link
Collaborator

The error is "execvp(external/remote_java_tools_linux/java_tools/src/tools/singlejar/singlejar_local, ...)": No such file or directory.

I expect this is because the while the executable exists, its elf interpreter (glibc's dynamic linker) does not exist on alpine.

@kigero
Copy link
Author

kigero commented Mar 3, 2021

I expect this is because the while the executable exists, its elf interpreter (glibc's dynamic linker) does not exist on alpine.

Agreed - and given that singlejar does seem to compile and run fine on alpine, using the NONPREBUILT_TOOLCHAIN_CONFIGURATION on the page that comius pointed to sounds like it might be a good option; I'll be trying that later today and will report back.

@kigero
Copy link
Author

kigero commented Mar 6, 2021

I spent some time trying to get this to compile from source on alpine and kept running into issues; it looks like I'll need to wait until either there's a release of the dist archive that includes these changes to try compiling again, or switch to ubuntu. I will try running this in the future once I can get the newer version compiled again and will update the issue then.

@GregBowyer
Copy link

So I dont want to add a whine but this puts me in a bit of a bind. I am using (have to use because reasons) Centos6. Right now this means that I am kinda forced to upgrade everyone (including devs) to bazel@HEAD (and 4.x is _supposed to be LTS right).

Is there a way to disable singlejar like ijar, or revert back a bit for bazel 4?

@comius
Copy link
Contributor

comius commented Mar 15, 2021

@GregBowyer There is a way. In Bazel 4.0.0 you need to define your own java_toolchain with ijar and singlejar not pointing to prebuilt binaries. Aliases for those are either in @bazel_tools//tools/jdk or in @remote_java_tools Then you can use that toolchain with --{,host_}java_toolchain flags.

Difference with Bazel@HEAD is the configuration for non-prebuilt toolchains is already provided @HEAD and different flags and process is used to determine "which" configuration is used. "What" is in the configuration has not changed much.

@kigero
Copy link
Author

kigero commented Mar 18, 2021

I had a chance to look into the 4.0.0 route mentioned by @comius, and I was able to get it working on Alpine. I grabbed the default java_toolchain configuration (from the DEFAULT_TOOLCHAIN_CONFIGURATION defined in the <bazel_source>/embedded_tools/tools/jdk/default_java_toolchain.bzl file), copied it into my BUILD file, and modified the singlejar property to point to a non-prebuilt target. I ended up with this:

load("@bazel_tools//tools/jdk:default_java_toolchain.bzl", "DEFAULT_JAVACOPTS", "JDK9_JVM_OPTS",)
java_toolchain(
    name = "repository_default_toolchain",
    bootclasspath = ["@bazel_tools//tools/jdk:platformclasspath"],
    forcibly_disable_header_compilation = 0,
    genclass = ["@bazel_tools//tools/jdk:genclass"],
    header_compiler = ["@bazel_tools//tools/jdk:turbine_direct"],
    header_compiler_direct = ["@bazel_tools//tools/jdk:turbine_direct"],
    ijar = ["@bazel_tools//tools/jdk:ijar"],
    jacocorunner = "@bazel_tools//tools/jdk:JacocoCoverageFilegroup",
    javabuilder = ["@bazel_tools//tools/jdk:javabuilder"],
    javac_supports_workers = 1,
    jvm_opts = [
        # Compact strings make JavaBuilder slightly slower.
        "-XX:-CompactStrings",
    ] + JDK9_JVM_OPTS,
    misc = DEFAULT_JAVACOPTS,
    singlejar = ["@bazel_tools//tools/jdk:bazel-singlejar_deploy.jar"],
    source_version = "8",
    target_version = "8",
    tools = [
        "@bazel_tools//tools/jdk:java_compiler_jar",
        "@bazel_tools//tools/jdk:javac_jar",
        "@bazel_tools//tools/jdk:jdk_compiler_jar",
    ],
)

My build then completed properly on Alpine with the --java_toolchain=//:repository_default_toolchain flag.

It looks like this should be quite a bit simpler when it's actually released, but this workaround is working for me.

@ckolli5
Copy link

ckolli5 commented Jun 2, 2022

Hey @kigero, with reference to above comment, can we close this issue?

@kigero
Copy link
Author

kigero commented Jun 3, 2022

Yep!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants