`
loyalbluer
  • 浏览: 41416 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

ICE入门

阅读更多
转载自:http://joeywanghome.spaces.live.com/blog/cns!ddf8393aef49368b!163.entry?wa=wsignin1.0&sa=984310076
只为自己日后翻阅方便,不做他用,特此声明
ICE初始用之经验教训

这个项目涉及两种语言,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才会生效。


但是实践是无情的,不论我怎么搞,WASP这个包始终必须放在class的跟目录下,即src目录下面,否则他就报错。真TMD服了它了!!谁要是知道麻烦教教我,谢谢啊。

 

注释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入门例子

    **Ice入门例子详解** Ice(又称为ZeroC Ice)是一种高性能、跨平台的分布式对象中间件,它提供了灵活、安全的远程过程调用(RPC)框架。本篇将基于提供的"ice入门例子"进行深入讲解,帮助初学者理解Ice的基本概念、...

    ICE入门文档

    《ICE入门文档》是针对ICE通信中间件的一份详尽指南,由Michi Henning和Mark Spruiell等人编著,并由马维达翻译。ICE(Internet Communications Engine)是一种分布式程序设计工具,它允许开发者构建跨平台、高性能...

    ice入门例子2

    这是继ice入门例子的第二个例子,主要讲述Ice.Application与配置文件的简单使用 所需jar在lib中 这个例子中集成了日志插件,在服务器启动时,该插件会工作一次, 文件名:config.server 服务端配置文件 #配置...

    Ice入门完整实例

    【Ice入门完整实例】是一个针对初学者的教程,旨在引导用户了解并掌握Ice中间件的基本用法和开发流程。在本实例中,我们将深入探讨Ice,一个强大的分布式对象框架,它提供了一种高效的、跨平台的方式来构建分布式...

    ice ppt ice 入门文档

    这个“ice ppt ice 入门文档”很显然是针对初学者设计的,旨在帮助他们理解并掌握ICE的基本概念和使用方法。下面我们将深入探讨ICE的相关知识点。 1. **ICE简介**:ICE是由ZeroC公司开发的,它提供了丰富的接口,...

    中间件技术:ice 入门介绍

    **中间件技术:ICE 入门介绍** ICE(Internet Communications Engine)是一种专为现实世界中的程序员设计的中间件平台,其目标是提供一种高性能、高效且功能强大的互联网通信解决方案。ICE 不仅包含了丰富的分层...

    ICE入门指南-分布式开发

    【ICE入门指南-分布式开发】 本文档是一份简明易懂的ICE(Internet Communication Engine)入门教程,旨在帮助初学者快速掌握ICE的使用方法,包括如何设置开发环境、配置编译参数以及创建并运行基本的分布式应用...

    zeroc ice教程 ice环境配置 Ice中文教程 C++ ICE java ICE ICE入门 ice基础教程 ice开发文档

    Zeroc ICE是一个开源的中间件平台,它支持C++、Java、Python、.NET等语言的分布式对象通信。ICE全称Internet Communications Engine,即互联网通信引擎,是一种用于开发分布式计算应用的强大工具。本文档主要围绕ICE...

    ICE入门 文章集

    《HelloWorld_ICE分布式应用开发入门_MichiHenning.pdf》这篇文章很可能是介绍ICE的基础知识,包括如何安装ICE,以及通过一个简单的"Hello, World!"程序来演示ICE的基本用法。开发者Michi Henning可能会讲解ICE的...

    ICE入门代码

    在这个“ICE入门代码”中,我们可以深入理解ICE的基本概念和使用方法。 首先,让我们了解一下ICE的核心特性: 1. **对象透明性**:ICE支持远程对象调用,就像调用本地对象一样简单,隐藏了网络通信的复杂性。 2. **...

    ice入门教程(马达维译)

    ice入门教程 - 马达维译 很经典的ice教程,完全版

    ICE入门教程

    讲述了ice详细的部署过程,让新手从0开始

    Ice 经典入门和实例

    总的来说,"Ice经典入门和实例"是一套完整的学习资料,涵盖了Ice的基本概念、核心功能、高级特性和实战应用,对于想要掌握这个分布式对象中间件的开发者来说,是非常宝贵的资源。通过深入学习和实践,你将能熟练地...

    zero ICE快速入门java版

    zero ICE快速入门文档, ice是最优秀的rpc框架。 4、开发服务端代码如下 步骤一:编写Servant类即带有Disp的存根文件也就是说继承_HelloWorldDisp 这个类,这个类是个抽象类定义如下: public abstract class _...

    zeroc ICE 教程

    标题《zeroc ICE 教程》所...综上所述,这份文档是一个全面的ICE入门教程,涉及了从基础概念到实际应用,再到编程语言映射的方方面面。通过这个教程,开发者可以学习到如何利用ICE技术,实现在分布式环境中的有效通信。

    ICE介绍与开发入门.pdf

    ### ICE介绍与开发入门 #### 一、ICE概述 ##### 1.1 什么是ICE ICE(Internet Communications Engine)是一款由ZeroC公司开发的高性能、跨平台、支持多种编程语言的中间件产品。ICE主要用于构建分布式应用程序,...

    HelloWorld_ICE分布式应用开发入门

    ### HelloWorld_ICE分布式应用开发入门 #### 概述 本文旨在通过一个简单的示例来介绍如何使用ICE(Internet Communications Engine)进行分布式应用开发。ICE是一种强大的中间件框架,用于构建可扩展、健壮且高...

    ICE例子(非常简单,使大家方便入门)

    总的来说,"ICE例子(非常简单,使大家方便入门)"是一个很好的起点,通过它,初学者可以快速掌握ICE的基本用法,并逐步深入到更复杂的分布式系统开发中去。记住,实践是检验知识的最好方式,动手尝试并不断调试,你...

    Ubuntu-zeroc-ice 环境安装

    在Ubuntu系统上安装Zeroc-ICE环境主要涉及以下知识点: ...安装Zeroc-ICE是进行相关开发或者搭建分布式系统的前提,因此对于想要在Ubuntu环境下利用Zeroc-ICE进行开发的用户来说,这些步骤是入门级别的必要知识。

    ice同步demo

    【描述】"简单入门的ICE同步学习demo,适合新手入门"表明这个压缩包包含了一个基础的示例项目,用于教学如何在ICE框架下实现同步通信。对于初学者来说,通过这个demo可以了解ICE的基础概念,包括对象代理、调用模式...

Global site tag (gtag.js) - Google Analytics