# JavaCompile A specialization of [Compile](Compile.md) which enables additional flexibility when compiling via `javac`. You are recommended to use `Compile` stage unless a deeper level of configuration is required. ## Config ``` javaCompile: input: [PathSpec] # Input files and/or directories classpath: [String]? # Classpath to pass to javac; Defaults to [] outDir: String? # Directory to output all compiled class files to; Defaults to `.` flags: [String]? # Other options to provide to javac experimental:optimize: Boolean? # Experimental: Optimize pipeline by creating as few pipeline stages as needed additional_packages: [String]? # Additional packages to install as dependencies ``` - `PathSpec` specified in `input` will be compiled in the order of appearance in the list - See [below](#pathspec) for more information - Do not specify `-cp ` or `-d ` to the `options` key - The grader will add/modify the classpath and output directory internally - Use `classpath` and `outDir` keys respectively instead - The legacy usage of `String`-based `input` and `compileDir` is now **UNSUPPORTED** - Users should migrate to using the `PathSpec`-based `input` key instead ### `PathSpec` `PathSpec` is a custom object format which facilitates specifying paths (either as files or directories). ``` PathSpec: file: String? dir: String? ``` Setting the value of either `file` or `dir` implies that the path you are specifying points to a file or a directory respectively. Note that you should only specify one of them; Specifying both is an error. You may use `*` as a wildcard in either keys. In the context of this stage: - Specifying `file` means to compile file(s) specified by the path. For example, the following compiles the file in `src/main/java/Main.java`. ```yaml input: file: src/main/java/Main.java ``` For example, the following compiles all files matching the wildcard `*.java` (the quotation marks are optional). Note that this will *not* recursively descend into subdirectories. ```yaml input: file: '*.java' ``` - Specifying `dir` means to compile all files with the file extension `.java` under the specified path (including subdirectories), treating the path as a directory. For example, the following compiles all Java source files under `src/main/java`. ```yaml input: dir: src/main/java ``` Note that while `javac` can generally resolve dependent classes in the classpath, you may need to specify directories in the `classpath` if `javac` cannot find dependent classes. This usually manifested in compiler errors such as: ``` Main.java:3: error: package example does not exist import example.Example; ^ Main.java:9: error: cannot find symbol Example.sayHello(); ^ symbol: variable Example location: class Main 2 errors ``` ## Experimental Optimization `JavaCompile` has an experimental optimization flag which enables input grouping and reduces the number of pipeline stages created. How this works is that the Grader will group all consecutive inputs and create pipeline stages which compile these input groups, as opposed to compiling each input in their own pipeline stage. This will result in a minor speedup due to less pipeline stages being verified and executed. Consider the following example: ```yaml javaCompile: input: - file: A.java - file: B.java - dir: main - dir: test - file: ./*.java experimental:optimize: true ``` By default, this will spawn 5 pipeline stages, with each pipeline stage compiling a `PathSpec` specified by `input`. ``` [ JavaCompile ] -> [ JavaCompile ] -> [ JavaCompile ] -> [ JavaCompile ] -> [ JavaCompile ] [ file:A.java ] [ file:B.java ] -> [ dir:main ] -> [ dir:test ] -> [file:./*.java] ``` With the flag enabled, this will spawn 3 pipeline stages, with each pipeline stage compiling a grouped `PathSpec`. ``` [ JavaCompile ] -> [ JavaCompile ] -> [ JavaCompile ] [ file:A.java ] [ dir:main } -> [file:./*.java] [ file:B.java ] [ dir:test ] [ ] ``` Note that this optimization will have several side effects: 1. Since this optimization aggregates `PathSpec` and compiles them within the same stage, the stage execution time may increase. This means that if `_settings.stage_wait_duration_secs` is set to a low value, turning this on may cause previously working pipelines to time out. A possible solution is to increase `_settings.stage_wait_duration_secs`. 2. This optimization will join all `PathSpec` into one command for compilation, meaning that if one source file (or a dependent source file) fails to compile, there is no guarantee which files will have been compiled. A possible workaround for this issue is to disable this optimization, or specify more than one `JavaCompile` stages. ## Report See the Report section of [Compile](Compile.md).