|
2006年11月8日
當(dāng)前,CORBA、DCOM、RMI等RPC中間件技術(shù)已廣泛應(yīng)用于各個(gè)領(lǐng)域。但是面對規(guī)模和復(fù)雜度都越來越高的分布式系統(tǒng),這些技術(shù)也顯示出其局限性:(1)同步通信:客戶發(fā)出調(diào)用后,必須等待服務(wù)對象完成處理并返回結(jié)果后才能繼續(xù)執(zhí)行;(2)客戶和服務(wù)對象的生命周期緊密耦合:客戶進(jìn)程和服務(wù)對象進(jìn)程都必須正常運(yùn)行;如果由于服務(wù)對象崩潰或者網(wǎng)絡(luò)故障導(dǎo)致客戶的請求不可達(dá),客戶會(huì)接收到異常;(3)點(diǎn)對點(diǎn)通信:客戶的一次調(diào)用只發(fā)送給某個(gè)單獨(dú)的目標(biāo)對象。 面向消息的中間件(Message Oriented Middleware,MOM)較好的解決了以上問題。發(fā)送者將消息發(fā)送給消息服務(wù)器,消息服務(wù)器將消息存放在若干隊(duì)列中,在合適的時(shí)候再將消息轉(zhuǎn)發(fā)給接收者。這種模式下,發(fā)送和接收是異步的,發(fā)送者無需等待;二者的生命周期未必相同:發(fā)送消息的時(shí)候接收者不一定運(yùn)行,接收消息的時(shí)候發(fā)送者也不一定運(yùn)行;一對多通信:對于一個(gè)消息可以有多個(gè)接收者。 已有的MOM系統(tǒng)包括IBM的MQSeries、Microsoft的MSMQ和BEA的MessageQ等。由于沒有一個(gè)通用的標(biāo)準(zhǔn),這些系統(tǒng)很難實(shí)現(xiàn)互操作和無縫連接。Java Message Service(JMS)是SUN提出的旨在統(tǒng)一各種MOM系統(tǒng)接口的規(guī)范,它包含點(diǎn)對點(diǎn)(Point to Point,PTP)和發(fā)布/訂閱(Publish/Subscribe,pub/sub)兩種消息模型,提供可靠消息傳輸、事務(wù)和消息過濾等機(jī)制。
1.JMS JAVA 消息服務(wù)(JMS)定義了Java 中訪問消息中間件的接口。JMS 只是接口,并沒有給予實(shí)現(xiàn),實(shí)現(xiàn)JMS 接口的消息中間件稱為JMS Provider,iLink實(shí)現(xiàn)了JMS接口,用戶可以通過使用JMS接口,在iLink中進(jìn)行JMS編程。 iLink支持JMS1.0.2版本。
2.JMS接口描述 JMS 支持兩種消息類型PTP 和Pub/Sub,分別稱作:PTP Domain 和Pub/Sub Domain,這兩種接口都繼承統(tǒng)一的JMS父接口,JMS 主要接口如下所示:
MS父接口
|
PTP
|
Pub/Sub
|
ConnectionFactory
|
QueueConnectionFactory
|
TopicConnectionFactory
|
Connection
|
QueueConnection
|
TopicConnection
|
Destination
|
Queue
|
Topic
|
Session
|
QueueSession
|
TopicSession
|
MessageProducer
|
QueueSender
|
TopicPublisher
|
MessageConsumer
|
QueueReceiver,QueueBrowse r
|
TopicSubscriber
|
|
ConnectionFactory :連接工廠,JMS 用它創(chuàng)建連接 Connection :JMS 客戶端到JMS Provider 的連接 Destination :消息的目的地 Session: 一個(gè)發(fā)送或接收消息的線程 MessageProducer: 由Session 對象創(chuàng)建的用來發(fā)送消息的對象 MessageConsumer: 由Session 對象創(chuàng)建的用來接收消息的對象
3.JMS消息模型 JMS 消息由以下幾部分組成:消息頭,屬性,消息體。 3.1 消息頭(Header) - 消息頭包含消息的識別信息和路由信息,消息頭包含一些標(biāo)準(zhǔn)的屬性如:JMSDestination,JMSMessageID 等。
消息頭
|
由誰設(shè)置
|
JMSDestination
|
send 或 publish 方法
|
JMSDeliveryMode
|
send 或 publish 方法
|
JMSExpiration
|
send 或 publish 方法
|
JMSPriority
|
send 或 publish 方法
|
JMSMessageID
|
send 或 publish 方法
|
JMSTimestamp
|
send 或 publish 方法
|
JMSCorrelationID
|
客戶
|
JMSReplyTo
|
客戶
|
JMSType
|
客戶
|
JMSRedelivered
|
JMS Provider
|
|
3.2 屬性(Properties) - 除了消息頭中定義好的標(biāo)準(zhǔn)屬性外,JMS 提供一種機(jī)制增加新屬性到消息頭 中,這種新屬性包含以下幾種: 1. 應(yīng)用需要用到的屬性; 2. 消息頭中原有的一些可選屬性; 3. JMS Provider 需要用到的屬性。 標(biāo)準(zhǔn)的JMS 消息頭包含以下屬性:
JMSDestination
|
消息發(fā)送的目的地
|
JMSDeliveryMode
|
傳遞模式, 有兩種模式: PERSISTENT 和NON_PERSISTENT,PERSISTENT 表示該消息一定要被送到目的地,否則會(huì)導(dǎo)致應(yīng)用錯(cuò)誤。NON_PERSISTENT 表示偶然丟失該消息是被允許的,這兩種模式使開發(fā)者可以在消息傳遞的可靠性和吞吐量之間找到平衡點(diǎn)。
|
JMSMessageID
|
唯一識別每個(gè)消息的標(biāo)識,由JMS Provider 產(chǎn)生。
|
JMSTimestamp
|
一個(gè)消息被提交給JMS Provider 到消息被發(fā)出的時(shí)間。
|
JMSCorrelationID
|
用來連接到另外一個(gè)消息,典型的應(yīng)用是在回復(fù)消息中連接到原消息。
|
JMSReplyTo
|
提供本消息回復(fù)消息的目的地址
|
JMSRedelivered
|
如果一個(gè)客戶端收到一個(gè)設(shè)置了JMSRedelivered 屬性的消息,則表示可能該客戶端曾經(jīng)在早些時(shí)候收到過該消息,但并沒有簽收(acknowledged)。
|
JMSType
|
消息類型的識別符。
|
JMSExpiration
|
消息過期時(shí)間,等于QueueSender 的send 方法中的timeToLive 值或TopicPublisher 的publish 方法中的timeToLive 值加上發(fā)送時(shí)刻的GMT 時(shí)間值。如果timeToLive值等于零,則JMSExpiration 被設(shè)為零,表示該消息永不過期。如果發(fā)送后,在消息過期時(shí)間之后消息還沒有被發(fā)送到目的地,則該消息被清除。
|
JMSPriority
|
消息優(yōu)先級,從0-9 十個(gè)級別,0-4 是普通消息,5-9 是加急消息。JMS 不要求JMS Provider 嚴(yán)格按照這十個(gè)優(yōu)先級發(fā)送消息,但必須保證加急消息要先于普通消息到達(dá)。
|
|
3.3 消息體(Body) - JMS API 定義了5種消息體格式,也叫消息類型,你可以使用不同形式發(fā)送接收 數(shù)據(jù)并可以兼容現(xiàn)有的消息格式,下面描述這5種類型:
消息類型
|
消息體
|
TextMessage
|
java.lang.String對象,如xml文件內(nèi)容
|
MapMessage
|
名/值對的集合,名是String對象,值類型可以是Java任何基本類型
|
BytesMessage
|
字節(jié)流
|
StreamMessage
|
Java中的輸入輸出流
|
ObjectMessage
|
Java中的可序列化對象
|
Message
|
沒有消息體,只有消息頭和屬性
|
|
下例演示創(chuàng)建并發(fā)送一個(gè)TextMessage到一個(gè)隊(duì)列: TextMessage message = queueSession.createTextMessage(); message.setText(msg_text); // msg_text is a String queueSender.send(message);
下例演示接收消息并轉(zhuǎn)換為合適的消息類型: Message m = queueReceiver.receive(); if (m instanceof TextMessage) { TextMessage message = (TextMessage) m; System.out.println("Reading message: " + message.getText()); } else { // Handle error }
4. 消息的同步異步接收 消息的同步接收是指客戶端主動(dòng)去接收消息,JMS 客戶端可以采用MessageConsumer 的receive方法去接收下一個(gè)消息。 消息的異步接收是指當(dāng)消息到達(dá)時(shí),主動(dòng)通知客戶端。JMS 客戶端可以通過注冊一個(gè)實(shí) 現(xiàn)MessageListener 接口的對象到MessageConsumer,這樣,每當(dāng)消息到達(dá)時(shí),JMS Provider 會(huì)調(diào)用MessageListener中的onMessage 方法。
5. PTP模型 PTP(Point-to-Point)模型是基于隊(duì)列的,發(fā)送方發(fā)消息到隊(duì)列,接收方從隊(duì)列接收消息,隊(duì)列的存在使得消息的異步傳輸成為可能。和郵件系統(tǒng)中的郵箱一樣,隊(duì)列可以包含各種消息,JMS Provider 提 供工具管理隊(duì)列的創(chuàng)建、刪除。JMS PTP 模型定義了客戶端如何向隊(duì)列發(fā)送消息,從隊(duì)列接收消息,瀏覽隊(duì)列中的消息。 下面描述JMS PTP 模型中的主要概念和對象:
名稱
|
描述
|
Queue
|
由JMS Provider 管理,隊(duì)列由隊(duì)列名識別,客戶端可以通過JNDI 接口用隊(duì)列名得到一個(gè)隊(duì)列對象。
|
TemporaryQueue
|
由QueueConnection 創(chuàng)建,而且只能由創(chuàng)建它的QueueConnection 使用。
|
QueueConnectionFactory
|
客戶端用QueueConnectionFactory 創(chuàng)建QueueConnection 對象。
|
QueueConnection
|
一個(gè)到JMS PTP provider 的連接,客戶端可以用QueueConnection 創(chuàng)建QueueSession 來發(fā)送和接收消息。
|
QueueSession
|
提供一些方法創(chuàng)建QueueReceiver 、QueueSender、QueueBrowser 和TemporaryQueue。如果在QueueSession 關(guān)閉時(shí),有一些消息已經(jīng)被收到,但還沒有被簽收(acknowledged),那么,當(dāng)接收者下次連接到相同的隊(duì)列時(shí),這些消息還會(huì)被再次接收。
|
QueueReceiver
|
客戶端用QueueReceiver 接收隊(duì)列中的消息,如果用戶在QueueReceiver 中設(shè)定了消息選擇條件,那么不符合條件的消息會(huì)留在隊(duì)列中,不會(huì)被接收到。
|
QueueSender
|
客戶端用QueueSender 發(fā)送消息到隊(duì)列。
|
QueueBrowser
|
客戶端可以QueueBrowser 瀏覽隊(duì)列中的消息,但不會(huì)收走消息。
|
QueueRequestor
|
JMS 提供QueueRequestor 類簡化消息的收發(fā)過程。QueueRequestor 的構(gòu)造函數(shù)有兩個(gè)參數(shù):QueueSession 和queue,QueueRequestor 通過創(chuàng)建一個(gè)臨時(shí)隊(duì)列來完成最終的收發(fā)消息請求。
|
可靠性(Reliability)
|
隊(duì)列可以長久地保存消息直到接收者收到消息。接收者不需要因?yàn)閾?dān)心消息會(huì)丟失而時(shí)刻和隊(duì)列保持激活的連接狀態(tài),充分體現(xiàn)了異步傳輸模式的優(yōu)勢。
|
|
6. PUB/SUB模型 JMS Pub/Sub 模型定義了如何向一個(gè)內(nèi)容節(jié)點(diǎn)發(fā)布和訂閱消息,這些節(jié)點(diǎn)被稱作主題(topic)。 主題可以被認(rèn)為是消息的傳輸中介,發(fā)布者(publisher)發(fā)布消息到主題,訂閱者(subscribe)從主題訂閱消息。主題使得消息訂閱者和消息發(fā)布者保持互相獨(dú)立,不需要接觸即可保證消息的傳送。 下面描述JMS Pub/Sub 模型中的主要概念和對象:
名稱
|
描述
|
訂閱(subscription)
|
消息訂閱分為非持久訂閱(non-durable subscription)和持久訂閱(durable subscrip-tion),非持久訂閱只有當(dāng)客戶端處于激活狀態(tài),也就是和JMS Provider 保持連接狀態(tài)才能收到發(fā)送到某個(gè)主題的消息,而當(dāng)客戶端處于離線狀態(tài),這個(gè)時(shí)間段發(fā)到主題的消息將會(huì)丟失,永遠(yuǎn)不會(huì)收到。持久訂閱時(shí),客戶端向JMS 注冊一個(gè)識別自己身份的ID,當(dāng)這個(gè)客戶端處于離線時(shí),JMS Provider 會(huì)為這個(gè)ID 保存所有發(fā)送到主題的消息,當(dāng)客戶再次連接到JMS Provider時(shí),會(huì)根據(jù)自己的ID 得到所有當(dāng)自己處于離線時(shí)發(fā)送到主題的消息。
|
Topic
|
主題由JMS Provider 管理,主題由主題名識別,客戶端可以通過JNDI 接口用主題名得到一個(gè)主題對象。JMS 沒有給出主題的組織和層次結(jié)構(gòu)的定義,由JMS Provider 自己定義。
|
TemporaryTopic
|
臨時(shí)主題由TopicConnection 創(chuàng)建,而且只能由創(chuàng)建它的TopicConnection 使用。臨時(shí)主題不能提供持久訂閱功能。
|
TopicConnectionFactory
|
客戶端用TopicConnectionFactory 創(chuàng)建TopicConnection 對象。
|
TopicConnection
|
TopicConnection 是一個(gè)到JMS Pub/Sub provider 的連接,客戶端可以用TopicConnection創(chuàng)建TopicSession 來發(fā)布和訂閱消息。
|
TopicSession
|
TopicSession 提供一些方法創(chuàng)建TopicPublisher、TopicSubscriber、TemporaryTopic 。它還提供unsubscribe 方法取消消息的持久訂閱。
|
TopicPublisher
|
客戶端用TopicPublisher 發(fā)布消息到主題。
|
TopicSubscriber
|
客戶端用TopicSubscriber 接收發(fā)布到主題上的消息。可以在TopicSubscriber 中設(shè)置消息過濾功能,這樣,不符合要求的消息不會(huì)被接收。
|
Durable TopicSubscriber
|
如果一個(gè)客戶端需要持久訂閱消息,可以使用Durable TopicSubscriber,TopSession 提供一個(gè)方法createDurableSubscriber創(chuàng)建Durable TopicSubscriber 對象。
|
恢復(fù)和重新派送(Recovery and Redelivery)
|
非持久訂閱狀態(tài)下,不能恢復(fù)或重新派送一個(gè)未簽收的消息。只有持久訂閱才能恢復(fù)或重新派送一個(gè)未簽收的消息。
|
TopicRequestor
|
JMS 提供TopicRequestor 類簡化消息的收發(fā)過程。TopicRequestor 的構(gòu)造函數(shù)有兩個(gè)參數(shù):TopicSession 和topic。TopicRequestor 通過創(chuàng)建一個(gè)臨時(shí)主題來完成最終的發(fā)布和接收消息請求。
|
可靠性(Reliability)
|
當(dāng)所有的消息必須被接收,則用持久訂閱模式。當(dāng)丟失消息能夠被容忍,則用非持久訂閱模式。
|
|
7. 開發(fā)JMS的步驟 廣義上說,一個(gè)JMS 應(yīng)用是幾個(gè)JMS 客戶端交換消息,開發(fā)JMS 客戶端應(yīng)用由以下幾步構(gòu)成: 用JNDI 得到ConnectionFactory 對象; 用JNDI 得到目標(biāo)隊(duì)列或主題對象,即Destination 對象; 用ConnectionFactory 創(chuàng)建Connection 對象; 用Connection 對象創(chuàng)建一個(gè)或多個(gè)JMS Session; 用Session 和Destination 創(chuàng)建MessageProducer 和MessageConsumer; 通知Connection 開始傳遞消息。
Some XA JDBC drivers do not support local transaction operations, which can cause an error similar to the following when optimistic concurrency is used with such a driver:
SQL operations are not allowed with no global transaction by default for XA drivers.
In other words, the error will occur when
SupportsLocalTransactions="true"
is specified for the JDBCConnectionPool.
This problem occurs because optimistic concurrency suspends a global transaction and does reads in a local transaction when the database is not Oracle. (When using Oracle, you can avoid this problem by explicitly setting
<database-type>Oracle</database-type>
in your CMP deployment descriptor.)
Workaround
: Use the "RollbackLocalTxUponConnClose" on the JDBCConnection.
在談到
XA
規(guī)范之前,必須首先了解分布式事務(wù)處理(
Distributed Transaction Processing
,
DTP
)的概念。
Transaction
,即事務(wù),又稱之為交易,指一個(gè)程序或程序段,在一個(gè)或多個(gè)資源如
數(shù)據(jù)庫
或文件上為完成某些功能的執(zhí)行過程的集合。
LU
人的博客
)vqfhOBA
分布式事務(wù)處理是指一個(gè)事務(wù)可能涉及多個(gè)數(shù)據(jù)庫操作,分布式事務(wù)處理的關(guān)鍵是必須有一種方法可以知道事務(wù)在任何地方所做的所有動(dòng)作,提交或回滾事務(wù)的決定必須產(chǎn)生統(tǒng)一的結(jié)果(全部提交或全部回滾)。
X/Open
組織(即現(xiàn)在的
Open Group
)定義了分布式事務(wù)處理模型。
X/Open DTP
模型(
1994
)包括應(yīng)用程序(
AP
)、事務(wù)管理器(
TM
)、資源管理器(
RM
)、通信資源管理器(
CRM
)四部分。一般,常見的事務(wù)管理器(
TM
)是交易中間件,常見的資源管理器(
RM
)是數(shù)據(jù)庫,常見的通信資源管理器(
CRM
)是消息中間件。
通常把一個(gè)數(shù)據(jù)庫內(nèi)部的事務(wù)處理,如對多個(gè)表的操作,作為本地事務(wù)看待。數(shù)據(jù)庫的事務(wù)處理對象是本地事務(wù),而分布式事務(wù)處理的對象是全局事務(wù)。
所謂全局事務(wù),是指分布式事務(wù)處理環(huán)境中,多個(gè)數(shù)據(jù)庫可能需要共同完成一個(gè)工作,這個(gè)工作即是一個(gè)全局事務(wù),例如,一個(gè)事務(wù)中可能更新幾個(gè)不同的數(shù)據(jù)庫。對數(shù)據(jù)庫的操作發(fā)生在系統(tǒng)的各處但必須全部被提交或回滾。此時(shí)一個(gè)數(shù)據(jù)庫對自己內(nèi)部所做操作的提交不僅依賴本身操作是否成功,還要依賴與全局事務(wù)相關(guān)的其它數(shù)據(jù)庫的操作是否成功,如果任一數(shù)據(jù)庫的任一操作失敗,則參與此事務(wù)的所有數(shù)據(jù)庫所做的所有操作都必須回滾。
LU
人的博客
8v:d?(~;~$A-Q9V D
一般情況下,某一數(shù)據(jù)庫無法知道其它數(shù)據(jù)庫在做什么,因此,在一個(gè)
DTP
環(huán)境中,交易中間件是必需的,由它通知和協(xié)調(diào)相關(guān)數(shù)據(jù)庫的提交或回滾。而一個(gè)數(shù)據(jù)庫只將其自己所做的操作(可恢復(fù))影射到全局事務(wù)中。
XA
就是
X/Open DTP
定義的交易中間件與數(shù)據(jù)庫之間的接口規(guī)范(即接口函數(shù)),交易中間件用它來通知數(shù)據(jù)庫事務(wù)的開始、結(jié)束以及提交、回滾等。
XA
接口函數(shù)由數(shù)據(jù)庫廠商提供。
XA
與兩階段提交協(xié)議
通常情況下,交易中間件與數(shù)據(jù)庫通過
XA
接口規(guī)范,使用兩階段提交來完成一個(gè)全局事務(wù),
XA
規(guī)范的基礎(chǔ)是兩階段提交協(xié)議。
在第一階段,交易中間件請求所有相關(guān)數(shù)據(jù)庫準(zhǔn)備提交(預(yù)提交)各自的事務(wù)分支,以確認(rèn)是否所有相關(guān)數(shù)據(jù)庫都可以提交各自的事務(wù)分支。當(dāng)某一數(shù)據(jù)庫收到預(yù)提交后,如果可以提交屬于自己的事務(wù)分支,則將自己在該事務(wù)分支中所做的操作固定記錄下來,并給交易中間件一個(gè)同意提交的應(yīng)答,此時(shí)數(shù)據(jù)庫將不能再在該事務(wù)分支中加入任何操作,但此時(shí)數(shù)據(jù)庫并沒有真正提交該事務(wù),數(shù)據(jù)庫對共享資源的操作還未釋放(處于上鎖狀態(tài))。如果由于某種原因數(shù)據(jù)庫無法提交屬于自己的事務(wù)分支,它將回滾自己的所有操作,釋放對共享資源上的鎖,并返回給交易中間件失敗應(yīng)答。
在第二階段,交易中間件審查所有數(shù)據(jù)庫返回的預(yù)提交結(jié)果,如所有數(shù)據(jù)庫都可以提交,交易中間件將要求所有數(shù)據(jù)庫做正式提交,這樣該全局事務(wù)被提交。而如果有任一數(shù)據(jù)庫預(yù)提交返回失敗,交易中間件將要求所有其它數(shù)據(jù)庫回滾其操作,這樣該全局事務(wù)被回滾。
以一個(gè)全局事務(wù)為例,
AP
首先通知交易中間件開始一個(gè)全局事務(wù),交易中間件通過
XA
接口函數(shù)通知數(shù)據(jù)庫開始事務(wù),然后
AP
可以對數(shù)據(jù)庫管理的資源進(jìn)行操作,數(shù)據(jù)庫系統(tǒng)記錄事務(wù)對本地資源的所有操作。操作完成后交易中間件通過
XA
接口函數(shù)通知數(shù)據(jù)庫操作完成。交易中間件負(fù)責(zé)記錄
AP
操作過哪些數(shù)據(jù)庫(事務(wù)分支)。
AP
根據(jù)情況通知交易中間件提交該全局事務(wù),交易中間件會(huì)通過
XA
接口函數(shù)要求各個(gè)數(shù)據(jù)庫做預(yù)提交,所有數(shù)據(jù)庫返回成功后要求各個(gè)數(shù)據(jù)庫做正式提交,此時(shí)一筆全局事務(wù)結(jié)束。
XA
規(guī)范對應(yīng)用來說,最大好處在于事務(wù)的完整性由交易中間件和數(shù)據(jù)庫通過
XA
接口控制,
AP
只需要關(guān)注與數(shù)據(jù)庫的應(yīng)用邏輯的處理,而無需過多關(guān)心事務(wù)的完整性,應(yīng)用設(shè)計(jì)開發(fā)會(huì)簡化很多。
具體來說,如果沒有交易中間件,應(yīng)用系統(tǒng)需要在程序內(nèi)部直接通知數(shù)據(jù)庫開始、結(jié)束和提交事務(wù),當(dāng)出現(xiàn)異常情況時(shí)必須由專門的程序?qū)?shù)據(jù)庫進(jìn)行反向操作才能完成回滾。如果是有很多事務(wù)分支的全局事務(wù),回滾時(shí)情況將變得異常復(fù)雜。而使用
XA
接口,則全局事務(wù)的提交是由交易中間件控制,應(yīng)用程序只需通知交易中間件提交或回滾事務(wù),就可以控制整個(gè)事務(wù)(可能涉及多個(gè)異地的數(shù)據(jù)庫)的全部提交或回滾,應(yīng)用程序完全不用考慮沖正邏輯。
在一個(gè)涉及多個(gè)數(shù)據(jù)庫的全局事務(wù)中,為保證全局事務(wù)的完整性,由交易中間件控制數(shù)據(jù)庫做兩階段提交是必要的。但典型的兩階段提交,對數(shù)據(jù)庫來說事務(wù)從開始到結(jié)束(提交或回滾)時(shí)間相對較長,在事務(wù)處理期間數(shù)據(jù)庫使用的資源(如邏輯日志、各種鎖),直到事務(wù)結(jié)束時(shí)才會(huì)釋放。因此,使用典型的兩階段提交相對來說會(huì)占用更多的資源,在網(wǎng)絡(luò)條件不是很好,如低速網(wǎng)、網(wǎng)絡(luò)顛簸頻繁,情況會(huì)更為嚴(yán)重。
當(dāng)一個(gè)全局事務(wù)只涉及一個(gè)數(shù)據(jù)庫時(shí),有一種優(yōu)化方式,即一階段提交。當(dāng)
AP
通知交易中間件提交事務(wù)時(shí),交易中間件直接要求數(shù)據(jù)庫提交事務(wù),省去兩階段提交中的第一階段,可以縮短處理一個(gè)事務(wù)的時(shí)間,以提高事務(wù)處理的效率。作為兩階段提交的一種特例,與兩階段一樣,一階段提交也是標(biāo)準(zhǔn)的。
If you encountered “
Cannot call Connection.commit in distributed transaction
” error, should check the weblogic connection pool and the datasource
?
If the connection pool is XA,
you should make sure that when you create the datasource to make it XA by select the check from "Honor Global Transaction" from the weblogic console.(default is selected)
If the connection pool is non-XA
you should make sure that when you create the datasource to make it non-XA by remove the check from "Honor Global Transaction" from the weblogic console.
問題描述:
<[ServletContext(id=18489944,name=EBLGWeb,context-path=/)]: Deployment descriptor "/WEB-INF/bhr-tags-pagination.tld" is malformed. Check against the DTD: Content is not allowed in prolog. (line 1, column 1).>
<[ServletContext(id=18489944,name=EBLGWeb,context-path=/)]: Error while parsing the Tag Library Descriptor at "/WEB-INF/bhr-tags-pagination.tld".
org.xml.sax.SAXException: [HTTP:101248][ServletContext(id=18489944,name=EBLGWeb,context-path=/)]: Deployment descriptor "/WEB-INF/bhr-tags-pagination.tld" is malformed. Check against the DTD: Content is not allowed in prolog. (line 1, column 1).
at weblogic.apache.xerces.parsers.DOMParser.parse(DOMParser.java:285)
at weblogic.apache.xerces.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:201)
at weblogic.servlet.jsp.dd.JSPEntityResolver.load(JSPEntityResolver.java:81)
at weblogic.servlet.jsp.dd.JSPEntityResolver.load(JSPEntityResolver.java:96)
at weblogic.servlet.internal.WebAppHelper.registerTagLibListeners(WebAppHelper.java:293)
at weblogic.servlet.internal.WebAppServletContext.activateFromDescriptors(WebAppServletContext.java:2530)
at weblogic.servlet.internal.WebAppServletContext.activate(WebAppServletContext.java:6163)
at weblogic.servlet.internal.WebAppServletContext.setActive(WebAppServletContext.java:6141)
at weblogic.servlet.internal.WebAppModule.activate(WebAppModule.java:836)
at weblogic.j2ee.J2EEApplicationContainer.activateModule(J2EEApplicationContainer.java:3322)
at weblogic.j2ee.J2EEApplicationContainer.activate(J2EEApplicationContainer.java:2201)
at weblogic.j2ee.J2EEApplicationContainer.activate(J2EEApplicationContainer.java:2174)
at weblogic.j2ee.J2EEApplicationContainer.activate(J2EEApplicationContainer.java:2122)
at weblogic.management.deploy.slave.SlaveDeployer$Application.setActivation(SlaveDeployer.java:3099)
at weblogic.management.deploy.slave.SlaveDeployer.setActivationStateForAllApplications(SlaveDeployer.java:1768)
at weblogic.management.deploy.slave.SlaveDeployer.resume(SlaveDeployer.java:351)
at weblogic.management.deploy.DeploymentManagerServerLifeCycleImpl.resume(DeploymentManagerServerLifeCycleImpl.java:229)
at weblogic.t3.srvr.SubsystemManager.resume(SubsystemManager.java:136)
at weblogic.t3.srvr.T3Srvr.resume(T3Srvr.java:965)
at weblogic.t3.srvr.T3Srvr.run(T3Srvr.java:360)
at weblogic.Server.main(Server.java:32)
>
原因分析和解決方法:
是由于某些文本編輯器(UltraEdit)存文本的時(shí)候產(chǎn)生的問題。可以使用text pad, word pad編輯XML格式的文件。
問題描述:
通過HTTP提交EDI請求,當(dāng)EDI處理時(shí)間超過了20分鐘后,就會(huì)看到在另一個(gè)weblogic server也接收到了這個(gè)EDI請求,重新處理這個(gè)報(bào)文.
如果報(bào)文處理時(shí)間更長,比如超過了50分鐘,就會(huì)發(fā)現(xiàn)這個(gè)報(bào)文被處理了3遍或5遍.
原因分析和解決方法:
When the Apache HTTP Server Plug-In attempts to connect to WebLogic Server, the plug-in uses several configuration
parameters to determine how long to wait for connections to the WebLogic Server host and, after a connection is
established, how long the plug-in waits for a response. If the plug-in cannot connect or does not receive a response,
the plug-in attempts to connect and send the request to other WebLogic Server instances in the cluster. If the
connection fails or there is no response from any WebLogic Server in the cluster, an error message is sent.
響應(yīng)等待時(shí)間參數(shù)WLIOTimeoutSecs (http://e-docs.bea.com/wls/docs81/plugins/plugin_params.html#1149781.
按照BEA 推薦的,這個(gè)值應(yīng)該設(shè)得大一些, 這個(gè)參數(shù)的缺省值為300s. 見下面:
<Location /EDIHandler>
SetHandler weblogic-handler
WebLogicCluster apc_app1wls1:7011,apc_app1wls2:7011
KeepAliveEnabled ON
WLIOTimeoutSecs 7200
</Location>
有時(shí)候使用的mq jar文件的版本不對給出現(xiàn)一些末名奇妙的問題,本文則是能接收消息但不能發(fā)送消息的一個(gè)問題.碰到這樣的問題一定要記得double-check你使用的mq jar文件的版本
問題描述:
MQJMS200713 Oct 2006 16:47:15,484 ERROR MessagingUtilServlet [ExecuteThread: '14' for queue: 'weblogic.kernel.Default'][]: **********EXCEPTION TRACE START*************
13 Oct 2006 16:47:15,484 ERROR MessagingUtilServlet [ExecuteThread: '14' for queue: 'weblogic.kernel.Default'][]: produce error
com.bhr.infra.messaging.exception.PMException: JMSException
at com.bhr.infra.messaging.PMHandler.send(PMHandler.java:419)
at com.bhr.epc.infra.messaging.util.MessagingUtilServlet.produce(MessagingUtilServlet.java:312)
at com.bhr.epc.infra.messaging.util.MessagingUtilServlet.service(MessagingUtilServlet.java:74)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at weblogic.servlet.internal.ServletStubImpl$ServletInvocationAction.run(ServletStubImpl.java:1072)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:465)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:348)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:6981)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121)
at weblogic.servlet.internal.WebAppServletContext.invokeServlet(WebAppServletContext.java:3892)
at weblogic.servlet.internal.ServletRequestImpl.execute(ServletRequestImpl.java:2766)
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:224)
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:183)
Caused by: javax.jms.JMSException: MQJMS2007: failed to send message to MQ queue
at com.ibm.mq.jms.services.ConfigEnvironment.newException(ConfigEnvironment.java:553)
at com.ibm.mq.jms.MQMessageProducer.sendInternal(MQMessageProducer.java:1589)
at com.ibm.mq.jms.MQMessageProducer.send(MQMessageProducer.java:1012)
at com.ibm.mq.jms.MQMessageProducer.send(MQMessageProducer.java:1046)
at com.bhr.infra.messaging.PMQueueSender.send(PMQueueSender.java:57)
at com.bhr.infra.messaging.PMHandler.send(PMHandler.java:410)
... 13 more
13 Oct 2006 16:47:15,486 ERROR MessagingUtilServlet [ExecuteThread: '14' for queue: 'weblogic.kernel.Default'][]: **********EXCEPTION TRACE END**************
原因分析和解決方法:
It may be caused by use of old version MQ jar. It can receive message, but cannot send message.
如果你碰到"Cannot Forward a Response that is Already Committed"這樣的錯(cuò)誤信息,一定是應(yīng)用對一次http請求做了多次頁面跳轉(zhuǎn)或?qū)esponse對象做過close后,又去寫響應(yīng).
這個(gè)問題的根本原因由于響應(yīng)本次請求的Response對象的狀態(tài)是已提交狀態(tài)造成的, 它不允許響應(yīng)提交多次。
什么時(shí)候Response對象的狀態(tài)變成已提交狀態(tài):當(dāng)你的應(yīng)用已經(jīng)實(shí)現(xiàn)了頁面跳轉(zhuǎn)邏輯。
通常原因:
1. 如果你使用了community的話, community的安全認(rèn)證和授權(quán)如果沒有通過,community內(nèi)部會(huì)進(jìn)行頁面跳轉(zhuǎn)。但你的應(yīng)用(對于workshop應(yīng)用的話,指的是action)又試圖進(jìn)行頁面跳轉(zhuǎn),就會(huì)出現(xiàn)這樣的問題。
/**
* @jpf:action
* @jpf:forward name="page" path="page.jsp"
*/
protected Forward actionMethod()
{
//如果已經(jīng)提交了響應(yīng),你仍然試圖再次進(jìn)行頁面跳轉(zhuǎn),即再次提交響應(yīng),可能出現(xiàn)問題
//通常可以加一個(gè)判斷
if (!getResponse().isCommitted()) {
return new Forward("success");
} else {
return null;
}
}
protected void beforeAction() {
SecurityManager.checkAuthorization(getRequest(), getResponse(), config.getString(
CDConstants.CREATE_TERM_ACTION_NAME, ""));
//這個(gè)調(diào)用可能實(shí)現(xiàn)了頁面跳轉(zhuǎn),即提交響應(yīng)
}
注意JSP中實(shí)現(xiàn)頁面跳轉(zhuǎn)后,加return 語句防止繼續(xù)提交響應(yīng):
<%
SecurityManager.checkAuthorization(getRequest(), getResponse(), config.getString(
CDConstants.CREATE_TERM_ACTION_NAME, ""));
{
//可能有實(shí)現(xiàn)頁面跳轉(zhuǎn)邏輯
……………forward();
return;//記得加retrun.
}
%>
2. .如果沒有使用community的話,下面情景也會(huì)出現(xiàn)這個(gè)問題
/**
* @jpf:action
* @jpf:forward name="page" path="page.jsp"
*/
protected Forward actionMethod()
//直接操作Response對象寫響應(yīng)
getResponse().getPrintWriter().println();
…
/
// 又執(zhí)行的頁面跳轉(zhuǎn),也可能出現(xiàn)問題
return new Forward("index");
}
一個(gè)頁面流在第一次使用時(shí),內(nèi)部屬性currentpage并沒有指定頁面,所以避免在begin方法里使用return-to: current page用法.同時(shí)在用的時(shí)候注意頁面流的工作方式
問題描述:
Error message like below in Web Page is displayed:
Page Flow:
/com/xxxx/xxx/xxx.jpf
Action:
update
Page Flow Error - No Relevant Page
You have tried to return to a recent page in the current page flow through return-to="currentPage",
but there is no appropriate page.
Exception's stack trace:
Exception: No previous page for return-to="currentPage" on action create in page flow
/com/gems/mt/web/CreateReleaseCntr/CreateReleaseCntrController.jpf.
com.bea.wlw.netui.pageflow.NoPreviousPageException: No relevant page for return-to="currentPage"
on action create in page flow /com/gems/mt/web/CreateReleaseCntr/CreateReleaseCntrController.jpf.
at com.bea.wlw.netui.pageflow.FlowController.doReturnToPage(FlowController.java:1328)
at com.bea.wlw.netui.pageflow.FlowController.forwardTo(FlowController.java:1023)
at com.bea.wlw.netui.pageflow.PageFlowController.forwardTo(PageFlowController.java:606)
at com.bea.wlw.netui.pageflow.FlowController.internalExecute(FlowController.java:765)
...
原因分析和解決方法:
When a new page flow is created and its current page is null (it mean you visit at the fist time),
so such an exception like NoPreviousPageException occur if you use return-to="currentPage".
if a new page flow finish a successful forward, it will treat last page as current page
so that we can use current page to display error message conveniently.
Solution:
ensure page flow finish a successful forward and use current page again.
You can also use path="specificPage.jsp" instead of return-to="currentPage"
if your original return-to is just one specific page.
We have known, the ListCellRenderer interface has only one method public Component getListCellRendererComponent(), and it returns a Component. When a JList needs to compute its dimension or paint its cell item, this method will be called. So it will be called frequently, and we have a best practice, try to reuse object, avoid time-consumed computation and unnecessary operation in this method.
?
Recently found, there is a memory leak bug for list cell renderer in both JDK 1.4.x and JDK 5 (don’t know whether has the same bug in earlier JDK). The component returned from getListCellRendererComponent() method could not be GC, and all its referenced objects also could not be GC. Unfortunately, this bug is only fixed in JDK 6.
?
So currently, if a JList use the ListCellRenderer, but only holds a little resource (eg: the JList only has little items, and the component is returned from ListCellRenderer is a simple JLable), you may not care about the memory leak.
?
But if a JList use the ListCellRenderer, and holds a large resource, you should remember to use the following way to avoid memory leak.
?
Work Around: Subclass JList and invoke removeAll after painting is done:
?????? public class xxxList extends JList {
??????????? private CellRendererPane renderer;
??????????? private CellRendererPane getRenderer() {
??????????????? if (renderer == null) {
??????????????????? for (int i=0; i<getComponents().length; i++) {
????????????????????????????????????????? Component c? = getComponents()[i];
??????????????????????? if (c instanceof CellRendererPane) {
??????????????????????????? renderer = (CellRendererPane)c;
??????????????????????????? break;
??????????????????????? }
??????????????????? }
??????????????? }
??????????????? return renderer;
??????????? }
??????????? protected void paintComponent(Graphics g) {
??????????????? super.paintComponent(g);
??????????????? CellRendererPane renderer = getRenderer();
??????????????? if (renderer != null) {
??????????????????? renderer.removeAll();
??????????????? }
??????????? }
??????? }
Please refer to http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5044798 for more details.
The logic to change state is only inside one method (initVesselView(…)) inside GrVessel.java.?
if (viewType == VIEW_STOWAGE) { ??????????? vslView_ = new VesselStowageView(leftPoint, bow2Left, leftCenter, ???????????????????????????????????????????? rightCenter, shipWidth_); ??????? } ??????? else if (viewType == VIEW_SIDE) { ??????????? vslView_ = new VesselSideView(leftPoint, bow2Left, leftCenter, ????????????????????????????????????????? rightCenter, shipWidth_); ??????? } ??????? else if (viewType == VIEW_PLAN) { ??????????? vslView_ = new VesselPlanView(leftPoint, bow2Left, leftCenter, ????????????????????????????????????????? rightCenter, shipWidth_); ??????? } ??????? else { ??????????? throw new IllegalArgumentException( ??????????????? "GrVessel::initVesselView-->Invalid view type!"); ??????? }
We do not need to repeat this logic of changing view in many other method.
This is the benefit of State design pattern.
The 3 state classes here are VesselPlanView.java, VesselSideView.java and VesselStowageView.java
Please note that in the state classes, if a method is supported by stateA and not supported by stateB.?
Then, in stateB, the method body will throw an exception (IllegalArgumentException) to indicate that coder call the wrong method in the wrong state.
Example, in VesselPlanView.java, public boolean addStowage(...).? This method is only meaningful to stowageView.
public boolean addStowage(IlvManager manager, List transformList, IlvGraphic stowage, String stadBayN, ????????????????????????????? boolean isSelect) { ??????? throw new IllegalArgumentException( ??????????????? "GrVessel::addStowage-->be sure the vessel at stowage view!"); ??? }
Hence, in PlanView, the method body will throw exception.
Just to share with you a better way to code.
摘要: 本文討論模型過濾技術(shù)。您可將這一技術(shù)用于 Swing 組件集,這樣即可在不改變底層數(shù)據(jù)的條件下提供模型數(shù)據(jù)的不同視圖。過濾器可以改變數(shù)據(jù)元素的外在內(nèi)容,將數(shù)據(jù)排除在視圖之外、將外部元素包含進(jìn)數(shù)據(jù)集中、或者以不同的順序呈現(xiàn)元素。過濾器既可應(yīng)用于數(shù)據(jù)模型,也可應(yīng)用于狀態(tài)模型。您還可以疊用過濾器,以將它們的效果組合起來。 閱讀全文
有時(shí)運(yùn)行ANT 時(shí)會(huì)拋出 java.lang.InstantiationException: org.apache.tools.ant.Main 異常 原因之一是在機(jī)器中存在2種不同版本的ANT,我碰到的情況是classpath 中即有weblogic.jar,又有1.6.5的ANT, 刪除weblogic.jar后運(yùn)行就正常了
public class GroupableHeaderExample extends JFrame {
? GroupableHeaderExample() { ??? super( "Groupable Header Example" );
??? DefaultTableModel dm = new DefaultTableModel(); ??? dm.setDataVector(new Object[][]{ ????? {"119","foo","bar","ja","ko","zh"}, ????? {"911","bar","foo","en","fr","pt"}}, ??? new Object[]{"SNo.","1","2","Native","2","3"});
??? JTable table = new JTable( dm ) { ????? protected JTableHeader createDefaultTableHeader() { ? return new GroupableTableHeader(columnModel); ????? } ??? }; ??? TableColumnModel cm = table.getColumnModel(); ??? ColumnGroup g_name = new ColumnGroup("Name"); ??? g_name.add(cm.getColumn(1)); ??? g_name.add(cm.getColumn(2)); ??? ColumnGroup g_lang = new ColumnGroup("Language"); ??? g_lang.add(cm.getColumn(3)); ??? ColumnGroup g_other = new ColumnGroup("Others"); ??? g_other.add(cm.getColumn(4)); ??? g_other.add(cm.getColumn(5)); ??? g_lang.add(g_other); ??? GroupableTableHeader header = (GroupableTableHeader)table.getTableHeader(); ??? header.addColumnGroup(g_name); ??? header.addColumnGroup(g_lang);
??? TableCellRenderer renderer =? new DefaultTableCellRenderer() { ??????? public Component getTableCellRendererComponent(JTable table, Object value, ???????????????????????? boolean isSelected, boolean hasFocus, int row, int column) { ????????? JTableHeader header = table.getTableHeader(); ????????? if (header != null) { ??????????? setForeground(header.getForeground()); ??????????? setBackground(header.getBackground()); ??????????? setFont(header.getFont()); ????????? } ????????? setHorizontalAlignment(JLabel.CENTER); ????????? setText((value == null) ? "" : value.toString()); ????????? setBorder(UIManager.getBorder("TableHeader.cellBorder")); ????????? return this; ??????? } ????? };
??? TableColumnModel model = table.getColumnModel(); ??? for (int i=0;i<model.getColumnCount();i++) { ????? model.getColumn(i).setHeaderRenderer(renderer); ??? } ??? JScrollPane scroll = new JScrollPane( table ); ??? getContentPane().add( scroll ); ??? setSize( 400, 120 ); ? }
? public static void main(String[] args) { ??? GroupableHeaderExample frame = new GroupableHeaderExample(); ??? frame.addWindowListener( new WindowAdapter() { ????? public void windowClosing( WindowEvent e ) { ? System.exit(0); ????? } ??? }); ??? frame.setVisible(true); ? } }
============================================= public void paint(Graphics g, JComponent c) { ??? Rectangle clipBounds = g.getClipBounds(); ??? if (header.getColumnModel() == null) return; //??? ((GroupableTableHeader)header).setColumnMargin(); ??? int column = 0; ??? Dimension size = header.getSize(); ??? Rectangle cellRect? = new Rectangle(0, 0, size.width, size.height); ??? Hashtable h = new Hashtable(); //??? int columnMargin = header.getColumnModel().getColumnMargin();
??? Enumeration enumeration = header.getColumnModel().getColumns(); ??? while (enumeration.hasMoreElements()) { ????? cellRect.height = size.height; ????? cellRect.y????? = 0; ????? TableColumn aColumn = (TableColumn)enumeration.nextElement(); ????? Enumeration cGroups = ((GroupableTableHeader)header).getColumnGroups(aColumn); ????? if (cGroups != null) { ??????? int groupHeight = 0; ??????? while (cGroups.hasMoreElements()) { ????????? ColumnGroup cGroup = (ColumnGroup)cGroups.nextElement(); ????????? Rectangle groupRect = (Rectangle)h.get(cGroup); ????????? if (groupRect == null) { ??????????? groupRect = new Rectangle(cellRect); ??????????? Dimension d = cGroup.getSize(header.getTable()); ??????????? groupRect.width? = d.width; ??????????? groupRect.height = d.height; ??????????? h.put(cGroup, groupRect); ????????? } ????????? paintCell(g, groupRect, cGroup); ????????? groupHeight += groupRect.height; ????????? cellRect.height = size.height - groupHeight; ????????? cellRect.y????? = groupHeight; ??????? } ????? } ????? cellRect.width = aColumn.getWidth() ;//+ columnMargin; ????? if (cellRect.intersects(clipBounds)) { ??????? paintCell(g, cellRect, column); ????? } ????? cellRect.x += cellRect.width; ????? column++; ??? } ? }
使用
IlvToolTipManager
創(chuàng)建一個(gè)多行的
tooltip
:
?
1)
首先需要注冊
view (IlvManagerView)I
lvToolTipManager.registerView(view);
?
2)
創(chuàng)建需要顯示的信息的數(shù)組,即每行的信息為數(shù)組中的一個(gè)元素:
new String[] tooltipArray ;
?
3)
創(chuàng)建
tooltip,
第一個(gè)參數(shù)是上面創(chuàng)建的數(shù)組,第二個(gè)參數(shù)是顯示位置,必須是
SwingConstants.LEFT
,
RIGHT
, or
CENTER
String tooltip = IlvToolTipManager.createMultiLineToolTipText(tooltipArray, SwingConstants.LEFT);
?
4)
設(shè)置
tooltip
:
IlvGraphic.setToolTipText(tooltip);
public static String createMultiLineToolTipText(String as[], int i) ??? { ??????? String s; ??????? switch(i) ??????? { ??????? case 2: // '\002' ??????????? s = "left"; ??????????? break;
??????? case 4: // '\004' ??????????? s = "right"; ??????????? break;
??????? case 0: // '\0' ??????????? s = "center"; ??????????? break;
??????? case 1: // '\001' ??????? case 3: // '\003' ??????? default: ??????????? throw new IllegalArgumentException("Alignment must be LEFT, RIGHT, or CENTER"); ??????? } ??????? Font font = UIManager.getFont("ToolTip.font"); ??????? StringBuffer stringbuffer = new StringBuffer("<p align=\""); ??????? stringbuffer.append(s); ??????? stringbuffer.append("\" style=\"font-family:"); ??????? stringbuffer.append(font.getName()); ??????? stringbuffer.append(";font-size:"); ??????? stringbuffer.append(font.getSize()); ??????? stringbuffer.append("pt\">"); ??????? String s1 = stringbuffer.toString(); ??????? StringBuffer stringbuffer1 = new StringBuffer("<html>"); ??????? for(int j = 0; j < as.length; j++) ??????? { ??????????? stringbuffer1.append(s1); ??????????? stringbuffer1.append(as[j]); ??????????? stringbuffer1.append("</p>"); ??????? }
??????? stringbuffer1.append("</html>"); ??????? return stringbuffer1.toString(); ??? }
?
下面這個(gè)異常是因?yàn)闆]有找到EJB, JNDI NAME 本來是 'ejb/ppp/sss/Resource' ,? 可找的卻是'ejb.ppp.sss/Resource' , 后來查到是因?yàn)?font color="#ff0033">EJB 的REMOTE 接口中的方法在BEAN中沒有定義. 不知道還有沒有其他什么原因可以導(dǎo)致這種情況.
Caused by: javax.naming.NameNotFoundException: While trying to lookup 'ejb.ppp.sss/Resource' didn't find subcontext 'ppp' Resolved ejb ?at weblogic.jndi.internal.BasicNamingNode.newNameNotFoundException(BasicNamingNode.java:924) ?at weblogic.jndi.internal.BasicNamingNode.lookupHere(BasicNamingNode.java:225) ?at weblogic.jndi.internal.ServerNamingNode.lookupHere(ServerNamingNode.java:154) ?at weblogic.jndi.internal.BasicNamingNode.lookup(BasicNamingNode.java:188) ?at weblogic.jndi.internal.BasicNamingNode.lookup(BasicNamingNode.java:196) ?at weblogic.jndi.internal.RootNamingNode_WLSkel.invoke(Unknown Source) ?at weblogic.rmi.internal.BasicServerRef.invoke(BasicServerRef.java:492) ?at weblogic.rmi.cluster.ReplicaAwareServerRef.invoke(ReplicaAwareServerRef.java:108) ?at weblogic.rmi.internal.BasicServerRef$1.run(BasicServerRef.java:435) ?at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363) ?at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:147) ?at weblogic.rmi.internal.BasicServerRef.handleRequest(BasicServerRef.java:430) ?at weblogic.rmi.internal.BasicExecuteRequest.execute(BasicExecuteRequest.java:35) ?at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:224) ?at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:183)
|