Skip to content

Commit daa663e

Browse files
Binary input java example (#363)
## Binary Input Example The goal of this example project is to test the performance of Engflow's remote execution and caching service based on the number of input binary files in the dependency graph. The project contains a `genrule` that generates a specified number of Java binaries for the `genbinary` Java library, which are then listed as dependencies in the main binary. The `Main.java` file loops through each generated class and calls its `greetNum` method. ### How It Works 1. **Generation of Java Binaries:** - The `genrule` in the `BUILD` file generates a specified number of Java classes (`Hello1.java`, `Hello2.java`, ..., `HelloN.java`). - Each generated class contains a `greetNum` method that prints a unique message. 2. **Main Class Execution:** - The `Main.java` file in `binaryinput` dynamically loads each generated class using reflection. - It then invokes the `greetNum` method of each class, printing the corresponding message. --------- Co-authored-by: Andrés Felipe Barco Santa <[email protected]> Co-authored-by: Andrés Felipe Barco <[email protected]>
1 parent 4564c69 commit daa663e

File tree

3 files changed

+102
-0
lines changed

3 files changed

+102
-0
lines changed

java/com/engflow/binaryinput/BUILD

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
load("@rules_java//java:defs.bzl", "java_binary", "java_library")
2+
3+
NUM_FILES = 100
4+
5+
# Generates a number of java files based on the value of NUM_FILES
6+
# Each file is named HelloX.java where X is the number of the file
7+
# Each file contains a class with a greetNum method that prints "Hello" + the number of the file
8+
[genrule(
9+
name = "Hello" + str(x),
10+
outs = ["Hello" + str(x) + ".java"],
11+
cmd_bash = "echo 'package com.engflow.binaryinput;" + "\n" +
12+
"public class Hello" + str(x) +
13+
" { public static void greetNum() { System.out.println(\"Hello " + str(x) + "\"); } }' > $@",
14+
) for x in range(1,NUM_FILES+1)]
15+
16+
# Generates a java library that contains all the generated java files
17+
[java_library(
18+
name = "genbinary" + str(x),
19+
srcs = [":Hello" + str(x) + ".java" for x in range(1,NUM_FILES+1)],
20+
visibility = ["//visibility:public"],
21+
) for x in range(1,NUM_FILES+1)]
22+
23+
# Main class
24+
java_binary(
25+
name = "main",
26+
srcs = ["Main.java"],
27+
main_class = "com.engflow.binaryinput.Main",
28+
deps = [
29+
":genbinary" + str(x) for x in range(1,NUM_FILES+1)
30+
],
31+
args = [str(NUM_FILES)],
32+
)
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.engflow.binaryinput;
2+
3+
import java.lang.reflect.InvocationTargetException;
4+
5+
public class Main {
6+
public static void main(String[] args) {
7+
try {
8+
// args[0] is the number of files to read
9+
int numFiles = Integer.parseInt(args[0]);
10+
11+
// Load and run the greetNum method from each class
12+
for(int i = 1; i <= numFiles; i++){
13+
Class<?> clazz = Class.forName("com.engflow.binaryinput.Hello" + i);
14+
clazz.getMethod("greetNum").invoke(null);
15+
}
16+
17+
} catch (ClassNotFoundException | InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {
18+
throw new RuntimeException(e);
19+
}
20+
}
21+
}
+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Multiple Binary Input Example
2+
3+
## Usage
4+
Set the `NUM_FILES` variable in the BUILD file to the desired input size.
5+
6+
To generate the test files, build the `genbinary` library using the `genrule`:
7+
```sh
8+
bazel build //java/com/engflow/binaryinput:genbinary{1..<NUM_FILES>}
9+
```
10+
11+
Then, the program can be built with the following command:
12+
```sh
13+
bazel build //java/com/engflow/binaryinput:main
14+
```
15+
16+
## How It Works
17+
18+
1. **Generation of Java Binaries:**
19+
- The `genrule` in the `BUILD` file generates a specified number of Java classes (`Hello1.java`, `Hello2.java`, ..., `HelloN.java`).
20+
- Each generated class contains a `greetNum` method that prints a unique message.
21+
- A java library is created for each file (`Hello1.jar`, `Hello2.jar`, ..., `HelloN.jar`).
22+
23+
2. **Building the main target:**
24+
- The previously created libraries are added to the main class as dependencies through a for loop.
25+
- The consistent naming scheme of the libraries simplifies their inclusion in the build process.
26+
27+
3. **Main Class Execution:**
28+
- The `Main.java` file in `binaryinput` dynamically loads each generated class using reflection.
29+
- It then invokes the `greetNum` method of each class, printing the corresponding message.
30+
31+
## Configuration
32+
33+
The number of generated files is controlled by the `NUM_FILES` variable in the `BUILD` file of the `binaryinput` package. Modify this variable to change the number of generated classes and observe the performance impact on Engflow's remote execution and caching service.
34+
35+
## Example
36+
37+
To generate and run the program with 10 input binary files:
38+
39+
1. Set `NUM_FILES` to 10 in `java/com/engflow/binaryinput/BUILD`.
40+
2. Build the `genbinary` library:
41+
```sh
42+
bazel build //java/com/engflow/binaryinput:genbinary{1..10}
43+
```
44+
3. Build the `main` binary:
45+
```sh
46+
bazel build //java/com/engflow/binaryinput:main
47+
```
48+
49+
This will generate 10 Java classes, build the `genbinary` library, and build the `main` binary. Using `bazel run` will also print messages from each generated class.

0 commit comments

Comments
 (0)