Gradle应该从mavenLocal()创建每个项目的JAR-s本地副本吗?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gradle应该从mavenLocal()创建每个项目的JAR-s本地副本吗?相关的知识,希望对你有一定的参考价值。

我有一些库Gradle Java项目,我目前正在使用publishToMavenLocal任务发布到我当地的Maven repositoty。我可以在我当地的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

给出错误(下面的清单设置):

 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中的清单设置也只是来自其他工作项目的副本。

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 repositor,即:

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 - 用于构建,运行,测试。

  • 这完全是意想不到的......

我的同事和我确信其他本地构建的文物被缓存或至少保存在本地dist/文件夹中。在这个例子中,base JAR不会被复制到任何地方。

我可以强制将mavenLocal资产(至少)复制到lib/文件夹中并准备好使用吗?

另外,查看当前SocketListener.jar清单的内容,我不相信所有必需的JAR文件都已加载。首先,我的base JAR所依赖的东西也将缺失。我觉得其他上游依赖也不存在。

确保为构建收集所有依赖项以及从Gradle和命令行提示符运行Java命令行应用程序的常用过程是什么?

这样使用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/文件夹。

此外,经过一些测试和实验,我们确认,除非Manifest还使用runtimeClasspath集合(或compileClasspath),否则此JAR将无法运行。

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示例”中找到ClassPath,因为它创建了一个在Web上运行的JAR。虽然你可以在没有ClassPath的情况下进行构建,但最好有一个用于实际使用imho。

关于实际问题。出现此问题的原因是所讨论的build.gradle文件使用:implementation( ... )依赖规范而不是:compile( ... )依赖项。

我能够通过将一个依赖从qaz​​xswpoi移动到implementation线并使用compile集合来证实这一点。结果JAR和runtime有我移动的模块。

我把你用的那个留给读者。这里有一些参考:

以上是关于Gradle应该从mavenLocal()创建每个项目的JAR-s本地副本吗?的主要内容,如果未能解决你的问题,请参考以下文章

gradle构建scala

IDEA开发工具创建Gradle项目发布到TOMCAT

安卓 eclipse 项目 迁移 android studio gradle 配置 热修复 annotations注解

Gradle打包jar可执行程序

更改gradle中央仓库,加快访问速度

Gradle 使用Maven本地缓存