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.ice。ICE將自動將其編譯成.java檔案。(參見注釋1)
3。取所有生成的java
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
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]
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.4之Java 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相關工作,還是非常有前景的。