📜Fast-forward to install-jdk.sh section.
Use Java source to build your modular Java project.
No need to be a maven to be able to use a build tool - forax/pro
Ranging from JDK Foundation Tools, over shell scripts and Apache Ant to multi-language, multi-purpose build tools...
...Bach.java
's target is between platform-specific shell scripts and Apache Ant.
Simplistic Use Bach.java as a Java-based script template and manually call JDK Foundation Tools -- just like in platform-specific shell scripts.
Call load(URI)
to load 3rd-party modules, run(String tool, String... args)
to run provided tools, and start(String... command)
to execute commands on the command-line.
Lightweight Let module de.sormuras.bach
automatically order the right calls to JDK Foundation Tools based on your module-info.java
declarations.
- Installation-free via
jshell https://bit.ly/bach-jsh
. - Download module
de.sormuras.bach
to yourlib/
directory and use it directly.
- zero installation required (besides JDK 11+, using
jshell
) - zero configuration required (conventions and information gathered from
module-info.java
files) - customize with properties to override auto-configured values (
.bach/project.properties
) - b-y-o-b program using plain old Java (
src/bach/Build.java
) - 3rd-party modules in plain sight (single
lib/
directory) - compilation is compile (
javac
) and package (jar
) as an atomic step - multi-module compilation in a single pass (
--module-source-path
,${PROJECT.NAME}-javadoc.jar
) - multi-release modules are supported (
java-7
,java-8
, ...,java-11
, ...,java-N
) - automated checks (aka testing) built-in (
test(${MODULE})
,junit
) - deployment support (via
${MODULE}-sources.jar
and consumerpom.xml
per module)
Enter the base directory of your Java project, open a shell, and execute one of the following commands:
- Long:
jshell https://raw.githubusercontent.com/sormuras/bach/master/src/bach/Bach.jsh
- Shorter:
jshell https://github.com/sormuras/bach/raw/master/src/bach/Bach.jsh
- Shortened:
jshell https://bit.ly/bach-jsh
That's it.
Almost all required information to build a modular Java project is either deduced from conventions or gathered from
module declarations, i.e. module-info.java
files.
- Required modules' versions via https://github.com/sormuras/modules
Also, the following attributes are extracted from comments (soon annotations?) found in module declarations:
- Module version
--module-version ...
- Module entry-point
--main-class ...
The default ProjectBuilder
implementation loads some properties from a .bach/project.properties
file.
Here, you may set different values for project properties like name
, version
, etc.
Does your project use a different structure? Want to execute tasks is a different order? Need additional tasks to be executed? Want skip tests?
Write your own build program using plain old Java!
Store your build program as src/bach/Build.java
and Bach.java will delegate to it.
To make your own build program runnable from within an IDE, you need to download and mount module de.sormuras.bach
first.
After that simply run the de.sormuras.bach
module.
All 3rd-party modules are stored in plain sight: lib/
3rd-party modules are all modules that are not declared in your project and that are not modules provided by the system, i.e. the current Java runtime.
How do you provide 3rd-party modules?
- Load and drop modular JAR files into the
lib/
directory.
Missing 3rd-party modules are being resolved in a best-effort manner using sormuras/modules database.
javac
+jar
Exploded class files are only a intermediate state. This ensures, that at test runtime, you're checking your modules as if they are already published. Including loading services and resources. And multi-release modules.
Using the --module-source-path
option from javac
all modules are compiled in a single pass.
With the exception multi-release modules - they are build before any other module.
Organize your Java sources in targeted directories to create a multi-release JAR.
src/${REALM}/
java-7/
java-8/
java-9/
module-info.java
...
java-N/
Multi-release modules are compiled ahead of any other (read: normal Jigsaw-style) module.
Two kinds of automated checks per module are supported:
-
Run a provided tool named
test(${MODULE})
via ToolProvider SPImodule m { provides java.util.spi.ToolProvider with m.MyModuleTestProgram; }
package m; // in module m public class MyModuleTestProgram implements java.util.spi.ToolProvider { @Override public String name() { return "test(m)"; } @Override public int run(java.io.PrintWriter out, java.io.PrintWriter err, String... args) { try { // HERE BE DRAGONS! Erm, calls to your "test" code. return 0; } catch (Throwable throwable) { throwable.printStackTrace(err); return 1; } } }
-
Run JUnit Platform with selecting the current module under test
open /*test*/ module t { requires org.junit.jupiter; // pulls in API, Params, and more... }
Write your JUnit 5 (read: Jupiter) tests as usual.
Bach supports full modular in-module testing with real test modules.
Test modules are declared as normal Java modules.
There's neither a need for an extra DSL nor resorting to command-line options via module-info.test
.
open /*test*/ module m /*extends "main" module*/ {
// "test"
requires org.junit.jupiter;
// "main" -- below statements are copied from the main module declaration
requires java.logging;
requires java.net.http;
requires java.xml;
exports m.api;
uses java.util.spi.ToolProvider;
}
Bach takes care to load and use the appropriate JUnit Platform modules and also resolves "missing" test engines.
- For each module a
${MODULE}-${VERSION}-sources.jar
is created. - If a consumer
pom.xml
is stored insrc/${MODULE}/main/maven/
, Maven-based install and deploy scripts will be created.
install-jdk.sh
main purpose is to install the latest-and-greatest available OpenJDK release from jdk.java.net.
Find a Travis CI matrix configuration at sormuras.github.io/.travis.yml.
-h|--help Displays this help
-d|--dry-run Activates dry-run mode
-s|--silent Displays no output
-e|--emit-java-home Print value of "JAVA_HOME" to stdout (ignores silent mode)
-v|--verbose Displays verbose output
-f|--feature 9|11|...|ea JDK feature release number, defaults to "ea"
-o|--os linux-x64|osx-x64 Operating system identifier
-u|--url "https://..." Use custom JDK archive (provided as .tar.gz file)
-w|--workspace PATH Working directory defaults to user's ${HOME}
-t|--target PATH Target directory, defaults to first real component of the tarball
-c|--cacerts Link system CA certificates (currently only Debian/Ubuntu is supported)
-
Source
install-jdk.sh
into current shell to install latest OpenJDK and let it updateJAVA_HOME
andPATH
environment variables:source ./install-jdk.sh
Caveat: if an error happens during script execution the calling shell will terminate
-
Provide target directory path to use as
JAVA_HOME
:JAVA_HOME=~/jdk && ./install-jdk.sh --target $JAVA_HOME && PATH=$JAVA_HOME/bin:$PATH
-
Run
install-jdk.sh
in a sub-shell to install latest OpenJDK and emit the installation path tostdout
:JAVA_HOME=$(./install-jdk.sh --silent --emit-java-home)
JAVA_HOME=$(./install-jdk.sh --emit-java-home | tail --lines 1)