java - Gradle 是否应该从 mavenLocal() 为每个项目制作 JAR-s 的本地副本?

标签 java maven gradle jar dependencies

我有一些库 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/有我移动的模块。

    我把你用哪一个留给读者。这里有一些引用:
  • Recognizing API and implementation dependencies ( The Java Library Plugin )
  • API and implementation separation (java 插件)
  • Declaring a concrete version of a dependency ( Declaring Dependencies )
  • 关于java - Gradle 是否应该从 mavenLocal() 为每个项目制作 JAR-s 的本地副本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52091046/

    相关文章:

    java jlist - AbstractListModel - fireContentsChanged 无法正常工作

    spring - 简单的工作 Spring MVC/Maven 配置

    android - 将库上传到 Bintray,但使用时无法解析

    gradle 无法使用 kotlin 类编译 java 类

    java - 设置 JProgressBar

    java - 如何在动态 jasper excel 报告中动态设置列宽?

    java - Java 应用程序启动非常慢

    java - 在 pom.xml 中添加 json 依赖项出现错误

    java - 无法解决 Maven 多模块项目中的依赖关系

    java - Gradle 2 android 项目使用相同的库