在http://blog.csdn.net/zero__007/article/details/50708166中简单介绍了使用gradle生成可运行jar包,但是在实践中可能会发现,生成的jar中包含一些不需要的文件,可以采用如下的示例来去除:
但是上面的方式生成的jar包还是过大,能不能不把第三方jar包打入我们自己的jar中,而是在一个lib目录,然后运行我们应用程序时,再去引入这些第三方jar呢?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任务中,会exclude第三方jar包的LICENSE.txt、NOTICE.txt等不需要的文件。
但是上面的方式生成的jar包还是过大,能不能不把第三方jar包打入我们自己的jar中,而是在一个lib目录,然后运行我们应用程序时,再去引入这些第三方jar呢?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",
//略
]
项目的工程目录结构如下:
/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
运行gradle build后在build/distributions目录中会生成projectname.tar和projectname.zip文件,解压后会有bin、conf、lib这三个目录。lib目录中是我们应用程序的jar和第三方jar。在conf目录中,由于
jar {
exclude '*.conf', '*.xml'
}
这会限制将*.conf、*.xml即相关配置文件打入jar包,而是将其移动到conf目录中:
contents {
into('conf') {
from { 'src/main/resources' }
}
}
这就方便修改配置文件,但是需要在代码中额外指定配置文件加载路径。于是我们在JVM启动参数中配置了"-Dproject.home=${projectpath}",这样就可以找到配置文件了。同时也将可能用到的shell脚本移动到bin目录中:
contents {
into('bin') {
from { 'src/main/bash/xxx.sh' }
}
}
在bin目录中,除了我们的脚本,插件还会为我们生成projectname和projectname.bat脚本,在上述两脚本中指定了JVM运行参数,即我们在build. gradle中写明的,还有jar启动脚本(会运行我们的jar,并将第三方jar添加至到-classpath参数中)。我们只需要在bin、conf、lib同级目录中运行bin/project(linux下)即可运行我们的应用程序。