简体   繁体   中英

How to access a dependency of a dependency in Java/Gradle?

I'm trying to access a library that is implemented in a library that I implement. I own both these libraries. Ie:

Lib1 has a certain class I want to access in the consumer app, say Car.java :

public class Car {
    public Int wheelsCount;
}

Lib2 has an api which returns the class Car from lib1:

gradle.build:

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

interface MyApi {
    public Car getCar();
}

Consumer's gradle.build: implementation 'com.me.lib2:1.0'

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

Cannot access class 'com.lib1.Car'. Check your module classpath for missing or conflicting dependencies

Question: Is there a way to do this using gradle?

I am not sure what you're asking. Here is an example which I think should roughly do what you were talking about?


We have a gradle project with 3 subprojects, car , garage and app . car and garage provide libraries, whereas app is our application. Aside from these directories, the root directory contains only a settings.gradle with this content:

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

Moving on, we have the car project which provides an interface. It's build.gradle looks like this:

plugins {
  id 'java-library'
}

Other than that, it only contains our interface at src/main/java/car/Car.java :

package car;

public interface Car {
  void drive();
}

garage is a consumer for the car project, and provides a way to get new Car s. So we need to declare an api dependency on :car like this:

plugins {
  id 'java-library'
}

dependencies {
  api project(':car')
}

The Garage class itself looks like this (under src/main/java/garage/Garage.java :

package garage;

import car.Car;

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

Finally, we have our application which just needs an implementation dependency on garage to use it and a JavaExec task to run it:

plugins {
  id 'java'
}

dependencies {
  implementation project(':garage')
}

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

The actual implementation again goes to 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();
  }
}

Now we can run the whole thing with gradle :app:run , which should give us output along these lines:

> Task :app:run
Hello World!

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

So as you can see, there's nothing special you need to do beyond the things you've already stated. This is assuming you're using classpaths. If you're using the Java 9+ module system there are some additional steps, but this would be beyond the scope of this question I think.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM