Skip to content
/ bach Public
forked from sormuras/bach

🎼 Java Shell Builder - Use jshell/java to build your modular Java project

License

Notifications You must be signed in to change notification settings

bbelovic/bach

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Bach.java 2.0-ea - Java Shell Builder

jdk11 experimental github actions jitpack bintray central slides

📜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... jdk-and-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 your lib/ directory and use it directly.

Uniques

  • 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 consumer pom.xml per module)

Zero Installation

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.

Zero Configuration

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.

Also, the following attributes are extracted from comments (soon annotations?) found in module declarations:

  • Module version --module-version ...
  • Module entry-point --main-class ...

Customize Via Properties

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.

Bring Your Own Build

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.

3rd-party Modules

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.

Compilation = Compile + Package

  • 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.

Multi Module

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.

Multi Release

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.

Automated Checks

Two kinds of automated checks per module are supported:

  • Run a provided tool named test(${MODULE}) via ToolProvider SPI

    module 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.

Deployment

  • For each module a ${MODULE}-${VERSION}-sources.jar is created.
  • If a consumer pom.xml is stored in src/${MODULE}/main/maven/, Maven-based install and deploy scripts will be created.

install-jdk.sh

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.

Options of install-jdk.sh

-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)

How to set JAVA_HOME with install-jdk.sh

  • Source install-jdk.sh into current shell to install latest OpenJDK and let it update JAVA_HOME and PATH 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 to stdout:

    • JAVA_HOME=$(./install-jdk.sh --silent --emit-java-home)
    • JAVA_HOME=$(./install-jdk.sh --emit-java-home | tail --lines 1)

be free - have fun

jsb

About

🎼 Java Shell Builder - Use jshell/java to build your modular Java project

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Java 94.8%
  • Shell 5.2%