【问题标题】:How to access a dependency of a dependency in Java/Gradle?如何在 Java/Gradle 中访问依赖项的依赖项?
【发布时间】:2020-02-18 19:01:44
【问题描述】:

我正在尝试访问在我实现的库中实现的库。我拥有这两个库。即:

Lib1 有一个我想在消费者应用程序中访问的类,比如Car.java

public class Car {
    public Int wheelsCount;
}

Lib2 有一个 api,它从 lib1 返回类 Car

gradle.build:

...
api 'com.me.lib1:1.0' //From maven central (not currently live)
import com.lib1.Car

interface MyApi {
    public Car getCar();
}

消费者的 gradle.build:implementation 'com.me.lib2:1.0'

MyApi api = getMyApi()
api.getCar() // Error

无法访问“com.lib1.Car”类。检查您的模块类路径是否存在缺失或冲突的依赖项

问题:有没有办法使用 gradle 做到这一点?

【问题讨论】:

  • 你是指消费者gradle.build中的lib2吗?
  • 无论如何,将 lib2 中的 lib1 依赖标记为 api 应该足以使用其类型。请仔细检查它是api 而不是implementation,如果是尝试创建stackoverflow.com/help/minimal-reproducible-example

标签: java gradle kotlin


【解决方案1】:

我不确定你在问什么。这是一个我认为应该大致按照您所说的示例的示例?


我们有一个带有 3 个子项目的 gradle 项目,cargarageappcargarage 提供库,而 app 是我们的应用程序。除了这些目录,根目录只包含一个settings.gradle,内容如下:

rootProject.name = 'example'
include 'car', 'garage', 'app'

继续,我们有提供接口的car 项目。它是build.gradle,看起来像这样:

plugins {
  id 'java-library'
}

除此之外,它只包含我们在src/main/java/car/Car.java的接口:

package car;

public interface Car {
  void drive();
}

garagecar 项目的消费者,并提供了一种获取新Cars 的方法。所以我们需要像这样声明api:car 的依赖:

plugins {
  id 'java-library'
}

dependencies {
  api project(':car')
}

Garage 类本身看起来像这样(在src/main/java/garage/Garage.java 下:

package garage;

import car.Car;

public class Garage {
  public Car getCar() {
    return () -> { System.out.println("Hello World!"); };
  }
}

最后,我们的应用程序只需要一个 implementation 依赖于 garage 来使用它,并且需要一个 JavaExec 任务来运行它:

plugins {
  id 'java'
}

dependencies {
  implementation project(':garage')
}

task run(type: JavaExec) {
  main = 'app.Main'
  classpath = sourceSets.main.runtimeClasspath
}

实际的实现再次转到src/main/java/app/Main.java

package app;

import garage.Garage;

public class Main {
  public static void main(String[] args) {
    Garage g = new Garage();
    g.getCar().drive();
  }
}

现在我们可以使用gradle :app:run 运行整个程序,这应该会为我们提供以下几行的输出:

> Task :app:run
Hello World!

BUILD SUCCESSFUL in 506ms
6 actionable tasks: 1 executed, 5 up-to-date
<-------------> 0% WAITING
> IDLE

如您所见,除了您已经说明的事情之外,您无需做任何特别的事情。这是假设您正在使用类路径。如果您使用的是 Java 9+ 模块系统,则有一些额外的步骤,但我认为这超出了这个问题的范围。

【讨论】:

  • 如果所有库都在同一个 gradle 项目中,我的示例将起作用,当它们作为 jar 导入时不起作用,classpath = sourceSets.main.runtimeClasspath 行有什么作用?
  • @JohnSardinha 这些东西并不都在同一个 gradle 项目中。它们分布在 3 个项目中,就像我在答案中所说的那样。它是否在 Jar 中没有任何区别。 classpath = sourceSets.main.runtimeClasspath like 将 JavaExec 任务的 classpath 属性设置为包含来自 main 源集及其依赖项的所有内容。它不影响编译,只是为了运行应用程序。
猜你喜欢
  • 1970-01-01
  • 2016-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-30
相关资源
最近更新 更多