Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Maven's <dependency> ... <scope> compile </> </> is transitive, but compiled down to bazel's :deps = ... which is not. #275

Closed
t-soliduslink opened this issue Oct 24, 2019 · 2 comments

Comments

@t-soliduslink
Copy link

Quoting Maven's documentation on "Dependency Scope":

compile
This is the default scope, used if none is specified. Compile dependencies are available in all classpaths of a project. Furthermore, those dependencies are propagated to dependent projects.

Emphasis mine. Compile is the default scope and it is transitive.

However, rules_jvm_external compiles Maven's dependency specifications down into jvm_import.deps which itself is a JavaInfo.deps which behaves like a java_library.deps and which is not transitive.

Instead of compiling down to deps, it should probably use exports instead for Maven's compile dependencies. I modified @maven//jvm_import.bzl and @maven//BUILD locally to do just that, and confirmed that this made the example below work.

Example for reproduction:

This can be reproduced by a simple Java project that depends on ch.qos.logback:logback-classic (and only that as explicit dependency.) logback-classic in turn specifies org.slf4j:slf4j-api as a compile dependency in its pom file.

The Java source file in that project will import the org.slf4j package.

When compiled via Maven, this will compile just fine because org.slf4j is brought in as a transitive compile-time dependency:

$ mvn compile
[INFO] Scanning for projects...
[INFO] 
[INFO] ------------------------< just.an.example:App >-------------------------
[INFO] Building App 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
...
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ App ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /home/trittweiler/Src/experiments/maven/target/classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS

However, the build will fail with bazel.

$ bazel build //src:App
INFO: Analyzed target //src:App (1 packages loaded, 7 targets configured).
INFO: Found 1 target...
ERROR: /home/trittweiler/Src/experiments/maven/src/BUILD:2:1: Building src/App.jar (1 source file) failed (Exit 1)
src/main/java/just/an/example/App.java:4: error: [strict] Using type org.slf4j.Logger from an indirect dependency (TOOL_INFO: "external/maven/v1/https/repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar").
import org.slf4j.Logger;
                ^
Target //src:App failed to build

The files are:

├── pom.xml
├── src
│   ├── BUILD
│   └── main
│       └── java
│           └── just
│               └── an
│                   └── example
│                       └── App.java
└── WORKSPACE
<?xml version="1.0" encoding="UTF-8"?>

<!-- pom.xml -->

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>just.an.example</groupId>
  <artifactId>App</artifactId>
  <version>1.0-SNAPSHOT</version>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.2.3</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>

</project>
# src/BUILD
java_binary(
    name = "App",
    srcs = [ "main/java/just/an/example/App.java" ],
    main_class = "just.an.example.App",
    deps = [
        "@maven//:ch_qos_logback_logback_classic",
    ],
)
// src/main/java/just/an/example/App.java
package just.an.example;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class App 
{
    public static void main( String[] args )
    {
        System.out.println("HelloWorld");
    }
}
# WORKSPACE

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

RULES_JVM_EXTERNAL_TAG = "2.8"
RULES_JVM_EXTERNAL_SHA = "79c9850690d7614ecdb72d68394f994fef7534b292c4867ce5e7dec0aa7bdfad"

http_archive(
    name = "rules_jvm_external",
    strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG,
    sha256 = RULES_JVM_EXTERNAL_SHA,
    url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG,
)

load("@rules_jvm_external//:defs.bzl", "maven_install")

maven_install(
    artifacts = [
        "ch.qos.logback:logback-classic:1.2.3",
    ],
    repositories = [
        "https://repo1.maven.org/maven2",
    ],
    fail_on_missing_checksum = True,
    strict_visibility = True,
)
@jin
Copy link
Collaborator

jin commented Oct 24, 2019

Thanks for the super detailed report. I believe this is #147 - let's merge the conversation there?

@t-soliduslink
Copy link
Author

Yes, indeed, it is the same issue. Closing this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants