tomcat 專案遷移到weblogic
【藏】Spring與weblogic jndi整合
至於如何配置hibernate,就和平時該怎麼配置就怎麼配置了。
雖然spring本身是可以直接使用jndi來進行獲取一些物件,但是在和weblogic整合的時候往往還是容易出現問題(在web應用的時候出現問題的可能性不大,因為container已經做了很多事情了.)但是在ide或者其他的應用環境下(不同的jvm的時候),通常找不到provider_url等屬性造成無法找到jndi.
修改配置檔案如下:
<!-- 通過jndi的方式來呼叫datasource,即使不一定是在j2ee環境中也可以正常使用預設情況下,如果沒有指定,"java:comp/env/"將放在後面jndi名稱前面
-->
<property name="jndiName">
<value>jdbc/myDatasource</value>
</property>
<!-- 如果你不想使用 'java:comp/env/'字首的話請設定下面的值為true, 預設值為false -->
<property name="resourceRef">
<value>false</value>
</property>
<property name="jndiEnvironment">
<props>
<!-- The value of Context.PROVIDER_URL -->
<prop key="java.naming.provider.url">t3://localhost:7001</prop>
<prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory
</prop>
</props>
</property>
</bean>
注意在設定的時候由於不在同一個jvm裡面,所以一定要設定provider.url和factory.initial的屬性值,否則會出現NoInitialContextException的異常出現.
此外如果和其他的應用伺服器整合的話可能不只是要設定上面的兩個屬性,還要設定相關的其他屬性。詳細情況參考:javax.naming.Context類的說明文件。
其中設定的:
<property name="jndiEnvironment">
<props>
<!-- The value of Context.PROVIDER_URL -->
<prop key="java.naming.provider.url">t3://localhost:7001</prop>
<prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory
</prop>
</props>
</property> 實際上就是設定Context初始化的時候設定的Properties屬性。
發表於 2005年1月28日 12:43
websphere:
java.naming.provider.url->iiop://websphere.machine.domain.com:900
java.naming.factory.initial ->com.ibm.websphere.naming.WsnInitialContextFactory
java.naming.factory.url.pkgs ->com.ibm.ws.naming
org.omg.CORBA.ORBClass->com.ibm.rmi.iiop.ORB
org.omg.CORBA.ORBSingletonClass->com.ibm.rmi.corba.ORBSingleton
javax.rmi.CORBA.UtilClass->com.ibm.rmi.javax.rmi.CORBA.Util
javax.rmi.CORBA.StubClass->com.ibm.rmi.javax.rmi.CORBA.StubDelegateImpl
javax.rmi.CORBA.PortableRemoteObjectClass->com.ibm.rmi.javax.rmi.PortableRemoteObject
weblogic:
java.naming.factory.initial -> weblogic.jndi.WLInitialContextFactory
java.naming.provider.url -> t3://localhost:7001
jboss:
ava.naming.factory.initial ->org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs->org.jboss.naming.client
java.naming.provider.url ->jnp://10.0.0.18:1099
sunone IMQ ldap:
java.naming.provider.url -> ldap://localhost:389/dc=yusong,dc=com
java.naming.factory.initial -> com.sun.jndi.ldap.LdapCtxFactory
sunone Application Server:
java.naming.provider.url -> iiop://192.168.0.34:3700
java.naming.factory.initial -> com.sun.jndi.cosnaming.CNCtxFactory
oracle oc4j:
java.naming.factory.initial->com.evermind.server.ApplicationClientInitialContextFactory
java.naming.provider.url->ormi://localhost/bmpapp
錯誤如下:
javax.naming.NameNotFoundException: Unable to resolve 'jdbc.mydb'. Resolved 'jdbc'; remaining name 'mydb' at weblogic.jndi.internal.BasicNamingNode.newNameNotFoundException(BasicNamingNode.java:1180) at weblogic.jndi.internal.BasicNamingNode.lookupHere(BasicNamingNode.java:270) at weblogic.jndi.internal.ServerNamingNode.lookupHere(ServerNamingNode.java:187) at weblogic.jndi.internal.BasicNamingNode.lookup(BasicNamingNode.java:210) at weblogic.jndi.internal.BasicNamingNode.lookup(BasicNamingNode.java:224) at weblogic.jndi.internal.WLEventContextImpl.lookup(WLEventContextImpl.java:253) at weblogic.jndi.internal.WLContextImpl.lookup(WLContextImpl.java:426) at javax.naming.InitialContext.lookup(InitialContext.java:411) at jsp_servlet.__index._jspService(__index.java:101) at weblogic.servlet.jsp.JspBase.service(JspBase.java:34) at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:280) at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:254) at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:136) at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:341) at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:238) at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3363) at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3333) at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321) at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120) at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:57) at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2220) at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2146) at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2124) at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1564) at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:254) at weblogic.work.ExecuteThread.execute(ExecuteThread.java:295) at weblogic.work.ExecuteThread.run(ExecuteThread.java:254) |
程式碼連線如下:
DataSource ds = (DataSource)ctx.lookup(“jdbc.mydb”);
出現這個是由於沒有找到JNDI,(其實是廢話,報錯已經說明了 ^_^);
解決方法:
在Weblogic資料來源管理中的
JDBC Data Source-0的設定
中設定目標選項
將服務勾選上,如預設的:AdminServer 儲存後即可;這裡還要說一下我使用的weblogic版本是10.3.3,提到版本是因為有些錯誤只會在特定的版本上出現,而針對某版本的解決方案也未必適用於所有版本。
- 部署後說ClassNotFoundException org.hibernate.FlushMode
weblogic類載入順序問題,這個很煩,因為我也不知道到底哪些jar包要放出來,啟動時載入,哪些不需要。暫時先在weblogic.xml中設定了
<container-descriptor>
<prefer-web-inf-classes>true</prefer-web-inf-classes>
</container-descriptor>
這個表示讓weblogic先載入web-inf下面lib下面的jar包
- 找不到sessionFactory這個bean,首先肯定配置是配好的,但是就是找不到,猜測是沒有讀到spring的配置檔案,google了一下,原來weblogic中的web.xml不支援萬用字元的寫法,如:
部署到tomcat中可以這樣寫
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/applicationContext*.xml</param-value>
</context-param>
但是在weblogic中必須這樣寫
<context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:/applicationContext.xml
classpath:/applicationContext-wssecurity.xml </param-value> </context-param>
- struts2 + convention plugin總是說no action found error,找不到action,然後根據coc的預設規則直接進入jsp,這個解決方案來自於http://aaa5131421.iteye.com/blog/558463
這種情況需要以下步驟來解決:
1、更新struts2到最新版,我的是2.1.8
2、專案中src目錄加入 META-INF資料夾,如果你不是直接在war中加入該資料夾,例如:在eclipse中專案的src加入該資料夾,則需要讓該資料夾包含檔案,任意一個檔案都可以,這樣export war的時候才會export meta-inf資料夾,才會有效果。
3、配置struts.xml加入如下屬性:
<constant name="struts.convention.action.fileProtocols" value="jar,zip" />
<constant name="struts.convention.action.includeJars" value=".*?/_wl_cls_gen.*?jar(!/)?" />
- 部署後報錯java.lang.ClassCastException: weblogic.xml.jaxp.RegistrySAXTransformerFactory cannot be cast to javax.xml.transform.TransformerFactory
這個錯有幾種說法,一個老外的帖子說,要把xml解析的jar包去掉
* xercesImpl-2.9.1.jar
* xml-apis-1.3.04.jar
* xmlParserAPIs-2.0.2.jar
我是使用第二個方法解決的。
- dbcp錯誤,這個問題比較傻,一開始用tomcat在跑的,所以資料庫連線池用了dbcp,換了weblogic後,忘記了配成jndi了。解決方法很簡單,加上spring的jndi查詢datasource即可,如:
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/xxxDS" />
由於weblogic安全問題,可能會出現如下錯誤 ... invalid subject .. principles[weblogic,Administrators],這樣的話配置要按以下寫法:
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/xxxDS">
<jee:environment>
java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory
java.naming.provider.url=t3://yourhost:yourport
java.naming.security.principal=yourprincipal
java.naming.security.credentials=yourcredentials
</jee:environment>
</jee:jndi-lookup>
另外需要在setDomainEnv.sh中設定WLS_JDBC_REMOTE_ENABLED="-Dweblogic.jdbc.remoteEnabled=true",預設值為false
cxf部署到weblogic,這是我花了最長時間解決的問題,有的錯誤非常離奇。雖然解決了都沒搞明白為什麼會發生。
前面提到版本,就是因為我部署在weblogic10.3.0時一點錯沒有,部署到10.3.2和10.3.3錯誤一堆。cxf官方也有說如何部署到weblogic中的說明,可惜它只驗證了weblogic9.2,至少我按照它的配置,一點效果沒有。
1、java.lang.LinkageError: loader constraints violated when linking javax/xml/namespace/QName class
我是找到自己專案下包含QName的類的那個jar,jaxrpc.jar,把裡面那個QName類刪了(這樣做好像不是很好)
2、org.apache.commons.logging.LogConfigurationException: org.apache.commons.logging.LogConfigurationException: org.apache.commons.logging.LogConfigurationException: Invalid class loader hierarchy. You have more than one version of 'org.apache.commons.logging.Log' visible, which is not allowed.
這個錯非常神奇,我因為它搞了一天多,一直以為是我使用的commons-logging的版本和weblogic使用的不一樣,才出現的這個錯,然後搜尋了weblogic目錄下的所有版本的commons-logging都換到我專案裡試了一把,全都不行,搜遍國外論壇的大街小巷,就是沒有一個結果,後來仔細檢視異常stack,裡面居然包含了一個spring.orm丟擲的資訊,我部署的只是一個非常簡單的cxf專案,並沒有包含任何orm框架,配置也檢查了一遍,也沒有配過orm的東西,為什麼異常會從這裡丟擲。最後發現是因為我使用了@Autowired和@Component註解來進行自動注入而引起的,但是還是搞不懂,我也只不過注入了一個plain javabean,為什麼使用@Autowired和@Component,異常會出現在orm上,然後我把spring-orm-2.5.6.jar扔到lib下,在部署一次,這個commons-logging的錯誤就消失了。真是神奇的錯誤。(滴汗)
3、java.lang.NoSuchMethodException: oracle.j2ee.ws.wsdl.extensions.soap.SOAPBindingImpl.getElementType()
這個錯誤也搜尋了很久,沒有找到很直接的解決方案,最後自己摸索著解決了,cxf要用的是wsdl4j.jar,然後我的weblogic裡安裝了webcenter中介軟體,然後在MW_HOME下面會多一個oracle_common目錄,這個目錄下的子目錄中會有一個jar叫orawsdl.jar裡面就有上面描述的的那個oracle.j2ee.ws.wsdl.extensions.soap.SOAPBindingImpl類,解決辦法是編輯startWeblogic.sh檔案,把wsdl4j.jar加在weblogic自己的CLASSPATH的前面,就不會出現這個錯誤了。
weblogic做了cluster後,session複製問題
這個網上有很多說明,但是大部分好像都是針對舊版本的weblogic,網上流行的寫法:
在weblogic.xml中增加如下配置:
<session-descriptor>
<session-param>
<param-name>PersistentStoreType</param-name>
<param-value>replicated</param-value>
</session-param>
</session-descriptor>
weblogic11g下的寫法是:
<session-descriptor>
<persistent-store-type>replicated</persistent-store-type>
<sharing-enabled>true</sharing-enabled>
</session-descriptor>
這應該跟不同版本的DTD有關
注意任何需要持久化的session中的內容必須都實現java.io.Serializable介面,否則無法進行復制。
不同weblogic中資源的遠端查詢與安全問題
這個問題是能解決,但是也會引發其他問題,在我的專案中,我有3個weblogic,一個a部署了oracle bpm10g,
另外2個b和c做叢集部署了oracle webcenter11g,b中包含了叢集的管理伺服器,webcenter專案中需要遠端查詢bpm的topic,如果不加ADF Security的話,不會出現錯誤,但是加上ADF Security的話,就會出現... invalid subject .. principles[xxxxx,xxxxx]的錯誤,現在我目前通過啟用weblogic中的全域性信任這個功能,暫時解決了這個遠端查詢的問題,
但是又出現了新問題,這個問題很奇怪,啟用全域性信任以後,b的管理伺服器不知道什麼時候會讀取到a的domain資訊,一旦這個出現,一旦我想改b的domain的配置就必須重啟b的管理伺服器,再次登入才可以。這個問題我非常不明白,而且也不知道什麼時候會發生,有時候讀取的正確,有時候不正確。目前還沒有辦法解決。