楼主:
qrtt1 (有些事,有时候。。。)
2016-04-15 18:46:58※ 引述《Neisseria (Neisseria)》之铭言:
: 小弟用 gradle 想包一些 groovy 命令稿和静态档案
: build.gradle 如网址:https://pastebin.com/EUGbHCmg
: 目前可以顺利产生 JAR,该 JAR 也可以顺利执行
: 不过 静态档案会跑到其他的资料夹
: 结构大致如下:
: ├── classes
: │ └── main
: │ └── SomeClass.class
: ├── libs
: │ └── SomeClass-1.0.jar
: ├── resources
: │ └── main
: │ └── static-file
: └── tmp
: ├── compileGroovy
: │ └── groovy-java-stubs
: └── uberjar
: └── MANIFEST.MF
: 我觉得我可能是误会了
: static-file 不会跑进 JAR 里
: 不过我不确定 所以 po 上来请各位大大解惑
: 感恩
我建了一些 sample class 与静态档:
qty:t qrtt1$ tree
.
├── build
│ ├── classes
│ │ └── main
│ │ └── Hello.class
│ ├── libs
│ │ └── t-1.0.jar
│ ├── resources
│ │ └── main
│ │ └── foo.txt
│ └── tmp
│ ├── compileGroovy
│ │ └── groovy-java-stubs
│ ├── jar
│ │ └── MANIFEST.MF
│ └── uberjar
│ └── MANIFEST.MF
├── build.gradle
└── src
├── groovy
│ └── Hello.groovy
└── resources
└── foo.txt
14 directories, 8 files
摘录会用到的部分如下:
sourceSets {
main {
groovy {
srcDir 'src/groovy'
}
resources {
srcDir 'src/resources'
}
}
}
task uberjar(type: Jar, dependsOn:[':compileJava', ':compileGroovy', ':processResources']) {
from files(sourceSets.main.output.classesDir)
from configurations.runtime.asFileTree.files.collect { zipTree(it) }
manifest {
attributes 'Main-Class': 'SomeClass'
}
}
若是怀疑档案没进去,那就检查一下源头吧!
很明显地黄字部分是源头,绿字部分是其它 library 档
那么就来研究黄子部分的 code 吧。
没头绪!没关系!gradle script 就是 groovy script
把它的类别印出来研究一下,在 build.gradle 最后面加上:
println sourceSets.main.output.class
println sourceSets.main.output.classesDir.class
执行一下:
# gradle -q
class org.gradle.api.internal.tasks.DefaultSourceSetOutput_Decorated
class java.io.File
classesDir 是个 File 物件,依它的命名猜是个录目
DefaultSourceSetOutput 就是某个 gradle 的物件,先不知道它做什用的。
先不理它,来研究一下 classesDir 目录内有什么:
再加印一下它的内容:
println "files in classesDir"
sourceSets.main.output.classesDir.eachFile { println it }
/Users/qrtt1/t/build/classes/main/Hello.class
你发会现它没有 静态档 只有 .class。
看来得换一条路来查了,如果在
sourceSets.main.output.classesDir
没有我们期待的档,那在它的上一层会不会有呢?
不确定要怎么查但它是个 groovy object 先用 each 看看运气:
sourceSets.main.output.each { println it }
/Users/qrtt1/t/build/classes/main
/Users/qrtt1/t/build/resources/main
你会发现它印出了二个目录,依刚刚变量的名字来看
sourceSets.main.output.classesDir
就会是
/Users/qrtt1/t/build/classes/main
那么代表目录
/Users/qrtt1/t/build/resources/main
的变量叫什么?
没头绪没关系,找一下 property 有 Dir 的看看。
加 build.gradle 印一下:
println sourceSets.main.output.properties.grep {
it.key.contains("Dir")
}
只要没有被 MOP 动手脚,groovy object 都有 properties
只要是 groovy object 就有基 grep 能用囉
qty:t qrtt1$ gradle
[classesDir=/Users/qrtt1/t/build/classes/main,
resourcesDir=/Users/qrtt1/t/build/resources/main]
========================================================
以上是简单的野外求生过程,
不过先前其实有查到是哪个类别了,直接看 source code 比较快
https://github.com/gradle/gradle/blob/master/subprojects/
plugins/src/main/groovy/
org/gradle/api/internal/tasks/DefaultSourceSetOutput.java
缩:http://bit.ly/1SPm1Ke
所以,由上述的历程可以知道你根本缺少了 resources 档的位置。
依直觉可以这么写:
task uberjar(type: Jar, dependsOn:[':compileJava', ':compileGroovy', ':processResources']) {
from files(sourceSets.main.output.classesDir)
from files(sourceSets.main.output.resourcesDir)
from configurations.runtime.asFileTree.files.collect { zipTree(it) }
manifest {
attributes 'Main-Class': 'SomeClass'
}
}
你就得到了有 resources file 的 uberjar
qty:t qrtt1$ unzip -l build/libs/t-1.0.jar |grep foo
0 04-15-16 18:01 foo.txt
不过依手册与 source code 的明示、暗示,
它是一个 Composite Pattern
public class DefaultSourceSetOutput extends
CompositeFileCollection implements SourceSetOutput { }
通俗一点的叫‘树’,简单地说应该要有获得 parent 就得到它包含物的效果
你可以改写成:
from files(sourceSets.main.output)
再加上 CopySpec 手册说明 http://bit.ly/1VtZKbl ,
from (...) 它会自动呼叫 project.files,所以又能再简化成:
from sourceSets.main.output
于是开心地打完收工,谢谢收看。