tweag/inline-java

Set the CLASSPATH in a wrapper for binaries

facundominguez opened this issue · 1 comments

We can build Haskell binaries that use inline-java. However, initializing the JVM in these programs requires specifying the paths to all the jar files that are needed by the Java part of the program.

Currently, inline-java achieves this by making a fat jar of the java dependencies as in

data = [":jar_deploy.jar"],

then we pass the path to the fat jar to the jvm as in

let jarPath = Runfiles.rlocation r "io_tweag_inline_java/benchmarks/wizzardo-http/jar_deploy.jar"
cpArg = "-Djava.class.path=" <> fromString jarPath

Fat jars, however, aren't always ideal, and there is some boilerplate to using these in BUILD files.

It would be nice defining a rule in inline-java to create script wrappers around binaries, which sets the classpath before calling the executable. Something like

haskell_binary(
  name = "hello-hs"
  deps = haskell_deps + some_java_deps,
  ...
)

classpath_wrapper(
  name = "hello-hs-wrapper"
  dep = ":hello-hs"
)

we can then run in the command line bazel-bin/hello-hs-wrapper.sh to execute the program with an environment variable like INLINE_JAVA_CLASSPATH=paths/to/jars/in/runfiles.

tweag/rules_haskell#1483 would be blocking this feature, which otherwise could be implemented with transitive_runtime_jars.

This should be implemented in bazel as part of the Java rule set. Any binary (written in any language) interacting with the jvm will have the same problem.

Some pointers by @aherrmann

rules_scala has the same kind of need. A scala executable is generated here: https://github.com/bazelbuild/rules_scala/blob/41005de813a5da7260c0094ad3169cf988592c8c/scala/private/phases/phase_write_executable.bzl#L73-L76

On Unix it uses a wrapper script https://github.com/bazelbuild/rules_scala/blob/master/java_stub_template/file/file.txt

On Windows it uses Bazel's launcher infrastructure: https://github.com/bazelbuild/rules_scala/blob/master/src/java/io/bazel/rulesscala/exe/LauncherFileWriter.java

Bazel's builtin Java rules use the above mentioned launcher infrastructure https://github.com/bazelbuild/bazel/blob/df2f77c2a8602d1b729b6802ba2bfcac3dc54402/src/tools/launcher/java_launcher.cc