Java 如何包含仅用于编译而非直接使用的依赖库?

Java 如何包含仅用于编译而非直接使用的依赖库?,java,gradle,maven-publish,Java,Gradle,Maven Publish,我有一个App模块和两个库模块X和Y,其中App取决于X和X取决于Y ┌─────┐ │ App │ └─────┘ │ uses ▼ ┌─────┐ │ X │ └─────┘ │ uses ▼ ┌─────┐ │ Y │ └─────┘ 在X中还有一个类XClass,在Y中还有一个类YClass,其中一个扩展了另一个: //在模块X中: 类XClass:YClass //在模块Y中: 类循环类 问题是,Y必须以某种方式对App可见才能正常工作,否则会出现如

我有一个
App
模块和两个库模块
X
Y
,其中
App
取决于
X
X
取决于
Y

┌─────┐
│ App │
└─────┘
   │ uses
   ▼
┌─────┐
│  X  │
└─────┘
   │ uses
   ▼
┌─────┐
│  Y  │
└─────┘
X
中还有一个类
XClass
,在
Y
中还有一个类
YClass
,其中一个扩展了另一个:

//在模块X中:
类XClass:YClass
//在模块Y中:
类循环类
问题是,
Y
必须以某种方式对
App
可见才能正常工作,否则会出现如下错误:

无法解析以下类的超类型。请确保在类路径中具有所需的依赖项:class XClass,未解析的超类型:YClass

自然的解决方案是将
Y
作为
api
依赖项:

// In build.gradle in X:
dependencies {
    api project(':y')
}
所以问题是:

  • 我不希望
    App
    中的用户能够使用
    Y
    中的类型。如何实现这一点,使其仍能编译
  • 我正在通过
    maven publish
    发布
    X
    Y
    的工件,因此理想情况下,该解决方案在发布时也可以工作

  • 为了使代码正常工作,
    Y
    必须位于类路径上。如果
    Y
    在类路径上,则
    App
    可以看到它。Maven/Gradle对此无能为力现在,如果您使用Java9+模块,可能会有所不同,但Java模块与Maven/Gradle模块无关。