首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 互联网 >

(转载)ICE 初步用之java经验教训例子

2013-06-25 
(转载)ICE 初始用之java经验教训例子转载自:http://joeywanghome.spaces.live.com/blog/cns!ddf8393aef493

(转载)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文件到本地,放到相应的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进行查看。?
mqq@dev_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就可以了。?

实在是奇怪啊。必须这么放才行!

热点排行