posts - 15,  comments - 34,  trackbacks - 27

          本文討論如何讓用 CORBA 支持的任何語言編寫的客戶端能夠訪問 Enterprise JavaBeansTM 組件 (“EJBTM 組件”)。本文針對(duì)深入了解 JavaTM 2 Platform, Enterprise Edition ("J2EETM") 和公共對(duì)象請(qǐng)求代理結(jié)構(gòu)(Common Object Request Broker Architecture,CORBA)的程序員。

          J2EE 技術(shù)簡化了企業(yè)應(yīng)用程序,因?yàn)樗鼘⑺鼈兘⒃跇?biāo)準(zhǔn)、模塊化和可重用組件的基礎(chǔ)上,而該組件又基于 Enterprise JavaBeansTM (EJBTM) 體系結(jié)構(gòu),它也提供了完整的一組針對(duì)于那些組件的服務(wù),并自動(dòng)處理應(yīng)用程序行為的許多細(xì)節(jié)。通過自動(dòng)化應(yīng)用程序開發(fā)的許多耗時(shí)且困難的任務(wù),J2EE 技術(shù)使企業(yè)開發(fā)人員能夠?qū)⒅攸c(diǎn)放在增值上,也就是增強(qiáng)業(yè)務(wù)邏輯,而不是放在構(gòu)建基礎(chǔ)結(jié)構(gòu)上。

          EJBTM 服務(wù)器端組件模型簡化了事務(wù)型、可伸縮和可移植的中間件組件的開發(fā)。Enterprise JavaBeans 服務(wù)器減少了中間件開發(fā)的復(fù)雜程度,因?yàn)樗鼮橹T如事務(wù)、安全、數(shù)據(jù)庫連接等中間件服務(wù)提供了支持。

          CORBA 是一個(gè)對(duì)象管理組織(Object Management Group,OMG)標(biāo)準(zhǔn),它是一個(gè)開放的、供應(yīng)商無關(guān)的體系結(jié)構(gòu)和基礎(chǔ)結(jié)構(gòu),計(jì)算機(jī)應(yīng)用程序可以使用它來通過網(wǎng)絡(luò)一起工作。由于使用了標(biāo)準(zhǔn)的 Internet Inter-ORB Protocol,(IIOP),因些來自任何供應(yīng)商的基于 CORBA 的程序可以與來自相同或其他供應(yīng)商的基于 CORBA 程序進(jìn)行互操作,前一程序可以在幾乎所有的計(jì)算機(jī)、操作系統(tǒng)、編程語言和網(wǎng)絡(luò)上,后一程序可以在幾乎所有的其他計(jì)算機(jī)、操作系統(tǒng)、編程語言和網(wǎng)絡(luò)上。 要進(jìn)一步學(xué)習(xí) CORBA,請(qǐng)?jiān)L問 http://www.omg.org/gettingstarted/gettingstartedindex.htm

          CORBA 技術(shù)補(bǔ)充了 Java 平臺(tái),因?yàn)樗峁┝朔植际綄?duì)象框架、支持此框架的服務(wù)以及與其他語言的互操作性。CORBA 技術(shù)是 Java 2 平臺(tái)的主要部分,它正用于 Enterprise JavaBeans 組件、 運(yùn)行在 Internet Inter-ORB 協(xié)議上的Java 遠(yuǎn)程方法調(diào)用 API ("Java RMI-IIOP"),以及 Java IDL API ("Java IDL")。

          OMG 接口定義語言(Interface Definition Language,IDL)可用于描述一些接口,該接口由遠(yuǎn)程對(duì)象實(shí)現(xiàn)。IDL 可用于定義接口的名稱,以及定義每個(gè)屬性和方法的名稱。一旦創(chuàng)建 IDL 文件,就可以在任何語言中,使用 IDL 編譯器來生成客戶端存根模塊 (stub) 和服務(wù)器骨架語句 (server skeleton),OMG已經(jīng)為此定義了這種語言映射的規(guī)范。要進(jìn)一步了解 OMG IDL,請(qǐng)?jiān)L問 http://www.omg.org/gettingstarted/omg_idl.htm

          Java IDL 使得分布式 Java 應(yīng)用程序能夠透明地調(diào)用遠(yuǎn)程網(wǎng)絡(luò)服務(wù)上的操作,而該服務(wù)使用對(duì)象管理組織 (http://www.omg.org/) 定義的行業(yè)標(biāo)準(zhǔn)  OMG IDL 和 IIOP。運(yùn)行在 IIOP API 上的 Java RMI 使得可以通過 javax.rmi API 來對(duì) CORBA 服務(wù)器和應(yīng)用程序進(jìn)行編程。

          編寫 EJB 組件的開發(fā)人員可以遵循 Java RMI 編程模型,并將它用于他們的分布式對(duì)象模型,在該模型中,跨越所有應(yīng)用程序服務(wù)器常見的所需傳輸是 Java RMI-IIOP。在異構(gòu)服務(wù)器環(huán)境中,到 CORBA 的 EJB 體系結(jié)構(gòu)的標(biāo)準(zhǔn)映射使得能夠進(jìn)行下述的互操作:

          • 使用來自某一供應(yīng)商 ORB 的客戶端可以訪問駐留在服務(wù)器上的企業(yè) bean,而該服務(wù)器支持由另一供應(yīng)商提供的 Enterprise JavaBeans 技術(shù)(“EJB 服務(wù)器”)。
          • 一臺(tái) EJB 服務(wù)器上的企業(yè) bean 可以訪問另一臺(tái) EJB 服務(wù)器上的企業(yè) bean。
          • 除了Java 編程語言之外,用某一語言編寫的 CORBA 客戶端可以訪問任何 EJB 組件,前提是要有一個(gè)從 OMG IDL 到那種編程語言的映射。

          本文檔的其余部分提供了 CORBA 客戶端應(yīng)用程序的例子,該應(yīng)用程序訪問了企業(yè) bean 對(duì)象。在本文檔中,CORBA 客戶端就是使用 CORBA 支持的任何語言編寫的客戶端應(yīng)用程序,這些編程語言包括 Java 編程語言、C++、C、Smalltalk、COBOL、Ada、Lisp 或 Python。雖然本例中的 Java 代碼特定于企業(yè) bean,但開發(fā) CORBA 的客戶端的過程是相同的,并且開發(fā)的 CORBA 客戶端可以訪問使用 Java RMI-IIOP API 創(chuàng)建的服務(wù)器。

          可以在 鏈接到類似例子 中找到一些鏈接,它們指向其他實(shí)現(xiàn)了 J2EE 技術(shù)的供應(yīng)商提供的類似應(yīng)用程序。




          開發(fā)訪問 Enterprise JavaBean 組件的 CORBA 客戶端

          這是一個(gè)關(guān)于如何開發(fā) CORBA 客戶端應(yīng)用程序以便訪問 EJB 組件的例子。在本例中,客戶端是用 C++ 編程語言編寫的,但客戶端可以是由 CORBA 支持的任何語言編寫的。

          下面的幾節(jié)展示了 CORBA 客戶端的一般開發(fā)過程,開發(fā)完的 CORBA 客戶端可以訪問企業(yè) bean:

          1. 編寫 Enterprise JavaBean 組件
          2. 生成 CORBA IDL
          3. 創(chuàng)建 CORBA 客戶端
          4. 部署 Enterprise JavaBean 組件
          5. 運(yùn)行客戶端可執(zhí)行文件

          本文檔也包括:

          為了使例子變得簡單,我們采取了一些捷徑。有關(guān)構(gòu)建更加高級(jí)的解決方案的信息,請(qǐng)參閱 針對(duì)復(fù)雜接口的技巧

            第 1 部分:編寫 Enterprise JavaBean 組件

            下面的一些例子展示了企業(yè) bean 的代碼,它將從 Java RMI-IIOP 和 CORBA 客戶端接收發(fā)送給應(yīng)用程序服務(wù)器的字符串日志消息。企業(yè) bean 將在服務(wù)器上把它們與當(dāng)前服務(wù)器時(shí)間一起打印出來。

          1. /Java/src/ejbinterop 目錄中創(chuàng)建如下文件:Logger.javaLoggerHome.javaLoggerEJB.java LogMessage.java。

            Logger.java

            Logger.java 文件是企業(yè) bean 的遠(yuǎn)程接口,因此,它擴(kuò)展了 EJBObject。遠(yuǎn)程接口提供了 EJB 對(duì)象的遠(yuǎn)程客戶端視圖,并定義了可由遠(yuǎn)程客戶端調(diào)用的 business 方法。

            
            //Code Example 1: Logger.java
            package ejbinterop;
            
            import javax.ejb.EJBObject;
            import java.rmi.RemoteException;
            
            /**
             * Accepts simple String log messages and prints
             * them on the server.
             */
            public interface Logger extends EJBObject
            {
                /**
                 * Logs the given message on the server with
                 * the current server time.
                 */
                void logString(String message) throws RemoteException;
            }

            LoggerHome.java

            LoggerHome.java 文件擴(kuò)展了 EJBHomeEJBHome 接口必須由所有 EJB 組件的遠(yuǎn)程 home 接口來擴(kuò)展。home 接口定義了一些方法,使得遠(yuǎn)程客戶端可以創(chuàng)建、查找和刪除 EJB 對(duì)象,以及創(chuàng)建、查找和刪除不針對(duì) EJB 實(shí)例的 home business 方法。

            
            //Code Example 2: LoggerHome.java
            package ejbinterop;
            
            import java.rmi.RemoteException;
            import javax.ejb.EJBHome;
            import javax.ejb.CreateException;
            
            public interface LoggerHome extends EJBHome
            {
                Logger create() throws RemoteException, CreateException;
            }

            LoggerEJB.java

            LoggerEJB.java 文件包含了會(huì)話 bean 的代碼。會(huì)話 bean 是一種企業(yè) bean,它由客戶端創(chuàng)建,并且通常只在一個(gè)客戶/服務(wù)器會(huì)話期間存在。會(huì)話 bean 執(zhí)行像計(jì)算或訪問客戶端數(shù)據(jù)庫這樣的操作。在本例中,企業(yè) bean 從客戶端接收簡單的字符串日志消息,并在服務(wù)器上打印它們。

            
            //LoggerEJB.java
            package ejbinterop;
            
            import javax.ejb.*;
            import java.util.*;
            import java.rmi.*;
            import java.io.*;
            
            /**
             * Accepts simple String log messages and prints
             * them on the server.
             */
            public class LoggerEJB implements SessionBean {
            
                public LoggerEJB() {}
                public void ejbCreate() {}
                public void ejbRemove() {}
                public void ejbActivate() {}
                public void ejbPassivate() {}
                public void setSessionContext(SessionContext sc) {}
            
                /**
                 * Logs the given message on the server with
                 * the current server time.
                 */
                public void logString(String message) {
                    LogMessage msg = new LogMessage(message);
            
                    System.out.println(msg);
                }
            }

            LogMessage.java

            LogMessage.java 文件取得當(dāng)前的日期和時(shí)間,然后創(chuàng)建格式化字串來顯示消息,并將消息打印到服務(wù)器。

            //LogMessage.java
            package ejbinterop;
            
            import java.io.Serializable;
            import java.util.Date;
            import java.text.*;
            
            /**
             * Simple message class that handles pretty
             * printing of log messages.
             */
            public class LogMessage implements Serializable
            {
                private String message;
                private long datetime;
            
                /**
                 * Constructor taking the message. This will
                 * take the current date and time.
                 */
                public LogMessage(String msg) {
                    message = msg;
                    datetime = (new Date()).getTime();
                }
            
                /**
                 * Creates a formatted String showing the message.
                 */
                public String toString() {
                    StringBuffer sbuf = new StringBuffer();
                    DateFormat dformat
                        = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
            	DateFormat.LONG);
                    FieldPosition fpos = new
                        FieldPosition(DateFormat.DATE_FIELD);
                    dformat.format(new Date(datetime), sbuf, fpos);
                    sbuf.append(": ");
                    sbuf.append(message);
                    return sbuf.toString();
                }
            }

          2. 編譯本節(jié)編寫的文件,例如:

            javac -classpath $J2EE_HOME/lib/j2ee.jar:.. *.java

            這些命令在當(dāng)前目錄中為所有的 .java 文件創(chuàng)建了類文件。這個(gè)命令和本文中的其他命令假定已經(jīng)正確設(shè)置了 J2EE_HOME 環(huán)境變量。使用 $J2EE_HOME 是 Unix? 操作系統(tǒng)的規(guī)定。當(dāng)在 Microsoft Windows 操作環(huán)境中,請(qǐng)?zhí)鎿Q %J2EE_HOME%

            第 2 部分:生成 CORBA IDL

            本節(jié)討論如何從 Java 類文件中生成接口定義語言(Interface Definition Language,IDL),并且假定 Java 類文件已在前一節(jié)中生成。在本例中,我們將使用 rmic 編譯器,以便將 Java 代碼映射到 IDL。IDL 提供了純聲明性的、編程語言無關(guān)的方式來指定對(duì)象的 API。

          3. 針對(duì) Java 類文件運(yùn)行 rmic 編譯器,該 Java 類文件已在前一步驟中生成,其命令如下:
            rmic -idl -noValueMethods -classpath 
              $J2EE_HOME/lib/j2ee.jar:<path_to_ejbinterop_dir> 
              -d <path_to_where_idl_files_should_be_generated> 
              ejbinterop.Logger ejbinterop.LoggerHome
            

            在前面的例子中,我們包括了 .jar 文件和 ejbinterop 文件的目錄,.jar 文件中包含有 javax.ejb 包的定義。如果您正在使用 JavaTM 2 Platform, Enterprise Edition (J2EETM), version 1.3 Reference Implementation (RI),那么 .jar 文件就位于 $J2EE_HOME/lib/j2ee.jar

            在上面的 rmic 命令行中,我們推薦了一種捷徑——使用 noValueMethods 選項(xiàng)。這個(gè)選項(xiàng)告訴 rmic 跳過具有參數(shù)或返回類型的任何方法,這里的返回類型將被映射到 CORBA 值類型。有利的方面在于它將防止我們生成許多不必要的 IDL,在 C++客戶端中,我們可能必須實(shí)現(xiàn)這些 IDL。不利的方面在于我們只能使用原始的數(shù)據(jù)類型、數(shù)組和字符串,而不能使用自己的 Java 類類型來作為參數(shù)或返回類型。 有關(guān)進(jìn)一步信息,請(qǐng)閱讀 針對(duì)復(fù)雜接口的技巧

            在 Java 類文件上運(yùn)行 rmic 編譯器會(huì)生成下面的一些文件,文件所處的目錄由上面 rmic 語句的 -d 選項(xiàng)指出:

            • java/lang/Ex.idl
            • java/lang/Exception.idl
            • java/lang/Object.idl
            • java/lang/Throwable.idl
            • java/lang/ThrowableEx.idl
            • javax/ejb/CreateEx.idl
            • javax/ejb/CreateException.idl
            • javax/ejb/EJBHome.idl
            • javax/ejb/EJBMetaData.idl
            • javax/ejb/EJBObject.idl
            • javax/ejb/Handle.idl
            • javax/ejb/HomeHandle.idl
            • javax/ejb/RemoveEx.idl
            • javax/ejb/RemoveException.idl
            • ejbinterop/Logger.idl
            • ejbinterop/LoggerHome.idl

             

            注意:許多生成文件包含了只能在 Java 編程環(huán)境中使用的 API 。 例如,目前 EJBMetaData 實(shí)現(xiàn)特定于每個(gè)應(yīng)用程序服務(wù)器,因此很難開發(fā)等效設(shè)施,以便在除 Java 平臺(tái)外的平臺(tái)上繼續(xù)超時(shí)工作。一種選擇是將它們從 IDL 中刪除,但如果這樣做,那么每次改變 Java 接口,并從 rmic 編譯器中重生成 IDL 文件時(shí),就必須從 IDL 中刪除它們。

            注意: 由于 CORBA 異常不支持繼承,因此針對(duì) IDL 映射的 Java 語言創(chuàng)建了 Ex 類,它包含了代表實(shí)際 Java 異常的 CORBA 值類型。在這個(gè)基本的例子中,不必過多擔(dān)心異常支持。有關(guān)異常的進(jìn)一步信息,請(qǐng)參閱 http://java.sun.com/j2se/1.4.2/docs/guide/idl/jidlExceptions.html

          4. 使用 C++ 供應(yīng)商的“IDL to C++”編譯器來編譯 IDL 文件,以便生成對(duì)應(yīng)于 IDL 的 C++ 代碼。不同的供應(yīng)商之間,這個(gè)過程的步驟會(huì)有區(qū)別,因此有必要參考產(chǎn)品文檔,取得針對(duì)供應(yīng)商的特定步驟。

            第 3 部分:創(chuàng)建 CORBA 客戶端

            客戶端應(yīng)用程序可以使用 CORBA 支持的任何語言編寫。下面的例子提供了針對(duì)于 C++ 客戶端的代碼,只要給予對(duì)象請(qǐng)求代理人( Object Request Broker,簡稱 ORB)和 LoggerHome 對(duì)象的 corbaname URL,它就會(huì)在服務(wù)器上將簡單字符串消息記錄到日志中。您必須根據(jù) C++ ORB 供應(yīng)商的庫來調(diào)整 include 語句,并修改注冊(cè)值工廠的代碼。本例是針對(duì)  ORBacus for C++ 4.0.5 編寫的,因此本例中的一些 C++ 代碼是特定于該產(chǎn)品的。

            corbaname URL 是可閱讀的 URL 格式,它允許您訪問 CORBA 對(duì)象。它用于從特定命名上下文解析字符串化的名稱。這是 J2EE v 1.3 平臺(tái)中的新特性,它作為 CORBA 互操作命名服務(wù)(Interoperable Naming Service,簡稱 INS)的一部分。INS 是 CORBA 對(duì)象服務(wù)(CORBA Object Services,簡稱COS)命名服務(wù)的擴(kuò)展,在以前版本的 J2EE 平臺(tái)中已經(jīng)交付使用。為了進(jìn)一步了解 INS,請(qǐng)?jiān)L問 http://java.sun.com/j2se/1.4.2/docs/guide/idl/jidlNaming.html#INS

            在本例中,客戶端代碼執(zhí)行下面的一些操作:

            • 創(chuàng)建對(duì)象請(qǐng)求代理(ORB)。ORB 將對(duì)象請(qǐng)求服務(wù)連接到提供它們的對(duì)象。

            • 注冊(cè)值工廠。

            • 在命名上下文中查找 corbaname URL 指向的 LoggerHome 對(duì)象。

            • 從返回給 LoggerHome 對(duì)象的對(duì)象中執(zhí)行安全的向下轉(zhuǎn)換。

            • 創(chuàng)建 LoggerEJB 對(duì)象引用。

            • 在日志中記錄消息。

            • 告訴應(yīng)用程序服務(wù)器不再使用 EJB 引用。

          5. 使用類似于下面的 C++ 代碼來創(chuàng)建客戶端。準(zhǔn)確的代碼可能與 C++ 實(shí)現(xiàn)有關(guān)。這些代碼是針對(duì)于 ORBacus for C++ 4.0.5 編寫的,因此本例中的一些 C++ 代碼可能特定于該產(chǎn)品。

            //Code Example: Client.cpp
            #include <fstream.h>
            
            // C++ ORB Vendor specific include files
            // These are from C++ ORBacus 4.0.5
            
            #include <OB/CORBA.h>
            #include <OB/OBORB.h>
            
            // Include files generated from our IDL
            #include <java/lang/Exception.h>
            #include <java/lang/Throwable.h>
            #include <javax/ejb/CreateException.h>
            #include <javax/ejb/RemoveException.h>
            #include <ejbinterop/Logger.h>
            #include <ejbinterop/LoggerHome.h>
            
            /**
             * Given an ORB and a corbaname URL for a LoggerHome
             * object, logs a simple string message on the server.
             */
            void
            run(CORBA::ORB_ptr orb, const char* logger_home_url)
            {
              cout << "Looking for: " << logger_home_url << endl;
            
              // Look up the LoggerHome object in the naming context
              // pointed to by the corbaname URL
              CORBA::Object_var home_obj
                = orb->string_to_object(logger_home_url);
            
              // Perform a safe downcast
              ejbinterop::LoggerHome_var home
                = ejbinterop::LoggerHome::_narrow(home_obj.in());
            
              assert(!CORBA::is_nil(home));
            
              // Create a Logger EJB reference
              ejbinterop::Logger_var logger = home->create();
            
              CORBA::WStringValue_var msg =
                new CORBA::WStringValue((const CORBA::WChar*)L"Message 
                  from a C++ client");
              
              cout << "Logging..." << endl;
            
              // Log our message
              logger->logString(msg);
            
              // Tell the application server we won't use this
              // EJB reference any more
              logger->remove();
            
              cout << "Done" << endl;
            }
            
            /**
             * Simple main method that checks arguments, creates an
             * ORB, and handles exceptions.
             */
            int
            main(int argc, char* argv[])
            {
              int exit_code = 0;
              CORBA::ORB_var orb;
            
              try {
            
              // Check the arguments
              if (argc != 2) {
                cerr << "Usage: Client <corbaname URL of LoggerHome>" << endl;
                return 1;
              }
            
              // Create an ORB
              orb = CORBA::ORB_init(argc, argv);
            
              // Register value factories
            
              // NOTE: This is overkill for the example since we'll never
              // get these exceptions.  Also, the _OB_id method is a
              // proprietary feature of ORBacus C++ generated code.
              CORBA::ValueFactory factory = new java::lang::Throwable_init;
              orb -> register_value_factory(java::lang::Throwable::_OB_id(),
                factory);
              factory -> _remove_ref();
            
              factory = new java::lang::Exception_init;
              orb -> register_value_factory(java::lang::Exception::_OB_id(),
                factory);
              factory -> _remove_ref();
            
              factory = new javax::ejb::CreateException_init;
              orb -> 		    register_value_factory(javax::ejb::CreateException::_OB_id(),
                  factory);
              factory -> _remove_ref();
            
              factory = new javax::ejb::RemoveException_init;
              orb ->
                register_value_factory(javax::ejb::RemoveException::_OB_id(),
                  factory);
              factory -> _remove_ref();
            
              // Perform the work
              run(orb, argv[1]);
            
            } catch(const CORBA::Exception& ex) {
              // Handle any CORBA related exceptions
              cerr << ex._to_string() << endl;
              exit_code = 1;
            }
            
              // Release any ORB resources
              if (!CORBA::is_nil(orb)) {
                try {
                  orb -> destroy();
                } catch(const CORBA::Exception& ex) {
                  cerr << ex._to_string() << endl;
                  exit_code = 1;
                }
              }
            
              return exit_code;
            }
          6. 使用 C++ 編譯器來編譯所有的 C++ 文件,包括 Client.cpp 文件,創(chuàng)建客戶端可執(zhí)行文件。不同平臺(tái)之間,這樣的一些工具的區(qū)別甚大,因此有必要參考產(chǎn)品文檔,獲得它的說明。

            第 4 部分:部署 Enterprise JavaBean 組件

          7. 使用滿意的應(yīng)用程序服務(wù)器部署企業(yè) bean。下面的一些步驟描述了如何部署 LoggerEJB 組件,它使用了 J2EE 1.3 Reference Implementation (RI)。

            1. 通過鍵入如下命令,從終端窗口或命令行提示中啟動(dòng) RI 應(yīng)用程序:
              	$J2EE_HOME/bin/j2ee -verbose

            2. 當(dāng) J2EE 1.3 RI 指出“J2EE 啟動(dòng)完成”時(shí),鍵入如下命令,從另一終端窗口或命令提示中運(yùn)行部署工具:

              	$J2EE_HOME/bin/deploytool

            3. 從部署工具中,選擇 File -> New -> Application。

            4. 在 Application File Name 字段中,輸入 Logger.ear,以指出要在其中創(chuàng)建應(yīng)用程序的文件。

            5. 在 Application Display Name 字段中,輸入 Logger。

            6. 選擇 OK 來保存設(shè)置,關(guān)閉這個(gè)對(duì)話窗口。

            7. 從部署工具中,選擇 File -> New -> Enterprise Bean。

            8. 如果出現(xiàn) Introduction 屏幕,選擇 Next,否則繼續(xù)。

            9. 在 New EnterpriseBean Wizard 中,在 Contents 框中選擇 Edit。

            10. 擴(kuò)展 Available Files 列表,添加下面的 4 個(gè) .class 文件,它們來自 ejbinterop 包:Logger.classLoggerHome.classLoggerEJB.class LogMessage.class。選擇 OK,然后選擇 Next。

            11. 選擇 Stateless Session Bean Type。

            12. 選擇 ejbinterop.LoggerEJB 用于 Enterprise Bean Class

            13. 選擇 ejbinterop.LoggerHome 用于 Remote Home Interface

            14. 選擇 ejbinterop.Logger 用于 Remote Interface

            15. 選擇 Next 按扭,直到看到 Security Settings 頁。

            16. 選擇 Deployment Settings 按扭。

            17. 選擇 Support Client Choice .

            18. 選擇 OK 保存設(shè)置并關(guān)閉這個(gè)對(duì)話窗口。

            19. 選擇 Finish.

            20. 從部署工具中,選擇 Tools -> Deploy。

            21. 如果只運(yùn)行 Java RMI-IIOP 客戶端,選擇 Return Client JAR。

            22. 選擇 Next。

            23. JNDI Name for our LoggerEJB 字段中輸入 ejbinterop/logger

            24. 選擇 Finish。

            25. 選擇 File -> Exit 來退出部署工具。

            現(xiàn)在已經(jīng)部署了具有 LoggerEJB 組件的 Logger 應(yīng)用程序,它準(zhǔn)備接收消息。

            第 5 部分:運(yùn)行客戶端可執(zhí)行文件

          8. 運(yùn)行客戶端可執(zhí)行文件。運(yùn)行客戶端可執(zhí)行程序的一種方法是,切換到包含可執(zhí)行客戶端文件的目錄,然后在終端窗口中輸入下面的 URL:

            Client corbaname:iiop:1.2@localhost:1050#ejbinterop/logger

            在這個(gè) URL 中,

            • Client 是要運(yùn)行的應(yīng)用程序的名稱。

            • corbaname 指出將從特定的命名上下文中解析字符串化的名稱。

            • iiop:1.2 告訴 ORB 使用 IIOP 協(xié)議和 GIOP 1.2。

            • 要在其上查找引用的宿主計(jì)算機(jī)是 localhost——本地計(jì)算機(jī)。為了擴(kuò)展這個(gè)例子,以便在兩臺(tái)計(jì)算機(jī)上運(yùn)行,請(qǐng)輸入計(jì)算機(jī)的 IP 地址和主機(jī)名,而不是 localhost,服務(wù)器要在該計(jì)算機(jī)上運(yùn)行。

            • 1050 是端口號(hào),命名服務(wù)會(huì)在該端口上偵聽請(qǐng)求。 在 J2EE v.1.3 RI 中,默認(rèn)情況下,命名服務(wù)要在其上偵聽的默認(rèn)端口號(hào)是端口 1050。到目前為止,散列標(biāo)記 (hash mark) 上的引用部分( Client corbaname:iiop:1.2@localhost:1050 ) 是某個(gè) URL,它返回根命名上下文。

            • ejbinterop/logger 是要在命名上下文中解析的名稱。

            如果您正在使用 J2EE 1.3 Reference Implementation,應(yīng)該會(huì)看到類似于如下的一條消息,該消息是在應(yīng)用程序服務(wù)器上被打印的:

            
            Sep 21, 2001 3:33:07 PM PDT: Message from a C++ client ejbinterop/
            logger is the name to be resolved from the Naming Service.
            

            第 6 部分:停止 J2EE 服務(wù)器

          9. 停止 J2EE 服務(wù)器。為了停止服務(wù)器,可以在終端窗口或命令行提示中,輸入這條命令。
            $J2EE_HOME/bin/j2ee -stop

            不同的操作系統(tǒng)之間,停止運(yùn)行中進(jìn)程的過程是不同的,因此如果正在使用不同的服務(wù)器,可以參考系統(tǒng)文檔以取得詳細(xì)信息。




          創(chuàng)建 Java RMI-IIOP 客戶端應(yīng)用程序

          使用相同的例子,可以容易地開發(fā)連接到企業(yè) bean 的 Java RMI-IIOP 客戶端,。與使用 C++ 的例子的區(qū)別在于:

          • 在客戶端 CLASSPATH 中,必須包括客戶端 .jar 文件的位置,該文件是由運(yùn)行需要的企業(yè) bean 的應(yīng)用程序服務(wù)器創(chuàng)建的。那個(gè) .jar 文件包含了必要的客戶端存根模塊。

          • 當(dāng)使用 J2EE 1.3 RI 部署應(yīng)用程序時(shí),檢查 Deploy 屏幕第一頁上的 Deploytool 中的 Return Client Jar 框。

          下面的代碼是 Java RMI-IIOP 版本的 LoggerEJB 組件客戶端。遵循與 C++ 客戶端例子所展示的相同步驟。當(dāng)運(yùn)行客戶端時(shí),使用與 C++ 例子中相同的 URL。

            //Code Example: LogClient.java
            package ejbinterop;
            
            import java.rmi.RemoteException;
            import javax.rmi.*;
            import java.io.*;
            import javax.naming.*;
            import javax.ejb.*;
            
            /**
             * Simple Java RMI-IIOP client that uses an EJB component.
             */
            public class LogClient
            {
                /**
                 * Given a corbaname URL for a LoggerHome,
                 * log a simple String message on the server.
                 */
                public static void run(String loggerHomeURL)
                    throws CreateException, RemoveException,
                           RemoteException, NamingException
                {
                    System.out.println("Looking for: " + loggerHomeURL);
            
                    // Create an InitialContext. This will use the
                    // CosNaming provider we will specify at runtime.
                    InitialContext ic = new InitialContext();
            
                    // Lookup the LoggerHome in the naming context
                    // pointed to by the corbaname URL
                    Object homeObj = ic.lookup(loggerHomeURL);
            
                    // Perform a safe downcast
                    LoggerHome home
                        = (LoggerHome)PortableRemoteObject.narrow(homeObj,
            	LoggerHome.class);
            
                    // Create a Logger EJB reference
                    Logger logger = home.create();
            
                    System.out.println("Logging...");
            
                    // Log our message
                    logger.logString("Message from a Java RMI-IIOP client");
            
                    // Tell the application server we won't use this
                    // EJB reference anymore
                    logger.remove();
            
                    System.out.println("Done");
                }
            
                /**
                 * Simple main method to check arguments and handle
                 * exceptions.
                 */
                public static void main(String args[])
                {
                    try {
            
                        if (args.length != 1) {
                            System.out.println("Args: corbaname URL of LoggerHome");
                            System.exit(1);
                        }
            
                        LogClient.run(args[0]);
            
                    } catch (Throwable t) {
                        t.printStackTrace();
                        System.exit(1);
                    }
                }
            }

          使用 Java RMI-IIOP 客戶端運(yùn)行應(yīng)用程序

          當(dāng)使用 Java RMI-IIOP 客戶端,而不是 C++ 客戶端運(yùn)行示例應(yīng)用程序時(shí),請(qǐng)遵循這些步驟:

          1. 使用下面的命令,在 ejbinterop / 目錄中編譯 . java 文件:
            javac -classpath $J2EE_HOME/lib/j2ee.jar:<ejbinterop_directory> *.java
            

          2. 部署 Enterprise JavaBean 組件中所描述的那樣部署 Enterprise JavaBean 組件。當(dāng)運(yùn)行 Java RMI-IIOP 客戶應(yīng)用程序時(shí),記得在 Tools -> Deploy 頁中選擇 Return Client JAR 。 Deployment 主題中的一些命令指導(dǎo)您啟動(dòng) J2EE RI 或其他應(yīng)用程序服務(wù)器。

          3. 使用類似于如下命令運(yùn)行客戶應(yīng)用程序:

            java -classpath $J2EE_HOME/lib/j2ee.jar:
            <path to LoggerClient.jar>/LoggerClient.jar:
            <directory_above_ejbinterop>:<ejbinterop_directory>
            ejbinterop.LogClient 
            corbaname:iiop:1.2@localhost:1050#ejbinterop/logger 

            在 J2EE RI 正在運(yùn)行的窗口中,將會(huì)看到:

            Jan 31, 2002 2:27:47 PM PST: Message from a Java RMI-IIOP client
            

            在運(yùn)行客戶端的窗口中,將會(huì)看到:

            Looking for: corbaname:iiop:1.2@localhost:1050#ejbinterop/logger
            Logging...
            Done
            

          4. 停止 J2EE 服務(wù)器。




          超越基本應(yīng)用程序

          本部分包括下述信息:

          如何增強(qiáng)應(yīng)用程序

          要增強(qiáng)應(yīng)用程序,您可以:

          • 開發(fā)使用值類型的例子。

            為達(dá)到此目的,當(dāng)運(yùn)行 rmic 時(shí)刪除 -noValueMethods 開關(guān)。重新運(yùn)行 C++ 語言的 IDL 的映射編譯器,檢查它是否支持已經(jīng)生成的值類型。

          • Logger 中添加另一方法,它實(shí)際取得 LogMessage

          針對(duì)復(fù)雜接口的技巧

          對(duì)于運(yùn)用不同語言的客戶端和服務(wù)器之間的通信,接口是關(guān)鍵。為了在這方面獲得成功,應(yīng)該考慮下面的建議:

          • 避免將復(fù)雜的 Java 類,比如 java.util 中的集合,用于方法參數(shù)或返回類型。

            在將這些類開映射到 IDL 后,將強(qiáng)制您使用客戶端編程語言實(shí)現(xiàn)它們。此外,由于 Java Object Serialization 和 RMI-IIOP API 使得類的線路格式和內(nèi)部表示能夠隨時(shí)間不斷發(fā)展,因此您的 CORBA 客戶端應(yīng)用程序可能在不同的 JavaTM 2 Platform, Standard Edition (J2SETM) 實(shí)現(xiàn)或版本上不兼容。

          • 從 IDL 開始。

            您可能想在返回類型或方法參數(shù)中使用復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。在本例中,試著從 IDL 開始。在 IDL 中定義數(shù)據(jù)結(jié)構(gòu),甚至定義異常,然后將它們用在 EJB 接口中。這將可以防止逆向映射的產(chǎn)出物進(jìn)入 CORBA 接口。

            例如,剛開始試著在 IDL 中定義 LogMessage 類,然后在 Logger EJB 組件中,將 IDL 編譯的 Java 語言結(jié)果類用作方法參數(shù)。

          • 避免重載 EJB 接口。

            CORBA IDL 不支持方法重載,符合 IDL 映射規(guī)范的 Java 語言解決了這一點(diǎn),其方式是創(chuàng)建 IDL 方法定義,將方法名與它的所有 IDL 參數(shù)類型組合起來。對(duì)于使用非 Java 編程語言的開發(fā)人員來說,這帶來了非常不友好的方法名。

          • 考慮使用橋。

            如果可用的選項(xiàng)仍然太有限,或者影響到想編寫的代碼,就可以考慮使用服務(wù)器端橋。在“鏈接到類似例子”一節(jié)列出了一些站點(diǎn),您可以從這些站點(diǎn)中獲得更多有關(guān)如何構(gòu)建橋的信息。

          鏈接到類似例子

          實(shí)現(xiàn) J2EE 技術(shù)的幾個(gè)供應(yīng)商都有一些優(yōu)秀的例子和技巧,用于集成 CORBA 和 Enterprise JavaBeans 技術(shù):

          posted on 2005-02-04 11:28 jacky 閱讀(258) 評(píng)論(0)  編輯  收藏

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          <2025年5月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          常用鏈接

          留言簿(10)

          隨筆檔案

          文章分類

          文章檔案

          相冊(cè)

          收藏夾

          java

          搜索

          •  

          最新評(píng)論


          主站蜘蛛池模板: 资兴市| 祁门县| 资溪县| 淮安市| 嘉祥县| 易门县| 石家庄市| 嘉鱼县| 德格县| 南乐县| 信宜市| 成武县| 永春县| 海淀区| 秦安县| 乐昌市| 砀山县| 丹凤县| 绵阳市| 泰来县| 基隆市| 肇庆市| 柯坪县| 全州县| 刚察县| 石景山区| 永福县| 称多县| 大兴区| 张家口市| 临桂县| 桂平市| 凤冈县| 蓝田县| 兴和县| 林甸县| 车险| 余庆县| 潢川县| 合肥市| 烟台市|