JavaDemo——探索CORBA的IDL与Java的应用

最近接触了一个C++项目,里面有个以.idl后缀的文件,于是查阅了一下,发现是CORBA技术的一部分,一个十分古老的技术,用作远程调用,现在都很少接触到,能查阅的资料也不是很多,后来发现java也支持这个技术,探索下做个笔记;

IDL(Interface description language)文件可以用idlj.exe转化成java文件,以供java调用,idlj.exe命令在jdk的bin目录下(jdk7到jdk10都有,jdk11移除了);

idlj.exe用法:

编译器用法:

    java com.sun.tools.corba.se.idl.toJavaPortable.Compile [选项] <idl 文件>

其中, <idl 文件> 是包含 IDL 定义的文件的名称, 而
[选项] 是下列选项的任意组合。选项
是可选的, 并且显示顺序并不固定; <idl 文件> 是必需的,
并且必须显示在最后。

选项:
-d <符号>               这等同于 IDL 文件中的
                          下面一行:  #define <符号>
-emitAll                  发出所有类型, 包括在 #included 文件中找到的类型。
-f<side>                  定义要发出哪些绑定。<side> 是 client,
                          server, all, serverTIE, allTIE 之一。serverTIE 和 allTIE
                          导致发出委派模型骨架。如果未使用
                          此标记, 将假定为 -fclient。
-i <包含路径>         默认情况下, 将在当前目录中扫描
                          包含的文件。此选项将添加另一个目录。
-keep                     如果要生成的文件已存在, 请不要
                          覆盖它。默认情况下会覆盖它。
-noWarn                   隐藏警告。
-oldImplBase              生成与旧版 (1.4 版之前) JDK ORB 兼容的骨架。
-pkgPrefix <t> <前缀>   当在文件范围内遇到类型或模块名 <t> 时,
                          在为 <t> 生成的所有文件的 Java 程序包名前
                          添加 <前缀>。
-pkgTranslate <t> <pkg>   当遇到类型或模块名 <t> 时, 在
                          生成的 Java 程序包中将其替换为 <pkg>。请注意,
                          将首先进行 pkgPrefix 更改。<t> 必须与
                          完整程序包名完全匹配。另外, <t> 不能为
                          org, org.omg 或 org.omg 的任何子程序包。
-skeletonName <xxx%yyy>   根据模式命名骨架。
                          默认值为:
                          %POA 表示 POA 基类 (-fserver 或 -fall)
                          _%ImplBase 表示 oldImplBase 基类
                          (-oldImplBase 和 (-fserver 或 -fall))。
-td <dir>                 使用 <dir> 表示输出目录以代替
                          当前目录。
-tieName <xxx%yyy>        根据模式命名 tie。默认值为:
                          %POATie 表示 POA tie (-fserverTie 或 -fallTie)
                          %_Tie 表示 oldImplBase tie
                          (-oldImplBase 和 (-fserverTie 或 -fallTie))。
-v, -verbose              详细模式。
-version                  显示版本号并退出。

还有个-fall参数比较重要(不知道为啥上面没介绍这个参数),-fall参数可以同时生成客户端和服务端代码,默认只生成客户端代码;

idl文件大概是这个样子:(module对应java的包路径,interface对应java的接口)(同样也用/*注释*/和//注释)

使用idlj命令生成:

生成这么多java类:

编程直接用到的类有接口类(用于接收接口引用)、Helper类(获取远程引用)、POA类(服务端用于实现接口);

生成的源码:_MyIStub.java

package idlpkg.objspkg;


/**
* idlpkg/objspkg/_MyIStub.java .
* 由IDL-to-Java 编译器 (可移植), 版本 "3.2"生成
* 从./test.idl
* 2021年4月21日 星期三 上午10时58分30秒 CST
*/

public class _MyIStub extends org.omg.CORBA.portable.ObjectImpl implements idlpkg.objspkg.MyI
{

  public void test ()
  {
            org.omg.CORBA.portable.InputStream $in = null;
            try {
                org.omg.CORBA.portable.OutputStream $out = _request ("test", true);
                $in = _invoke ($out);
                return;
            } catch (org.omg.CORBA.portable.ApplicationException $ex) {
                $in = $ex.getInputStream ();
                String _id = $ex.getId ();
                throw new org.omg.CORBA.MARSHAL (_id);
            } catch (org.omg.CORBA.portable.RemarshalException $rm) {
                test (        );
            } finally {
                _releaseReply ($in);
            }
  } // test

  // Type-specific CORBA::Object operations
  private static String[] __ids = {
    "IDL:idlpkg/objspkg/MyI:1.0"};

  public String[] _ids ()
  {
    return (String[])__ids.clone ();
  }

  private void readObject (java.io.ObjectInputStream s) throws java.io.IOException
  {
     String str = s.readUTF ();
     String[] args = null;
     java.util.Properties props = null;
     org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init (args, props);
   try {
     org.omg.CORBA.Object obj = orb.string_to_object (str);
     org.omg.CORBA.portable.Delegate delegate = ((org.omg.CORBA.portable.ObjectImpl) obj)._get_delegate ();
     _set_delegate (delegate);
   } finally {
     orb.destroy() ;
   }
  }

  private void writeObject (java.io.ObjectOutputStream s) throws java.io.IOException
  {
     String[] args = null;
     java.util.Properties props = null;
     org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init (args, props);
   try {
     String str = orb.object_to_string (this);
     s.writeUTF (str);
   } finally {
     orb.destroy() ;
   }
  }
} // class _MyIStub

生成的源码:MyI.java

package idlpkg.objspkg;


/**
* idlpkg/objspkg/MyI.java .
* 由IDL-to-Java 编译器 (可移植), 版本 "3.2"生成
* 从./test.idl
* 2021年4月21日 星期三 上午10时58分30秒 CST
*/

public interface MyI extends MyIOperations, org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity 
{
} // interface MyI

生成的源码:MyIHelper.java

package idlpkg.objspkg;


/**
* idlpkg/objspkg/MyIHelper.java .
* 由IDL-to-Java 编译器 (可移植), 版本 "3.2"生成
* 从./test.idl
* 2021年4月21日 星期三 上午10时58分30秒 CST
*/

abstract public class MyIHelper
{
  private static String  _id = "IDL:idlpkg/objspkg/MyI:1.0";

  public static void insert (org.omg.CORBA.Any a, idlpkg.objspkg.MyI that)
  {
    org.omg.CORBA.portable.OutputStream out = a.create_output_stream ();
    a.type (type ());
    write (out, that);
    a.read_value (out.create_input_stream (), type ());
  }

  public static idlpkg.objspkg.MyI extract (org.omg.CORBA.Any a)
  {
    return read (a.create_input_stream ());
  }

  private static org.omg.CORBA.TypeCode __typeCode = null;
  synchronized public static org.omg.CORBA.TypeCode type ()
  {
    if (__typeCode == null)
    {
      __typeCode = org.omg.CORBA.ORB.init ().create_interface_tc (idlpkg.objspkg.MyIHelper.id (), "MyI");
    }
    return __typeCode;
  }

  public static String id ()
  {
    return _id;
  }

  public static idlpkg.objspkg.MyI read (org.omg.CORBA.portable.InputStream istream)
  {
    return narrow (istream.read_Object (_MyIStub.class));
  }

  public static void write (org.omg.CORBA.portable.OutputStream ostream, idlpkg.objspkg.MyI value)
  {
    ostream.write_Object ((org.omg.CORBA.Object) value);
  }

  public static idlpkg.objspkg.MyI narrow (org.omg.CORBA.Object obj)
  {
    if (obj == null)
      return null;
    else if (obj instanceof idlpkg.objspkg.MyI)
      return (idlpkg.objspkg.MyI)obj;
    else if (!obj._is_a (id ()))
      throw new org.omg.CORBA.BAD_PARAM ();
    else
    {
      org.omg.CORBA.portable.Delegate delegate = ((org.omg.CORBA.portable.ObjectImpl)obj)._get_delegate ();
      idlpkg.objspkg._MyIStub stub = new idlpkg.objspkg._MyIStub ();
      stub._set_delegate(delegate);
      return stub;
    }
  }

  public static idlpkg.objspkg.MyI unchecked_narrow (org.omg.CORBA.Object obj)
  {
    if (obj == null)
      return null;
    else if (obj instanceof idlpkg.objspkg.MyI)
      return (idlpkg.objspkg.MyI)obj;
    else
    {
      org.omg.CORBA.portable.Delegate delegate = ((org.omg.CORBA.portable.ObjectImpl)obj)._get_delegate ();
      idlpkg.objspkg._MyIStub stub = new idlpkg.objspkg._MyIStub ();
      stub._set_delegate(delegate);
      return stub;
    }
  }

}

生成的源码:MyIHolder.java

package idlpkg.objspkg;

/**
* idlpkg/objspkg/MyIHolder.java .
* 由IDL-to-Java 编译器 (可移植), 版本 "3.2"生成
* 从./test.idl
* 2021年4月21日 星期三 上午10时58分30秒 CST
*/

public final class MyIHolder implements org.omg.CORBA.portable.Streamable
{
  public idlpkg.objspkg.MyI value = null;

  public MyIHolder ()
  {
  }

  public MyIHolder (idlpkg.objspkg.MyI initialValue)
  {
    value = initialValue;
  }

  public void _read (org.omg.CORBA.portable.InputStream i)
  {
    value = idlpkg.objspkg.MyIHelper.read (i);
  }

  public void _write (org.omg.CORBA.portable.OutputStream o)
  {
    idlpkg.objspkg.MyIHelper.write (o, value);
  }

  public org.omg.CORBA.TypeCode _type ()
  {
    return idlpkg.objspkg.MyIHelper.type ();
  }

}

生成的源码:MyIOperations.java

package idlpkg.objspkg;


/**
* idlpkg/objspkg/MyIOperations.java .
* 由IDL-to-Java 编译器 (可移植), 版本 "3.2"生成
* 从./test.idl
* 2021年4月21日 星期三 上午10时58分30秒 CST
*/

public interface MyIOperations 
{
  void test ();
} // interface MyIOperations

生成的源码:MyIPOA.java

package idlpkg.objspkg;


/**
* idlpkg/objspkg/MyIPOA.java .
* 由IDL-to-Java 编译器 (可移植), 版本 "3.2"生成
* 从./test.idl
* 2021年4月21日 星期三 上午10时58分30秒 CST
*/

public abstract class MyIPOA extends org.omg.PortableServer.Servant
 implements idlpkg.objspkg.MyIOperations, org.omg.CORBA.portable.InvokeHandler
{

  // Constructors

  private static java.util.Hashtable _methods = new java.util.Hashtable ();
  static
  {
    _methods.put ("test", new java.lang.Integer (0));
  }

  public org.omg.CORBA.portable.OutputStream _invoke (String $method,
                                org.omg.CORBA.portable.InputStream in,
                                org.omg.CORBA.portable.ResponseHandler $rh)
  {
    org.omg.CORBA.portable.OutputStream out = null;
    java.lang.Integer __method = (java.lang.Integer)_methods.get ($method);
    if (__method == null)
      throw new org.omg.CORBA.BAD_OPERATION (0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);

    switch (__method.intValue ())
    {
       case 0:  // idlpkg/objspkg/MyI/test
       {
         this.test ();
         out = $rh.createReply();
         break;
       }

       default:
         throw new org.omg.CORBA.BAD_OPERATION (0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);
    }

    return out;
  } // _invoke

  // Type-specific CORBA::Object operations
  private static String[] __ids = {
    "IDL:idlpkg/objspkg/MyI:1.0"};

  public String[] _all_interfaces (org.omg.PortableServer.POA poa, byte[] objectId)
  {
    return (String[])__ids.clone ();
  }

  public MyI _this() 
  {
    return MyIHelper.narrow(
    super._this_object());
  }

  public MyI _this(org.omg.CORBA.ORB orb) 
  {
    return MyIHelper.narrow(
    super._this_object(orb));
  }


} // class MyIPOA

 

IDL数据类型到java的映射:

1、整数类型:

short,2字节,对应java的short;

long,4字节,对应java的int;

long long,8字节,对应java的long;

这3个类型都有unsigned类型,对java内部好像影响不大(但Helper类里还是会区分有无符号);

2、浮点数类型:

float,跟java一致;

double,跟java一致;

long double,似乎java不支持;

3、字符和超大字符类型:

char,映射为java的char;

wchar,映射为java的char;

在java内部都映射为char,Helper类里有区分;

4、逻辑类型:

boolean,只有true和false,跟java一致;

5、位类型:

octet,传输过程中不会转换高低位,映射为java的byte;

6、any类型:

any,任意类型,映射为java的org.omg.CORBA.Any对象;

注意:以上6个类型不能直接定义在module下;

 

关于typedef关键字,用于定义一个新的类型;

 

7、枚举类型

enum,对应java里的一个类;

只生成3个文件

注意:枚举里不能为空的,枚举内超过232也能编译成java类;

8、结构类型

struct,映射为java类,类似javabean功能;

注意:如果struct定义在interface里面,会以“interface名字+Package”为包名定义该struct生成的类;

9、联合类型

union和switch,

根据switch的匹配确定union里存储的数据类型,一个case里只能有一个字段,switch()里需要是整形、char、boolean、enum类型;

package idlpkg.objspkg;


/**
* idlpkg/objspkg/MyU.java .
* 由IDL-to-Java 编译器 (可移植), 版本 "3.2"生成
* 从./test.idl
* 2021年4月21日 星期三 下午02时53分29秒 CST
*/

public final class MyU implements org.omg.CORBA.portable.IDLEntity
{
  private int ___a;
  private short ___b;
  private char ___c;
  private int __discriminator;
  private boolean __uninitialized = true;

  public MyU ()
  {
  }

  public int discriminator ()
  {
    if (__uninitialized)
      throw new org.omg.CORBA.BAD_OPERATION ();
    return __discriminator;
  }

  public int a ()
  {
    if (__uninitialized)
      throw new org.omg.CORBA.BAD_OPERATION ();
    verifya (__discriminator);
    return ___a;
  }

  public void a (int value)
  {
    __discriminator = 1;
    ___a = value;
    __uninitialized = false;
  }

  public void a (int discriminator, int value)
  {
    verifya (discriminator);
    __discriminator = discriminator;
    ___a = value;
    __uninitialized = false;
  }

  private void verifya (int discriminator)
  {
    if (discriminator != 1)
      throw new org.omg.CORBA.BAD_OPERATION ();
  }

  public short b ()
  {
    if (__uninitialized)
      throw new org.omg.CORBA.BAD_OPERATION ();
    verifyb (__discriminator);
    return ___b;
  }

  public void b (short value)
  {
    __discriminator = 2;
    ___b = value;
    __uninitialized = false;
  }

  public void b (int discriminator, short value)
  {
    verifyb (discriminator);
    __discriminator = discriminator;
    ___b = value;
    __uninitialized = false;
  }

  private void verifyb (int discriminator)
  {
    if (discriminator != 2)
      throw new org.omg.CORBA.BAD_OPERATION ();
  }

  public char c ()
  {
    if (__uninitialized)
      throw new org.omg.CORBA.BAD_OPERATION ();
    verifyc (__discriminator);
    return ___c;
  }

  public void c (char value)
  {
    __discriminator = -2147483648;
    ___c = value;
    __uninitialized = false;
  }

  public void c (int discriminator, char value)
  {
    verifyc (discriminator);
    __discriminator = discriminator;
    ___c = value;
    __uninitialized = false;
  }

  private void verifyc (int discriminator)
  {
    if (discriminator == 1 || discriminator == 2)
      throw new org.omg.CORBA.BAD_OPERATION ();
  }

} // class MyU

 注意:case列出所有可能的值的时候不可使用default;(boolean只有TRUE和FALSE,枚举也是又穷个)

10、数组类型

数组需要指定大小,Helper里会有使用这个大小设定;

数组单独使用需要用typedef指定,或者用在struct、union里;

使用typedef只生成了两个文件

11、序列类型

sequence,可以指定大小也可以不指定大小,会映射成java的数组;

string,字符串,表示char序列,映射成java的string;

wstring,字符串,表示wchar序列,映射成java的string;(Helper里区分string和wstring)

12、异常类型

exception,定义用户自己的异常,使用raises指定要抛出的异常,多个异常用逗号隔开,会映射成java的一个final类;

 

关于常量:

使用const关键字定义常量,不能用于any和用户自定义类型,可使用整形,浮点,字符,字符串,boolean,octet;

注意:在module下定义的const变量会映射为java的一个接口,在interface里定义的const变量会映射为接口里的常量;

关于接口继承:

使用英文冒号来继承接口;

关于interface的attribute:

interface里除了有接口方法外还可以有attribute属性,会生成两个方法,一个用于获取属性一个用于设定属性;

关于attribute的readonly:

只会生成一个读取属性的方法;

关于接口内方法的参数:

参数需要带上in,out,inout说明之一;

in参数,用于客户端将实参传给服务端,服务端修改不会影响客户端;

out参数,用于服务端返回数据给客户端,服务端收到的参数只是参数的初始化值;(除了函数的返回值,参数也可返回数据)

inout参数,服务端会收到客户端的实参,并且修改后会返回给客户端;

in的参数直接就是参数类型,out和inout参数是Holder类,Holder类的value属性才是参数类型;

在in参数里,服务端实现的方法里直接就能获得参数的各种数据;

在out参数里,服务端获得的holder.value的值是默认值null,赋值时直接使用“holder.value=新值;”,客户端调用完方法后传入的holder参数的value已经指向新的地址了(里面包含了服务端返回的数据);

在inout参数里,服务端能获得客户端传来的数据,也能通过修改数据使客户端数据发生变化;

关于oneway修饰的方法:

oneway修饰的方法为单向方法,单向方法必须: 返回空值; 只有 in 参数; 不引发异常错误;

关于接口里方法使用不同module里结构的情况:

能识别接口同级和上级的module(识别不到module里的内容)和struct,识别不到需要通过可以识别的module和::符号指定位置;

关于相同名称的问题:

会从最近的位置开始向上找,找到则停止,指定module的时候要确保找到的该module位置下的资源存在,或者指定一个更上级的唯一的module往下指定;

 

完整小Demo:

使用idl整体过程:

1、写idl文件,并编译成java代码;

2、启动orbd服务;(位于jdk/bin下的orbd.exe,启动参数:orbd.exe -ORBInitialPort xxxx -ORBInitialHost xxx.xxx.xxx.xxx)

3、服务端:继承POA抽象类实现方法,获得ORB,获得rootPOA并激活manager,通过Helper和接口实现拿到远端引用,获得上下文,通过上下文将name和引用绑定,运行ORB;

4、客户端:获得ORB,获得上下文,通过上下文和name获得引用,传参调用方法;

编写idl文件:

module idlpkg{
	module interfacepkg{
		struct Rectangle{
			long width;
			long height;
			long area;
		};
		interface MyIdlInterface{
			boolean isSquare(in Rectangle r);
			Rectangle getRectangle(out Rectangle r, in long w, in long h);
			long getsetArea(inout Rectangle r);
		};
	};
};

生成java代码:

将生成的代码copy到我的eclipse里;

编写接口的实现类:MyIdlImpl.java

/**
 * 2021年4月21日下午6:10:28
 */
package test;

import idlpkg.interfacepkg.MyIdlInterfacePOA;
import idlpkg.interfacepkg.Rectangle;
import idlpkg.interfacepkg.RectangleHolder;

/**
 * @author XWF
 *
 */
public class MyIdlImpl extends MyIdlInterfacePOA {

	@Override
	public boolean isSquare(Rectangle r) {
		System.out.println("\n===function isSquare run.(in)===");
		int w = r.width;
		int h = r.height;
		System.out.println("server receive: r.width=" + w);
		System.out.println("server receive: r.height=" + h);
		return w == h;
	}

	@Override
	public Rectangle getRectangle(RectangleHolder r, int w, int h) {
		System.out.println("\n===function getRectangle run.(out)===");
		System.out.println("server receive: r.value=" + r.value);
		Rectangle rec = new Rectangle(w, h, w * h);
		r.value = rec;
		return rec;
	}

	@Override
	public int getsetArea(RectangleHolder r) {
		System.out.println("\n===function getsetArea run.(inout)===");
		System.out.println("server receive: r.value=" + r.value);
		int w = r.value.width;
		int h = r.value.height;
		System.out.println("server receive: r.value.width=" + w);
		System.out.println("server receive: r.value.height=" + h);
		System.out.println("server receive: r.value.area=" + r.value.area);
		int area = w * h;
		r.value.area = area;
		return area;
	}

}

编写服务端:IDLServer.java

/**
 * 2021年4月21日下午6:08:49
 */
package test;

import java.util.Properties;

import org.omg.CORBA.ORB;
import org.omg.CORBA.ORBPackage.InvalidName;
import org.omg.CosNaming.NamingContextExt;
import org.omg.CosNaming.NamingContextExtHelper;
import org.omg.CosNaming.NamingContextPackage.CannotProceed;
import org.omg.CosNaming.NamingContextPackage.NotFound;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.POAHelper;
import org.omg.PortableServer.POAManagerPackage.AdapterInactive;
import org.omg.PortableServer.POAPackage.ServantNotActive;
import org.omg.PortableServer.POAPackage.WrongPolicy;

import idlpkg.interfacepkg.MyIdlInterface;
import idlpkg.interfacepkg.MyIdlInterfaceHelper;

/**
 * @author XWF
 *
 */
public class IDLServer {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.println("server starting...");
		//初始化ORB
		Properties prop = new Properties();
		prop.put("org.omg.CORBA.ORBInitialHost", "192.168.1.181");
		prop.put("org.omg.CORBA.ORBInitialPort", "4321");
		ORB orb = ORB.init(args, prop);
		
		//设定10s后服务停止
		new Thread(() -> {
			try {
				Thread.sleep(10 * 1000);
				orb.destroy();
				System.out.println("orb destroyed.");
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}).start();
		
		try {
			//通过ORB获得rootpoa并激活POAmanager
			POA rootpoa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
			rootpoa.the_POAManager().activate();
			//接口的实现
			MyIdlImpl myIdlImpl = new MyIdlImpl();
			//获得远端接口引用
			MyIdlInterface ref = MyIdlInterfaceHelper.narrow(rootpoa.servant_to_reference(myIdlImpl));
			//获得上下文
			NamingContextExt context = NamingContextExtHelper.narrow(orb.resolve_initial_references("NameService"));
			//绑定
//			ncext.bind(path, helloRef);
			context.rebind(context.to_name("testidl"), ref);
			
			System.out.println("server started wait....");
			//运行orb
			orb.run();
		} catch (InvalidName e) {
			e.printStackTrace();
		} catch (AdapterInactive e) {
			e.printStackTrace();
		} catch (ServantNotActive e) {
			e.printStackTrace();
		} catch (WrongPolicy e) {
			e.printStackTrace();
		} catch (org.omg.CosNaming.NamingContextPackage.InvalidName e) {
			e.printStackTrace();
		} catch (NotFound e) {
			e.printStackTrace();
		} catch (CannotProceed e) {
			e.printStackTrace();
//		} catch (AlreadyBound e) {
//			e.printStackTrace();
		}
		
		System.out.println("server stoped...");
	}

}

编写客户端:IDLClient.java

/**
 * 2021年4月21日下午6:09:03
 */
package test;

import java.util.Properties;

import org.omg.CORBA.ORB;
import org.omg.CORBA.Object;
import org.omg.CORBA.ORBPackage.InvalidName;
import org.omg.CosNaming.NamingContextExt;
import org.omg.CosNaming.NamingContextExtHelper;
import org.omg.CosNaming.NamingContextPackage.CannotProceed;
import org.omg.CosNaming.NamingContextPackage.NotFound;

import idlpkg.interfacepkg.MyIdlInterface;
import idlpkg.interfacepkg.MyIdlInterfaceHelper;
import idlpkg.interfacepkg.Rectangle;
import idlpkg.interfacepkg.RectangleHolder;

/**
 * @author XWF
 *
 */
public class IDLClient {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.println("client starting...");
		//初始化ORB
		Properties prop = new Properties();
		prop.put("org.omg.CORBA.ORBInitialHost", "192.168.1.181");
		prop.put("org.omg.CORBA.ORBInitialPort", "4321");
		ORB orb = ORB.init(args, prop);
		
		try {
			//获得上下文
			Object objRef = orb.resolve_initial_references("NameService");
			NamingContextExt context = NamingContextExtHelper.narrow(objRef);
			//获得上下文中引用
//			MyIdlInterface myIdlInterface = MyIdlInterfaceHelper.narrow(context.resolve(context.to_name("testidl")));
			MyIdlInterface myIdlInterface = MyIdlInterfaceHelper.narrow(context.resolve_str("testidl"));
			
			System.out.println("=====================");
//			RectangleHolder holder = new RectangleHolder();
			RectangleHolder holder = new RectangleHolder(new Rectangle(100, 100, 0));//即使设置了服务端也收不到(idl参数为out类型)
			System.out.println("holder.value=" + holder.value);
			Rectangle result = myIdlInterface.getRectangle(holder, 2, 4);
			System.out.println("result:" + result);
			System.out.println("result:width=" + result.width + ";height=" + result.height + ";area=" + result.area);
			System.out.println("holder.value:" + holder.value);
			System.out.println("holder.value:w=" + holder.value.width + ";h=" + holder.value.height + ";a=" + holder.value.area);
			
			System.out.println("=====================");
			System.out.println("result isSquare:" + myIdlInterface.isSquare(result));
			System.out.println("new isSquare:" + myIdlInterface.isSquare(new Rectangle(3, 3, 9)));
			
			System.out.println("=====================");
			Rectangle r = new Rectangle(10, 10, -1);
			RectangleHolder h = new RectangleHolder(r);
			System.out.println("h.value.area=" + h.value.area);
			System.out.println("result:" + myIdlInterface.getsetArea(h));
			System.out.println("h.value.area:" + h.value.area);
		} catch (InvalidName e) {
			e.printStackTrace();
		} catch (NotFound e) {
			e.printStackTrace();
		} catch (CannotProceed e) {
			e.printStackTrace();
		} catch (org.omg.CosNaming.NamingContextPackage.InvalidName e) {
			e.printStackTrace();
		}
		
		System.out.println("client stoped...");
	}

}

启动orbd服务,我在虚拟机里用jdk8的orbd服务,虚拟机ip是192.168.1.181,使用4321端口;(应该是服务端和客户端都通过这个orbd服务交互数据)

启动服务端,启动客户端运行结果:

大概就探索了这么点东西;

 

 

 

 

 

 

 

 

 

参考:https://docs.oracle.com/javase/8/docs/technotes/guides/idl/jidlExample2.html

https://blog.csdn.net/zacklin/article/details/8207673

https://blog.csdn.net/casularm/article/details/92266

https://blog.csdn.net/weiwangchao_/article/details/6990697

https://blog.csdn.net/anlian523/article/details/98476033

https://blog.csdn.net/weixin_30256901/article/details/98234799

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值