Giter Site home page Giter Site logo

java-rules's Introduction

Java rules

This repo provides Java rules for the please build system.

Basic usage

See ./example in this repo for a working example.

# BUILD
# This adds the plugin to your project
github_repo(
    name = "java_rules",
    repo = "please-build/java-rules",
    revision = "<Some git tag, commit, or other reference>",
)

# src/main/java/build/please/foo/BUILD
# This defines a java library that can be depended on by other Java rules
java_library(
    name = "foo",
    srcs = ["Foo.java"],
    visibility = ["//src/test/java/build/please/..."]
)

# src/test/java/build/please/foo/BUILD
# A test for the above library. 
java_test(
    name = "foo_test",
    srcs = ["FooTest.java"],
    deps = [
        "//third_party/java:junit", 
        "//src/main/java/build/please/foo",
    ]
)

# src/main/java/build/please/foo/BUILD
# This produces a self-executing .jar 
java_binary(
    name = "app",
    main_class = "build.please.Main",
    srcs = ["Main.java"],
    deps = ["//src/main/java/build/please/foo"]
)

# third_party/java/BUILD
# These rules pull down third party dependencies from maven. 
maven_jar(
    name = "junit",
    hash = "59721f0805e223d84b90677887d9ff567dc534d7c502ca903c0c2b17f05c116a",
    id = "junit:junit:4.12",
    deps = [
        ":hamcrest",
    ],
)

maven_jar(
    name = "hamcrest",
    hash = "4877670629ab96f34f5f90ab283125fcd9acb7e683e66319a68be6eb2cca60de",
    id = "org.hamcrest:hamcrest-all:1.3",
)

Then add this to your .plzconfig:

[Parse]
PreloadSubincludes = @java_rules//build_defs:java

Alternatively, if you're not using Java everywhere, you may add subinclude("@java_rules//build_defs:java") to each BUILD individually.

Toolchain

By default, Please will use the JDK on the path. Optionally, you may use java_toolchain() to manage your JDK:

# third_party/java/BUILD
java_toolchain(
    name = "toolchain",
    jdk_url = "https://corretto.aws/downloads/resources/11.0.8.10.1/amazon-corretto-11.0.8.10.1-linux-x64.tar.gz",
)

This can then be configured to be used by adding the following config:

[Plugin "Java"]
Toolchain = //third_party/java:toolchain

Configuration

Plugins are configured through the Plugin section like so:

[Plugin "java"]
SomeConfig = some value

The available configuration options for this plugin are documented here.

JavacTool

The path to the Java compiler to use. Defaults to javac.

[Plugin "java"]
JavacTool = /opt/java/bin/javac

JavacFlags

Any additional flags to apply to the javac tool.

[Plugin "java"]
JavacFalgs = --flag1 --flag2

JavacTestFlags

Any additional flags to apply to the javac tool when compiling tests.

[Plugin "java"]
TestJavacFlags = --flag1 --flag2

JunitRunner

The tool used to run Java tests. Defaults to the junit runner for this plugin version i.e. @java_rules//tools:junit_runner

[Plugin "java"]
JunitRunner = /opts/please/bin/junit_runner

or

[Plugin "java"]
JunitRunner = //tools:my_custom_junit_runner

SourceLevel

The source level of the project. Defaults to 8.

[Plugin "java"]
SourceLevel = 15

TargetLevel

The target level of the project. Defaults to 8.

[Plugin "java"]
TargetLevel = 15

ReleaseLevel

The release level of the project. Defaults to 8.

[Plugin "java"]
ReleaseLevel = 15

Toolchain

If set, please will use the jdk provided by the java_toolchain() rule specified by this build label. See the toolchain section above for more info.

[Plugin "java"]
Toolchain = //third_party/java:toolchain

DefaultTestPackage

The test package to use when none is specifically set on the java_test() rule. If not set, Please will run all tests present in the .jar that are not from third party code.

[Plugin "java"]
DefaultTestPackage = please.build.

MavenRepo

The maven repositories to load jars from. This value can be repeated and defaults to https://repo1.maven.org/maven2 and https://repo.maven.apache.org/maven2, the canonical Maven Central repository URLs.

To add a custom repo, you may do so by setting the following:

[Plugin "java"]
MavenRepo = https://repo1.maven.org/maven2
MavenRepo = https://repo.maven.apache.org/maven2
MavenRepo = https://maven.repo.org

java-rules's People

Contributors

chrisnovakovic avatar peterebden avatar samwestmoreland avatar tatskaari avatar

Watchers

 avatar

java-rules's Issues

JREs created from `java_toolchain` JDKs may lack required dependencies

Native-code objects (binaries, shared objects) inside the modules that comprise a JDK will usually rely on shared libraries. This isn't a problem for widely-installed libraries like glibc/musl; where it does become a problem is when shared libraries are linked to the JDK at compile time but they then aren't bundled with the JDK distribution, in which case the JDK relies on them existing in the loader's default search path. An example of this is Corretto, which contains a java.base module with shared objects that link to zlib but now no longer has zlib bundled in its release tarballs.

This really becomes a problem for JREs that are generated from JDKs using jlink, because any missing external dependencies in the JDK also become missing dependencies in the generated JRE. The JRE then can't be used in a stripped-down runtime environment (e.g. a distroless container image) without the missing dependencies being copied into the image - these will typically be pre-built shared objects provided by Linux distributions, which will be defined and managed separately from the java_toolchain target that created the JRE.

To solve this, it would be useful to have the ability to make the java_toolchain output "complete" at the time at which it is declared - that is, provide a new parameter, e.g. jmod_extras, that allows the user to define additional files that should be slipstreamed into the toolchain's jmod archives:

java_toolchain(
    name = "toolchain",
    hashes = ["008fae961dfd0df99cbc888a0279561458fe830797646234efe7daed8e512040"],
    jdk_url = "https://corretto.aws/downloads/resources/11.0.23.9.1/amazon-corretto-11.0.23.9.1-linux-x64.tar.gz",
    jmod_extras = {
        "java.base": {
            "lib/libz.so.1": ":libz", # or some other target providing the zlib shared object
        },
    },
)

The JDK toolchain outputted by this target would then be fully self-contained (with the obvious exception of glibc).

`java_runtime_image` has confusing and unnecessary `main_*` parameters

java_runtime_image has two mandatory parameters, main_module and main_class, which become part of the --launcher argument to jlink.

There are two problems here:

  1. The naming of the parameters implies that the given module and class are somehow the entry point into the runtime image (which is how, say, a JAR file would work), but this isn't the case - the --launcher argument simply creates a launcher script in the runtime image it outputs (cmd.exe-compatible for Windows, sh-compatible for POSIX). It's perfectly fine to ignore this script and run some other module/class with the copy of bin/java in the image, or indeed any of the other tools in bin/ with no module/class at all.
  2. --launcher isn't a mandatory argument to jlink - if omitted, jlink simply won't create a launcher script in the runtime image it outputs. This artificially limits the power of java_runtime_image - for example, it could be used to generate a JRE from a JDK, but can't because of this restriction.

It'd be good to rename these parameters so their purpose is clearer - I suggest launcher_module and launcher_class - and make them optional, omitting the --launcher argument to jlink if they aren't specified.

"Empty source path" error when `JavacTool` is undefined

Perhaps not a bug, but the behaviour is a bit surprising, and it might be confusing to track down the source of the problem if you don't know what's going on in this plugin.

MWE (with the Java plugin already enabled, and without defining a value for Toolchain):

java_library(
    name = "x",
    srcs = ["X.java"], # Can be an empty file - it's not important for the purposes of this MWE
)
$ plz build //:x
    //:x
Empty source path
Traceback:
plz-out/gen/java/build_defs/java.build_defs:80:16:   <source unavailable>

plz-out/gen/java/build_defs/java.build_defs, line 38: 5:   <source unavailable>
                 BUILD: 1: 1:

This happens because JavacTool doesn't have a default value if no default Java toolchain is defined, meaning that javac in the java_library build def has the value None, and (of course) it's illegal to pass None as the value of a tool to build_rule. I think it makes sense to define javac as the default value for JavacTool - other plugins expect to find tools by their default name on the system path, so at least this would be consistent.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.