在http://blog.csdn.net/zero__007/article/details/50708166中簡單介紹了使用gradle生成可運(yùn)行jar包,但是在實踐中可能會發(fā)現(xiàn),生成的jar中包含一些不需要的文件,可以采用如下的示例來去除:
但是上面的方式生成的jar包還是過大,能不能不把第三方j(luò)ar包打入我們自己的jar中,而是在一個lib目錄,然后運(yùn)行我們應(yīng)用程序時,再去引入這些第三方j(luò)ar呢?gradle提供這樣的插件:application。
示例:
- apply plugin: 'scala'
- apply plugin: 'java'
- [compileJava, compileTestJava, javadoc]*.options*.encoding = 'utf-8'
- [compileJava, compileTestJava]*.sourceCompatibility = "1.8"
- [compileJava, compileTestJava]*.targetCompatibility = "1.8"
- ext {
- jarName = project.name
- mainClassName = 'com.zero.HelloWorld'
- finagleVersion = '6.33.0'//注意: ' 與 "
- }
- repositories {
- mavenLocal()
- maven { url 'http://maven.oschina.net/content/groups/public/' }
- maven { url 'http://uk.maven.org/maven2/' }
- maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
- maven { url 'https://repo.spring.io/libs-snapshot/' }
- mavenCentral()
- }
- project.configurations {
- all*.exclude group: 'log4j', module: 'log4j'
- all*.exclude group: 'org.slf4j', module: 'slf4j-log4j12'
- }
- dependencies {
- compile "org.scala-lang:scala-library:2.11.8"
- compile "org.scala-lang:scala-compiler:2.11.8"
- compile "org.scala-lang:scala-reflect:2.11.8"
- //finagle
- compile "com.twitter:finagle-core_2.11:${finagleVersion}"
- compile "com.twitter:finagle-http_2.11:${finagleVersion}"
- compile "com.twitter:finagle-mysql_2.11:${finagleVersion}"
- compile "com.twitter:finagle-redis_2.11:${finagleVersion}"
- //。。。。。。
- }
- task "mkdirs" << {
- sourceSets*.scala.srcDirs*.each { it.mkdirs() }
- sourceSets*.java.srcDirs*.each { it.mkdirs() }
- sourceSets*.resources.srcDirs*.each { it.mkdirs() }
- }
- jar.manifest.attributes 'Main-Class': mainClassName
- jar.baseName = jarName
- jar {
- from {
- configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
- configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) }
- }
- exclude('LICENSE.txt', 'NOTICE.txt', 'rootdoc.txt')
- exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA'
- exclude 'META-INF/NOTICE', 'META-INF/NOTICE.txt'
- exclude 'META-INF/LICENSE', 'META-INF/LICENSE.txt'
- exclude 'META-INF/DEPENDENCIES'
- }
- // important(把java與scala的源代碼目錄全映射到scala上,
- // 這樣gradle compileScala時就能同時編譯java與scala的源代碼)
- sourceSets {
- main {
- scala {
- srcDirs = ['src/main/scala', 'src/main/java']
- }
- java {
- srcDirs = []
- }
- }
- test {
- scala {
- srcDirs = ['src/test/scala', 'src/test/java']
- }
- java {
- srcDirs = []
- }
- }
- }
上面的jar任務(wù)中,會exclude第三方j(luò)ar包的LICENSE.txt、NOTICE.txt等不需要的文件。但是上面的方式生成的jar包還是過大,能不能不把第三方j(luò)ar包打入我們自己的jar中,而是在一個lib目錄,然后運(yùn)行我們應(yīng)用程序時,再去引入這些第三方j(luò)ar呢?gradle提供這樣的插件:application。
示例:
- apply plugin: 'scala'
- apply plugin: 'java'
- apply plugin: 'application'
- [compileJava, compileTestJava, javadoc]*.options*.encoding = 'utf-8'
- [compileJava, compileTestJava, compileScala]*.sourceCompatibility = "1.8"
- [compileJava, compileTestJava, compileScala]*.targetCompatibility = "1.8"
- // generate gradle wrapper
- task wrapper(type: Wrapper) {
- gradleVersion = '2.14.1'
- }
- // scala compiler options
- tasks.withType(ScalaCompile) {
- sourceCompatibility = 1.8
- targetCompatibility = 1.8
- configure(scalaCompileOptions.forkOptions) {
- memoryMaximumSize = '512m'
- }
- }
- ext {
- finagleVersion = '6.36.0'
- projectpath = '/xxx/yyy'
- }
- applicationName = 'xxx' // name of tar, zip and script
- mainClassName = 'com.zero.HelloWorld' // project main class name
- jar {
- exclude '*.conf', '*.xml'
- }
- repositories {
- //略
- }
- project.configurations {
- //略
- }
- dependencies {
- //略
- }
- task "mkdirs" << {
- //略
- }
- sourceSets {
- //略
- }
- // customize gradle distribution
- distributions {
- main {
- contents {
- into('conf') {
- from { 'src/main/resources' }
- }
- }
- contents {
- into('bin') {
- from { 'src/main/bash/xxx.sh' }
- }
- }
- }
- }
- // project runtimes JVM options
- applicationDefaultJvmArgs = ["-server",
- "-Dproject.home=${projectpath}",
- "-Dlog4j.configurationFile=${projectpath}/conf/log4j2.xml",
- "-Xms16g",
- "-Xmx16g",
- //略
- ]
項目的工程目錄結(jié)構(gòu)如下:- /src
- /src/main
- /src/main/bash
- /src/main/bash/xxx.sh
- /src/main/java
- /src/main/resources
- /src/main/resources/xxx.conf
- /src/main/resources/log4j2.xml
- /src/main/scala
- /src/test
運(yùn)行g(shù)radle build后在build/distributions目錄中會生成projectname.tar和projectname.zip文件,解壓后會有bin、conf、lib這三個目錄。lib目錄中是我們應(yīng)用程序的jar和第三方j(luò)ar。在conf目錄中,由于- jar {
- exclude '*.conf', '*.xml'
- }
這會限制將*.conf、*.xml即相關(guān)配置文件打入jar包,而是將其移動到conf目錄中:- contents {
- into('conf') {
- from { 'src/main/resources' }
- }
- }
這就方便修改配置文件,但是需要在代碼中額外指定配置文件加載路徑。于是我們在JVM啟動參數(shù)中配置了"-Dproject.home=${projectpath}",這樣就可以找到配置文件了。同時也將可能用到的shell腳本移動到bin目錄中:- contents {
- into('bin') {
- from { 'src/main/bash/xxx.sh' }
- }
- }
在bin目錄中,除了我們的腳本,插件還會為我們生成projectname和projectname.bat腳本,在上述兩腳本中指定了JVM運(yùn)行參數(shù),即我們在build. gradle中寫明的,還有jar啟動腳本(會運(yùn)行我們的jar,并將第三方j(luò)ar添加至到-classpath參數(shù)中)。我們只需要在bin、conf、lib同級目錄中運(yùn)行bin/project(linux下)即可運(yùn)行我們的應(yīng)用程序。