我有一個不知道是好還是不好的習慣,搞不懂的一些玩意兒,喜歡調試然后單步執行看這玩意兒到底是怎么運行的.
今天看到正則表達式的時候,appendReplacement()這個方法怎么也看不明白它是怎么工作的,於是想調試源碼單步執行,然后watch幾個關鍵的變量看看.
剛開始的時候,eclipse里調試模,單步,發現沒有辦法進入方法內. 用google百度了一下,發現是JRE配置的問題. 使用jre是不可以的,需要使用jdk的環境.(之前真的沒有注意到這一點)
於是window->Preferences->Java->Installed JREs 添加換到jdk_xxx.
這里注意一下源碼是不是正確的,如果不對的話Source Attachment哪里手動改一下.
然后Project的BuildPath里remove掉jre的環境,換成剛添加jdk_xxx
然后再調試的時候就可以進入到jdk提供的方法體內了.
之后又出現一個問題,折騰了我快兩個小時(折騰的時間長的一個重要原因是,今天我"嘿嘿嘿那啥牆"的VPS不知道怎么了,google半天打不開...).
不得不說一下,微信就是一個扯閑篇的地方,前不久加了某某論壇的一個群,大家平時除了扯淡就是調戲女群主,問了一個正經問題,沒人搭理...
添加監視變量之后,發現無論怎么執行,jdk方法體內的變量都一直是"cannot be resolved to a variable". 當然這個問題最常見的原因就是變量超出作用域. 但是,很明顯,這里不是...
由於谷歌一直打不開,只能百度了一下,可以說百度今天終於靠譜一回,一下就查到問題原因了,是因為官方jdk在打包的時候,為了控制體積有意去掉了一些用於debug的信息,有人說是LocalVariableTable這個表被移除了,所以無法從上下文中獲取足夠的信息來監控變量.
想重新得到這個表可以使用javac -g來重新編譯源碼.
還查到一個常識問題...
eclipse並不是使用javac來編譯的,而是使用自己的編譯器EJC. EJC也可以得到javac -g的效果,需要勾選Add variable attributes to generated class files這個復選框. 具體位置看這個圖:
但是現在的問題,自己的代碼調試的時候沒問題. jdk提供的方法還是不行啊. 於是十分不情願的去查怎么重新編譯jdk源碼.
查到一個貌似很牛的辦法:http://www.cnblogs.com/davidwang456/p/3790550.html
但是嘗試了很多次都不成功(試之前一定記得備份一下rt.jar...)
恰好這個時候又看到一篇博客...
這個簡單很多了,
直接把src.zip解壓,eclipse里新建一個工程,把java和javax這兩個源碼文件夾復制到新工程里,build一下. 然后把對應的class文件覆蓋回rt.jar...
遇到一個問題,源碼拖進來之后一片飄紅,各種報錯. 大概看了一下,都是因為調用了com.sun這個package里的內容. 不管他,把這個直接改成warning保證build成功就可以了. 因為之后還是會放到原來的地方.package路徑,調用的內容都沒有變,我們只是重新編譯添加了一些信息而已.
Windows -> Preferences -> Java -> Compiler -> Errors/Warnings -> Deprecated and trstricted API -> Forbidden reference ->改成warning
之后檢查一下還有沒error的文件,有的話直接刪除掉.
我的eclipse幾乎都是默認配置,是自動build的,所以源碼一拖進來,內容太多,直接電腦干死了.
等編譯完成后,找到JAVA_HOME\jre\lib\rt.jar文件,用解壓縮軟件打開,找到工程對應目錄bin下的對應的文件夾,拖進去覆蓋原先的java和javax. 然后重啟eclipse.
目前來看,調試的時候,監控變量是正常的. 程序跑起來也沒有其他問題.
剛開始用1.6這樣搞的時候,classloader老是報錯. 后來在1.8上試了一下是可以的.
先用着,以后萬一有問題,應該也是很嚴重到一眼就能看出來的.
這里覺得oracle有點擰巴了,既然都放到jdk里了,肯定都是開發人員在用.何必還閹割調試需要的信息呢. 估計也很少有人閑到去調試jdk源碼...但是感覺debug單步執行,是學習的一個好辦法呀. 至少比死摳源碼來的直觀.