spring ä¸?osgi的第一个障¼„?
eclipse3.1, spring2.0.1åQŒå°†spring.jar攑ֈ°ä¸€ä¸ªæ’ä»¶ä¸åQŒåœ¨å¦ä¸€ä¸ªæ’ä»¶ä¸åŽÖM‹É用ã€?最½Ž€å•的例ååQŒåœ¨context.getBean的时候就报了一个异常:
先是æœäº†ä¸€é,没有å‘现很有帮助的内å®V€‚ç„¶åŽè·Ÿäº†ä¸€ä¸‹ï¼Œå‘现˜q˜æ˜¯å› 䨓xsdçš„æ˜ ž®„找ä¸åˆ°ã€‚è€Œé€ æˆ˜q™ä¸ªé—®é¢˜çš„åŽŸå› ï¼Œ 是在 spring.jar当ä¸çš„META-INF/spring.schemas ˜q™ä¸ªæ‰¾ä¸åˆ°ã€?/font>
而这个找ä¸åˆ°çš„æœ€æ ÒŽœ¬åŽŸå› åQŒæ˜¯å› äØ“åœ¨eclipse当ä¸åQŒMETA-INF目录是ä¸èƒ½å¤Ÿè¢«å…¶ä»–æ’件找到的。也ž®±æ˜¯è¯ß_¼ŒMETA-INF 目录是拥有spring.jar的那个æ’件所独å 的,而其他æ’ä»¶å°±½Ž—ä¾èµ–于˜q™ä¸ªæ’äšgåQŒä¹Ÿæ˜¯æ— 法找到META-INF目录下的文äšgåQ?ä»Žè€ŒæŠ›å‡ø™¿™ä¸ªå¼‚常ã€?/font>
è§£å†³é—®é¢˜çš„åŠžæ³•æœ‰å‡ ä¸ªåQŒæœ€½Ž€å•的莫过于拷è´spring.schemasæ–‡äšg到需è¦çš„æ’äšgä¸ï¼Œå¦ä¸€ä¸ªåŠžæ³•æ˜¯æŠŠspringçš„context 装貞®±æ”¾åœ¨spring.jar所在的æ’äšgä¸ï¼Œæˆ–者改eclipse的代ç ã€?:(
˜q™ä¸ªé—®é¢˜è§£å†³ä¹‹åŽåQŒç´§æŽ¥ç€½W¬äºŒä¸ªé—®é¢˜å°±æ˜?
é€ æˆ˜q™ä¸ªçš„åŽŸå› å’Œ½W¬ä¸€ä¸ªç±»ä¼û|¼Œž®†spring.handlers拯‚´åˆ°META-INF目录下就ok了ã€?br />
ä¸Šé¢æ˜¯æˆ‘以å‰çš„一个ç»éªŒï¼Œä»Šå¤©ä»”ç»†ç ”ç©¶äº†ä¸€ä¸‹ï¼Œå‘现自己掉进äº?¾l验ä¸ÖM¹‰çš„圈套ã€?/font>
˜q™ä¸ª¾l验是这æ ïL§¯ç´¯è“væ¥çš„åQšåœ¨åˆšå¼€å§‹å°è¯•ä‹É用eclipse的时候,用的æ˜?.0å’?.1Mx¾pÕdˆ—åQŒå½“æ—?ä¸çŸ¥é“osgi是个什么东è¥?:$ 创å¾çš„å‡ ä¸ªæ’ä»Óž¼Œéƒ½æ²¡æœ‰åˆ›å»ºosgi bundle manifest。也ž®±æ˜¯è¯ß_¼Œ åªæœ‰plugin.xmlåQŒè€Œæ²¡æœ‰META-INF/MANIFEST.MFæ–‡äšg的。但是在˜q行期,eclipse会自动的 从plugin.xml当ä¸è¯Õd–ä¿¡æ¯åQŒç”ŸæˆäÍæ—¶çš„MANIFEST.MFæ–‡äšgåQŒæ”¾åœ?runtimeçš?configuration/org.eclipse.osgi/manifests 目录下。而生æˆè¿™ä¸ªMANIFEST.MFæ–‡äšgåQŒæ˜¯ 通过 PluginConverterImpl ˜q™ä¸ª¾cÀL¥å®žçŽ°çš„ï¼Œåœ¨å®ƒçš?isValidPackageName æ–ÒŽ³•ä¸ï¼Œæ‰€æœ‰çš„ META-INF或者以META-INF开头的目录åQŒéƒ½ä¸ä¼šè¢«è‡ªåŠ¨çš„export出去åQŒä»Žè€Œåœ¨ä¸´æ—¶ç”Ÿæˆçš„MANIFEST.MF æ–‡äšgä¸ï¼Œæ°¸è¿œä¸ä¼šæœ‰META-INF目录的exportã€?/font>
当时刚开始接触eclipseå’ŒosgiåQŒæ ¹æœ¬ä¸çŸ¥é“自己当时最佳的解决æ–ÒŽ¡ˆž®±æ˜¯åˆ›å¾ä¸€ä¸?bundle manifeståQ?ç„¶åŽåœ¨å…¶ä¸å°†META-INF目录export出æ¥ã€‚è€Œæ˜¯é€šè¿‡ç›²ç›®çš„ä¿®æ”¹ä»£ç æ¥¾l•过˜q™ä¸ªå¼¯ã€‚åŽæ¥è¿™ä¸ªå¼¯¾l•过åŽÖMº†åQ?留给我的¾l验ž®±æ˜¯åQšMETA-INF˜q™ä¸ªç›®å½•åQŒæ˜¯æ’äšg独äín的,别的æ’äšgä¸å…许访问的ã€?/font>
于是åQŒåœ¨å‰å‡ 天,当spring.jar当ä¸çš„å‡ ä¸ªMETA-INF目录下的文äšg讉K—®ä¸äº†æ—Óž¼Œæˆ‘ä¹Ÿè®¤äØ“˜q™ä¸ª¾l验有用åQ?差点ž®±åŽ»æ”¹eclipse的代ç 了。幸好å°è¯•了一下,把spring.jar所在的æ’äšgä¸ï¼Œž®†META-INF目录å…׃ín出æ¥åQ?å±…ç„¶ž®±å¥½äº†ã€‚ä»”¾l†æŸ¥äº†ä¸€ä¸‹ï¼Œå‘现å±è”½META-INF的代ç åªå‡ºçŽ°åœ¨PluginConverterImpl˜q™ä¸ª¾cÕd½“ä¸ã€?回头想了惻I¼Œ¾lˆäºŽæ˜Žç™½è‡ªå·±˜q™æ¬¡æ˜¯æŽ‰åœ¨ç»éªŒä¸»ä¹‰çš„å‘里é¢äº†ã€?/font>
¾l验ä¸ÖM¹‰å®Ïx»äººå•Šã€‚唉ã€?br />
ä¸È«™åQ?http://blogsite.3322.org/
˜q™é‡Œä¸ä»…class loader 众多åQŒè€Œä¸”å…³ç³»å¤æ‚。一ä¸å°å¿ƒå°±å®ÒŽ˜“抛出 class not found 异常åQŒæˆ–者是 class cast 异常。相对而言åQŒåªæ”¯æŒservlet ž®Þq‹ ½Ž€å•ï¼Œå› äØ“åªè¦æŠ?servlet çš?context class loader ç”?eclipse bundler loader æ›¿æ¢æŽ‰å°±è¡Œã€‚è€Œjsp的编译机åˆÓž¼Œå¯ÆD‡´äº†é—®é¢˜çš„出现ã€?/p>
我对于这¿U夿‚classloader情况的心得,ž®±æ˜¯æŠŠé”™¾l¼å¤æ‚çš„ class loader 关系¾|‘拉ç›ß_¼Œå˜æˆä¸€‹‚? æ ‘ã€‚è¿™æ ïLš„好处ž®±æ˜¯åQŒå¯¹äºŽloader 的关¾pÀL¯”较清晎ͼŒå‡ºçްClassNotFoundExceptionå’? ClassCastException˜q™ä¸¤¿U情å†ëŠš„æ—¶å€™ï¼Œéƒ½ç‹ å®ÒŽ˜“åˆ¤æ–æ€Žä¹ˆå›žäº‹åQŒä¸ä¼šè¢«¾l•晕。这¿Uæ—¶å€™ï¼Œå•æ¥è·Ÿè¸ª åªæ˜¯æ‰¾æ»åQŒæŠŠclassloader关系ç”Õd‡ºæ¥ï¼Œæœ‰åˆ©äºŽå¯¹é—®é¢˜çš„分æžã€?/p>
于是ç”ÖMº†˜q™æ ·ä¸€ä¸ªå›¾åQŒæŠŠå¤æ‚的网拉直了,问题ž®Þp¿Žåˆƒè€Œè§£äº†ã€?/p>
å…¶ä¸çš„关键就æ˜?LauncherClassLoader。这个就是我们自å·Þqš„ClassLoaderåQŒæŠŠå®ƒè®¾¾|®äØ“ servlet context classloader çš?parentåQŒåƈ且把 context classloader çš„è£…è½½é¡ºåºæ”¹å˜æˆä¸ºå…ˆç”±parent 装è²åQŒå†è‡ªå·±è£…è²çš„æ¨¡å¼ã€‚è¿™æ øP¼Œjsp的编译还是由 context loader åŽÕd¤„ç†ï¼Œæˆ‘å°±ä¸ç®¡äº†ã€‚å…¶ä»–çš„ 该装载的地方åQŒè¿˜æ˜¯æœ‰ eclipse bundler 去装载,˜q™æ ·é—®é¢˜åŸºæœ¬è§£å†³ã€?/p>
ä¸è¿‡˜q™æ ·å…¶å®ž˜q˜æ˜¯æœ‰ä¸ªé—®é¢˜åQŒå¦‚æžœè¦åœ?jsp 当ä¸è°ƒç”¨æŸä¸ªæ’äšg当ä¸çš?classåQŒé‚£ä¹ˆåœ¨¾~–译期就会出çŽ? 问题。丘q‡ç”±äºŽç›®å‰åªæ˜¯è§£å†?legacy jsp 应用的问题,所以这个暂时ä¸å˜åœ¨ã€‚我能想到的解决æ–ÒŽ¡ˆ å…¶å®žä¹Ÿç‹ ½Ž€å•,把这äº?jar æ–‡äšgçš„url也åšä¸ºæ‰©å±•点出现åQŒé‚£ä¹ˆå½“jspéœ€è¦æŸä¸ªclassæ—Óž¼Œåªè¦æŠŠå®ƒ 所需è¦çš„ jar æ–‡äšgçš?url åšäؓ一个扩展,åœ?LauncherClassLoader 当丞®†è¿™äº›jaræ–‡äšgæ·ÕdŠ åˆ? url loader 当ä¸åQŒè€Œè¿™äº?url 会出现在 jsp 的编译class path当ä¸ã€?/p>
ä¸È«™åQ?a >http://blogsite.3322.org/jspwiki/
for (ExtensionBean bean : servletMappingBeans) {
ServletHandler handler = new ServletHandler();
handler.addServlet( bean.getProperty( "mapping"), bean.getClassName());
context.addHandler( handler);
}
ServletHandler handler = new ServletHandler();
for (ExtensionBean bean : servletMappingBeans) {
handler.addServlet( bean.getProperty( "mapping"), bean.getClassName());
}
context.addHandler( handler);
½W¬ä¸‰¿U:部çÖv模å¼åQŒä¿®æ”¹äº†ä»£ç 之åŽåQŒå¿…™å»é¦–先部¾|ÔŒ¼Œç„¶åŽé‡å¯åº”用æœåС噍æ‰èƒ½çœ‹åˆ? 修改效果。这¿Uæ¨¡å¼æœ€ä¸çˆ½åQŒä¼ ¾lŸçš„ejbå¼€å‘就是这¿U模å¼ã€?/p>
ç›®å‰æˆ‘们ž®?eclipse åšäØ“æ ¸å¿ƒçš?web appåQŒè¿˜æ˜¯ç¬¬ä¸‰ç§å¼€å‘模å¼ã€‚é€ æˆ˜q™ç§å¼€å‘模å¼?
çš„åŽŸå› ï¼Œå¯ä»¥è¯´æ˜¯å› äØ“å½“æ—¶å¯?eclipse ä¸ç†Ÿæ‚‰ï¼Œå¯?osgi ä¸ç†Ÿæ‚‰ï¼Œå¯?eclipse class
loader ä¸ç†Ÿæ‚‰é€ æˆçš„。我打算ž®†å…¶æ”šw€ 戽W¬äºŒ¿U模å¼ï¼Œç„¶åŽå†è€ƒè™‘½W¬ä¸€¿U是å¦å¯è¡Œã€‚最˜q?
çœ?ror, å®ƒå°†çŽ¯å¢ƒåˆ†äØ“ dev/product/test å‡ ç§åQŒå¾ˆå—å¯å‘。我å¯ä»¥åœ¨product环境ä¸?
采用½W¬äºŒ¿U,在dev环境下采用第一¿U模å¼ã€?/p>ä¸È«™åQ?http://blogsite.3322.org/jspwiki/