我有一些库 Gradle Java 项目,我目前正在使用 publishToMavenLocal
将它们发布到我的本地 Maven 存储库中。任务。我可以寻找一个名为 base
的库我本地的文件.m2\repository\...
区域,并找到它(比如说):
... lib\base\08.00.003-SNAPSHOT\
base-08.00.003-SNAPSHOT.jar
一个客户项目,
socket_listener
使用 base
并声明本地存储库,如图所示。该项目构建良好并从 Gradle 命令行成功运行。repositories {
mavenLocal()
jcenter()
}
// later in the file...
//
assemble.dependsOn distDirectory
跑 ...
gradle socket_listener:run
:
lots of logger output
:
socket_listener
项目创建一个 dist
socket_listener.jar
的目录在 lib/*
中具有所需依赖项的程序集用于依赖项的文件夹:task distDirectory( type: Copy ) {
into 'dist'
from jar
from 'src/dist'
into( 'lib' )
{
from configurations.runtime
}
}
在我尝试从命令行运行我的监听器项目之前,我也认为这没问题;它因此失败了。
cd socket_listener\dist
java -jar SocketListener.jar
给出错误(下面的 list 设置):
Error: Could not find or load main class example.app.cmd.SocketListener
当我检查
lib/
文件夹 -- 否 base-08.00.003-SNAPSHOT.jar
是要被发现的。没有mavenLocal
JAR 文件位于 lib/
.这是我的第一个障碍,没有这些程序将无法运行 mavenLocal
JAR-s。gradle 中的 list 设置也只是来自其他工作项目的副本。
mainClassName = 'example.app.cmd.SocketListener'
:
jar
{
manifest
{
attributes( "Main-Class": mainClassName )
attributes( "Application-Name": "socket_listener" )
attributes( "Class-Path": 'lib/' + ( configurations.runtime.collect { it.getName() }.join(' lib/') ) )
attributes( "Codebase": "*" )
attributes( "Permissions": "all-permissions" )
}
}
那不应该是问题#2。
发现
base-08.00.003-SNAPSHOT.jar
来自 lib/
的行动缺失目录,我开始寻找那个文件。你猜怎么了?我找到 JAR 文件的唯一地方是 Maven 存储库,即:
dir /s/b d:\*08.00.003-SNAPSHOT.jar
d:\.rep\.m2\repository\local\lib\driver_model\08.00.003-SNAPSHOT\driver_model-08.00.003-SNAPSHOT.jar
d:\.rep\.m2\repository\local\lib\base\08.00.003-SNAPSHOT\base-08.00.003-SNAPSHOT.jar
dir /s/b d:\*08.00.003-SNAPSHOT.jar
File Not Found
这有点像 linux
find / -name "*08.00.003-SNAPSHOT.jar"
命令。就是PC上的每个目录,成功后直接gradle socket_listener:build -x test --refresh-dependencies
gradle socket_listener:run
并确保加载最新的依赖项。从我的小实验结果中可以清楚地看出,该项目的 Gradle 构建是直接从存储库中使用库 JAR-s -- For 构建 , 对于 运行 , 对于 测试 .
我的同事和我确信其他本地构建的人工制品被缓存或至少在本地保存到
dist/
文件夹。在这个例子中 base
JAR 不会被复制到任何地方。我可以强制
mavenLocal
要(至少)复制到 lib/
中的 Assets 文件夹并准备好使用?另外,查看当前 SocketListener.jar 的 的内容 list 我不相信全部 已加载必要的 JAR 文件。首先,我的
base
JAR 依赖也将丢失。我觉得其他上游依赖项也不存在。确保从 为构建和运行 Java 命令行应用程序收集所有依赖项的通常过程是什么?两个 Gradle 和命令行提示符??
这样使用maven仓库正常吗?
它怎么能被覆盖?
最佳答案
configurations.runtime
不是我需要的。 from
中的子句distDirectory
任务应该如下
task distDirectory( type: Copy ) {
into 'dist'
from jar
from 'src/dist'
into( 'lib' )
{
from configurations.from configurations.runtimeClasspath
}
}
runtimeClasspath
为我提供了 socket_listener
的所有直接依赖项. 我不确定
build.gradle
的“如何”我从其他项目的表演中获取了该模型。我希望这些项目可以制作安装程序,并且不需要使用它dist/
明确的文件夹。此外,经过一些测试和实验,确认此 JAR 不会运行,除非 list 也使用
runtimeClasspath
。集合(或 compileClasspath
),即。jar {
manifest {
attributes( "Main-Class": mainClassName )
attributes( "Application-Name": "socket_listener" )
attributes( "Class-Path": 'lib/' + ( configurations.runtimeClasspath.collect { it.getName() }.join(' lib/') ) )
attributes( "Codebase": "*" )
attributes( "Permissions": "all-permissions" )
}
}
但是,我怀疑情况并非总是如此。主类
SocketListener
runtimeClasspath
中可能需要一个不存在的 JAR装载。其他程序可能加载正常。他们可能会因堆栈跟踪而跌倒,该堆栈跟踪将识别外观。或者只是工作正常。java启动器会不会那么好。
顺便说一句,我没有在许多“简单的 Gradle 示例”中找到任何用于制作在网络上运行的 JAR 的 ClassPath。虽然您可以在没有 ClassPath 的情况下进行构建,但最好有一个供实际使用的 imho。
关于实际问题。出现此问题是因为
build.gradle
有问题的文件使用: implementation
( ... )
依赖规范而不是:compile( ... )
依赖关系。我可以通过从
implementation
移动一个依赖项来确认这一点。到 compile
行并使用 runtime
Collection 。生成的 JAR 和 lib/
有我移动的模块。我把你用哪一个留给读者。这里有一些引用:
关于java - Gradle 是否应该从 mavenLocal() 为每个项目制作 JAR-s 的本地副本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52091046/