# Java 技術(shù)雷達(dá):工具篇

Java 相關(guān)工具

gradle

項(xiàng)目網(wǎng)址

Overview

gradle 是一款基于JVM 的自動(dòng)化構(gòu)建工具。

gradle.build文件是gradle 的配置文件,?其使用groovy 來(lái)構(gòu)建DSL 腳本。

在gradle 中, 有兩個(gè)基本概念:

  • 項(xiàng)目是構(gòu)建產(chǎn)物(如jar 包)或?qū)嵤┊a(chǎn)物(將應(yīng)用程序部署到生成環(huán)境),一個(gè)項(xiàng)目包含若干個(gè)任務(wù)。
  • 任務(wù)是指不可分割的最小工作單元,任務(wù)用來(lái)執(zhí)行真正的構(gòu)建工作。

在gradle 中,所有的特性都是由gradle 插件提供的, gradle 本身只提供了DSL 語(yǔ)言。

Usage

  • 應(yīng)用gradle 插件:

    apply plugin: 'java'
    
  • 定義變量:

    project.ext {
        guavaVersion = '18.0'
        ...
    }
    
  • 定義依賴(lài):

    project.dependencies {
        compile(...)
        runtime(...)
        testCompile(...)
    }
    
  • 定義任務(wù):

    task uberjar(type: Jar, dependsOn: jar) {...}
    

Tips

  • 由于gradle 的各個(gè)版本間存在兼容性問(wèn)題,使用wrapper 讓每個(gè)項(xiàng)目的構(gòu)建環(huán)境獨(dú)立。

    在build.gradle 文件中使用以下的配置來(lái)指定本項(xiàng)目使用的gradle 半版本信息:

    task wrapper(type: Wrapper) {
        gradleVersion = '2.5'
    }
    
  • gradle的項(xiàng)目構(gòu)建過(guò)程分為三個(gè)步驟:初始化, 配置和執(zhí)行任務(wù)。使用org.gradle.daemon=true 來(lái)啟動(dòng)后臺(tái)進(jìn)程來(lái)在構(gòu)建過(guò)程中跳過(guò)初始化步驟,從而加速gradle 的構(gòu)建執(zhí)行。

  • 將項(xiàng)目拆分為多個(gè)子項(xiàng)目,可以利用gradle 提供的并行構(gòu)建能力。

    • 在root 項(xiàng)目中的build.gradle中定義公共變量,任務(wù)和依賴(lài)。
    • 在root 項(xiàng)目中的settings.gradle中定義包含的子項(xiàng)目。
    • 在各個(gè)子項(xiàng)目的build.gradle中定義各項(xiàng)目所需的變量,任務(wù)和依賴(lài)。
  • 從cvs 中新獲取的項(xiàng)目后,在命令行中依次執(zhí)行以下的命令:

    >> gradle wrapper
    >> ./gradlew clean idea
    >> ./gradlew clean check
    

    如果check任務(wù)通過(guò),說(shuō)明項(xiàng)目已經(jīng)在本地成功構(gòu)建。

Nexus

項(xiàng)目網(wǎng)址

Overview

nexus是一款支持多種流行組件(如Maven,Docker 等)的倉(cāng)庫(kù)管理軟件。

在nexus 中,有兩個(gè)核心的概念:

  • component:一種資源,例如library或者framework。作為應(yīng)用程序的一部分,component 可以在運(yùn)行時(shí),集成,單元測(cè)試執(zhí)行,或者在構(gòu)建過(guò)程中被引用。

    build.gradle中的表現(xiàn)為:

    project.dependencies {
        compile(...)
        runtime(...)
        testCompile(...)
    }
    

    component 通常又被稱(chēng)為artifact, package, bundle, achive 等。

  • repository:為了方便components 的使用,repository 聚合了components 集合,并在internet 上提供service。

    • 組件通常有不同的格式,例如maven repository 依賴(lài)于特殊的目錄結(jié)構(gòu)和XML 格式的元數(shù)據(jù), 并通過(guò)plain HTTP 命令和附帶的XML 文件來(lái)對(duì)component 進(jìn)行交互。

Usage

  • 指定從自建的nexus 倉(cāng)庫(kù)中獲取依賴(lài):

    buildscript {
        repositories {
            jcenter()
            maven {
                url "your-nexus-repository-url"
            }
        }
        dependencies {
            classpath 'your-dependencies'
        }
    }
    
  • gradle upload命令的上傳配置:

    project.uploadArchives {
        repositories {
            mavenDeployer {
                repository(url: "your-nexus-repository-url") {
                    authentication(userName: "", password: "")
                }
                pom.version = "${project.version}"
                pom.artifactId = "${project.name}"
                pom.groupId = "${project.group}"
            }
        }
    }
    

Tips

  • 本地緩存導(dǎo)致的依賴(lài)不及時(shí)刷新新版本:

    configurations.all {
      resolutionStrategy.cacheChangingModulesFor 0, 'hours'
    }
    
* 根據(jù)版本號(hào)來(lái)分別存儲(chǔ)snapshot 和release 組件:   

mavenDeployer {
          repository(url: "your-nexus-repository-url" +
                  "${project.version.endsWith('-SNAPSHOT') ? 'snapshots' : 'releases'}") {...
?```

checkstyle

項(xiàng)目網(wǎng)址

Overview

checkstyle 是一款Java 代碼風(fēng)格的檢查工具。

它是高度可配置化的,通過(guò)配置可以支持任意的代碼風(fēng)格(例如Sun Code ConvensionsGoogle Java Style)。

checkstyle 的配置文件位于project/config/checkstyle/sun_checks.xml

通過(guò)修改該配置文件來(lái)統(tǒng)一項(xiàng)目的代碼風(fēng)格。例如,出于源碼閱讀的考慮,想要限制代碼行的長(zhǎng)度為100 個(gè)字符,則修改以下的配置:

<module name="LineLength">
     <property name="max" value="100"/>
</module>

Usage

在項(xiàng)目的build.gradle文件中,通過(guò)以下的配置使用checkstyle:

apply plugin: 'checkstyle'

checkstyle {
    configFile = file("$project.projectDir/config/checkstyle/sun_checks.xml")
    toolVersion = '6.7'
}

// 是否對(duì)測(cè)試代碼進(jìn)行代碼風(fēng)格的檢查。
checkstyleTest {
    enabled = false
}

Tips

  • 不可變形參需要加上final.
  • 將數(shù)字定義為有意義的static final常量(否則,會(huì)被認(rèn)為是magic number)。
  • 在代碼提交前, 使用IDE 提供的format 快捷鍵, 過(guò)濾掉一些低級(jí)的風(fēng)格問(wèn)題(如無(wú)用的引用, 代碼對(duì)其等等)。

findbugs

項(xiàng)目網(wǎng)址

Overview

findbugs 是一款靜態(tài)檢查Java 代碼中bug 的工具。

在項(xiàng)目開(kāi)發(fā)過(guò)程中,執(zhí)行gradle check 命令時(shí),findbugs 會(huì)在coverageCheck 通過(guò)后執(zhí)行。

如果代碼中含有工具認(rèn)為可能會(huì)引發(fā)Bug 的寫(xiě)法,那么會(huì)在/yourProject/build/reports/findbugs目錄中的生成一個(gè)main.xml文件來(lái)記錄。

Usage

如果在check過(guò)程中,出現(xiàn)了Execution failed for task ':findbugsMain'.,那么打開(kāi)main.xml 文件并找到以下的節(jié)點(diǎn):

  <BugInstance type="" priority="" rank="" abbrev="" category="">

根據(jù)type 字段,在網(wǎng)站中可以找到對(duì)應(yīng)的bug 的描述。

根據(jù)Class, Field, SouceLine 字段, 可以在Java 源代碼中找到bug 對(duì)應(yīng)的源碼位置。

Tips

  • 方法忽略了返回值(這常見(jiàn)于對(duì)不可變對(duì)象進(jìn)行調(diào)用方法,而誤以為不可變對(duì)象會(huì)被更新)。
  • 忘記資源釋放(方法可能沒(méi)有關(guān)閉stream)。
  • switch-case 語(yǔ)句塊中缺少break關(guān)鍵字。

jacoco

項(xiàng)目網(wǎng)址

Overview

jacoco 是一款檢查代碼單元測(cè)試覆蓋率的工具。

jacoco 的配置文件位于config/scripts/coverage.gradle

如果代碼的覆蓋率沒(méi)有達(dá)到指定的標(biāo)準(zhǔn),那么會(huì)在yourproject/build/report/jacoco 目錄下生成index.html 和相關(guān)的結(jié)果文件,打開(kāi)該文件,可以看到圖形化顯示的沒(méi)有覆蓋到的代碼所在的文件和代碼位置。

Usage

  • 在gradle 項(xiàng)目中,在該配置文件中定義jacoco 在gradle 的擴(kuò)展和任務(wù):
project.extensions.create('coverage', CoverageExtension)
task coverageCheck(dependsOn: test) << {...}
  • 在實(shí)際使用中,我們定義了excludePackagesexcludeClasses 對(duì)象來(lái)讓jacoco 跳過(guò)一些包和類(lèi)的覆蓋率檢查。
coverage.excludePackages.each() {
    exclude name: "${it.replaceAll('\\.', '/') + '/*'}"
}
coverage.excludeClasses.each() {
    exclude name: "${it.replaceAll('\\.', '/') + '.class'}"
}
  • 然后在build.gradle中使用以下的配置來(lái)在gradle check 任務(wù)中啟用jacoco 任務(wù)。
check.dependsOn "coverageCheck"

Tips

  • 盡量使用TDD 的開(kāi)發(fā)方式。
  • 在實(shí)際開(kāi)發(fā)過(guò)程中,除了一些無(wú)法模擬的Exception 之外,盡量不要使用exclude 來(lái)跳過(guò)單元測(cè)試覆蓋率的檢查。

flyway

項(xiàng)目網(wǎng)址

Overview

flyway 是一款數(shù)據(jù)庫(kù)migration 工具。

相比于手動(dòng)的sql 腳本的數(shù)據(jù)庫(kù)數(shù)據(jù)版本管理,數(shù)據(jù)庫(kù)migration 能夠帶來(lái)以下的優(yōu)勢(shì):

  • 從零開(kāi)始重建一個(gè)數(shù)據(jù)庫(kù)。
  • 清晰地獲知當(dāng)期數(shù)據(jù)庫(kù)狀態(tài)。
  • 從當(dāng)前版本到任意的一個(gè)新?tīng)顟B(tài)。

flyway 使用schema_version 數(shù)據(jù)表管理數(shù)據(jù)庫(kù)的數(shù)據(jù)版本。

Usage

  • 在build.gradle 中進(jìn)行以下的配置:

    apply plugin: "org.flywaydb.flyway"
    
    flyway {
      url = 'your-database-schema-url'
      user = ''
      password = ''
    }
    
  • 在以下的位置中放置數(shù)據(jù)庫(kù)migration 腳本:
    yourProject/src/main/resources/db.migration

  • 數(shù)據(jù)庫(kù)migration 腳本的命名格式:
    V1__Create_demo_table.sql。 需要注意的是版本號(hào)后面是兩個(gè)下劃線(xiàn)。

Tips

  • 在測(cè)試中自動(dòng)化地進(jìn)行flywayCleanflywayMigrate

    test.dependsOn "flywayClean"
    test.dependsOn "flywayMigrate"
    
  • 數(shù)據(jù)schema 的更新原則是只增不刪,例如要修改某個(gè)既存表的結(jié)構(gòu),那么在一個(gè)新建的migration 腳本中進(jìn)行,而不用去修改該寄存表的創(chuàng)建腳本。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,748評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,165評(píng)論 3 414
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 175,595評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 62,633評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,435評(píng)論 6 405
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 54,943評(píng)論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,035評(píng)論 3 440
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,175評(píng)論 0 287
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,713評(píng)論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,599評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,788評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,303評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,034評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,412評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,664評(píng)論 1 280
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,408評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,747評(píng)論 2 370

推薦閱讀更多精彩內(nèi)容

  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,887評(píng)論 6 342
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,778評(píng)論 18 139
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,601評(píng)論 25 707
  • 1,簡(jiǎn)介 1)gradle基于JVM的構(gòu)建工具,需要安裝JDK或者JRE。2)全面支持已有的maven和ivy倉(cāng)庫(kù)...
    沐兮_d64c閱讀 1,138評(píng)論 0 3
  • 早起是一件可以令人開(kāi)心的事,但早起到醫(yī)院檢查身體可以讓一天開(kāi)心的心情都煙消云散,尤其是還要排著長(zhǎng)長(zhǎng)的隊(duì)伍等待...
    Sophie七小朵閱讀 262評(píng)論 0 0