Giter Site home page Giter Site logo

rules_jvm's Introduction

contrib_rules_jvm

Handy rules for working with JVM-based projects in Bazel.

This ruleset is designed to complement rules_java (and Bazel's built-in Java rules), not replace them.

The intended way of working is that the standard rules_java rules are used, and this ruleset adds extra functionality which is compatible with rules_java.

Using these rules

In order to use these in your own projects, in your WORKSPACE once you've used an http_archive, you can load all the necessary dependencies by:

load("@contrib_rules_jvm//:repositories.bzl", "contrib_rules_jvm_deps")

contrib_rules_jvm_deps()

load("@contrib_rules_jvm//:setup.bzl", "contrib_rules_jvm_setup")

contrib_rules_jvm_setup()

If you're looking to get started quickly, then take a look at java_test_suite (a macro for generating a test suite from a glob of java test sources) and java_junit5_test (a drop-in replacement for java_test that can run JUnit5 tests)

Linting

Many of the features in this repo are designed to be exposed via apple_rules_lint, which provides a framework for integrating linting checks into your builds. To take advantage of this perform the following steps:

# In your WORKSPACE, after loading `apple_rules_lint`

load("@apple_rules_lint//lint:setup.bzl", "lint_setup")

lint_setup({
  # Note: this is an example config!
  "java-checkstyle": "@contrib_rules_jvm//java:checkstyle-default-config",
  "java-pmd": "@contrib_rules_jvm//java:pmd-config",
  "java-spotbugs": "@contrib_rules_jvm//java:spotbugs-default-config",
})

You are welcome to include all (or none!) of these rules, and linting is "opt-in": if there's no lint_setup call in your repo's WORKSPACE then everything will continue working just fine and no additional lint tests will be generated.

The linters are configured using specific rules. The mappings are:

Well known name Lint config rule
java-checkstyle checkstyle_config
java-pmd pmd_ruleset
java-spotbugs spotbugs_config

Requirements

These rules require Java 11 or above.

The gazelle plugin requires Go 1.18 or above.

Java Rules

checkstyle_config

checkstyle_config(name, checkstyle_binary, config_file, data, output_format)

Rule allowing checkstyle to be configured. This is typically used with the linting rules from @apple_rules_lint to configure how checkstyle should run.

ATTRIBUTES

Name Description Type Mandatory Default
name A unique name for this target. Name required
checkstyle_binary Checkstyle binary to use. Label optional @contrib_rules_jvm//java:checkstyle_cli
config_file The config file to use for all checkstyle tests Label required
data Additional files to make available to Checkstyle such as any included XML files List of labels optional []
output_format Output format to use. Defaults to plain String optional "plain"

pmd_ruleset

pmd_ruleset(name, format, pmd_binary, rulesets, shallow)

Select a rule set for PMD tests.

ATTRIBUTES

Name Description Type Mandatory Default
name A unique name for this target. Name required
format Generate report in the given format. One of html, text, or xml (default is xml) String optional "xml"
pmd_binary PMD binary to use. Label optional //java:pmd
rulesets Use these rulesets. List of labels optional []
shallow Use the targetted output to increase PMD's depth of processing Boolean optional True

pmd_test

pmd_test(name, ruleset, srcs, target)

Use PMD to lint the srcs.

ATTRIBUTES

Name Description Type Mandatory Default
name A unique name for this target. Name required
ruleset - Label required
srcs - List of labels optional []
target - Label optional None

spotbugs_config

spotbugs_config(name, effort, exclude_filter, fail_on_warning, plugin_list, spotbugs_binary)

Configuration used for spotbugs, typically by the //lint rules.

ATTRIBUTES

Name Description Type Mandatory Default
name A unique name for this target. Name required
effort Effort can be min, less, default, more or max. Defaults to default String optional "default"
exclude_filter Report all bug instances except those matching the filter specified by this filter file Label optional None
fail_on_warning Whether to fail on warning, or just create a report. Defaults to True Boolean optional True
plugin_list Specify a list of plugin Jar files to load List of labels optional []
spotbugs_binary The spotbugs binary to run. Label optional @contrib_rules_jvm//java:spotbugs_cli

spotbugs_test

spotbugs_test(name, config, deps, only_output_jars)

Use spotbugs to lint the srcs.

ATTRIBUTES

Name Description Type Mandatory Default
name A unique name for this target. Name required
config - Label optional @contrib_rules_jvm//java:spotbugs-default-config
deps - List of labels required
only_output_jars If set to true, only the output jar of the target will be analyzed. Otherwise all transitive runtime dependencies will be analyzed Boolean optional True

checkstyle_binary

checkstyle_binary(name, main_class, deps, runtime_deps, srcs, visibility, kwargs)

Macro for quickly generating a java_binary target for use with checkstyle_config.

By default, this will set the main_class to point to the default one used by checkstyle but it's ultimately a drop-replacement for straight java_binary target.

At least one of runtime_deps, deps, and srcs must be specified so that the java_binary target will be valid.

An example would be:

checkstyle_binary(
    name = "checkstyle_cli",
    runtime_deps = [
        artifact("com.puppycrawl.tools:checkstyle"),
    ]
)

PARAMETERS

Name Description Default Value
name The name of the target none
main_class The main class to use for checkstyle. "com.puppycrawl.tools.checkstyle.Main"
deps The deps required for compiling this binary. May be omitted. None
runtime_deps The deps required by checkstyle at runtime. May be omitted. None
srcs If you're compiling your own checkstyle binary, the sources to use. None
visibility

-

["//visibility:public"]
kwargs

-

none

checkstyle_test

checkstyle_test(name, size, timeout, kwargs)

PARAMETERS

Name Description Default Value
name

-

none
size

-

"medium"
timeout

-

"short"
kwargs

-

none

java_binary

java_binary(name, kwargs)

Adds linting tests to Bazel's own java_binary

PARAMETERS

Name Description Default Value
name

-

none
kwargs

-

none

java_export

java_export(name, maven_coordinates, pom_template, deploy_env, visibility, kwargs)

Adds linting tests to rules_jvm_external's java_export

PARAMETERS

Name Description Default Value
name

-

none
maven_coordinates

-

none
pom_template

-

None
deploy_env

-

None
visibility

-

None
kwargs

-

none

java_junit5_test

java_junit5_test(name, test_class, runtime_deps, package_prefixes, jvm_flags, include_tags,
                 exclude_tags, include_engines, exclude_engines, kwargs)

Run junit5 tests using Bazel.

This is designed to be a drop-in replacement for java_test, but rather than using a JUnit4 runner it provides support for using JUnit5 directly. The arguments are the same as used by java_test.

By default Bazel, and by extension this rule, assumes you want to always run all of the tests in a class file. The include_tags and exclude_tags allows for selectively running specific tests within a single class file based on your use of the @Tag Junit5 annotations. Please see the JUnit 5 docs for more information about using JUnit5 tag annotation to control test execution.

The generated target does not include any JUnit5 dependencies. If you are using the standard @maven namespace for your maven_install you can add these to your deps using JUNIT5_DEPS or JUNIT5_VINTAGE_DEPS loaded from //java:defs.bzl

Note: The junit5 runner prevents System.exit being called using a SecurityManager, which means that one test can't prematurely cause an entire test run to finish unexpectedly. This security measure prohibits tests from setting their own SecurityManager. To override this, set the bazel.junit5runner.allowSettingSecurityManager system property.

While the SecurityManager has been deprecated in recent Java releases, there's no replacement yet. JEP 411 has this as one of its goals, but this is not complete or available yet.

PARAMETERS

Name Description Default Value
name The name of the test. none
test_class The Java class to be loaded by the test runner. If not specified, the class name will be inferred from a combination of the current bazel package and the name attribute. None
runtime_deps

-

[]
package_prefixes

-

[]
jvm_flags

-

[]
include_tags Junit5 tag expressions to include execution of tagged tests. []
exclude_tags Junit tag expressions to exclude execution of tagged tests. []
include_engines A list of JUnit Platform test engine IDs to include. []
exclude_engines A list of JUnit Platform test engine IDs to exclude. []
kwargs

-

none

java_library

java_library(name, kwargs)

Adds linting tests to Bazel's own java_library

PARAMETERS

Name Description Default Value
name

-

none
kwargs

-

none

java_test

java_test(name, kwargs)

Adds linting tests to Bazel's own java_test

PARAMETERS

Name Description Default Value
name

-

none
kwargs

-

none

java_test_suite

java_test_suite(name, srcs, runner, test_suffixes, package, deps, runtime_deps, size, kwargs)

Create a suite of java tests from *Test.java files.

This rule will create a java_test for each file which matches any of the test_suffixes that are passed to this rule as srcs. If any non-test sources are added these will first of all be compiled into a java_library which will be added as a dependency for each test target, allowing common utility functions to be shared between tests.

The generated java_test targets will be named after the test file: FooTest.java will create a :FooTest target.

In addition, a test_suite will be created, named using the name attribute to allow all the tests to be run in one go.

PARAMETERS

Name Description Default Value
name A unique name for this rule. Will be used to generate a test_suite none
srcs Source files to create test rules for. none
runner One of junit4 or junit5. "junit4"
test_suffixes The file name suffix used to identify if a file contains a test class. ["Test.java"]
package The package name used by the tests. If not set, this is inferred from the current bazel package name. None
deps A list of java_* dependencies. None
runtime_deps A list of java_* dependencies needed at runtime. []
size The size of the test, passed to java_test None
kwargs

-

none

pmd_binary

pmd_binary(name, main_class, deps, runtime_deps, srcs, visibility, kwargs)

Macro for quickly generating a java_binary target for use with pmd_ruleset.

By default, this will set the main_class to point to the default one used by PMD but it's ultimately a drop-replacement for a regular java_binary target.

At least one of runtime_deps, deps, and srcs must be specified so that the java_binary target will be valid.

An example would be:

pmd_binary(
    name = "pmd",
    runtime_deps = [
        artifact("net.sourceforge.pmd:pmd-dist"),
    ],
)

PARAMETERS

Name Description Default Value
name The name of the target none
main_class The main class to use for PMD. "net.sourceforge.pmd.PMD"
deps The deps required for compiling this binary. May be omitted. None
runtime_deps The deps required by PMD at runtime. May be omitted. None
srcs If you're compiling your own PMD binary, the sources to use. None
visibility

-

["//visibility:public"]
kwargs

-

none

spotbugs_binary

spotbugs_binary(name, main_class, deps, runtime_deps, srcs, visibility, kwargs)

Macro for quickly generating a java_binary target for use with spotbugs_config.

By default, this will set the main_class to point to the default one used by spotbugs but it's ultimately a drop-replacement for a regular java_binary target.

At least one of runtime_deps, deps, and srcs must be specified so that the java_binary target will be valid.

An example would be:

spotbugs_binary(
    name = "spotbugs_cli",
    runtime_deps = [
        artifact("com.github.spotbugs:spotbugs"),
        artifact("org.slf4j:slf4j-jdk14"),
    ],
)

PARAMETERS

Name Description Default Value
name The name of the target none
main_class The main class to use for spotbugs. "edu.umd.cs.findbugs.LaunchAppropriateUI"
deps The deps required for compiling this binary. May be omitted. None
runtime_deps The deps required by spotbugs at runtime. May be omitted. None
srcs If you're compiling your own spotbugs binary, the sources to use. None
visibility

-

["//visibility:public"]
kwargs

-

none

Freezing Dependencies

At runtime, a handful of dependencies are required by helper classes in this project. Rather than pollute the default @maven workspace, these are loaded into a @contrib_rules_jvm_deps workspace. These dependencies are loaded using a call to maven_install, but we don't want to force users to remember to load our own dependencies for us. Instead, to add a new dependency to the project:

  1. Update frozen_deps in the WORKSPACE file
  2. Run ./tools/update-dependencies.sh
  3. Commit the updated files.

Freezing your dependencies

As noted above, if you are building Bazel rules which require Java parts, and hence Java dependencies, it can be useful to freeze these dependencies. This process captures the list of dependencies into a zip file. This zip file is distributed with your Bazel rules. This makes your rule more hermetic, your rule no longer relies on the user to supply the correct dependencies, because they get resolved under their own repository namespace rather than being intermingled with the user's, and your dependencies no longer conflict with the users selections. If you would like to create your dependencies as a frozen file you need to do the following:

  1. Create a maven install rule with your dependencies and with a unique name, this should be in or referenced by your WORKSPACE file.
    maven_install(
         name = "frozen_deps",
         artifacts = [...],
         fail_if_repin_required = True,
         fetch_sources = True,
         maven_install_json = "@workspace//:frozen_deps_install.json",
    )
    
    load("@frozen_deps//:defs.bzl", "pinned_maven_install")
    
    pinned_maven_install()
  2. Run bazel run //tools:freeze-deps -- --repo <repo name> --zip <path/to/dependency.zip>. The <repo name> matches the name used for the maven_install() rule above. This will pin the dependencies then collect them into the zip file.
  3. Commit the zip file into your repo.
  4. Add a zip_repository() rule to your WORKSPACE to configure the frozen dependencies:
    maybe(
        zip_repository,
        name = "workspace_deps",
        path = "@workspace//path/to:dependency.zip",
    )
  5. Make sure to pin the maven install from the repostitory:
    load("@workspace_deps//:defs.bzl", "pinned_maven_install")
    
    pinned_maven_install()
  6. Use the dependencies for your java_library rules from the frozen deps:
    java_library(
         name = "my_library",
         srcs = glob(["*.java"]),
         deps = [
              "@workspace_deps//:my_frozen_dep",
         ],
    )

NOTE: If you need to generate the compat_repositories for the dependencies, usually because your rule depends on another rule which is still using the older compat repositories, you need to make the following changes and abide by the following restrictions.

  1. Add the generate_compat_repositories = True, attribute to the original maven_install() rule.
  2. In step 2, add the parameter --zip-repo workspace_deps to match the name used in the zip_repository() rule (step 4). If you don't supply this, it uses the base name of the zip file, which may not be what you want.
  3. In step 5, add the call to generate the compat_repositories:
    load("@workspace_deps//:compat.bzl", "compat_repositories")
    
    compat_repositories()

rules_jvm's People

Contributors

alexeagle avatar bartoszpop avatar blorente avatar bonigarcia avatar caseyduquettesc avatar chrismgrayftsinc avatar firov avatar fmeum avatar gaurav-narula avatar gibfahn avatar guw avatar hanikesn avatar hisener avatar hjellek avatar ignas avatar illicitonion avatar luangong avatar lyao-77 avatar marcphilipp avatar meowcakes avatar mwindmark avatar rdesgroppes avatar robertgates55 avatar rsalvador avatar shs96c avatar stevebarrau avatar tharakadesilva avatar thirtyseven avatar tjoneslo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rules_jvm's Issues

Fetching dependencies for JUnit5 runner tries to use local java

I have a simple project that uses Bazel 6.3 and bzlmod:

bazel_dep(name = "bazel_skylib", version = "1.4.1")
bazel_dep(name = "rules_jvm_external", version = "5.3")
bazel_dep(name = "contrib_rules_jvm", version = "0.13.0")

# Maven

maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
maven.install(
    artifacts = [
        # Null-check annotations
        "com.google.code.findbugs:jsr305:3.0.2",
        # Record Builders
        "io.soabase.record-builder:record-builder-core:37",
        "io.soabase.record-builder:record-builder-processor:37",
        # JUnit 5
        "org.junit.jupiter:junit-jupiter-api:5.10.0",
        "org.junit.jupiter:junit-jupiter-params:5.10.0",
        "org.junit.jupiter:junit-jupiter-engine:5.10.0",
        "org.junit.platform:junit-platform-console:1.10.0",
        "org.junit.platform:junit-platform-launcher:1.10.0",
        "org.junit.platform:junit-platform-reporting:1.10.0",
        "org.assertj:assertj-core:3.11.1",
    ],
    lock_file = "//:maven_install.json",
)
use_repo(maven, "maven", "unpinned_maven")

In my .bazelrc I'm passing the following options:

--host_jvm_args=-DBAZEL_TRACK_SOURCE_DIRECTORIES=1
  Inherited 'common' options: --isatty=0 --terminal_columns=80
  Inherited 'common' options: --enable_platform_specific_config --heap_dump_on_oom
  Inherited 'common' options: --java_language_version=17 --java_runtime_version=remotejdk_17 --tool_java_language_version=17 --tool_java_runtime_version=remotejdk_17
  Inherited 'common' options: --enable_bzlmod --@aspect_rules_ts//ts:skipLibCheck=honor_tsconfig
  'build' options: --noexperimental_check_external_repository_files --reuse_sandbox_directories --noexperimental_action_cache_store_output_metadata
  'build' options: --keep_going --show_result=20
  'build' options: --noremote_upload_local_results --sandbox_default_allow_network=false --incompatible_strict_action_env --experimental_allow_tags_propagation --incompatible_default_to_explicit_init_py
  'build' options: --noexperimental_check_output_files --incompatible_remote_results_ignore_disk --reuse_sandbox_directories --nolegacy_external_runfiles --modify_execution_info=PackageTar=+no-remote
  'build' options: --enable_runfiles
  'build' options: --announce_rc --show_timestamps --show_progress_rate_limit=60 --curses=no --color=yes --terminal_columns=120

Note the 'remotejdk_17' for both 'java_runtime_version' and 'tool_java_runtime_version'. The build succeeds locally where I have a JDK installed, but on a CI worker that has not default JDK, it fails with the following errors:

(09:03:59) ERROR: /home/runner/.cache/bazel/_bazel_runner/e6da7a7eb18341b583e9a02b4c4359f9/external/contrib_rules_jvm~0.13.0/java/src/com/github/bazel_contrib/contrib_rules_jvm/junit5/BUILD.bazel:44:13: @contrib_rules_jvm~0.13.0//java/src/com/github/bazel_contrib/contrib_rules_jvm/junit5:junit5-compile depends on @rules_jvm_external~5.3~maven~contrib_rules_jvm_deps//:org_junit_platform_junit_platform_commons in repository @rules_jvm_external~5.3~maven~contrib_rules_jvm_deps which failed to fetch. no such package '@rules_jvm_external~5.3~maven~contrib_rules_jvm_deps//': Unable to run coursier: /home/runner/.cache/bazel/_bazel_runner/e6da7a7eb18341b583e9a02b4c4359f9/external/rules_jvm_external~5.3~maven~contrib_rules_jvm_deps/coursier: 26: exec: java: not found

Same error repeats for other JUnit dependencies. AFAIK, this is the internal dependencies of rules_jvm that we are trying to fetch, but somewhere along the line the JDK toolchain is no longer remote.

Is this a bug, or am I doing something wrong? Can I somehow pass the correct toolchain to rules_jvm to use?

Checkstyle version should be configurable

Checkstyle as a project seems to rename and deprecate config settings relatively quickly, when fixing #3 I discovered that the sample configs already checked into this repo aren't even compatible with the Checkstyle version pinned in contrib_rules_jvm_deps.zip.

It's inconvenient for new users of this rule to have to manually update existing config files that might be quite old, and going forwards when Checkstyle makes config changes in new versions, either this project will have to stay stuck on the old version to prevent breaking downstream users, or users will be stuck on old releases until they can update their configs.

That being said this is probably a pretty low priority item right now, but might be worth considering in the future especially when a new major version of Checkstyle is released.

Support exclusions in addition to test_suffixes in java_test_suite

java_test_suite currently supports test_suffixes for detecting test classes and separating them from shared code.

The code doing the selection tests for the suffix matching.

def _is_test(src, test_suffixes):
for suffix in test_suffixes:
if src.endswith(suffix):
return True
return False

I was wondering if it's possible to allow exclusions there. We have a large existing code base and many files end with ...BaseTest.java. They are not tests but base classes for other tests. Perhaps something like:

    test_suffixes = ["Test.java"],
    test_suffixes_excludes = ["BaseTest.java"],

FR: Gazelle flag to pass in maven_install path

Was looking at RegisterFlags and it'd be nice to be able to pass in the path to our maven_install.json file through the command line flags. This would, in theory, allow us to pass in a target label there that bazel could resolve to an actual path for us.

I'm imagining something like this

gazelle(
    name = "gazelle",
    gazelle = ":gazelle_bin",
    args = [
        "-java-maven-install-file=$(location @maven_dependencies//:maven_install.json)",
    ],
)

My use case is we have a rule that has abstracted away the locking process to avoid potential merge conflicts by managing the file for our devs. However, this means we don't have a stable path to provide the directive in the build file for gazelle.

The workaround I'm exploring now is pointing //:gazelle to a genrule instead that copies the maven_install.json to a stable location and then calls gazelle and then removes the file.

`bazel run //:gazelle` could not find javaparser-wrapper

When attempting to run gazelle I get the following error:

12:05PM FTL external/contrib_rules_jvm/java/gazelle/private/javaparser/javaparser.go:29 > could not find javaparser-wrapper

rules_jvm version: commit f1b987eeecaaa457b3d4a4367f7fff734799e95a
bazel version: both 4.2.1 and 5.1.1

I have confirmed that javaparser-wrapper exists in bazel-bin.

FR: Allow disabling or customizing proto rule generation

Currently this always generates the following rules when a proto_library rule is present:

java_proto_library(
    name = "my_java_proto",
    deps = [":my_proto"],
)

java_library(
    name = "my_java_library",
    visibility = ["//:__subpackages__"],
    exports = [":my_java_proto"],
)

It would be nice if this could be disabled by config or customizable so that it is compatible with other rules, e.g. https://rules-proto-grpc.com/en/latest/lang/java.html#java-proto-library

No way of providing suppressions.xml to checkstyle_config

Common usage of checkstyle involves defining errors to suppress in a separate file and including it like so:

<module name="SuppressionFilter">
        <property name="file" value="suppressions.xml"/>
</module>

However, such files will not be visible to any checkstyle_test targets due to sandboxing, resulting in an error like the following:

com.puppycrawl.tools.checkstyle.api.CheckstyleException: cannot initialize module SuppressionFilter - Unable to find: suppressions.xml
	at com.puppycrawl.tools.checkstyle.Checker.setupChild(Checker.java:473)
	at com.puppycrawl.tools.checkstyle.api.AutomaticBean.configure(AutomaticBean.java:201)
	at com.puppycrawl.tools.checkstyle.Main.runCheckstyle(Main.java:405)
	at com.puppycrawl.tools.checkstyle.Main.runCli(Main.java:332)
	at com.puppycrawl.tools.checkstyle.Main.execute(Main.java:191)
	at com.puppycrawl.tools.checkstyle.Main.main(Main.java:126)
Caused by: com.puppycrawl.tools.checkstyle.api.CheckstyleException: Unable to find: suppressions.xml
	at com.puppycrawl.tools.checkstyle.utils.CommonUtil.getResourceFromClassPath(CommonUtil.java:457)
	at com.puppycrawl.tools.checkstyle.utils.CommonUtil.getFilepathOrClasspathUri(CommonUtil.java:434)
	at com.puppycrawl.tools.checkstyle.utils.CommonUtil.getUriByFilename(CommonUtil.java:385)
	at com.puppycrawl.tools.checkstyle.filters.SuppressionsLoader.loadSuppressions(SuppressionsLoader.java:222)
	at com.puppycrawl.tools.checkstyle.filters.SuppressionFilter.finishLocalSetup(SuppressionFilter.java:274)
	at com.puppycrawl.tools.checkstyle.api.AutomaticBean.configure(AutomaticBean.java:197)
	at com.puppycrawl.tools.checkstyle.Checker.setupChild(Checker.java:468)
	... 5 more
Checkstyle ends with 1 errors.

Worse, since checkstyle_cli does not check the exit code of checkstyle, and the string ERROR is not printed on stdout in the message above, any checkstyle_test that defines a suppression filter will pass without actually being linted.

Two possible changes to make here, let me know if a PR implementing them would be welcome:

  1. Add a data parameter to checkstyle_config allowing extra files to be included in runfiles
  2. Update the checkstyle_cli script to bubble up return code of checkstyle

Failed to find javaparser in runfiles

Attempting to convert a project and am getting a javaparser error.

Expected Outcome:
(At the very least a migrated listed of maven dependencies)

Actual Outcome:
11:03PM FTL external/contrib_rules_jvm/java/gazelle/configure.go:133 > could not start javaparser error="failed to start / connect to javaparser server: failed to find javaparser in runfiles"

Files/Stepts to Reproduce:
Workspace:

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
    name = "io_bazel_rules_go",
    sha256 = "278b7ff5a826f3dc10f04feaf0b70d48b68748ccd512d7f98bf442077f043fe3",
    urls = [
        "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.41.0/rules_go-v0.41.0.zip",
        "https://github.com/bazelbuild/rules_go/releases/download/v0.41.0/rules_go-v0.41.0.zip",
    ],
)

http_archive(
    name = "bazel_gazelle",
    sha256 = "d3fa66a39028e97d76f9e2db8f1b0c11c099e8e01bf363a923074784e451f809",
    urls = [
        "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.33.0/bazel-gazelle-v0.33.0.tar.gz",
        "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.33.0/bazel-gazelle-v0.33.0.tar.gz",
    ],
)

load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository")

go_rules_dependencies()

go_register_toolchains(version = "1.20.5")

gazelle_dependencies()

http_archive(
    name = "contrib_rules_jvm",
    sha256 = "bd0f82def1879df85ff0a80767e6455911e1c9c1eac5db1de8f68dcccd4a3d7a",
    strip_prefix = "rules_jvm-0.18.0",
    url = "https://github.com/bazel-contrib/rules_jvm/releases/download/v0.18.0/rules_jvm-v0.18.0.tar.gz",
)

load("@contrib_rules_jvm//:repositories.bzl", "contrib_rules_jvm_deps")

contrib_rules_jvm_deps()

load("@contrib_rules_jvm//:setup.bzl", "contrib_rules_jvm_setup")

contrib_rules_jvm_setup()

load("@contrib_rules_jvm//:setup.bzl", "contrib_rules_jvm_setup")

contrib_rules_jvm_setup()

load("@contrib_rules_jvm//:repositories.bzl", "contrib_rules_jvm_deps", "contrib_rules_jvm_gazelle_deps")

contrib_rules_jvm_deps()

contrib_rules_jvm_gazelle_deps()

load("@contrib_rules_jvm//:setup.bzl", "contrib_rules_jvm_setup")

contrib_rules_jvm_setup()

load("@contrib_rules_jvm//:gazelle_setup.bzl", "contrib_rules_jvm_gazelle_setup")

contrib_rules_jvm_gazelle_setup()

http_archive(
    name = "com_google_protobuf",
    sha256 = "a79d19dcdf9139fa4b81206e318e33d245c4c9da1ffed21c87288ed4380426f9",
    strip_prefix = "protobuf-3.11.4",
    urls = [
        "https://mirror.bazel.build/github.com/protocolbuffers/protobuf/archive/v3.11.4.tar.gz",
        "https://github.com/protocolbuffers/protobuf/archive/v3.11.4.tar.gz",
    ],
)

load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")

protobuf_deps()

BUILD file:

load("@bazel_gazelle//:def.bzl", "DEFAULT_LANGUAGES", "gazelle", "gazelle_binary")

gazelle(
    name = "gazelle",
    gazelle = ":gazelle_bin",
)

gazelle_binary(
    name = "gazelle_bin",
    languages = DEFAULT_LANGUAGES + [
        "@contrib_rules_jvm//java/gazelle",
    ],
)

Output of bazel build:

bazel build //:gazelle_bin
INFO: Analyzed target //:gazelle_bin (15 packages loaded, 1187 targets configured).
INFO: Found 1 target...
Target //:gazelle_bin up-to-date:
  bazel-bin/gazelle_bin_/gazelle_bin
INFO: Elapsed time: 9.545s, Critical Path: 5.50s
INFO: 84 processes: 3 internal, 70 darwin-sandbox, 11 worker.
INFO: Build completed successfully, 84 total actions

Full Error:

bazel run //:gazelle
INFO: Analyzed target //:gazelle (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //:gazelle up-to-date:
  bazel-bin/gazelle-runner.bash
  bazel-bin/gazelle
INFO: Elapsed time: 0.191s, Critical Path: 0.00s
INFO: 1 process: 1 internal.
INFO: Build completed successfully, 1 total action
INFO: Running command line: bazel-bin/gazelle
11:03PM FTL external/contrib_rules_jvm/java/gazelle/configure.go:133 > could not start javaparser error="failed to start / connect to javaparser server: failed to find javaparser in runfiles"

bazel test fails on 11.0.19 with `ClassNotFoundException: allow` when setting up `SecurityManager`

I am debugging a weird issue where test execution fails with:

Error occurred during initialization of VM
java.lang.Error: Could not create SecurityManager
	at java.lang.System.initPhase3([email protected]/System.java:2065)
Caused by: java.lang.ClassNotFoundException: allow
	at jdk.internal.loader.BuiltinClassLoader.loadClass([email protected]/BuiltinClassLoader.java:581)
	at jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass([email protected]/ClassLoaders.java:178)
	at java.lang.ClassLoader.loadClass([email protected]/ClassLoader.java:522)
	at java.lang.Class.forName0([email protected]/Native Method)
	at java.lang.Class.forName([email protected]/Class.java:398)
	at java.lang.System.initPhase3([email protected]/System.java:2050)

The flag is added by JUnit5 macros.

jvm_flags = jvm_flags + ["-Djava.security.manager=allow"]

I inspected the runfiles tree and liballow.jar as well as the allow.class is on the classpath. Yet the JVM (Azul 11.0.19) is failing to load the SecurityManager.

Discussion at https://bazelbuild.slack.com/archives/CDCE4DFAP/p1693898959307139

A possible workaround is:

bazel test //test_target --test_env="JVM_FLAGS=--version -Djava.lang.SecurityManager=default"

For some reasone --test_env="JVM_FLAGS=-Djava.lang.SecurityManager=default" did not work. I had to use --test_env="JVM_FLAGS=--version -Djava.lang.SecurityManager=default".

FR: Test rule for running google-java-format check

Currently we are doing this outside of the build, e.g. with this alias:

  $ alias gjf
  alias gjf='git show --diff-filter=AMR --pretty="" --name-only HEAD | grep java$ | xargs -r /home/davido/projects/gerrit/tools/format/google-java-format-1.7 -i'

On Slack @shs96c commented how this test rule could be implemented:

We’ve not got a rule for that yet, but the process of writing one is simple enough:

o Create a java_google_format_test rule (it’s important that it’s a test rule!)

o Hook it into _create_lint_tests (the pattern should be obvious)

o Optionally create a rule that when run will actually do the reformatting

o Create either a config rule or just allow people to set True as the value for the workspace’s lint_setup

Once that’s done, anyone using the java_library, java_binary, java_test or java_export rules from contrib_rules_jvm can opt into the linting framework and have the google java formatter be part of their regular test suites.

Update

Linting can be disabled by adding a no-lint tag to any rule that needs it.
And for everything in a build file by using package_lint_config(linters = {}).

It was also pointed out, that there is another PR was uploaded upstream.

java_test_suite silently drops `data`

java_test_suite(
    name = "testsuite",
    size = "small",
    srcs = glob([
        "src/test/java/**/*.java",
    ]),
    data = glob(["src/test/data/**"]),
    resources = glob(["src/test/resources/**"]),
    runner = "junit5",
    runtime_deps = [
        "@org_junit_jupiter_junit_jupiter_engine",
        "@org_junit_platform_junit_platform_launcher",
        "@org_junit_platform_junit_platform_reporting",
        ...
    ],
    deps = [
        ...
    ],
)

I was expecting data to work but looks like it's not passed to the tests.
bazel query --output=build ... unveils:

java_test(
  name = "src/test/java/...Test",
  visibility = ["//visibility:private"],
  tags = [],
  generator_name = "testsuite",
  generator_function = "java_test_suite",
  generator_location = "...",
  size = "small",
  test_class = "...",
  srcs = ["//...Test.java"],
  deps = [...],
  resources = [],
  runtime_deps = [...],
  data = [],
  launcher = "@bazel_tools//tools/jdk:launcher_flag_alias",
  main_class = "com.github.bazel_contrib.contrib_rules_jvm.junit5.JUnit5Runner",
  jvm_flags = ["-Djava.security.manager=allow"],
)

Data is empty in the generated java_test

Gazelle failed to resolve dependencies with v2 lock-file

Hi, I am migrating from v1 to v2 lock-file and getting this error when running gazelle

ERR external/contrib_rules_jvm/java/gazelle/private/maven/resolver.go:77 > Append one of the following to BUILD.bazel: _c=maven-resolver
ERR external/contrib_rules_jvm/java/gazelle/private/maven/resolver.go:79 > # gazelle:resolve java {org.keycloak} @maven//:org_keycloak_keycloak_services _c=maven-resolver
ERR external/contrib_rules_jvm/java/gazelle/private/maven/resolver.go:79 > # gazelle:resolve java {org.keycloak} @maven//:org_keycloak_keycloak_core _c=maven-resolver
ERR external/contrib_rules_jvm/java/gazelle/private/maven/resolver.go:79 > # gazelle:resolve java {org.keycloak} @maven//:org_keycloak_keycloak_server_spi_private _c=maven-resolver
WRN external/contrib_rules_jvm/java/gazelle/resolve.go:231 > Unable to find package for import in any dependency from rule={my_target} package=org.keycloak

ERR external/contrib_rules_jvm/java/gazelle/private/maven/resolver.go:77 > Append one of the following to BUILD.bazel: _c=maven-resolver
ERR external/contrib_rules_jvm/java/gazelle/private/maven/resolver.go:79 > # gazelle:resolve java {org.keycloak.authentication} @maven//:org_keycloak_keycloak_services _c=maven-resolver
ERR external/contrib_rules_jvm/java/gazelle/private/maven/resolver.go:79 > # gazelle:resolve java {org.keycloak.authentication} @maven//:org_keycloak_keycloak_server_spi_private _c=maven-resolver
WRN external/contrib_rules_jvm/java/gazelle/resolve.go:231 > Unable to find package for import in any dependency from rule={my_target} package=org.keycloak.authentication

And this this the snippet of packages attribute of the maven_install.json, we can see the org.keycloak (and the org.keycloak.authentication as well) is provided by different dependencies

"org.keycloak:keycloak-core": [
    "org.keycloak",
    ...
]

"org.keycloak:keycloak-server-spi-private": [
    "org.keycloak",
    ...
]
"org.keycloak:keycloak-services": [
    "org.keycloak",
    ...
]

and this code will fail to resolve

default:
r.logger.Error().Msg("Append one of the following to BUILD.bazel:")
for k := range v {
r.logger.Error().Msgf("# gazelle:resolve java %s %s", pkg, k)
}
return label.NoLabel, errors.New("many possible imports")
}

Should gazelle be removing runtime_deps?

I have noticed that running Gazelle removes any runtime deps that are missing # keep. I'm wondering if that's really desired behavior because presumably Gazelle couldn't know what deps a library needs at runtime? Should Gazelle be ignoring that attribute, so we don't need to add # keeps everywhere?

For the sake of the discussion, here's an example

load("@rules_java//java:defs.bzl", "java_library")

java_library(
    name = "client",
    visibility = ["//:__subpackages__"],
    runtime_deps = ["@maven//:org_glassfish_jersey_core_jersey_common"],
    deps = ["@maven//:javax_ws_rs_javax_ws_rs_api"],
)

Gazelle will always remove @maven//:org_glassfish_jersey_core_jersey_common here because it isn't aware that InternalServerErrorException tries to dynamically load a class.

image

image

Was this a deliberate design decision that I'm just not seeing the reason for?

How to use? (New Bazel User)

New Bazel user here... Sorry for what is probably a very basic question. I am trying to setup a test project and make use of JUnit5 which is what landed me here.

I have the following in my WORKSPACE file

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
    name = "contrib_rules_jvm",
    sha256 = "59af045d288ad3e2d9000b1cddb1135f889d798830f7106a4792cc95427bcd99",
    strip_prefix = "rules_jvm-0.7.0",
    url = "https://github.com/bazel-contrib/rules_jvm/archive/refs/tags/v0.7.0.zip",
)

# Fetches the contrib_rules_jvm dependencies.
# If you want to have a different version of some dependency,
# you should fetch it *before* calling this.
load("@contrib_rules_jvm//:repositories.bzl", "contrib_rules_jvm_deps")

contrib_rules_jvm_deps()

# Now ensure that the downloaded deps are properly configured
load("@contrib_rules_jvm//:setup.bzl", "contrib_rules_jvm_setup")

contrib_rules_jvm_setup()

As the docs, and release page mention, but when I try to use the new rules java_junit5_test in my BUILD file it says java_junit5_test is not defined

Again sorry for such a basic question. But there is surprisingly very little useful Bazel learning resources on the web for what is such a widely used build system. Is there a command I should be running to make Bazel "reload" the WORKSPACE or something?

I was able to load in and make use of maven_install just fine...

Checkstyle tests don't work with a generated checkstyle.xml

I am trying to run checkstyle tests with a generated checkstyle.xml instead of a file in the source tree. It seems like there is something wrong with the rule that isn't allowing this use case.

I wrote a minimal reproducible example and pushed it to a repo here: https://github.com/vinnybod/bazel_java_example/tree/generated-checkstyle-config

For the minimal reproduction, the macro just copies the checkstyle config from the source tree into the bazel-out runfiles and the label of that genrule is what gets passed into the checkstyle_config.

INFO: Invocation ID: 300a43af-8451-4adb-b49f-a69bfe52a210
INFO: Analyzed 7 targets (2 packages loaded, 11 targets configured).
INFO: Found 6 targets and 1 test target...
FAIL: //:entrypoint-checkstyle (see /private/var/tmp/_bazel_vrose/17aacbd88bcaf1ce194e6bbdb78e4a29/execroot/__main__/bazel-out/darwin_arm64-fastbuild/testlogs/entrypoint-checkstyle/test.log)
INFO: From Testing //:entrypoint-checkstyle:
==================== Test output for //:entrypoint-checkstyle:
/private/var/tmp/_bazel_vrose/17aacbd88bcaf1ce194e6bbdb78e4a29/sandbox/darwin-sandbox/106/execroot/__main__/bazel-out/darwin_arm64-fastbuild/bin/entrypoint-checkstyleexec.runfiles/__main__/entrypoint-checkstyleexec: line 5: cd: bazel-out/darwin_arm64-fastbuild/bin: No such file or directory
================================================================================
INFO: Elapsed time: 0.795s, Critical Path: 0.70s
INFO: 5 processes: 3 internal, 2 darwin-sandbox.
INFO: Build completed, 1 test FAILED, 5 total actions
//:entrypoint-checkstyle                                                 FAILED in 0.5s
  /private/var/tmp/_bazel_vrose/17aacbd88bcaf1ce194e6bbdb78e4a29/execroot/__main__/bazel-out/darwin_arm64-fastbuild/testlogs/entrypoint-checkstyle/test.log

Executed 1 out of 1 test: 1 fails locally.

expects maven_install.json to be in the root folder

Tried running this on our open source harness repository: https://github.com/harness/harness-core

and noticed that "blaze run //:gazelle" expects the maven_install.json to be present in the root folder - which is not the case for our repo.

At the same time, @contrib_rules_jvm//java/gazelle/cmd/parsejars has an option to pass in -maven-install flag - probably we can add something similar to the gazelle target too.

Duplicate artifacts versions

Upon using the contrib_rules_jvm and the rules_jvm_external in my project, I get the following warning:

DEBUG: /home/zshaban/.cache/bazel/_bazel_zshaban/31dd816ecc4dd5f7e9765c5f08aebaf2/external/rules_jvm_external~5.3/coursier.bzl:597:18: Found duplicate artifact versions
    com.google.errorprone:error_prone_annotations has multiple versions 2.11.0, 2.9.0
    com.google.guava:guava has multiple versions 30.1.1-jre, 31.0.1-android

Since those duplicate versions are explicitly mentioned in the MODULE.bazel of the contrib_rules_jvm, would it make sense to set duplicate_version_warning = "none" in the maven extension used in the contrib_rules_jvm?

Warning - System::setSecurityManager deprecated in Java 17

==================== Test output for //crypto/src/test/java/com/hellowd/crypto:Sha256Test:
WARNING: A terminally deprecated method in java.lang.System has been called
WARNING: System::setSecurityManager has been called by com.github.bazel_contrib.contrib_rules_jvm.junit5.ActualRunner (file:/private/var/tmp/_bazel_chulki/f3de409d11213140d88cb4bf7c678f64/execroot/__main__/bazel-out/darwin-fastbuild/bin/external/contrib_rules_jvm/java/src/com/github/bazel_contrib/contrib_rules_jvm/junit5/junit5-runner.jar)
WARNING: Please consider reporting this to the maintainers of com.github.bazel_contrib.contrib_rules_jvm.junit5.ActualRunner
WARNING: System::setSecurityManager will be removed in a future release
Failures: 0
================================================================================

.bazelrc

build --java_language_version=17
build --java_runtime_version=17
build --tool_java_language_version=17
build --tool_java_runtime_version=17
test --test_output=all

bazel info

java-runtime: OpenJDK Runtime Environment (build 11.0.6+10-LTS) by Azul Systems, Inc.
java-vm: OpenJDK 64-Bit Server VM (build 11.0.6+10-LTS, mixed mode) by Azul Systems, Inc.
release: release 6.0.0-pre.20211215.3

no way of customizing prefixes for java_test_suite

when the test-code does NOT start with any of the predefined prefixes (_PREFIXES = (".com.", ".org.", ".net.", ".io.", ".ai.", ".co.", ".me.")), the runner cannot find the class.
for example, i created a test-class in directory src/test/java/de/greeter, resulting in Caused by: java.lang.ClassNotFoundException: src.test.java.de.greeter.GreetingTest

when changing to com.greeter package, everything works. setup from the BUILD file:

java_test_suite(
    name = "test",
    srcs = glob(["src/test/java/**/*.java"]),
    runner = "junit5",
    test_suffixes = ["Test.java"],
    runtime_deps = JUNIT5_DEPS,
    deps = [
        ":libraryX",
        artifact("org.junit.jupiter:junit-jupiter-api"),
        artifact("org.junit.jupiter:junit-jupiter-params"),
        artifact("org.assertj:assertj-core"),
        artifact("org.projectlombok:lombok"),
    ],
)

it should be possible to at least customize the prefixes, maybe there is even a better solution to it...

FR: Way to exclude jar from gazelle resolution

Our repository has a list of shared maven dependencies that includes a jar ("org.openapitools:openapi-generator-cli:6.0.0") that gazelle thinks would work for a lot of different packages, and this leads to a lot of gazelle:resolve lines in our top-level BUILD files. It would be nice if there was a gazelle:do-not-resolve type of annotation that we could use to exclude that one jar.

Issues with airgapped usage

Hi there,

When trying to use the rules in an environment without an internet connection I get this error:
'''
Error in download: java.io.IOException: Error downloading [https://repo1.maven.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar]
'''

This happens when running contrib_rules_jvm_setup()

All the other dependencies e.g. apple_rules_lint have been resolved with downloading them with http_archive before loading rules_jvm but not sure how to resolve these maven dependencies.

Using version 0.11.0.

Ideally there should be a way to use my own maven repo.

Please help bump PMD version

Currently shipped PMD version is at 6.46.0, released in May 2022.
Since then, a handful of fixes & enhancements got released, among which:

The latter also states that:

This release is the last planned release of PMD 6. The first version 6.0.0 was released in December 2017. Over the course of more than 5 years we published almost every month a new minor version of PMD 6 with new features and improvements.

Before PMD 7 is out, I therefore gave a try bumping up PMD version to 6.55.0 but miserably failed running tools/update-dependencies.sh, which doesn't work on my machine:

$ ./tools/update-dependencies.sh
go: downloading github.com/rs/zerolog v1.26.1
[...]
ERROR: Skipping '@unpinned_maven//:pin': No repository visible as '@unpinned_maven' from main repository
WARNING: Target pattern parsing failed.
ERROR: No repository visible as '@unpinned_maven' from main repository
INFO: Elapsed time: 0.096s
INFO: 0 processes.
FAILED: Build did NOT complete successfully (0 packages loaded)
ERROR: Build failed. Not running target

Could you please help (or do) bump PMD version to 6.55.0?

Can't clone it in our windows kokoro jobs

all in the title, this
https://github.com/bazel-contrib/rules_jvm/blob/main/java/test/com/github/bazel_contrib/contrib_rules_jvm/javaparser/generators/workspace/com/gazelle/java/javaparser/generators/AnnotationFromJavaStandardLibrary.java is waaaaaaay too long on windows...

error in kokoro (using our bazel based build of google/or-tools for windows):
WORKSPACE:

git_repository(
    name = "contrib_rules_jvm",
    tag = "v0.9.0",
    #tag = "v0.19.0", # didn't work with junit5
    remote = "https://github.com/bazel-contrib/rules_jvm.git",
)

And the kokoro (fusion2 trace)

C:\tmpfs\src>choco install bazel -y -i 
....
C:\tmpfs\src>bazel version
Build label: 6.3.2
...
C:\tmpfs\src\git\or-tools>bazel build -c opt -s //ortools/... 
...
Error in fail: error running 'git reset --hard tags/v0.9.0' while working with @contrib_rules_jvm:
error: unable to create file java/test/com/github/bazel_contrib/contrib_rules_jvm/javaparser/generators/workspace/com/gazelle/java/javaparser/generators/AnnotationFromJavaStandardLibrary.java: Filename too long
fatal: Could not reset index file to revision 'tags/v0.9.0'.

FR: Gazelle Kotlin Support

Hi is there any thought / interest in adding kotlin support to the gazelle extension?

Have briefly started to look at the changes required and curious if its on others radar.

Thanks!

FR: Gazelle plugin supports multiple maven install rules

We split our maven dependencies into multiple maven install rules to make adding/upgrading etc deps easier. It looks like the gazelle plugin here only supports a single maven install rule. How do people feel about making it possible to support multiple maven install rules?

bazel run //:gazelle fails on https://github.com/harness/harness-core

Hey! I tried running gazelle java extension on harness-core following instructions from the README.

At the final step "bazel run //:gazelle", I see the following exception thrown.

panic: runtime error: index out of range [0] with length 0

I have also documented the steps I performed to build and execute this extension. Can you please look into this?

Here is the complete stack trace.

~/source-code/harness-core $ bazel run //:gazelle 

INFO: Invocation ID: d2e52257-4e7a-46ac-824a-4b00b13df3ccDEBUG: Rule 'contrib_rules_jvm' indicated that a canonical reproducible form can be obtained by modifying arguments sha256 = "21a8d42058eca9cec198070e09d6a6806f28149ef1804473caef69e145f4e242"DEBUG: Repository contrib_rules_jvm instantiated at:  /Users/gauravnanda/source-code/harness-core/WORKSPACE:9:13: in Repository rule http_archive defined at:  /private/var/tmp/_bazel_gauravnanda/31c0a55cc70a91108079d63a7aab4a62/external/bazel_tools/tools/build_defs/repo/http.bzl:336:31: in INFO: Analyzed target //:gazelle (0 packages loaded, 0 targets configured).INFO: Found 1 target...Target //:gazelle up-to-date:  /private/var/tmp/_bazel_gauravnanda/31c0a55cc70a91108079d63a7aab4a62/execroot/harness_monorepo/bazel-out/darwin_arm64-fastbuild/bin/gazelle-runner.bash  /private/var/tmp/_bazel_gauravnanda/31c0a55cc70a91108079d63a7aab4a62/execroot/harness_monorepo/bazel-out/darwin_arm64-fastbuild/bin/gazelleINFO: Elapsed time: 0.189s, Critical Path: 0.02sINFO: 1 process: 1 internal.INFO: Build completed successfully, 1 total actionINFO: Running command line: /private/var/tmp/_bazel_gauravnanda/31c0a55cc70a91108079d63a7aab4a62/execroot/harness_monorepo/bazel-out/darwin_arm64-fastbuild/bin/gINFO: Build completed successfully, 1 total actionINFO GrpcServer - Set of classes has no packagepanic: runtime error: index out of range [0] with length 0goroutine 4218 [running]:github.com/bazel-contrib/rules_jvm/java/gazelle/private/java.NewImport({0x1400029e798, 0x15})        external/contrib_rules_jvm/java/gazelle/private/java/import.go:19 +0x2b8main.filterImports(0x140001e07e0, {0x140004db220, 0x5, 0x5})        external/contrib_rules_jvm/java/gazelle/private/javaparser/cmd/javaparser-wrapper/main.go:276 +0xbcmain.(*server).ParsePackage(0x1400042c100, {0x1051f4c00, 0x14000301890}, 0x14000310550)        external/contrib_rules_jvm/java/gazelle/private/javaparser/cmd/javaparser-wrapper/main.go:212 +0x124github.com/bazel-contrib/rules_jvm/java/gazelle/private/javaparser/proto/gazelle/java/javaparser/v0.JavaParser_ParsePackage_Handler.func1({0x1051f4c00, 0x14000301890}, {0x1051ab020, 0x14000310550})        bazel-out/darwin_arm64-fastbuild/bin/external/contrib_rules_jvm/java/gazelle/private/javaparser/proto/gazelle/java/javaparser/v0/gazelle_java_build_v0_go_proto/github.com/bazel-contrib/rules_jvm/java/gazelle/private/javaparser/proto/gazelle/java/javaparser/v0/javaparser.pb.go:319 +0x7cmain.activityTrackerUSI.func1({0x1051f4c00, 0x14000301890}, {0x1051ab020, 0x14000310550}, 0x1400040f680, 0x14000134a80)        external/contrib_rules_jvm/java/gazelle/private/javaparser/cmd/javaparser-wrapper/main.go:182 +0x54github.com/bazel-contrib/rules_jvm/java/gazelle/private/javaparser/proto/gazelle/java/javaparser/v0.JavaParser_ParsePackage_Handler({0x105167b40, 0x1400042c100}, {0x1051f4c00, 0x14000301890}, 0x140002577a0, 0x14000424310)        bazel-out/darwin_arm64-fastbuild/bin/external/contrib_rules_jvm/java/gazelle/private/javaparser/proto/gazelle/java/javaparser/v0/gazelle_java_build_v0_go_proto/github.com/bazel-contrib/rules_jvm/java/gazelle/private/javaparser/proto/gazelle/java/javaparser/v0/javaparser.pb.go:321 +0x14cgoogle.golang.org/grpc.(*Server).processUnaryRPC(0x14000466000, {0x1051fbac0, 0x14000186820}, 0x140001fe900, 0x140004204b0, 0x1054c8b70, 0x0)        external/org_golang_google_grpc/server.go:1282 +0xc3cgoogle.golang.org/grpc.(*Server).handleStream(0x14000466000, {0x1051fbac0, 0x14000186820}, 0x140001fe900, 0x0)        external/org_golang_google_grpc/server.go:1619 +0xa54google.golang.org/grpc.(*Server).serveStreams.func1.2(0x1400019a0d0, 0x14000466000, {0x1051fbac0, 0x14000186820}, 0x140001fe900)        external/org_golang_google_grpc/server.go:921 +0x94created by google.golang.org/grpc.(*Server).serveStreams.func1        external/org_golang_google_grpc/server.go:919 +0x1f0panic: rpc error: code = Unavailable desc = error reading from server: EOFgoroutine 1 [running]:github.com/bazel-contrib/rules_jvm/java/gazelle.javaLang.GenerateRules({{0x103798cd8, 0x14000010288}, {0x103798d10, 0x14000193f60}, 0x1400015a000, {{0x103794c88, 0x14000193f40}, 0x1, {0x0, 0x0}, ...}, ...}, ...)        external/contrib_rules_jvm/java/gazelle/generate.go:113 +0x1dd8main.runFixUpdate.func1({0x140032a2300, 0x55}, {0x14005508510, 0x29}, 0x1400610c580, 0x1, 0x0, {0x0, 0x0, 0x0}, ...)        external/bazel_gazelle/cmd/gazelle/fix-update.go:294 +0xc0cgithub.com/bazelbuild/bazel-gazelle/walk.Walk.func1(0x1400591de40, {0x140032a2300, 0x55}, {0x14005508510, 0x29}, 0x1)        external/bazel_gazelle/walk/walk.go:179 +0x500github.com/bazelbuild/bazel-gazelle/walk.Walk.func1(0x1400591dce0, {0x14003d5bf90, 0x50}, {0x1400502c360, 0x24}, 0x1)        external/bazel_gazelle/walk/walk.go:172 +0x694github.com/bazelbuild/bazel-gazelle/walk.Walk.func1(0x1400591dc30, {0x14003d5bd10, 0x48}, {0x14004bf8e80, 0x1c}, 0x1)        external/bazel_gazelle/walk/walk.go:172 +0x694github.com/bazelbuild/bazel-gazelle/walk.Walk.func1(0x1400591dad0, {0x14003d5b720, 0x45}, {0x14004bf8dc0, 0x19}, 0x1)        external/bazel_gazelle/walk/walk.go:172 +0x694github.com/bazelbuild/bazel-gazelle/walk.Walk.func1(0x1400591d970, {0x14005471880, 0x40}, {0x14005473650, 0x14}, 0x1)        external/bazel_gazelle/walk/walk.go:172 +0x694github.com/bazelbuild/bazel-gazelle/walk.Walk.func1(0x1400591d810, {0x14005471780, 0x3b}, {0x14002754620, 0xf}, 0x1)        external/bazel_gazelle/walk/walk.go:172 +0x694github.com/bazelbuild/bazel-gazelle/walk.Walk.func1(0x140001e9080, {0x14005470980, 0x37}, {0x14002754060, 0xb}, 0x1)        external/bazel_gazelle/walk/walk.go:172 +0x694github.com/bazelbuild/bazel-gazelle/walk.Walk.func1(0x140001e9080, {0x14000036270, 0x2b}, {0x0, 0x0}, 0x0)        external/bazel_gazelle/walk/walk.go:172 +0x694github.com/bazelbuild/bazel-gazelle/walk.Walk(0x140001e9080, {0x14000134180, 0x7, 0xc}, {0x1400017e010, 0x1, 0x1}, 0x0, 0x1400091f968)        external/bazel_gazelle/walk/walk.go:182 +0x198main.runFixUpdate({0x1400004210a, 0x2b}, 0x0, {0x140001b8010, 0x0, 0x0})        external/bazel_gazelle/cmd/gazelle/fix-update.go:271 +0x5a0main.run({0x1400004210a, 0x2b}, {0x140001b8010, 0x1, 0x1})        external/bazel_gazelle/cmd/gazelle/gazelle.go:95 +0x29cmain.main()        external/bazel_gazelle/cmd/gazelle/gazelle.go:72 +0x140

Gazelle support for junit4

Hey! I am trying out gazelle java extension for https://github.com/harness/harness-core

After running the tool, I noticed that the java_test_suite it generates has runner5 hardcoded and its adds respective runtime_deps also. We are still using junit4 -- can I somehow configure it to generate runner for junit4 without any runtime deps?

Allow setting SecurityManager

We have a need to allow unit tests set a SecurityManager as part of their testing. As such we would like to contribute a way to prevent installation of the default SecurityManager.

Can we get some guidance on the wanted/acceptable design?

A) Using Test Runner

It looks like one possible way is to introduce a new test runner:

_RUNNERS = [
    "junit4",
    "junit5",
    "junit5_without_security_manager",
]

This test runner would use a custom test definition function:

_TEST_GENERATORS = {
    "junit4": _define_junit4_test,
    "junit5": _define_junit5_test,
    "junit5_without_security_manager": _define_junit5_test_without_security_manager,
}

def _define_junit5_test_without_security_manager(name, **kwargs):
    java_junit5_test(
        name = name,
        include_engines = kwargs.pop("include_engines", None),
        exclude_engines = kwargs.pop("exclude_engines", None),
        disable_security_manager = True,
        **kwargs
    )
    return name

And then the logic in junit5.bzl to:

  • add attribute disable_security_manager
  • skip any SecurityManager work if disable_security_manager is set to True
  • use a different main_class if disable_security_manager is set to True

As well as a new main class based on JUnit5Runner that skips all the system exit stuff.

B) Using a special system property

The junit5 macro already has special support for detecting -Djava.security.manager= jvm_flag.

Can we add another jvm_flag (eg., -Dbazel.junit5runner.skipSecurityManagerInstallation=true) that once set will:

  • trigger the macro to not set any -Djava.security.manager= options
  • trigger existing Junit5Runner to not install any SecurityManager

Option B seems easier to implement and would make it less obvious that this mode of operation is supported.

It might be possible to implement option B without a new system property. For example, when -Djava.security.manager=my.custom.Class is set we could change the JUnit5Runner to not install its SecurityManager at all. However, that would be a breaking change in terms of behavior for existing users and might not work for us because the code under tests needs to call setSecurityManager.

Discussion: what's the relationship between rules_jvm and rules_java?

Hi all,

I'm starting to add Java support to an existing Bazel project. Would anyone mind outlining the differences between rules_jvm and rules_java?

Specifically, I'm trying to figure out:

  • Do I use rules_java or rules_jvm? Is rules_jvm a replacement or complement to rules_java?
  • Is rules_java "officially" supported?
  • Gazelle support: I saw Gazelle support in rules_jvm, does it only work with rules_jvm?
  • What's the future of rules_jvm? Will it keep up with bzlmod?

Happy to close or post elsewhere if you'd prefer.

@Suite `test_class` not picking up matching selected classes.

I have the following UnitTestSuite.java file

@Suite
@IncludeClassNamePatterns("^(Test.*|.+[.$]Test.*|.*Tests?)$")
public class UnitTestSuite {}

And following macro

load("@contrib_rules_jvm//java:defs.bzl", "java_junit5_test")

def java_unit_test(name, srcs, deps, **kwargs):
    java_junit5_test(
        name = name,
        test_class = "com.foo.testsuite.UnitTestSuite",
        srcs = srcs + ["//tools/test/java/testsuite:src/main/java/com/foo/testsuite/UnitTestSuite.java"],
        runtime_deps = [
            "@maven//:org_junit_platform_junit_platform_runner",
            "@maven//:org_junit_platform_junit_platform_reporting",
        ],
        deps = deps + ["@maven//:org_junit_platform_junit_platform_suite_api"],
        **kwargs
    )

called with

java_unit_test(
    name = "unit_test",
    srcs = glob(["src/test/java/com/foo/**/*UnitTest.java"]),
    deps = [
        ":base_gateway",
        "@maven//:org_junit_jupiter_junit_jupiter_api",
        "@maven//:org_junit_jupiter_junit_jupiter_engine",
    ],
)

and

public class FooUnitTest {
  @Test
  public void test() {
    Assertions.assertEquals(0, 2);
  }

  @Test
  public void test3() {
    Assertions.assertEquals(0, 2);
  }
}

When I run bazel test //foo:unit_test it seems that it is only running the actual UnitTestSuite without executing the other suite classes matching the pattern and provided in srcs.

Is there something wrong?

I used to be able to do that using native.java_test and previous @Suite() / @SuiteClasses.

If I add a test in UnitTestSuite:

@Suite
@IncludeClassNamePatterns("^(Test.*|.+[.$]Test.*|.*Tests?)$")
public class UnitTestSuite {
  @Test
  public void test() {
    Assertions.assertEquals(0, 2);
  }
}

then test is correctly run and fails:

INFO: Analyzed target //foo/base:unit_test (0 packages loaded, 0 targets configured).
INFO: Found 1 test target...
...
INFO: Elapsed time: 1.034s, Critical Path: 0.95s
INFO: 3 processes: 1 internal, 1 darwin-sandbox, 1 worker.
INFO: Build completed, 1 test FAILED, 3 total actions
//foo/base:unit_test                                       FAILED in 0.8s
...
expected: <0> but was: <2>
Expected :<0>
Actual   :<2>
Executed 1 out of 1 test: 1 fails locally.

Thanks for your help

0.5.0 release page is incorrect

It says

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
    name = "contrib_rules_jvm",
    sha256 = "099b0dacf8263e0ef8c0d05073120b7350cef1dcac3223d3bfee66576446dd13",
    strip_prefix = "contrib_rules_jvm-0.5.0",
    url = "https://github.com/bazel-contrib/contrib_rules_jvm/archive/v0.5.0.tar.gz",
)

But I had to use this - please note the checksum is also different.

http_archive(
    name = "contrib_rules_jvm",
    sha256 = "29400200fdcada5d86b2616ac7c588f608ec5b1b00cb4eec3e248827f889fad9",
    strip_prefix = "rules_jvm-0.5.0",
    url = "https://github.com/bazel-contrib/rules_jvm/archive/v0.5.0.tar.gz",
)

Could you double check the github archive, and update the release page accordingly?

Gazelle with java fails: undefined: btree.NewG

Configuring "@contrib_rules_jvm//java/gazelle" and running bazel run :gazelle, following the guide, fails due to a missing btree dependency. This code was added fairly recently: https://github.com/bazel-contrib/rules_jvm/commits/main/java/gazelle/private/sorted_set/btreeset.go

I'm using gazelle v0.29: https://github.com/bazelbuild/bazel-gazelle/releases/tag/v0.29.0

Error:

Use --sandbox_debug to see verbose messages from the sandbox and retain the sandbox build root for debugging
external/contrib_rules_jvm/java/gazelle/private/sorted_set/btreeset.go:9:14: undefined: btree.BTreeG
external/contrib_rules_jvm/java/gazelle/private/sorted_set/btreeset.go:16:27: undefined: btree.Ordered
external/contrib_rules_jvm/java/gazelle/private/sorted_set/btreeset.go:18:15: undefined: btree.NewOrderedG
external/contrib_rules_jvm/java/gazelle/private/sorted_set/btreeset.go:28:47: undefined: btree.LessFunc
external/contrib_rules_jvm/java/gazelle/private/sorted_set/btreeset.go:30:15: undefined: btree.NewG
compilepkg: error running subcommand external/go_sdk/pkg/tool/darwin_arm64/compile: exit status 2
Target //:gazelle failed to build

We wire up the workspace as specified in the readme, but the go dependencies appear to be missing?

load("@contrib_rules_jvm//:repositories.bzl", "contrib_rules_jvm_deps", "contrib_rules_jvm_gazelle_deps")

contrib_rules_jvm_deps()

contrib_rules_jvm_gazelle_deps()

load("@contrib_rules_jvm//:setup.bzl", "contrib_rules_jvm_setup")

contrib_rules_jvm_setup()

load("@contrib_rules_jvm//:gazelle_setup.bzl", "contrib_rules_jvm_gazelle_setup")

contrib_rules_jvm_gazelle_setup()

Cannot build java gazelle bin on Ubuntu 22.04

Hello I tried building the Gazelle java extension on Ubuntu 22.04 using the following:

WORKSPACE:

("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
    name = "io_bazel_rules_go",
    sha256 = "16e9fca53ed6bd4ff4ad76facc9b7b651a89db1689a2877d6fd7b82aa824e366",
    urls = [
        "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.34.0/rules_go-v0.34.0.zip",
        "https://github.com/bazelbuild/rules_go/releases/download/v0.34.0/rules_go-v0.34.0.zip",
    ],
)

load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")

go_rules_dependencies()

go_register_toolchains(version = "1.18.3")

http_archive(
    name = "com_google_protobuf",
    sha256 = "d0f5f605d0d656007ce6c8b5a82df3037e1d8fe8b121ed42e536f569dec16113",
    strip_prefix = "protobuf-3.14.0",
    urls = [
        "https://mirror.bazel.build/github.com/protocolbuffers/protobuf/archive/v3.14.0.tar.gz",
        "https://github.com/protocolbuffers/protobuf/archive/v3.14.0.tar.gz",
    ],
)

load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")

protobuf_deps()

http_archive(
    name = "bazel_gazelle",
    sha256 = "501deb3d5695ab658e82f6f6f549ba681ea3ca2a5fb7911154b5aa45596183fa",
    urls = [
        "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.26.0/bazel-gazelle-v0.26.0.tar.gz",
        "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.26.0/bazel-gazelle-v0.26.0.tar.gz",
    ],
)

load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository")

gazelle_dependencies()

http_archive(
    name = "contrib_rules_jvm",
    sha256 = "29400200fdcada5d86b2616ac7c588f608ec5b1b00cb4eec3e248827f889fad9",
    strip_prefix = "rules_jvm-0.5.0",
    url = "https://github.com/bazel-contrib/rules_jvm/archive/refs/tags/v0.5.0.tar.gz",
)

load("@contrib_rules_jvm//:repositories.bzl", "contrib_rules_jvm_deps", "contrib_rules_jvm_gazelle_deps")

contrib_rules_jvm_deps()

contrib_rules_jvm_gazelle_deps()

load("@contrib_rules_jvm//:setup.bzl", "contrib_rules_jvm_setup")

contrib_rules_jvm_setup()

load("@contrib_rules_jvm//:gazelle_setup.bzl", "contib_rules_jvm_gazelle_setup")

contib_rules_jvm_gazelle_setup()

BUILD:

load("@bazel_gazelle//:def.bzl", "DEFAULT_LANGUAGES", "gazelle", "gazelle_binary")

# gazelle:prefix github.com/your/project
gazelle(
    name = "gazelle",
    gazelle = ":gazelle_bin",
)

gazelle_binary(
    name = "gazelle_bin",
    languages = DEFAULT_LANGUAGES + [
        "@contrib_rules_jvm//java/gazelle",
    ],
)

But I get the following error every time trying to build the gazelle bin:

bazel build --java_runtime_version=remotejdk_11 //:gazelle_bin


INFO: Build options --java_runtime_version and --platforms have changed, discarding analysis cache.
INFO: Analyzed target //:gazelle_bin (26 packages loaded, 11751 targets configured).
INFO: Found 1 target...
ERROR: /home/ali/.cache/bazel/_bazel_ali/4a1126a8538496440d4036a94732d2f6/external/org_golang_google_grpc/internal/channelz/BUILD.bazel:3:11: GoCompilePkg external/org_golang_google_grpc/internal/channelz/channelz.a failed: (Exit 1): builder failed: error executing command bazel-out/k8-opt-exec-2B5CBBC6/bin/external/go_sdk/builder compilepkg -sdk external/go_sdk -installsuffix linux_amd64 -src external/org_golang_google_grpc/internal/channelz/funcs.go -src ... (remaining 35 arguments skipped)

Use --sandbox_debug to see verbose messages from the sandbox and retain the sandbox build root for debugging
compilepkg: missing strict dependencies:
        /home/ali/.cache/bazel/_bazel_ali/4a1126a8538496440d4036a94732d2f6/sandbox/linux-sandbox/671/execroot/__main__/external/org_golang_google_grpc/internal/channelz/types_linux.go: import of "golang.org/x/sys/unix"
No dependencies were provided.
Check that imports in Go sources match importpath attributes in deps.
Target //:gazelle_bin failed to build
Use --verbose_failures to see the command lines of failed build steps.

Need recipe for JUnit @Suite.SuiteClasses with `java_test_suite`

Consider the following test suite:

@RunWith(Suite.class)				
@Suite.SuiteClasses({				
  SomeTest.class,
  AnotherTest.class,  			
})		

public class MyTestSuite {				
    // how to support this?
}

All three types are defined in the same Java package, same directory.

With test_suffixes = ["Test.java", "TestSuite.java"] the type MyTestSuite cannot be compiled by Bazel because it has neither access to SomeTest nor AnotherTest.

Cannot be used with `--override_repository`: cannot load '@@rules_java//java:repositories.bzl': no such file

We are using rules_jvm without problems with this in the workspace:

load("@contrib_rules_jvm//:repositories.bzl", "contrib_rules_jvm_deps")

contrib_rules_jvm_deps()

load("@contrib_rules_jvm//:setup.bzl", "contrib_rules_jvm_setup")

contrib_rules_jvm_setup()

However, as soon as we add --override_repository= rules_jvm=/path/to/rules_jvm the build fails with:

ERROR: Error computing the main repository mapping: at /Users/.../.cache/bazel/.../external/contrib_rules_jvm/setup.bzl:4:6: cannot load '@@rules_java//java:repositories.bzl': no such file
Computing main repo mapping: 
    Fetching repository @@contrib_rules_jvm_deps; starting

Note, the outer build is running with --noenable_bzlmod (Bazel 7.0.1) because we have not migrated yet.

No maven lockfile for bzlmod

MODULE.bazel maven.install does not use lock_file (docs)

If i try to add it, build fails with

 no such target '@@rules_jvm_external~6.0~maven~contrib_rules_jvm_deps//:com_puppycrawl_tools_checkstyle'

I suppose problem in _artifact macro

Bzlmod support done here: #170 #123

FR: Gazelle resolve class directives

For the most part, resolving dependencies by packages works pretty well and the cases where it does not aren't hard to workaround, however, there's one use case I found where it would be a much better user experience if class-level resolve directives were supported.

For a concrete example, I'll be using everyone's favorite (sarcasm), lombok

# gazelle:resolve java lombok //:lombok

java_plugin(
    name = "lombok_plugin",
    generates_api = 1,
    processor_class = "lombok.launch.AnnotationProcessorHider$AnnotationProcessor",
    deps = [artifact("org.projectlombok:lombok")],
)

java_library(
    name = "lombok",
    exported_plugins = [":lombok_plugin"],
    neverlink = 1,
    visibility = ["//visibility:public"],
    exports = [artifact("org.projectlombok:lombok")],
)

So, here we have declared that any importer of lombok.* shall require //:lombok instead of @maven//:org_projectlombok_lombok. This mostly works, but what happens when a package tries to use the CustomLog annotation?

import lombok.CustomLog;

@CustomLog
public class MyClass {}

CustomLog injects a logger of a class specified in a config file according to the javadoc.

image

So let's say we want to inject a logger of type com.mycompany.myapp.logger.AppLogger

lombok.log.custom.declaration = com.mycompany.myapp.logger.AppLogger

What I would normally do in this situation is add a dependency on com.mycompany.myapp.logger.AppLogger to //:lombok, however our logging class depends on a StructuredLogging class (log lines), which depends on lombok.{Builder,Value}, so that would create a cycle in the graph.

Barring any refactoring, what I'd like to be able to do is say "any imports of lombok.CustomLog resolve to labelA and any imports of lombok.* resolve to labelB"

# gazelle:resolve java lombok.CustomLog //:logging
# gazelle:resolve java lombok //:lombok

issue with java_test_suite package inference

So from what I can tell unless your package begins with a common domain (".com.", ".org.", ".net.", ".io.", ".ai.") it won't correctly load the class file.

So for example if I have a test class at src/test/java/fish/boxjelly/web/WebApplicationTests.java and has the package of package fish.boxjelly.web; It will attempt to load the class using the full path with the src.test.java.fish.boxjelly.web.WebApplicationTests instead of fish.boxjelly.web.WebApplicationTests

Is there a way to supply a base folder to exclude? If I could tell the test suite that src.test.java should be ignored things would work.

Support bzlmod

  • Create MODULE.bazel file and e2e test in this repo
  • Setup the Publish-to-BCR app and publish a release to the Bazel Central Registry
  • Provide instructions for bzlmod users
  • Gazelle extension should work with bzlmod

Preserve Cache between the runs

We have large build targets (one for each top level directory) in https://github.com/harness/harness-core.

When I run gazelle - I have to deal (manually fix) with a bunch of cyclic dependencies. Each time I refactor, I run gazelle to regenerate the build files. Even if changes are isolated to a sub-directory, I have to run gazelle on entire workspace. It appears on each run, we map package to build target -- so if we try running gazelle only on a sub-directory, it does not resolve imports from other directories.

Is there a way to create a cache of such mapping and update it with new runs?

[Gazelle] Resolve deps that are testonly libraries in the test hierarchy

I added a Spring Boot test configuration that is meant to be shared among many tests. Since it is a library that is meant only to be used in tests, I added it in the /src/test/ subtree of my project. I ran gazelle and it generated a junit5_test_suite, but since it is a library, I adjusted the generated BUILD rule to be a java_library (and also set the visibility and testonly flags appropriately). However, gazelle was not able to pick up this library and automatically add it as a dependency. I was able to work around this by adding a gazelle:resolve directive, but it would be nice if that wasn't the case.

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.