maven(多個子產品)項目 部署 開發環境 問題處理曆程【異常Name jdbc is not bound in this Context 異常java.lang.NoSuchMethodE】
2018年01月18日 18:14:38 守望dfdfdf 閱讀數:439更多
個人分類: 工作 問題
編輯
版權聲明:本文為部落客原創文章,轉載請注明文章連結。 https://blog.csdn.net/xiaoanzi123/article/details/79099343
把maven項目三個子產品項目【本地運作啟動是沒有問題的】,maven package ,生成war包部署到開發環境【tomcat和jdk都是新安裝的】tomcat,啟動報錯。
Unexpected exception parsing XML document from file
[/MaYi/city/paoject/apache-tomcat-6.0.29/webapps/paoject-service/WEB-INF/classes/spring_core/applicationContext.xml]; nested exception is
java.lang.NoSuchMethodError: org.springframework.beans.MutablePropertyValues.add(Ljava/lang/String;Ljava/lang/Object;)Lorg/springframework/beans/MutablePropertyValues;at org.springframework.beans.factory.xml.XmlBeanDefinitio
java.lang.NoSuchMethodError 這個錯誤,網上一般都說是spring版本沖突 ,需删除重複的低版本jar包。
比如:
http://blog.csdn.net/javaburning/article/details/7321247
http://blog.csdn.net/zongzhankui/article/details/6844317
由于擔心是子產品之間的jar沖突,就先部署一個子產品,可還是報同樣的錯誤。
經過查找,MutablePropertyValues 這個類出現在如下兩個jar中。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBHL0FWby9mZvwVZnFWbp1zczV2YvJHctM3cv1Ce-4WNHNWdnRlT4NGVNdXWE5kewM1TwkFROBTRE5EeJpnT3FFRNVTRE1UewMkT5FFRPlXQU1kdRRUT1UERNlHOD5UeRR0T5FEVNZ3YyI2cKJDT0ljMZVXTzold41WW15UbMRTRE1UejdlYwlTeMZTTINGMShUYvwlbj5yZtlmbkN3YuQnclZnbvN2Ztl2Lc9CX6MHc0RHaiojIsJye.jpg)
但是,第一個jar裡面找不到add方法。第二個裡面有add方法。因為我是往開發環境部署,就去和生産環境對比一下。Jar包差别很大。生産環境的jar與本地不一緻。就這兩個jar而言,生産環境沒有 spring-2.5.6.jar,隻有
,況且spring-2.5.6.jar中也沒有add方法,是以我就删除了spring-2.5.6.jar
https://www.cnblogs.com/BensonHe/p/3903050.html這篇文章介紹了spring各個jar的作用,這是以我猜測這個spring-2.5.6.jar是老版本的spring的單一整合jar包,現在用的3.1.2的拆分spring 子產品jar包。再次啟動,java.lang.NoSuchMethodError 錯誤沒有了。看來貌似是解決了沖突。但出現新的很多錯誤。
錯誤主要是:
①無法建立bean對象 systemCacheFactoryBean paojectZdCacheLoadImpl sessionFactory dataSource
,其中 systemCacheFactoryBean 和 paojectZdCacheLoadImpl 存在于依賴的另一個子產品打成的jar包,這個jar是存在的。而 sessionFactory 和 dataSource 是出現在application.xml 裡面的。
② javax.naming.NameNotFoundException: Name jdbc is not bound in this Context
參考
http://blog.sina.com.cn/s/blog_598764b10100a9e2.html。
③ servlet-api-2.4.jar not locad
/WEB-INF/lib/servlet-api-2.4.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class
【這個問題是删除jar包之前就有的,貌似在啟動階段對于程式沒什麼影響】
參考文章 http://blog.csdn.net/jingjingwin5/article/details/7837866 解決。 删除了 servlet-api.2.4.jar ,可是生産環境裡面是有這個jar的。= =!
再次嘗試:把生産環境的所有jar複制出來,替換自己的所有的jar【生産環境的jar比自己的jar多,此外還有一些不一緻】,啟動測試,還是不行,問題同上。
之後
查詢 Error creating bean with name 'sessionFactory' , http://bbs.csdn.net/topics/391921636 有說 jar包沖突了,spring和hibernate都asm-2.2.3.jar和asm.jar,删掉其中一個就好了。
我這裡有這幾個jar,
,嘗試删掉前三個,還是同樣的錯誤。暫時擱置問題①。
再次查詢問題②,結合https://stackoverflow.com/questions/12928030/javax-naming-namenotfoundexception-name-jdbc-eswastha-is-not-bound-in-this-co 和 ②中記錄的那個部落格,恍然大悟,決定對比一下生産環境tomcat的conf目錄下那幾個配置檔案有無改動。果然有所發現。在context.xml中,生産環境配置了依賴的兩個資料庫的連接配接資訊:如圖
在service.xml中,生産環境有以下三處改動,但是 應該不影響程式的啟動,是一些參數的配置 優化 什麼的。
其中 jvmRoute="tomcat8080" 這個配置第一次見,便查了一下。參考文章:
nginx 解決session共享問題(jvm-route)方式 。
Tomcat 配置詳解/優化方案 。
在此提及一下,我的tomcat是6.0.29版本。生産環境是6.0.41.
經過對比,web.xml中差别很大,多出很多 <mime-mapping> 标簽配置的内容,我就直接替換了自己的web.xml。
tomcat-users.xml,也多出一些内容,多配置了一些使用者,也進行替換更改。
啟動,所有問題得到解決。
目前小結: java.lang.NoSuchMethodError: 問題 肯定是jar沖突導緻的,我也進行了驗證。目前一共就删除一個jar包。就那個 spring-2.5.6.jar 。 别的問題原因是 tomcat/conf 下的contex.xml 沒有配置資料源資訊導緻的。
ps: 沒有部署文檔好無語啊。。。耗時多,但是解決了問題還是很高興的。但是有一個疑問,為什麼會把資料源(庫)資訊配置到tomcat的context.xml裡面?【項目中也有資料庫配置,這裡context.xml中配置的資料庫連接配接資訊是什麼意思?】
參考文章:在tomcat下context.xml中配置各種資料庫連接配接池-----------全文如下----------------
Tomcat6的伺服器配置檔案放在 ${tomcat6}/conf 目錄底下。我們可以在這裡找到 server.xml 和 context.xml。當然,還有其他一些資源檔案。但是在在本文中我們隻用得上這兩個,其他的就不介紹了。
1. 首先,需要為資料源配置一個JNDI資源。我們的資料源JNDI資源應該定義在context元素中。在tomcat6版本中,context元素已經從server.xml檔案中獨立出來了,放在一個context.xml檔案中。因為server.xml是不可動态重加載的資源,伺服器一旦啟動了以後,要修改這個檔案,就得重新開機伺服器才能重新加載。而context.xml檔案則不然,tomcat伺服器會定時去掃描這個檔案。一旦發現檔案被修改(時間戳改變了),就會自動重新加載這個檔案,而不需要重新開機伺服器。我們當然推薦把應用需要的JNDI資源配置在context.xml檔案中,而不是server.xml檔案中。
1、首先,将資料庫的驅動程式copy到tomcat6.0\lib下,這一部是關鍵,如果沒有copy 當運作程式的時候後報-找不到驅動-的異常。
2、将下面的代碼放到Tomcat 6.0\conf\context.xml中間,如:
<Context reloadable="true">
<Resource
name="jdbc/資料庫名"
type="javax.sql.DataSource"
maxActive="100"
maxIdle="30"
maxWait="5000"
username="使用者名"
password="密碼"
driverClassName="資料庫的驅動"
url="資料庫的連接配接位址" />
</Context>
解釋:(100 30 5000 為上面的資料)
maxActive="最大可以有100名使用者連接配接資料源"
maxIdle="如果沒有使用者連接配接,空出30個連接配接等待使用者連接配接"
maxWait="如果已連接配接使用者5000秒内沒有再次連接配接資料源,則放棄此連接配接"
完成這兩部,資料源就可以用了。
另外,也可以在項目root下的WEB-INF下建立context.xml進行配置
<?xml version="1.0" encoding="UTF-8"?>
<Context>/直連
<Resource
name="jdbc/book"
type="javax.sql.DataSource"
password=""
driverClassName="com.microsoft.jdbc.sqlserver.SQLServerDriver"
maxIdle="5"
maxWait="5000"
username="sa"
url="jdbc:microsoft:sqlserver://localhost:1433;databaseName=book"直連資料源
maxActive="10"/>
</Context>
<!-->
<Context>橋連
<Resource
name="jdbc/book"
type="javax.sql.DataSource"
password=""
driverClassName="sun.jdbc.odbc.JdbcOdbcDriver"
maxIdle="2"
maxWait="5000"
username="sa"
url="jdbc:odbc:bb"///橋連的資料源
maxActive="4"/>
<WatchedResource>C:\Program Files\Apache Software Foundation\Tomcat 5.5\conf\context.xml</WatchedResource>
</Context>
<!-->
直接在Context檔案中加入入:
<Resource
name="jdb/dbsource"
type="javax.sql.DataSource"
driverClassName="com.microsoft.jdbc.sqlserver.SQLServerDriver"
maxIdle="2"
maxWait="5000"
url="jdbc:microsoft:sqlserver://localhost:1433;databaseName=jspdev"
maxActive="4"/>
username="he"
password="he"
通過java的jndi就可以了
InitialContext initCtx = new InitialContext();
DataSource ds = (DataSource)initCtx.lookup("java:comp/env/jdbc/資料庫名");
Connection conn = ds.getConnection();
以下是各種資料庫的配置
1.sql2000
<Resource
name="jdbc/資料庫名"
type="javax.sql.DataSource"
maxActive="100"
maxIdle="30"
maxWait="5000"
username="使用者名"
password="密碼"
driverClassName="com.microsoft.jdbc.sqlserver.SQLServerDriver"
url="jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=資料庫名"
/>
2.oracle
<Resource
name="jdbc/資料庫名"
type="javax.sql.DataSource"
maxActive="100"
maxIdle="30"
maxWait="5000"
username="使用者名"
password="密碼"
driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@127.0.0.1:1521:ora9"
/>
3.mysql
<Resource name="jdbc/mysql"
auth="Container"
type="javax.sql.DataSource" //資源類型
driverClassName="org.gjt.mm.mysql.Driver"
url="jdbc:mysql://localhost/資料庫名"
username="使用者名"
password="密碼"
maxActive="100" //最大連結數
maxIdle="30" //最大空閑時間,0為無限制
maxWait="10000"/> //建立連接配接的的最大等待時間
-------------------------over-------------------------
目前隻把一個子產品的項目部署啟動沒問題了。同樣的思路,部署另外兩個項目,三者部署在同一tomcat下。
啟動後出現了兩個主要的異常:
① IOException while loading persisted sessions: java.io.EOFException
這個問題解決的很順利:原因是【引用原文作者的話:錯誤的原因是:EOFException表示輸入過程中意外地到達檔案尾或流尾的信号,導緻從session中擷取資料失敗。這是由于tomcat上次非正常關閉時有一些活動session被持久化(表現為一些臨時檔案),在重新開機時,tomcat嘗試去恢複這些session的持久化資料但又讀取失敗造成的。此異常不影響系統的使用。】參考http://blog.csdn.net/redarmy_chen/article/details/17756725
② 另一個異常出現在日志的最後,java.lang.OutOfMemoryError: PermGen space 記憶體溢出。
原因是 加載了 過多的class檔案。 需要在tomcat的catalina.sh 裡面配置參數增大記憶體參數。
參見:http://blog.csdn.net/wi_232995/article/details/78222595