通过 Bazel 使用 Spark 库出现 ClassNotFoundException

Fel*_*rdo 1 spark-java bazel

我正在尝试在 Spark 中使用 Bazel 构建它来运行“hello world”服务器,但我收到此错误:

$ bazel run //:app
INFO: Analysed target //:app (0 packages loaded).
INFO: Found 1 target...
Target //:app up-to-date:
  bazel-bin/app.jar
  bazel-bin/app
INFO: Elapsed time: 0.201s, Critical Path: 0.00s
INFO: 0 processes.
INFO: Build completed successfully, 1 total action
INFO: Build completed successfully, 1 total action
Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
        at spark.Service.<clinit>(Service.java:56)
        at spark.Spark$SingletonHolder.<clinit>(Spark.java:51)
        at spark.Spark.getInstance(Spark.java:55)
        at spark.Spark.<clinit>(Spark.java:61)
        at io.app.server.Main.main(Main.java:7)
Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        ... 5 more
Run Code Online (Sandbox Code Playgroud)

建造:

java_binary(
    name = "app",
    main_class = "io.app.server.Main",
    srcs = ["src/main/java/io/app/server/Main.java"],
    deps = [
        "@org_slf4j_slf4j_simple//jar",
        "@com_sparkjava_spark_core//jar",
    ]
)
Run Code Online (Sandbox Code Playgroud)

如果我不包含 slf4j,也会发生同样的错误,并且它不应该是 Spark 的必需依赖项。

工作空间:

maven_jar(
    name = "com_sparkjava_spark_core",
    artifact = "com.sparkjava:spark-core:2.7.2"
)

maven_jar(
    name = "org_slf4j_slf4j_simple",
    artifact = "org.slf4j:slf4j-simple:1.7.21"
)
Run Code Online (Sandbox Code Playgroud)

最后,src/main/java/io/app/server/Main.java:

package io.app.server;

import static spark.Spark.*;

public class Main {
  public static void main(String[] args) {
    port(3000);
    get("/", (req, res) -> "Hello World");
  }
}
Run Code Online (Sandbox Code Playgroud)

知道我在这里可能做错了什么吗?

Fel*_*rdo 5

找到了我所缺少的东西。似乎 maven_jar 不会自动获取库本身具有的“传递依赖项”,请参阅此

Bazel 仅读取 WORKSPACE 文件中列出的依赖项。如果您的项目 (A) 依赖于另一个项目 (B),而该项目在其 WORKSPACE 文件中列出了对第三个项目 (C) 的依赖关系,则您必须将 B 和 C 添加到项目的 WORKSPACE 文件中。这一要求可能会增加 WORKSPACE 文件大小,但希望限制一个库包含版本 1.0 的 C 且另一个库包含版本 2.0 的 C 的机会。

可以使用工具generate_workspace 生成大型WORKSPACE 文件。有关详细信息,请参阅从 Maven 项目生成外部依赖项。

所以解决方案似乎是编写 pom.xml 并使用generate_workspace

编辑:generate_workspace似乎已被弃用,请改用bazel_deps