1. 程式人生 > >Gradle打可執行Jar包(包含依賴第三方庫中的類)

Gradle打可執行Jar包(包含依賴第三方庫中的類)

使用Gradle來打Jar包,在引入Gradle的java外掛後,直接就能實現

在build.gradle檔案中引入java外掛

plugins {
    id 'java'
}

然後配置maifest主類

jar {
    manifest {
        attributes "Main-Class": "cn.buddie.GradleTest"
    }
}

最後執行jar任務就能打出來jar包了

gradle jar

但這樣,打出來的Jar包中,只包含了自己編寫的程式碼編譯成的Class檔案。其它依賴的Jar包中的類,不在其中。

解決方式有兩種。

一種是引用application外掛,通過distTar或distZip打包。這樣生成的包裡不僅包含了自己專案中寫的原始碼編輯成的jar包,還包括gradle中配置依賴的jar包,同時還生成了shell和bat指令碼,通過指令碼,可以直接執行我們的程式。

另一種,是在打jar包,直接依賴的第三方類庫中的類,一起打包到我們的jar中。

具體如下:

jar {
    manifestContentCharset 'utf-8'
    metadataCharset 'utf-8'
    manifest {
        attributes "Main-Class": "cn.buddie.GradleTest"
    }
    from {
        configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
    }
}

這樣打出來的jar包,可以使用java -jar的方式執行

java -jar myapp.jar

如果領導說,你即需要提供單個的jar,又需要提供tar包,怎麼辦呢?因為修改了task jar,而task distTar是依賴於task jar。這樣的後果就是打出來的tar包中,已經包含了所有你依賴的第三方jar包,同時,你自己專案打出的jar包中,又包含了這些第三方jar包中的類。也就是所有第三方的類,都double了!

我這裡最終成功的解決方案為:增加引數,讓task jar根據引數來決定是否將第三方依賴類打入自己的jar包。

jar {
    manifestContentCharset 'utf-8'
    metadataCharset 'utf-8'
    manifest {
        attributes "Main-Class": "cn.buddie.GradleTest"
    }
    if (project.hasProperty("allInOne")) {
        from {
            configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
        }
    }
}

這裡增加了一個“allInOne”的引數,如果不指定引數,就不會將第三方依賴類打入jar包。這樣在執行task distTar時,不指定引數,打出來的tar中,第三方依賴類就只有一份。

而在需要所有類在一個Jar包中的Jar檔案時,可以使用引數打包

gradle jar -PallInOne

這樣不管領導要什麼包,都可以在不做任何改動的情況下,滿足領導的需求