1. 程式人生 > >ICE 初始用之java經驗教訓例子

ICE 初始用之java經驗教訓例子

轉載自:http://joeywanghome.spaces.live.com/blog/cns!ddf8393aef49368b!163.entry?wa=wsignin1.0&sa=984310076 
只為自己日後翻閱方便,不做他用,特此宣告 

這個專案涉及兩種語言,c++和java。使用ICE中介軟體。其中有一部分就是java通過ICE呼叫後臺的由c++實 

現的函式。java端呼叫的過程是這樣的: 
1。定義好介面,檔案型別全部是*.ice檔案。(在這個專案中這部分是C++同志完成的) 
2。執行slice2java -I. XXX.iceICE將自動將其編譯成.java檔案。(參見注釋1) 
3。取所有生成的java

檔案到本地,放到相應的package裡面。(參見注釋2) 
4。把ICE.jar放在lib裡面。 
5。編譯java檔案,生成class。 
6。配置Config檔案,聯接ICE時使用。(參見注釋3) 
7。在自己的類裡面實現ICE呼叫。(參見注釋4) 
8。完成任務! 
其他問題(參見注釋5) 

在這一系列的過程中可能會出現很多問題,我將我在各個階段遇到的問題進行了一些總結,供參考: 

註釋1: 
直接執行slice2java wasptrans.ice。當時報了一大堆錯誤,例如: 
wasptrans.ice:7: No include path in which to find wasp.ice 
wasptrans.ice
:20: `FeeWay' is not defined 
wasptrans.ice:30: `UserInfo' is not defined 
wasptrans.ice:31: `ProductInfo' is not defined 
...... 
即找不到wasp.ice裡面定義的許多類。 
後來用slice2java -I. wasptrans.ice就可以解決這個問題。 “-I” 是告訴編譯器在編譯的時候要包含 

路徑,“.”指當前目錄。合在一起“-I.” 就相當於指定當前目錄也是其在編譯過程中查詢的路徑。還 

有其他多種引數可以在編譯的時候使用,可以用slice2java -h進行檢視。 
[email protected]
_bj_kevinzhao:~/wasp/interface$ slice2java -h 
Usage: slice2java [options] slice-files... 
Options: 
-h, --help              Show this message. 
-v, --version           Display the Ice version. 
-DNAME                  Define NAME as 1. 
-DNAME=DEF              Define NAME as DEF. 
-UNAME                  Remove any definition for NAME. 
-IDIR                   Put DIR in the include file search path. 
--output-dir DIR        Create files in the directory DIR. 
--tie                   Generate TIE classes. 
--impl                  Generate sample implementations. 
--impl-tie              Generate sample TIE implementations. 
--depend                Generate Makefile dependencies. 
-d, --debug             Print debug messages. 
--ice                   Permit `Ice' prefix (for building Ice source code only) 
--checksum CLASS        Generate checksums for Slice definitions into CLASS. 
--stream                Generate marshaling support for public stream API. 


註釋2 
生成的檔案數量會多的讓你嚇一大跳,我們這個專案中,我用到的一共是生成了200個java檔案。把生成的java檔案放在本地工程的package裡面,但是一定要注意,不能隨便亂放,隨便新建一個package,隨便起個名字,然後把java檔案放進去,這個是肯定不行的,因為在每個java檔案裡都有package,所以必須符合其package的路徑。同時,儘量不要修改java檔案裡面的package。因為在本地呼叫這些類的時候,代理類(也是ICE編譯時自動生成的)會根據當時編譯生成的package的路徑去找相應的class,如果你修改了A.java檔案開頭的package,而沒有修改其代理類裡面呼叫此A.class的路徑的話,那麼將來必然報錯。 
從開發的角度講,我們不需要研究究竟其內部是怎麼編譯生成這些java檔案的,也不需要研究這些class究竟是怎麼被使用的。我們只需要找到一個最快最簡單的途徑去實現我們的應用就可以了(當然有時間有興趣的情況下研究一下此過程還是很有好處的) 
那麼隨後檔案就產生了,java檔案裡面的package路徑是ICE自動生成的,我怎麼才能設定呢? 
設定package路徑有2種方式: 
1.通過在.ice裡面修改module的名字對其進行設定: 
我們開啟看.ice檔案。例如:wasptrans.ice,開頭部分: 
/* 
*業務邏輯處理介面 
*/ 
#ifndef __WASP_TRANS_STATEMENT_ICE_ 
#define __WASP_TRANS_STATEMENT_ICE_ 

#include <wasp.ice
module WASP 

..... 

其module的名字即WASP就是將來生成的java檔案的package的名字。如果在這裡直接編譯,那麼生成 

的.java裡面可以看到開頭的package都是 
package WASP; 
那麼相應的,我們就需要在自己的工程裡面在src的根目錄下面建一個package叫做WASP,然後把生成的java檔案全放進去進行編譯才可以保證不會出錯。但是一般大家都不會這麼安排package。 
可以通過修改module的名字實現package的改變。例如 
module com { 
module tencent { 
module wasp { 
   class Document { 
    // ... 
   }; 
}; 
}; 
}; 
這樣編譯出來的java檔案package就是 com.tencent.wasp了。 
但是這樣就帶了一個問題,那就是package滿足java的需求了,C++的就變了,C++在編譯的時候還要再進行修改,很不方便。這種情況可以使用方法2 

2.在.ice開投增加一段[["java:package:com.tencent.wasp.ice"]],即: 
/* 
*業務邏輯處理介面 
*/ 
#ifndef __WASP_TRANS_STATEMENT_ICE_ 
#define __WASP_TRANS_STATEMENT_ICE_ 

#include <wasp.ice
[["java:package:com.tencent.wasp.ice"]] 
module WASP 

..... 

這樣只有在編譯生成java檔案的時候package才會生效。 






註釋3: 
Config檔案例子: 

Ice.Default.Locator=IcePack/Locator:tcp -h 192.122.3.23 -p 11001 

IcePack.Registry.Client.Endpoints=tcp -h 192.122.3.23 -p 11001 
IcePack.Registry.Server.Endpoints=tcp -h 192.122.3.23 -p 11002 
IcePack.Registry.Internal.Endpoints=tcp -h 192.122.3.23 -p 11003 
IcePack.Registry.Admin.Endpoints=tcp -h 192.122.3.23 -p 11004 
IcePack.Registry.Data=db/registry 

IcePack.Node.Name=wasp 
IcePack.Node.Endpoints=tcp -h 192.122.3.23 -p 11005 
IcePack.Node.Data=db/node 
IcePack.Node.CollocateRegistry=1 

IcePack.Node.Trace.Activator=3 
IcePack.Node.Trace.Adapter=2 
IcePack.Node.Trace.Server=3 

IcePack.Node.Output=/usr/local/mqq/app/wasp/icepack/log 

Ice.Override.ConnectTimeout=5000 
Ice.Override.Timeout=5000 

Ice.UseSyslog=1 


聯接ICE代理類: 
package com.tencent.wasp.ice.proxy; 


import Ice.Communicator; 
import IcePack.QueryPrxHelper; 
import IcePack.QueryPrx; 
public class ICEProxy 


public final String sConfig = ICEProxy.class.getClassLoader(). 
getResource("com/tencent/wasp/ice/proxy/config").getFile(); 

/** 
* 根據輸入引數sc的引數得到Communciator物件 
* @param sConfig icepack配置檔案config的具體路徑 
* @return Communicator 
*/ 
public Communicator getComm(String sConfig) 

     String[] tmp ={"t"}; ///Ice.Util.initializeWithProperties方法引數,任意引數都可 

以 
     Communicator communicator = null; 
       try { 
           Ice.Properties properties = Ice.Util.createProperties(); 
           //System.out.println("Starting load");           
           properties.load(sConfig); 
           //System.out.println("end load"); 
           communicator = Ice.Util.initializeWithProperties(tmp, properties); 
           if (communicator == null) 
           { 
            System.out.println("ICE get Communicator by properties is 

null!!!!!!"); 
           } 
           
       } catch (Exception e) { 
           System.err.println(e.getMessage()); 
           System.out.println(e.toString()); 
         
       } 
       return communicator; 


public QueryPrx getQueryPrx( Communicator communicator ) 

QueryPrx query = null;        
        query = QueryPrxHelper.checkedCast(communicator.stringToProxy("IcePack/Query")); 
        if (query == null) 
        { 
         System.out.println("ICE get query by properties is null!!!!!!"); 
        } 
return query; 


public int destory(Communicator communicator) 

int result = 0; 
          try 
          { 
              communicator.destroy(); 
          } 
          catch(Ice.LocalException ex) 
          { 
              ex.printStackTrace(); 
              result = 1; 
          }       
return result; 



註釋4: 
在應用中呼叫ICE,為了測試方便,建議自己先寫一個獨立的類,在main中呼叫所有的介面進行除錯,這 

樣比在應用中去除錯方便的多,例如: 
package com.tencent.wasp.ice.proxy; 

import WASP.PlayerInfo; 
import WASP.wasptransPrx; 
import WASP.wasptransPrxHelper; 
import WASP.*; 
import Ice.Communicator; 
import Ice.ObjectPrx; 
import IcePack.QueryPrx; 


public class CallICE { 

/** 
* @param args 
*/ 
public static void main(String[] args) { 
// TODO Auto-generated method stub 

//呼叫ICE 
ICEProxy ice = new ICEProxy();   
QueryPrx query = null;   
Communicator com = ice.getComm(ice.sConfig);    
query = ice.getQueryPrx(com); 
try{ 
ObjectPrx base= (ObjectPrx) query.findObjectByType 

("::WASP::WaspTransTest");//在application.xml裡面定義         
wasptransPrx waspTrans1 = wasptransPrxHelper.checkedCast(base); 
//可以得到ice的wasptrans1代理了,自由使用wasptrans1物件 
int test[] = new int[1]; 
test[0] = 1; 
FluxInfo[] fluxInfo = waspTrans1.GetFluxInfo(test,1); 

PlayerInfo[] playerInfo =waspTrans1.GetVoteObjInfo(1,1); 

FluxInfo[] fluxInfo1 = waspTrans1.GetFluxInfos(1,1,0,0); 

IssuePart[] issuePartList = waspTrans1.GetIssuePartInfos 

(2,"1111111",1,0,0); 

IssueDetail[] issueDetailList = waspTrans1.GetIssuePartDetail 

(2,"222222",1,0,0); 

PlayerInfo PlayerInfoList[] = waspTrans1.GetVoteObjInfo(1,1); 

VotePart[] votePartList = waspTrans1.GetVotePartInfos 

(1,"333333",1,0,0); 

VoteDetail[] voteDetailList = waspTrans1.GetVotePartDetail 

(1,"444444",1,0,0); 

VoteDetail[] voteDetailList2 = waspTrans1.GetVotePartDetail 

(1,"5555555",2,0,0);     
VoteDetail[] voteDetailList3 = waspTrans1.GetVotePartDetail 

(1,"666666",3,0,0); 

}catch(Exception e){ 
   e.printStackTrace(System.out); 




註釋5: 
出現錯誤: 
IcePack.ObjectNotExistException 
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
at sun.reflect.NativeConstructorAccessorImpl.newInstance 

(NativeConstructorAccessorImpl.java:39) 
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance 

(DelegatingConstructorAccessorImpl.java:27) 
at java.lang.reflect.Constructor.newInstance(Constructor.java:274) 
at java.lang.Class.newInstance0(Class.java:308) 
at java.lang.Class.newInstance(Class.java:261) 
at IceInternal.BasicStream$DynamicUserExceptionFactory.createAndThrow 

(BasicStream.java:2011) 
at IceInternal.BasicStream.throwException(BasicStream.java:1413) 
at IcePack._QueryDelM.findObjectByType(_QueryDelM.java:143) 
at IcePack.QueryPrxHelper.findObjectByType(QueryPrxHelper.java:99) 
at IcePack.QueryPrxHelper.findObjectByType(QueryPrxHelper.java:84) 
at com.tencent.wasp.ice.proxy.CallICE.main(CallICE.java:41) 

呼叫方式: 
ObjectPrx base= (ObjectPrx) query.findObjectByType 

("::com.tencent.wasp.ice.WASP::WaspTransTest"); 

錯誤原因路徑不對:要看application.xml裡面是怎麼定義的路徑! 
在application.xml裡面是這樣寫的: 
<server name="wasptranstest" kind="cpp" exe="/home/joey/wasp/bin 
/WaspTransTest" activation="on-demand"> 
                <adapters> 
                    <adapter name="WaspTransAdapterTest" endpoints="tcp -h 192.1 
68.3.235 -p 20090" register="true"> 
                        <object identity="WaspTransTest" type="::WASP::WaspTrans 
Test"/> 
                    </adapter> 
                </adapters> 

                <properties> 
                    <property name="Adapter" value="WaspTransAdapterTest"/> 
                    <property name="Object" value="WaspTransTest"/> 
                    <property name="Identity" value="WaspTransTest"/> 
                    <property name="Config" value="/home/joey/wasp/conf/wasp 
transtest.conf"/> 
                </properties> 
            </server> 
所以修改為: 
ObjectPrx base= (ObjectPrx) query.findObjectByType("::WASP::WaspTransTest"); 



另一種錯誤: 

Ice.NoObjectFactoryException 
    reason = (null) 
    type = "::WASP::PlayerInfo" 


expected element of type com.tencent.wasp.ice.status.PlayerInfo but received Ice.ObjectImpl 



就是java檔案放的位置不對,放在根目錄下,即src/WASP/***.java就可以了。 

實在是奇怪啊。必須這麼放才行!

相關推薦

ICE 初始java經驗教訓例子

轉載自:http://joeywanghome.spaces.live.com/blog/cns!ddf8393aef49368b!163.entry?wa=wsignin1.0&sa=984310076 只為自己日後翻閱方便,不做他用,特此宣告 這個專案涉及兩種語言

別人的經驗教訓自己

畢業 進口 漲停 庫存 用料 四十 配方 事物 民生 01.我一個朋友開娛樂城的,最開始主要是經營KTV、看球賽、做生日PARTY、按摩什麽的,後來看到他人搞三陪服務很掙錢,於是就學別人這樣做,結果就出事兒了,2014年的一天,被100多個公安封了場地,還把他自己關進了,最

ElasticSearch2.3.4Java Api呼叫例子

ElasticSearch2.3.4 序號 覆蓋功能例子 1 客戶端連結初始化 2 filte無評分查詢用法 3 query有評分查詢用法 4 單欄位分組用法 5 多欄位分組用法 6 讀取有索引無儲存資料的用法 7 設定指定欄位返回 程式碼如下: package com.

Java面向對象例子(一)

顯示 人類 運算 例子 ble person 成員變量 年月日 pub 定義一個人類,給這個類定義一個從身份證獲取生日的方法,輸入身份證,獲取出生年月日 //主方法 package com.hanqi.maya.model; import java.util.Scanne

jvm系列學習--Java類的初始化順序

parent main方法 println () 類成員 -- sys div 開始 本文主要演示Java類的初始化順序 初始化順序 對於靜態變量、靜態初始化塊、變量、初始化塊、構造器,它們的初始化順序依次是(靜態變量、靜態初始化塊)>(變量、初始化塊)>構造器

關於百度地圖例子坑人的經驗教訓

rem 文件中 ins repo over 相關 百度地圖 dir include 先是把百度地圖API樣例下載來,折騰了幾天,總算編譯通過了。這時寫以下幾點註意的: 通過java或android studio提供的工具,生成SHA1,然後將SHA1填入你自己帳號的控制臺,

Tomcat筆記初始

Tomcat目錄結構 bin目錄 --存放程式指令碼檔案 重點關注指令碼檔案: startup.sh --啟動 shotdown.sh --停止 catalina.sh --啟動和停止都會呼叫該指令碼 conf目錄 --存放程式配置檔案 重點關注配置檔

Hbase的極限測試經驗java專案的jar包匯入

Hbase的極限測試的內容是把之前編過的網站的後臺資料庫改成hbase即可。 我很快就在hbase資料庫中建完表,也把關於操作資料庫的函式寫好了。 當我除錯時,發現在jsp中的操作資料庫的函式都不能用。 提示我與沒有找到與hbase的類,可是我當時已經通過Build Path的方式把與Hbase有關的所

設計模式觀察者-Java(簡單例子

1、定義:源於GOF的Design Patterns一書。 Define a one-to-many dependency between objects so that when oneobject changes state, all its dependents are notifie

java併發包學習系列:執行緒複執行緒池

什麼是執行緒池 頻繁使用new Thread來建立執行緒的方式並不太好。因為每次new Thread新建和銷燬物件效能較差,執行緒缺乏統一管理。好在Java提供了執行緒池,它能夠有效的管理、排程執行緒,避免過多的資源消耗。優點如下: 重用存在的執行緒,減少物

Java開發經驗分享JAVA簡單實現DES加密與實現DES解密

exc final secret for 操作 好的 16進制 subst ace 前言:相信很多小夥伴在開發過程中都會加密問題。當然,小菜在開發中也遇到了,這裏呢,小菜想說的是JAVA簡單實現DES加密。 今天就簡單實現一下如何DES加密解密。話不多說,代碼如下。直接可用

java多執行緒死鎖的例子

在java多執行緒編寫程式中特別害怕的一種情況就是死鎖,他會讓程式死在哪裡不在繼續執行下面就來看一個死鎖的例子: /** * 死鎖的例子 */ public class SiSuoTest

Java學習篇--Java的JDBC驅動程式實現與資料庫連線

用純Java的JDBC驅動程式實現與資料庫連線         最近在研究JAVA中資料庫的連線,將知識整理一下分享給大家:         Java程式可以用純Java的JDBC驅動程式實現與資料庫連線。這種方法應用較廣泛,但是需要下載相應的驅動程式包,因為不同的資

Linux IO多路複epoll網路程式設計,高併發的使用例子 (含原始碼)

#include <unistd.h> #include <sys/types.h> /* basic system data types */ #include <sys/socket.h> /* basic socket definiti

CQRS旅——旅程8(後記:經驗教訓)

旅程8:後記:經驗教訓 我們的地圖有多好?我們走了多遠?我們學到了什麼?我們迷路了嗎? “這片土地可能對那些願意冒險的人有益。”亨利.哈德遜 這一章總結了我們旅程中的發現。它強調了我們在這個過程中所學到的最重要的經驗教訓,提出瞭如果我們用新知識開始這段旅程,我們將以不同的方式做的一些事情,並指出了Conto

JVM 方法調動態分派

public super 1. 動態分派一個體現是重寫(override)。下面的代碼,運行結果很明顯。 1 public class App { 2 3 public static void main(String[] args) { 4 Super

jdk源碼閱讀筆記java集合框架(四)(LinkedList)

ray private array public 源碼閱讀 jdk源碼閱讀 oid color 解釋 關於LinkedList的分析,會從且僅從其添加(add)方法入手。 因為上一篇已經分析過ArrayList,相似的地方就不再敘述,關註點在LinkedList的特點。 屬

Java虛擬機Java內存區域

器) 輪換 .com 虛擬 解釋器 控制 虛擬機 關心 分配 Java虛擬機運行時數據區域 ⑴背景:對於c/c++來說程序員來說,需要經常去關心內存運行情況,但對於Java程序員,只需要在必要時關心內存運行情況,這是因為在Java虛擬機自動內存管理機制的幫助下,不再Ja

Android學習探索Java 8 在Android 開發中的應用

相關 概念 容易 並不是 min etc bstr trac flavor 前言: Java 8推出已經將近2年多了,引入很多革命性變化,加入了函數式編程的特征,使基於行為的編程成為可能,同時減化了各種設計模式的實現方式,是Java有史以來最重要的更新。但是Androi

Java Killer系列Java經典面試套路講解

Java Killer系列之Java經典面試套路講解 java編程語言是目前應用較為廣泛的一門計算機編程語言,目前java市場需求量有增無減。java作為目前IT軟件開發行業的重要技術之一,人才市場出現大量缺口,所以從事java相關工作,還是非常有前景的。