How do I debug a 'java_binary' target executed by a Bazel rule via 'ctx.actions.run(...)'? - bazel

I have a java_binary target in my workspace that I'm later passing as an executable to ctx.actions.run inside the rule. So far so good.
Now I want to debug this java_binary while Bazel is executing the rule. In order to attach a debugger I need the java_binary run in debug mode. So far, the only thing I came up with is setting jvm_flags on the java_binary. I was able to get that to work. But I was wondering if there is a way to achieve it from the command line instead of baking it into the java_binary.
java_binary(
...
jvm_flags = [
"-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000"
],
)
Is it possible to achieve this from the command line without hard coding jvm_flags?

Try:
bazel run //:my-target -- --debug
One strategy is to run the build with --subcommands, which will tell bazel to print out all the commands it's running during the build. Then find the command line corresponding to the invocation of the java_binary you're interested in. Then you can copy/paste that command (including the cd part) and modify it to include the debug flags, and debug it as you would any other process.
Note also that java_binary outputs a wrapper script that includes a --debug[=<port>] flag, so that should be all that needs to be added to the command line.
Note also that --subcommands will only print the commands that are actually executed during the build, so a fully cached / fully incremental build will print nothing. You may need to do a clean, or delete some of the outputs of the action you're interested in so that bazel runs that command.

It looks like you can pass the --jvm_flag option as part of the program options after the --.
BUILD:
java_binary(
name = "extract",
main_class = "com.pkg.Main",
resources = glob(["src/main/resources/**/*"]),
)
CLI:
bazel run //:extract -- --jvm_flag="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=7942" -path %cd%\config.json
It seems that the --jvm_flag option needs to come immediately after the --, before the program options (-path in the example). This is with Bazel 3.7.0.

Related

Is it possible to run a command in a Docker image as a test in Bazel?

I would like to run a command inside a container to test that it works. It should be invoked by bazel test.
Something like this:
container_test(
image = "//:my_image"
test_command = "exit 1"
)
I noticed this: https://github.com/bazelbuild/rules_docker/blob/master/contrib/test.bzl#L125
However it isn't documented.
How should I approach this in Bazel?
Take a look at the sample test rule here
This is a test rule which creates a script (script) that can be invoked in the CLI
The script will then exit with a non-zero error-code to indicate that the test failed (or 0 for success)
The script is then written as an executable output (ctx.actions.write), declares the list of files it needs available at runtime (runfiles)
This python function is then wrapped as a bazel rule (see full guide here)
So, how would you proceed towards creating your container test rule?
The script we want to generate above is probably some usage of docker run --rm IMAGE [COMMAND] [ARG...] to create a container from an image, run a command, and remove the container when done
Don't forget to set the script exit status based on the exit status of the docker command (as done in the example, where they copy the exit status of grep as the exit status for the overall script)
Update the sample above to use the above docker command, and plant the path to the image accordingly
See f.path in the script above showing how they access the path of an individual source file
You will need to make sure docker is available when your bazel rules are evaluated
I haven't done this fully myself since I don't have a computer with both bazel and docker, but this should be enough to get you started :)
Good luck!

Premake, command line options don't do anything

I have the following section in my lua script:
newoption {
trigger = "build-tests",
description = "Build tests."
}
configuration "build-tests"
print("bbbbbbbbb")
include("Src/tests/tests.lua")
configuration "not build-tests"
print("aaaaaaaaaaa")
running premake5 gmake --help gives:
Usage: premake5 [options] action [arguments]
OPTIONS - General
--build-benchmarks Build benchmarks.
--build-tests Build tests.
--debugger Start MobDebug remote debugger. Works with ZeroBrane Studio
--fatal Treat warnings from project scripts as errors
--file=FILE Read FILE as a Premake script; default is 'premake5.lua'
--help Display this information
However running premake5 --build-tests gmake outputs:
bbbbbbbbb
aaaaaaaaaaa
Building configurations...
Running action 'gmake'...
Done (362ms).
BOTH versions are running, I don't understand. I am trying to get a toggle to select whether I want to build tests or not.
configuration() is a function, not an if-then. Your example above is equivalent to...
configuration("build-tests")
print("bbbbbbbbb")
include("Src/tests/tests.lua")
configuration("not build-tests")
print("aaaaaaaaaaa")
It has no effect on which code runs or does not run in your script; all the code in your script is always run, and then the configuration conditions are evaluated later.
Instead look at the actual generated project output to see if things are working or not.

How can users get bazel-run.sh?

bazel run typically occupies the Bazel server, blocking other commands.
https://github.com/bazelbuild/bazel/blob/c484f19a2cf7427887d6e4c71c8534806e1ba83e/scripts/bazel-run.sh is a fantastic replacement
Question: what's a good way for end-users to get hold of that shell script and add to their path? Can we make that part of the bazel install?
I tried ls -R $(bazel info install_base) | grep bazel-run but no luck there.
Bazel run is a good replacement for end-user to run a Bazel command if you need to run interactively or multiple command (#2337). There has been no need for us to consider it as an installation script.
Please file an issue on Github to discuss the possibility of installing it along with Bazel.

Apache Ant: Run ant without showing the target names

When I run my build file, it always shows the target name.
For example, in my build file if I have targets A, B, C.
Then on when I type the command ant A, it shows
A: <...whatever>
How do I avoid displaying the A?
Any help is very much appreciated.
The command line switch is -q
$ ant -q A
A few options:
try -q for quiet mode
try -emacs (not sure if this dumps the targets or not, but worth trying)
write a custom logger
You might also have a look at the following blog entry http://codefeed.com/blog/?p=82. The author provides some code for a custom task to set the loglevel in a build script. This way you can enable and disable log output for specific operations.

Analysing a shell script

This would be part of a reverse-engineering project.
To determine and document what a shell script (ksh, bash, sh) does, it is comfortable, if you have information about what other programs/scripts it calls.
How could one automate this task? Do you know any program or framework that can parse a shell script? This way for instance, I could recognize external command calls -- a step to the right direction.
For bash/sh/ksh, I think you can easily modify their source to log what has been executed. That would be a solution.
How about:
Get a list of distinct words in that script
Search $PATH to find a hit for each
?
bash -v script.sh ?
Bash's xtrace is your friend.
You can invoke it with:
set -x at the top of your script,
by calling your script with bash -x (or even bash --debugger -x),
or recursively by doing (set -x; export SHELLOPTS; your-script; )
If you can't actually run the script, try loading it into a text editor that supports syntax highlighting for Bash. It will color-code all of the text and should help indicate what is a reserved word, variable, external command, etc.

Resources