我們首先看一下這里面有幾種 class loader,首先,啟動(dòng) eclipse 的是一個(gè)system loader,然后 是 eclipse starter 的 loader,啟動(dòng)我們的核心class loader,這個(gè)核心負(fù)責(zé)啟動(dòng) jetty 和我們 的 web app兩個(gè)插件,每個(gè)插件都有自己的 eclipse bundler loader。而jetty插件啟動(dòng)jetty 應(yīng)用服務(wù)器,應(yīng)用服務(wù)器本身有 context class loader,它還要負(fù)責(zé)去裝載 WEB-INF/lib 下的所有jar文件,以及 WEB-INF/classes 目錄下的文件,做為編譯期使用。
這里不僅class loader 眾多,而且關(guān)系復(fù)雜。一不小心就容易拋出 class not found 異常,或者是 class cast 異常。相對(duì)而言,只支持servlet 就狠簡(jiǎn)單,因?yàn)橹灰?servlet 的 context class loader 用 eclipse bundler loader 替換掉就行。而jsp的編譯機(jī)制,導(dǎo)致了問(wèn)題的出現(xiàn)。
我對(duì)于這種復(fù)雜classloader情況的心得,就是把錯(cuò)綜復(fù)雜的 class loader 關(guān)系網(wǎng)拉直,變成一棵 樹(shù)。這樣的好處就是,對(duì)于loader 的關(guān)系比較清晰,出現(xiàn)ClassNotFoundException和 ClassCastException這兩種情況的時(shí)候,都狠容易判斷怎么回事,不會(huì)被繞暈。這種時(shí)候,單步跟蹤 只是找死,把classloader關(guān)系畫(huà)出來(lái),有利于對(duì)問(wèn)題的分析。
于是畫(huà)了這樣一個(gè)圖,把復(fù)雜的網(wǎng)拉直了,問(wèn)題就迎刃而解了。
其中的關(guān)鍵就是 LauncherClassLoader。這個(gè)就是我們自己的ClassLoader,把它設(shè)置為 servlet
context classloader 的 parent,并且把 context classloader 的裝載順序改變成為先由parent
裝載,再自己裝載的模式。這樣,jsp的編譯還是由 context loader 去處理,我就不管了。其他的
該裝載的地方,還是有 eclipse bundler 去裝載,這樣問(wèn)題基本解決。 不過(guò)這樣其實(shí)還是有個(gè)問(wèn)題,如果要在 jsp 當(dāng)中調(diào)用某個(gè)插件當(dāng)中的 class,那么在編譯期就會(huì)出現(xiàn)
問(wèn)題。不過(guò)由于目前只是解決 legacy jsp 應(yīng)用的問(wèn)題,所以這個(gè)暫時(shí)不存在。我能想到的解決方案
其實(shí)也狠簡(jiǎn)單,把這些 jar 文件的url也做為擴(kuò)展點(diǎn)出現(xiàn),那么當(dāng)jsp需要某個(gè)class時(shí),只要把它
所需要的 jar 文件的 url 做為一個(gè)擴(kuò)展,在 LauncherClassLoader 當(dāng)中將這些jar文件添加到
url loader 當(dāng)中,而這些 url 會(huì)出現(xiàn)在 jsp 的編譯class path當(dāng)中。
只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。 | ||
![]() |
||
網(wǎng)站導(dǎo)航:
博客園
IT新聞
Chat2DB
C++博客
博問(wèn)
管理
|
||