『转贴』比较Eclipse与Mozilla中的COM/XPCOM Java Wrapper技术

『转贴』比较Eclipse与Mozilla中的COM/XPCOM Java Wrapper技术
http://liumspace.spaces.live.com/blog/cns!bc24129fc2e42afd!122.entry

JavaXPCOM

JavaXPCOM基于一套与Eclipse SWT不同的思路。在JavaXPCOM中,每一个XPCOM interface有一个对应的Java interface,注意这里是Java interface,而不是Java class。那么,在JavaXPCOM中怎么生成一个XPCOM对象的Java wrapper呢?在JavaXPCOM中,巧妙地使用了reflection。对每一个XPCOM对象,会生成一个 Proxy 来作为Java wrapper,这个Proxy对象实现XPCOM对象所实现的interface。然后这个Proxy把Java interface中的方法调用再delegate到一个JavaXPCOM提供的 XPCOMJavaProxy(实现 InvocationHandler)上。

这 里有几个问题:1。系统根据一个XPCOM对象的指针,怎么知道这个XPCOM对象实现了什么XPCOM接口?再怎么根据这个XPCOM接口找到对应的 Java interface来生成Proxy?2。XPCOMJavaProxy怎么把一个Java调用再映射到底层的XPCOM调用上?

JavaXPCOM是这样实现的:
  1. 对每一个XPCOM对象的指针,知道其实现的interface的IID。
  2. 使用nsIInterfaceInfoManager来reflect 这个IID,得到这个interface的meta data(nsIInterfaceInfo
  3. 将这个XPCOM对象的指针及nsIInterfaceInfo组合在一起,放在一个JavaXPCOMInterface的数据结构里。
  4. 用这个JavaXPCOMInterface结构的指针来构建XPCOMJavaProxy(java wrapper)。构建XPCOMJavaProxy对象时(XPCOMJavaProxy#createProxy(Class aInterface, long aXPCOMInterface))有两个参数,第一个为这个proxy实现的Java interface。这个Java interface的名字由"org.mozilla.xpcom" + (XPCOM interface name)得来。
  5. 当XPCOMJavaProxy上的方法被调用时,native code会得到方法名、参数数组以及JavaXPCOMInterface的指针。从JavaXPCOMInterface可以得到 nsIInterfaceInfo,通过nsIInterface里所包含的meta data,可以得到这个方法在virtual table中的位置。同时meta data还会包含信息说明每个参数的数据类型,根据这个信息,可以把每个参数marshall成一个nsXPTCVariant结构。
  6. 通过xptcall,就可以完成对virtual table中的方法的调用。
  7. 对方法调用的结果,可以再根据meta data来unmarshall成Java对象。如果某个out参数或return参数是一个XPCOM对象,在meta data中会描述这个参数的interface的IID,那么又可以象第一步一样来对其生成Java wrapper(XPCOMJavaProxy)(nsJavaXPCOMBindingUtils.cpp#GetNewOrUsedJavaObject)。
当然,实际的实现更复杂,比如说有一个global table来记录Java wrapper与native的JavaXPCOMInterface之间的关系以避免不必要的多次为同一XPCOM对象建立Java wrapper等。

在Java中实现COM/XPCOM组件(component)

前面讨论了怎么从Java中调用COM/XPCOM中的组件,接下来讨论怎么用Java语言来实现COM/XPCOM组件。


JavaXPCOM

 JavaXPCOM中的支持还是依赖了type information,这是有了这个依赖,JavaXPCOM中实现XPCOM组件要容易得多。在JavaXPCOM中,只需要这个Java对象实现了 所需要实现的XPCOM interface所对应的Java interface即可。
  1. 当一个Java object作为参数传给某个XPCOM方法时,native code会通过这个方法的meta data,知道这个参数应该是一个XPCOM对象。
  2. native code会检查这个Java object是不是一个Java wrapper,如果是,那么可以直接从这个Java wrapper知道它所wrap的XPCOM对象。
  3. 接下来会检查是不是已经给这个Java object生成过stub,如果没有则生成一个nsJavaXPTCStub。nsJavaXPTCStub 会根据meta data生成virtual table,而且当virtual table中的方法被调用时,会根据meta data知道被调用方法的名字,再根据这个名字到Java object中通过reflect找到对应的Java方法并调用它。
另外JavaXPCOM的实现中还实现了reference management,这样在Java code中不再需要去实现如AddRef/Release,系统已经都管理好了。


JavaXPCOM

优点:
  1. 每个XPCOM interface对应到Java中还是interface。
  2. 支持Java的garbase collection。在XPCOMJavaProxy中,重载了finalize()方法,所以Java programmer不需要再去调用Release。
  3. 增加新的XPCOM interface容易。只需在org.mozilla.xpcom这个package中增加相应的Java interface即可。
  4. Java interface可以通过工具自动生成。
  5. 用Java实现XPCOM组件非常简单。
缺点:
  1. 由于实现依赖nsIInterfaceInfoManager,也就依赖typelib。这样一来,方法调用不能象Eclipse SWT中一样直接转换为virtual table调用,效率要明显低一些。另外,只能支持那些支持typelib的interface。
  2. 虽然增加新的XPCOM interface容易,但这个interface必须放在org.mozilla.xpcom这个package中,不适合第三方扩充。




你可能感兴趣的:(『转贴』比较Eclipse与Mozilla中的COM/XPCOM Java Wrapper技术)