我正在编写一个Java库,我想用Gradle构建库,然后从本地测试项目中测试它。
我更倾向于使用Gradle 3.3作为我的目标。 该库应该为Java5及更高版本构建。
到目前为止,我的build.gradle
看起来像这样:
plugins {
id 'jvm-component'
id 'java-lang'
}
repositories {
mavenCentral()
}
model {
components {
main(JvmLibrarySpec) {
sources {
java {
dependencies {
module 'commons-codec:commons-codec:1.10'
module 'org.apache.httpcomponents:httpcore:4.4.6'
module 'org.apache.httpcomponents:httpclient:4.5.3'
}
}
}
api {
exports 'io.simplepush'
}
targetPlatform 'java5'
}
}
}
该库的源代码位于src/main/java/io/simplepush/Notification.java
,取决于build.gradle
文件中所述的依赖项。
使用./gradlew build
构建库可以正常工作并生成build/jars/main/jar/main.jar
。
然而,当我从IntelliJ运行测试项目(包括main.jar
之后进入测试项目)时,我收到以下运行时错误:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/http/HttpEntity
。
似乎测试项目不知道我的库所需的运行时依赖性。
我不确定告诉测试项目关于我的库的依赖关系的正确方法是什么。 我不想要一个包含所有依赖关系的胖罐子 列出测试项目本身中的所有依赖项也不是一种选择 我希望库本身能够告诉测试项目它需要哪些依赖项。
答案 0 :(得分:5)
您创建的库jar不包含IDE / Gradle随后可以解析的任何依赖性信息,以便能够编译/运行测试项目。我看到你正在使用maven中央存储库,所以你需要做的是将你的库发布到你的本地maven存储库,在测试项目中只需添加一个依赖信息(不仅仅是普通的jar文件)。
因此,在库和测试项目build.gradle
中添加maven本地存储库配置。
repositories {
mavenLocal()
mavenCentral()
}
现在您需要将库发布到本地存储库。在使用gradle 3.3时,您可以使用Maven Publishing。
因此,在库build.gradle
中添加maven发布信息。
publishing {
publications {
maven(MavenPublication) {
groupId 'io.simplepush'
artifactId 'project1-sample'
version '1.1'
from components.java
}
}
}
Gradle“maven-publish”插件可以轻松地将其发布到本地存储库,自动创建PublishToMavenLocal任务。 所以你可以运行
gradle publishToMavenLocal
将把包含所有相关性信息的库发布到本地maven存储库中。
然后您只需要向测试项目build.gradle
dependencies {
// other dependencies .....
module 'io.simplepush:project1-sample:1.1'
}
答案 1 :(得分:2)
我通过改变几件事来解决它
感谢@Babl让我指向了正确的方向
我的新图书馆build.gradle
看起来像这样:
plugins {
id 'java'
id 'maven-publish'
}
sourceCompatibility = 1.5
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
compile 'commons-codec:commons-codec:1.10'
compile 'org.apache.httpcomponents:httpcore:4.4.6'
compile 'org.apache.httpcomponents:httpclient:4.5.3'
}
publishing {
publications {
maven(MavenPublication) {
groupId 'io.simplepush'
artifactId 'project1-sample'
version '1.1'
from components.java
}
}
}
现在我可以使用./gradlew publishToMavenLocal
将库推送到本地maven存储库。
测试项目的build.gradle
使用application
插件并定义一个主类(在我的例子中是Hello
)。然后我可以运行./gradlew installDist
来生成一个可执行文件(参见Application plugin docs),它将所有依赖项放在类路径中并运行得很好。
group 'com.test'
version '1.0-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'application'
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
compile 'io.simplepush:project1-sample:1.1'
}
mainClassName = "Hello"
答案 2 :(得分:0)
这指定要检查的存储库以从
获取依赖项repositories {
mavenCentral()
}
因此,dependecies{}
中的任何内容都将从上面的内容中获取。
如果测试项目没有与库项目结合,(@ RaGe示例)新测试项目需要知道从哪里获取依赖项 - 您需要使用首选方法发布它。
之后,您的新测试项目需要在build.gradle dependencies{}
之后,根据IDE,您需要刷新类路径并从指定的存储库中下载依赖项,库依赖项中指定的传递依赖项(在本例中)将从测试项目repositories{}
中获取
Library build.gradle
repositories {
mavenCentral()
}
dependencies {
module 'commons-codec:commons-codec:1.10'
module 'org.apache.httpcomponents:httpcore:4.4.6'
module 'org.apache.httpcomponents:httpclient:4.5.3'
}
测试项目build.gradle
repositories {
mavenCentral() repository to fetch transitives
mavenLocal() or any other repo that you published the library to
}
dependencies {
pref-conf librarygroup:name:version
}
您可以在gradle中使用idea或eclipse插件来执行gradle idea
或gradle eclipseClasspath
任务,以使用新添加的依赖项刷新它。
使用此解决方案,您不需要在库中打包传递依赖项
PS。在你说你想要可执行jar之后我很困惑。