編譯Spring

編譯Spring

為了深入了解Spring-Framework不狮,閱讀項目源碼路召,第一步是編譯源碼续室。

代碼地址如下 https://github.com/spring-projects/spring-framework

準(zhǔn)備編譯環(huán)境

本人的工具和環(huán)境如下:

類型 描述
設(shè)備 Dell筆記本(i5-6550HQ 8G 256SSD)
操作系統(tǒng) Window 10 家庭中文版 64位(10.0 16299)
IDE(開發(fā)集成環(huán)境) IntelliJ IDEA Ultimate2017.2
JDK(Java 開發(fā)套件) 1.8.0_144
Git 2.10.2
Gradle 4.6

查看效果如下

C:\Users\shalk>gradle -v

------------------------------------------------------------
Gradle 4.6
------------------------------------------------------------

Build time:   2018-02-28 13:36:36 UTC
Revision:     8fa6ce7945b640e6168488e4417f9bb96e4ab46c

Groovy:       2.4.12
Ant:          Apache Ant(TM) version 1.9.9 compiled on February 2 2017
JVM:          1.8.0_144 (Oracle Corporation 25.144-b01)
OS:           Windows 10 10.0 amd64

C:\Users\shalk>git version
git version 2.10.2.windows.1

C:\Users\shalk>java -version
java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)

IDEA,JDK挺狰,Git for windows,gradle 都去各自的官網(wǎng)下載丰泊,安裝簡單薯定,稍微有一些配置。

配置方面瞳购,

JDK配置環(huán)境變量(windows配置環(huán)境變量的方法在系統(tǒng)屬性->高級->環(huán)境變量)

CLASSPATH=,;C:\bin\Java\jdk1.8.0_144\lib\tools.jar
JAVA_HOME=C:\bin\Java\jdk1.8.0_144
PATH=其他;C:\bin\Java\jdk1.8.0_60\bin;其他;

Gradle 配置環(huán)境變量

PATH=其他;D:\bin\gradle\gradle-4.6\bin;其他;

Gradle全局配置文件修改学赛,路徑為C:\User\用戶名\.gradle\init.gradle(目錄可以自己創(chuàng)建,文件自己創(chuàng)建)变丧,目的是為了使用國內(nèi)鏡像

allprojects{  
  repositories {  
    def REPOSITORY_URL = 'http://maven.aliyun.com/nexus/content/groups/public/'  
      all { ArtifactRepository repo ->  
        if(repo instanceof MavenArtifactRepository){  
          def url = repo.url.toString()  
          if (url.startsWith('https://repo1.maven.org/maven2') || url.startsWith('https://jcenter.bintray.com/')) {  
            project.logger.lifecycle "Repository ${repo.url} replaced by $REPOSITORY_URL."  
            remove repo  
          }  
       }  
    }  
    maven {  
      url REPOSITORY_URL  
    }  
  }  
}  

Git 貌似會自動配置環(huán)境變量缠捌,如果沒有需要自己添加。

IDEA 配置(如果第一次使用)谊却,配置JDK哑芹,配置Gradle_Home.

另外還有一個重要環(huán)節(jié)是,網(wǎng)絡(luò)需要可以自由訪問google碴萧。

編譯過程

按照官網(wǎng)的步驟(https://github.com/spring-projects/spring-framework/wiki/Build-from-Source)以及IDEA的文檔(https://github.com/spring-projects/spring-framework/blob/master/import-into-idea.md) 并不能完全成功,需要額外的調(diào)整虎谢。

先用命令行下載源碼

git clone  https://github.com/spring-projects/spring-framework.git

編譯 spring-oxm

./gradlew :spring-oxm:compileTestJava

打開idea曹质,

image.png

選中 build.gradle羽德,點擊OK几莽。

image.png

這里選中 Use auto-import; Create separate module per source set; Use local gradle 宅静。
(最后使用default gradle wrapper 和local gradle 其實沒有什么區(qū)別姨夹,既然下載了gradle,這里選用local gradle)

導(dǎo)入之后IDEA洒忧,會進(jìn)行一系列的代碼解析和依賴下載够颠,等待處理完成榄鉴。
(雖然文檔建議要源碼把spring-aspects 排除掉,但是這個BUG已經(jīng)修復(fù)剃诅,不需要排除這個模塊驶忌。)

接下來做一些調(diào)整:

調(diào)整1

解決的問題:避免 gradle dokka失敗

修改文件gradle.properties (給Gradle配置代理)

version=5.1.0.BUILD-SNAPSHOT

version=5.1.0.BUILD-SNAPSHOT
systemProp.http.proxyHost=localhost
systemProp.http.proxyPort=1080
systemProp.https.proxyHost=localhost
systemProp.https.proxyPort=1080

# 需要驗證時
# systemProp.https.proxyUser=userid
# systemProp.https.proxyPassword=password

# 直接連接而不走代理設(shè)置
# systemProp.https.nonProxyHosts=localhost

為了確保萬無一失付魔,給IDEA配置代理


image.png

調(diào)整2:

修改spring-framework\gradle\docs.gradle

task schemaZip(type: Zip) {
    group = "Distribution"
    baseName = "spring-framework"
    classifier = "schema"
    description = "Builds -${classifier} archive containing all " +
            "XSDs for deployment at http://springframework.org/schema."
    duplicatesStrategy 'exclude'
    moduleProjects.each { subproject ->
        def Properties schemas = new Properties();

        subproject.sourceSets.main.resources.find {
            it.path.endsWith("META-INF/spring.schemas")
        }?.withInputStream { schemas.load(it) }

        for (def key : schemas.keySet()) {
            def shortName = key.replaceAll(/http.*schema.(.*).spring-.*/, '$1')
            assert shortName != key
            File xsdFile = subproject.sourceSets.main.resources.find {
                it.path.endsWith(schemas.get(key))
            }
            assert xsdFile != null
            into (shortName) {
                from xsdFile.path
            }
        }
    }
}
task schemaZip(type: Zip) {
    group = "Distribution"
    baseName = "spring-framework"
    classifier = "schema"
    description = "Builds -${classifier} archive containing all " +
            "XSDs for deployment at http://springframework.org/schema."
    duplicatesStrategy 'exclude'
    moduleProjects.each { subproject ->
        def Properties schemas = new Properties();

        subproject.sourceSets.main.resources.find {
            it.path.endsWith("META-INF\\spring.schemas")
        }?.withInputStream { schemas.load(it) }

        for (def key : schemas.keySet()) {
            def shortName = key.replaceAll(/http.*schema.(.*).spring-.*/, '$1')
            assert shortName != key
            File xsdFile = subproject.sourceSets.main.resources.find {
                it.path.endsWith(schemas.get(key).replaceAll('\\/','\\\\'))
            }
            assert xsdFile != null
            into (shortName) {
                from xsdFile.path
            }
        }
    }
}

由于windows路徑的問題翻屈,這里修改之后妻坝,可以讓gradle schemaZip產(chǎn)生zip文件惊窖,避免gradle distZip失敗厘贼。

最后在IDEA中執(zhí)行 gradle build


image.png

執(zhí)行結(jié)果如下:

11:42:30: Executing external task 'build'...
:buildSrc:compileJava NO-SOURCE
:buildSrc:compileGroovy UP-TO-DATE
:buildSrc:processResources UP-TO-DATE
:buildSrc:classes UP-TO-DATE
:buildSrc:jar UP-TO-DATE
:buildSrc:assemble UP-TO-DATE
:buildSrc:compileTestJava NO-SOURCE
:buildSrc:compileTestGroovy NO-SOURCE
:buildSrc:processTestResources NO-SOURCE
:buildSrc:testClasses UP-TO-DATE
:buildSrc:test NO-SOURCE
:buildSrc:check UP-TO-DATE
:buildSrc:build UP-TO-DATE
Repository https://jcenter.bintray.com/ replaced by http://maven.aliyun.com/nexus/content/groups/public/.
:spring-core:cglibRepackJar UP-TO-DATE
:spring-core:objenesisRepackJar UP-TO-DATE
:spring-jcl:compileKotlin UP-TO-DATE
:spring-jcl:compileJava UP-TO-DATE
(略)
:spring-websocket:check UP-TO-DATE
:spring-websocket:build UP-TO-DATE

Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0.
See https://docs.gradle.org/4.6/userguide/command_line_interface.html#sec:command_line_warnings

BUILD SUCCESSFUL in 1m 59s
239 actionable tasks: 4 executed, 235 up-to-date
11:44:30: External task execution finished 'build'.

每個模塊的構(gòu)建結(jié)果都在build目錄下嘴秸,jar包都在 build/lib下面赁遗。

補充

    以下是構(gòu)建release版本遇到的問題

由于又用另外一臺電腦編譯了一遍,由于之前是用master分支(snapshot)進(jìn)行編譯岩四,為了后續(xù)的分析的穩(wěn)定剖煌,我使用了v5.0.5-release的tag,checkout出了一個release的分支耕姊。遇到了一些新問題茉兰。

問題1. 導(dǎo)入項目之后,idea無法正常解析gradle項目规脸,出現(xiàn) Unindexed remote maven repositories found的bug莫鸭。
解決: IDEA 2017.1的版本遇到的 ,升級到了IDEA 2018.1解決被因。

問題2. spring-beans.gradle 的 30行報錯
解決: 參考master分支和 當(dāng)前分支的差異梨与,修改如下

description = "Spring Beans"

apply plugin: "groovy"

dependencies {
    compile(project(':spring-core'))
    optional("javax.inject:javax.inject:1")
    optional("org.yaml:snakeyaml:1.20")
    optional("org.codehaus.groovy:groovy-all:${groovyVersion}")
    optional("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}")
    optional("org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}")
    testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
}

// This modules does joint compilation for Java and Groovy code,
// with the compileGroovy task.
sourceSets {
    main.groovy.srcDirs += "src/main/java"
    main.java.srcDirs = []
}

compileGroovy {
    sourceCompatibility = 1.8
    targetCompatibility = 1.8
}

// This module also builds Kotlin code and the compileKotlin task
// naturally depends on compileJava.
// We need to redefine dependencies to break task cycles.
compileGroovy.dependsOn = compileGroovy.taskDependencies.values - 'compileJava'
compileKotlin.dependsOn(compileGroovy)
compileKotlin.classpath += files(compileGroovy.destinationDir)

修改成

description = "Spring Beans"

apply plugin: "groovy"

dependencies {
    compile(project(':spring-core'))
    optional("javax.inject:javax.inject:1")
    optional("org.yaml:snakeyaml:1.20")
    optional("org.codehaus.groovy:groovy-all:${groovyVersion}")
    optional("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}")
    optional("org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}")
    testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
}

// This modules does joint compilation for Java and Groovy code,
// with the compileGroovy task.
sourceSets {
    main.groovy.srcDirs += "src/main/java"
    main.java.srcDirs = []
}

compileGroovy {
    sourceCompatibility = 1.8
    targetCompatibility = 1.8
}

// This module also builds Kotlin code and the compileKotlin task
// naturally depends on compileJava.
// We need to redefine dependencies to break task cycles.
def deps = compileGroovy.taskDependencies.immutableValues + compileGroovy.taskDependencies.mutableValues
compileGroovy.dependsOn = deps - 'compileJava'
compileKotlin.dependsOn(compileGroovy)
compileKotlin.classpath += files(compileGroovy.destinationDir)

問題3蛋欣,asciidoctor 任務(wù)報錯,錯誤提示 (SystemCallError) Unknown error 123 - FindFirstFile
解決: 參考 https://github.com/jruby/jruby/issues/3957 這個問題是 asciidoctor-pdf 模塊調(diào)用了jruby到踏,在windows10 文件路徑之類的兼容性問題,里面討論是在某些版本解決了楣富,經(jīng)過一翻折騰伴榔,調(diào)整build.gradlebuildscript的依賴,也沒有解決塘安。

辦法1: 由于release版本會構(gòu)建pdf文檔援奢,修改gradle/doc.gradle修改91-94

    // only ouput PDF documentation for non-SNAPSHOT builds
    if(!project.getVersion().toString().contains("BUILD-SNAPSHOT")) {
    // 注釋此行 backends += "pdf"
    }

辦法2: 我瞎試出來的,修改build.gradlebuildscript的依賴

buildscript {
    repositories {
        maven { url "https://repo.spring.io/plugins-release" }
    }
    dependencies {
        classpath("io.spring.gradle:propdeps-plugin:0.0.8")
        classpath("io.spring.gradle:docbook-reference-plugin:0.3.1")
        classpath("org.asciidoctor:asciidoctorj-pdf:1.5.0-alpha.16")
        classpath("org.asciidoctor:asciidoctorj-epub3:1.5.0-alpha.7")
    }
}

修改成

buildscript {
    repositories {
        maven { url "https://repo.spring.io/plugins-release" }
    }
    dependencies {
        classpath("io.spring.gradle:propdeps-plugin:0.0.8")
        classpath("io.spring.gradle:docbook-reference-plugin:0.3.1")
        classpath("org.asciidoctor:asciidoctorj-pdf:1.5.0-alpha.14")
        classpath("org.asciidoctor:asciidoctorj-epub3:1.5.0-alpha.7")
    }
}

我非常懷疑切黔,asciidoctorj-pdf在alpha.16又把這個bug又引入了纬霞。

參考
https://github.com/spring-projects/spring-framework/wiki/Build-from-Source
https://stackoverflow.com/questions/34916981/build-spring-framework-source-code-encounter-an-error
https://blog.csdn.net/wei987654wei/article/details/50635026

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末诗芜,一起剝皮案震驚了整個濱河市埃疫,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌熔恢,老刑警劉巖臭笆,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件愁铺,死亡現(xiàn)場離奇詭異,居然都是意外死亡茂洒,警方通過查閱死者的電腦和手機(jī)瓶竭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來智哀,“玉大人,你說我怎么就攤上這事屯吊∧〔ぃ” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵蔽介,是天一觀的道長糟需。 經(jīng)常有香客問我洲押,道長,這世上最難降的妖魔是什么杈帐? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任挑童,我火速辦了婚禮,結(jié)果婚禮上娃兽,老公的妹妹穿的比我還像新娘尽楔。我一直安慰自己,他們只是感情好阔馋,可當(dāng)我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布呕寝。 她就那樣靜靜地躺著,像睡著了一般客蹋。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上嚼酝,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天闽巩,我揣著相機(jī)與錄音,去河邊找鬼洼冻。 笑死隅很,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的屋彪。 我是一名探鬼主播绒尊,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蟹但!你這毒婦竟也來了谭羔?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤客叉,失蹤者是張志新(化名)和其女友劉穎话告,沒想到半個月后超棺,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體呵燕,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年氧苍,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片紊撕。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡对扶,死狀恐怖惭缰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情漱受,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布絮记,位于F島的核電站虐先,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏赴穗。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望甸赃。 院中可真熱鬧,春花似錦络断、人聲如沸项玛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至遭商,卻和暖如春捅伤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背丛忆。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工蘸际, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人粮彤。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓导坟,卻偏偏與公主長得像,于是被迫代替她去往敵國和親尘惧。 傳聞我的和親對象是個殘疾皇子递递,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,033評論 2 355

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

  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,822評論 6 342
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理登舞,服務(wù)發(fā)現(xiàn),斷路器疙剑,智...
    卡卡羅2017閱讀 134,659評論 18 139
  • 深入研究spring 必然少不了研究源碼践叠。首先便是編譯源碼。源代碼地址:https://github.com/sp...
    瘋狂的冰塊閱讀 1,871評論 1 0
  • afinalAfinal是一個android的ioc,orm框架 https://github.com/yangf...
    passiontim閱讀 15,434評論 2 45
  • 用到的組件 1僻孝、通過CocoaPods安裝 2、第三方類庫安裝 3皮璧、第三方服務(wù) 友盟社會化分享組件 友盟用戶反饋 ...
    SunnyLeong閱讀 14,618評論 1 180