JSP編譯成Servlet(四)JSP與Java行關系映射


我們知道java虛擬機只認識class文件,要在虛擬機上運行就必須要遵守class文件格式,所以JSP編譯成servlet后還需要進一步編譯成class文件,但從JSP文件到java文件再到class文件的過程需要考慮的事情比較多,其中一個比較重要的就是調試問題,由於語法不一樣,jsp某行執行的邏輯怎樣與java文件對應起來,這樣在JVM執行過程發生異常或錯誤才能找到JSP對應的行,提供一個友好的調試信息。類似的,jsp文件名編譯后的java文件名同樣也要有映射關系。

    總的來說,為了解決從非java語言到java語言調試時文件名及行號映射的問題,java community process組織提出了JSR-45(Debugging Support for Other Languages)規范,它為非java語言提供了一個進行調試的標准機制。這里的JSP其實就是屬於非java語言,JSP如果想要方便開發者開發,它就必須要遵循JSR-45規范。其實可以簡單的說就是為了解決JSP編譯后的java文件與JSP文件的對應關系,而且是提供一個統一的標准,從而避免不同廠商有不同的實現方式。

JSR-45規范的核心對象是資源映射表(Source Map),簡稱SMAP。在這里它是指JSP文件文件名及行號的映射表,這個映射表存放到class文件中,在基於JPDA的調試工具中就可以通過此映射表獲取到對應JSP文件及行號,向開發者提示對應JSP文件的信息。

接下去以前面的HelloWorld.jsp例子看看SMAP映射表是如何映射的,HelloWorld.jsp文件被編譯后變成HelloWorld_jsp.java文件,根據JSR-45的規范最終我們會生成一份如下的映射表,這里不打算探究SMAP的整個語法,只專注行號映射相關的部分,即從*L*E中間的內容,其中1,10:62表示HelloWorld.jsp文件與HelloWorld_jsp.java的映射關系為1-622-633-64...10-71。同樣的,10,3:72表時的對應關系為10-7211-7312-74。有了這些映射表就可以方便地將java執行的行號與JSP的行號對應起來了。

SMAP

HelloWorld_jsp.java

JSP

*S JSP

*F

+ 0 HelloWorld.jsp

HelloWorld.jsp

*L

1,10:62

10,3:72

*E

說完SMAP,我們已經知道生成的SMAP的格式,那么要如何保存?保存到哪里呢?因為JVM只會通過Class文件去加載相關信息,所以唯一的辦法是通過class文件附帶SMAP消息,class文件格式中可以附帶信息的就只有屬性表集合,在class文件格式中其他數據項都有嚴格的長度、順序和格式,而屬性列表集合則沒有嚴格要求,只要屬性名不與已有屬性沖突即可,任何人都可以往class文件的屬性列表中寫入自定義的屬性,虛擬機會自動忽略不認識的屬性,所以我們需要在支持調試信息的JVM中附帶此屬性,這里的屬性名稱就是SourceDebugExtension屬性。這個屬性的結構如下,首先2個字節表示名稱的索引值,接着4個字節表示屬性長度,最后一個數組表示屬性值。按照格式寫入class文件JVM即可識別。

SourceDebugExtension_attribute {

u2 attribute_name_index;

u4 attribute_length;

u1 debug_extension[attribute_length];

}

通過JSR45標准解決了JSPjava之間的映射關系問題,從而讓調試更加方便。在Java的世界中為了達到統一而又不失靈活,基本都是由java community process制定規范然后由廠商按照規范進行實現。


點擊訂購作者《Tomcat內核設計剖析》




注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com