【问题标题】:gradle - how do I build a jar with a lib dir with other jars in it?gradle - 如何构建一个带有 lib 目录的 jar,其中包含其他 jar?
【发布时间】:2011-03-27 15:01:55
【问题描述】:

在 gradle 中 - 如何将 jars 嵌入到 lib 的构建输出 jar 中 目录(特别是 lib/enttoolkit.jar 和 lib/mail.jar)?

【问题讨论】:

标签: jar gradle uberjar


【解决方案1】:

如果你的项目中有一个目录中的所有 jars(我们称之为libs),你只需要这个:

jar {
    into('lib') {
        from 'libs'
    }
}

我猜这些 jar 更有可能是某种依赖项。然后你可以这样做:

configurations {
    // configuration that holds jars to copy into lib
    extraLibs
}
dependencies {
    extraLibs 'org.something:something-dep1:version'
    extraLibs 'org.something:something-dep2:version'
}

jar {
    into('lib') {
        from configurations.extraLibs
    }
}

【讨论】:

  • 如果你想要所有的依赖,你也可以从configurations.runtime复制,它给你默认的compile依赖,省去你创建自己的extraLibs配置的麻烦。
  • 错误:在 org.gradle.api.Project 类型的项目 ':app' 上找不到参数 [build_bndovev91pu8trwrdngc8qh7i$_run_closure5@3be2321e] 的方法 jar()。
  • @Thunderforge 要获取所有依赖项,我必须从configurations.runtimeClasspath 而不是configurations.runtime 复制,同时避免需要extraLibs 定义。
  • 我们只需要在srcDirsprocessResources{ from(zipTree("src/main/resources/lib/local-jar-name.jar")) }之后添加资源
【解决方案2】:

逐字逐句来自:http://docs.codehaus.org/display/GRADLE/Cookbook#Cookbook-Creatingafatjar

Gradle 0.9:

jar {
    from configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}

Gradle 0.8:

jar.doFirst {
    for(file in configurations.compile) {
        jar.merge(file)
    }
}

上面的 sn-ps 将只包括该项目的编译依赖项,而不包括任何传递的运行时依赖项。如果您还想合并这些,请将configurations.compile 替换为configurations.runtime。

编辑:只选择你需要的罐子

做一个新的配置,releaseJars 可能

configurations {
    releaseJars
}

将您想要的 jar 添加到该配置中

dependencies {
    releaseJars group: 'javax.mail', name: 'mail', version: '1.4'
    //etc
}

然后在上述 jar 任务中使用该配置。

【讨论】:

  • 我在 0.9rc1。所以尝试了你的第一个建议。拉了各种我不想要的东西.....
  • 我认为更接近...问题是我需要 lib 目录中的罐子。这会从 jar 中提取类。我想要输出 jar 中的 lib/mail 和 lib/enttoolkit
  • 我知道这并没有回答问题,而是一个绝妙的提示。谢谢卢卡斯。
  • 很好的提示,但完全错过了非常具体的问题。
  • 链接不可用,原因是“所有Codehaus服务都已终止”
【解决方案3】:

简单:

task copyToLib( type: Copy ) {
    into "$buildDir/libs/lib"
    from configurations.runtime
}

jar { dependsOn copyToLib }

运行它:

$ gradle jar
...
$ tree build/libs

build/libs
├── your-project-0.0.1.BUILD-SNAPSHOT.jar
└── lib
    ├── akka-actor-2.0.jar
    ├── akka-camel-2.0.jar
    ├── ... ... ...
    ├── spring-expression-3.1.0.RELEASE.jar
    └── zmq-2.1.9.jar

1 directory, 46 files

【讨论】:

  • 这会将库复制到输出目录,但不会复制到 JAR 文件本身——这是问题所在。
【解决方案4】:

我还需要做一些类似的事情,但不太能够得到 Guus 和 stigkj 建议的工作,但在他们的帮助下已经足够接近了(Guus 的示例在 dependencies { compile { extendsFrom myLibs }} 关闭对我来说是爆炸性的) .

apply plugin: 'groovy'

repositories {
    mavenCentral()
}

configurations {
    // custom config of files we want to include in our fat jar that we send to hadoop
    includeInJar
}

dependencies {
    includeInJar 'org.codehaus.groovy:groovy:1.8.6'

    configurations.compile.extendsFrom(configurations.includeInJar)
}

jar {
    into('lib') {
        println "includeInJar: " + configurations.includeInJar.collect { File file -> file }
        from configurations.includeInJar
    }

}

然后运行 ​​gradle jar 并检查创建的 jar 会给我这个输出,表明我得到的 jar 文件具有 groovy 以及它在“胖 jar”中依赖的所有 jar:

%  gradle jar                                                                                                                         
includeInJar: [/Users/tnaleid/.gradle/caches/artifacts-8/filestore/org.codehaus.groovy/groovy/1.8.6/jar/553ca93e0407c94c89b058c482a404427ac7fc72/groovy-1.8.6.jar, /Users/tnaleid/.gradle/caches/artifacts-8/filestore/antlr/antlr/2.7.7/jar/83cd2cd674a217ade95a4bb83a8a14f351f48bd0/antlr-2.7.7.jar, /Users/tnaleid/.gradle/caches/artifacts-8/filestore/asm/asm/3.2/jar/9bc1511dec6adf302991ced13303e4140fdf9ab7/asm-3.2.jar, /Users/tnaleid/.gradle/caches/artifacts-8/filestore/asm/asm-tree/3.2/jar/cd792e29c79d170c5d0bdd05adf5807cf6875c90/asm-tree-3.2.jar, /Users/tnaleid/.gradle/caches/artifacts-8/filestore/asm/asm-commons/3.2/jar/e7a19b8c60589499e35f5d2068d09013030b8891/asm-commons-3.2.jar, /Users/tnaleid/.gradle/caches/artifacts-8/filestore/asm/asm-util/3.2/jar/37ebfdad34d5f1f45109981465f311bbfbe82dcf/asm-util-3.2.jar, /Users/tnaleid/.gradle/caches/artifacts-8/filestore/asm/asm-analysis/3.2/jar/c624956db93975b7197699dcd7de6145ca7cf2c8/asm-analysis-3.2.jar]
:compileJava UP-TO-DATE
:compileGroovy UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:jar

BUILD SUCCESSFUL

Total time: 3.387 secs

%  jar tvf build/libs/gradletest.jar                                                                                                  
     0 Mon Mar 12 11:40:00 CDT 2012 META-INF/
    25 Mon Mar 12 11:40:00 CDT 2012 META-INF/MANIFEST.MF
     0 Mon Mar 12 11:40:00 CDT 2012 lib/
5546084 Mon Mar 05 13:13:32 CST 2012 lib/groovy-1.8.6.jar
445288 Mon Mar 05 13:13:38 CST 2012 lib/antlr-2.7.7.jar
 43398 Mon Mar 05 13:13:40 CST 2012 lib/asm-3.2.jar
 21878 Mon Mar 05 13:13:40 CST 2012 lib/asm-tree-3.2.jar
 33094 Mon Mar 05 13:13:40 CST 2012 lib/asm-commons-3.2.jar
 36551 Mon Mar 05 13:13:40 CST 2012 lib/asm-util-3.2.jar
 17985 Mon Mar 05 13:13:40 CST 2012 lib/asm-analysis-3.2.jar

【讨论】:

  • 好的,我已经完成了这里描述的操作,但我仍然收到Exception in thread "main" java.lang.NoClassDefFoundError: com/rabbitmq/client/ConnectionFactory。我应该以某种方式设置类路径吗?
【解决方案5】:

可以尝试以下代码。依赖于jar任务,属于Jar类型

task createJobJar(dependsOn:jar,type:Jar) {
    manifest {
        attributes(
                "Implementation-Title": 'Job '
                ,"Implementation-Version": version
        )
    }
    classifier 'job'
    destinationDir new File("$buildDir")
    into('libs'){
         from configurations.compile
    }
    into('classes'){
        from "$buildDir/classes"
    }
    into('resources'){
        from "$projectDir/src/main/resources"
    }
    into('scripts'){
        from "$projectDir/src/main/scripts"
    }
}

上面的代码会将不同的内容打包到不同的目录中。 在 gradle 2.2 上测试

【讨论】:

    【解决方案6】:

    我需要你问的同样的事情,并使用了这种方法。您可能不需要自定义配置声明,但我需要将本地使用的 jar 文件与超级构建文件中声明的文件分开。

    configurations{
        //declare custom config if necessary, otherwise just use compile
        myLibs
    }
    dependencies {
        //add lib/*.jar files to myLibs
        myLibs fileTree(dir: 'lib', include: '*.jar')
        compile {
            //set compile configuration to extend from myLibs
            extendsFrom myLibs
        }
    }
    // task to copy libs to output/lib dir
    task copyToLib(type: Copy) {
        into "$buildDir/output/lib"
        from configurations.myLibs
    }
    
    jar {
        //include contents of output dir
        from "$buildDir/output"
        manifest {
            //...
        }
    }
    
    //set build task to depend on copyToLib
    build.dependsOn(copyToLib)
    

    【讨论】:

      【解决方案7】:

      我遇到了同样的问题。我是这样解决的:

      使用 copyToLib 将文件复制到 lib 文件夹中,并使用 Class-Path 引用依赖项

      ext.mainClass = 'test.main'
      
      dependencies {
          compile fileTree(include: ['*.jar'], dir: 'libs')
          compile 'com.google.code.gson:gson:2.8.2'
          //....
      }
      
      jar {
          from "$buildDir/libs/lib"
          manifest {
              attributes 'Main-Class': 'test.main',
              'Class-Path': configurations.compile.collect { 'lib/'+it.getName() }.join(' ')
          }
      }
      
      task copyToLib(type: Copy) {
          into "$buildDir/libs/lib"
          from configurations.compile
      }
      
      build.dependsOn(copyToLib)
      

      【讨论】:

        【解决方案8】:

        在我的情况下,我需要将根项目 Jar 的内容包含到子项目 Jar 中。因此,要使其正常工作,可以使用此模板:

        jar{
          manifest{
            attributes 'Main-Class':'<main class>'
          }
          def conf= configurations.find {it.name.equals('compile') }
          File jar= conf.files.find {it.name.contains('<name or part of the name of produced Jar>')}
        
          FileTree fileTree=zipTree(jar)
          from fileTree
        }
        

        我的例子:

        jar{
           manifest{
               attributes 'Main-Class':'alexiy.jace.Jace'
           }
           description='Make a runnable API Jar'
           def conf= configurations.find {it.name.equals('compile') }
           File tools= conf.files.find {it.name.contains('Tools')}
        
           FileTree fileTree=zipTree(tools)
           from fileTree
        }
        

        【讨论】:

          【解决方案9】:

          以下是我使用 Gradle 成功实现此构建设置的方法。这会将您的应用程序构建为 Jar,将生成的库 jar 复制到 build/libs 下的 libs 目录中,并配置类路径以将 jar 包含在创建的 build/libs/libs 目录中。

           plugins {
              id 'application'
           }
          
           group 'org.pkg'
           version '1.0-SNAPSHOT'
          
           ext.mainClass = 'org.pkg.MainClass'
          
           repositories {
              mavenCentral()
              mavenLocal()
           }
          
           dependencies {
              compile fileTree(include: ['*.jar'], dir: 'libs')
              testCompile group: 'junit', name: 'junit', version: '4.12'
          
              implementation group: 'com.mchange', name: 'c3p0', version: '0.9.5.5'
           }
           
           task copyToLib(type: Copy) {
              into "$buildDir/libs/libs"
              // configurations.runtimeClasspath includes maven jars
              from configurations.runtimeClasspath 
           }
          
           def archiveVersion = "1.0.0"
          
           task uberJar(type: Jar) {
              archiveClassifier = 'uber'
          
              from sourceSets.main.output
              // include the copy task
              dependsOn(copyToLib)
          
              // use onfigurations.runtimeClasspath to collect all the jars
              manifest {
                attributes(
                      'Class-Path': configurations.runtimeClasspath.collect { 'libs/' + it.getName() }.join(' '),
                      'Main-Class': 'org.pkg.MainClass',
                      "Implementation-Title": "Gradle",
                      "Implementation-Version": archiveVersion
                )
              }
           }
          

          【讨论】:

            【解决方案10】:
            task <taskname>(type: Jar) {
                archiveName 'nameofjar.jar'
                doFirst {
                manifest {
                        attributes 'Class-Path': configurations.compile.files.collect{ project.uri(it) }.join(' ')
                    }
                }
            }
            

            【讨论】:

            • 稍微解释一下这段代码的作用可能有助于解释一些特定的位?
            猜你喜欢
            • 2017-04-07
            • 1970-01-01
            • 2011-04-11
            • 2017-05-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-15
            相关资源
            最近更新 更多