原專案採用 Velocity + Spring MVC + Spring IOC + iBatis (VSSI) 架構,雖然功能跑通,但單人開發維護成本極高:持久層需手寫映射、Bean、SQL,開發效率低下。為提升生產力,決定遷移至成熟的 SSH (Struts2 + Spring + Hibernate) 技術棧。
15:20:54,093 ERROR ContextLoader:203 - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'SessionFactory' defined in class path resource [applicationContext.xml]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: org.objectweb.asm.ClassVisitor.visit(IILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V
Caused by: java.lang.NoSuchMethodError: org.objectweb.asm.ClassVisitor.visit(IILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V
錯誤明確指向 org.objectweb.asm 包版本衝突。檢查專案 lib 目錄發現同時存在多個 ASM 相關 JAR:
其中 asm-2.2.3.jar 與 asm.jar 版本不一致,導致類載入時方法簽名不匹配。
移除 asm-2.2.3.jar 即可解決問題。 保留 asm.jar (通常為 3.x 版本) 可滿足 Hibernate 3.2+ 與 Spring 2.x 的 ASM 依賴需求。
為了完整性,記錄 Spring 容器啟動的三種標準配置:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<servlet>
<servlet-name>context</servlet-name>
<servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation" value="/WEB-INF/applicationContext.xml" />
</plug-in>
細心檢查 JAR 衝突比盲目搜尋網路答案更有效。實測 MyEclipse 5.5 GA 下,Spring 1.2 + Hibernate 3.2 + JSF 1.1 組合最穩定,若專案無強制版本要求,優先採用此組合可避開大量版本衝突坑。