一介绍
IKVMNET是一个针对Mono和微软net框架的java实现其设计目的是在NET平台上运行java程序它包含了以下的组建* 一个用NET实现的java虚拟机* 一个java类库的NET实现* 致力于在java和NET之间交互的工具
二IKVMNET的组件
IKVMNET包含以下的部分* IKVMRuntimedll VM运行时和所有支持代码它包括以下的功能Byte Code JIT 编译器和验证器 使用JIT将Java Byte Code编译为CIL(C中间语言)
对象模式映射结构 将NET中的SystemObjectSystemStringSystemException映射为java代码中的javalangObject javalangStringjavalangThrowable管理本地方法(在Classpath中)的NET重新实现
* IKVMGNUClasspathdll 被编译的GNU Classpath版本它是由自由软件基金会实现的java类库和一些IKVMNET附加代码组成的注意这里的GNU Classpath不是IKVMNET的一部分但是前者被用在IKVMNET中
* IKVMJNI[Mono|CLRWin]dll 通过实现JNI接口管理C++汇编作为一个可选部分只在程序使用自己的本地库时才被用到而对于纯java程序来讲是不会被用到的
* ikvmexe 与javaexe很类似的启动执行程序(动态模式)
* ikvmcexe 静态编译器被用来编译java类和jar使其成为NET汇编(静态模式)
* ikvmstubexe 一个从NET汇编生成存根类的工具就如javap一样反编译NET汇编IKVMNET了解如何存根并用实际的NET类型引用替换对存根的引用
* IKVMAWTWinFormsdll 非常有限的零散AWT实现
二项目状态
此项目目前正在开发将最大化实现与JDK的兼容但是仍存在一些漏洞(尤其在Classpth API中)
* AWT和Swing还未有功能
* 安全性是IKVM平台的一个大遗漏此问题将依靠NET平台提供的旧有的但功能强大的安全模式而被解决 虽然这样目前项目已具备能成功运行大型java项目的能力
三IKVM原理
如何替换JVM IKVM应用包含了采用NET实现的java虚拟机在一些场合我们可以用它替换掉java例如 java jar myappjar 将被替换为 ikvm jar myappjar
在NET应用中使用java类库IKVMNET包含ikvmc这个在java bytecode与NET中间语言的转换器如果我们使用一个被用在NET平台的java库的话 运行ikvmc –targetlibrary mylibjar(mylibjar在这里指代我们的jar文件)来生成mylibdll例如apache FOP项目是一个开源的XSLFO处理器项目它使用java语言编写的用于从xml生成PDF文档使用IKVMNET技术我们可以将apache FOP用在任何的NET应用中这样在开发NET应用的同时利用IKVM便可以使用java开源项目这个免费的软件仓库尽管在IKVMNET没有提供在NET中使用的java编译器但是我们可用开源的Jikes编译器将java源代码编译为JVM bytecode然后使用ikvmc –targetexe myappjar来生产NET执行文件我们甚至可以通过包含ikvmstub应用的方式在我们的java代码中用NET API
四IKVM使用入门
系统准备Windows平台Microsoft NET Framework SDK Windows或者Linux平台Mono Framework
开始安装在Windows和Linux平台上安装过程是相同的在下载二进制发布版后将文件解压缩打开命令或者shell窗口cd进入ikvm\bin目录执行ikvm如果我们操作正确的话我们将看到以下的输出
usage ikvm [options] <class> [args……] (to execute a class) or ikvm jar [options] <jarfile> [args……] (to execute a jar file) ……
为了方便使用我们可将ikvm\bin目录加入到系统path现在我们将使用IKVM就像使用JVM一样并不需要配置如果我们需要在NET或者Mono环境下使用IKVM请仔细阅读下面的文字说明* 首先下载Jikes编译器如果我们计划开发在java中开发代码 运行于NET环境的话我们将要一个java编译器IKVMNET没有提供这个编译器所以我们需要能生成标准java类文件的编译器Jlikes是一个好选择它是一个优秀的开源项目并应用在多种平台当然Sun提供的jdk也很好
* 在Windows的全局汇编缓沖区中安装IKVM dll在Windows中运行基于IKVM dll的NET应用程序时NET框架必须定位这些dll的位置系统首先在全局汇编缓沖区中查找然后再当前目录中查找如果我们想不在当前目录中安装这些dll文件的话我们就要将它们安装在全局汇编缓沖区中在Windows控制面板中访问NET框架配置增加一个汇编缓沖区我们至少要安装IKVMGNUClasspathdll和IKVMRuntimedll
设置环境在我们开始编写代码之前需要准备一下我们的环境添加以下路径到系统PATH环境变量中* 包含IKVM执行文件的目录
* 包含C#编译器(在Windows/Mono中为csc)的目录通常在Windows中为C\WINDOWS\MicrosoftNET\Framework\v * 包含java编译器(javac或者jikes)的目录
动态执行java应用程序IKVMNET包括了一个C#实现的java虚拟机我们可以从一个例子开始——进入IKVMROOT\samples\hello目录编译示例程序
Javac Hello jar cfm hellojar manifestmf Helloclass
现在在使用javac编译了Hello类后我们使用IKVM运行此类
ikvm Hello
这个命令将启动IKVMIKVM查找名为Helloclass的文件如果找到则将其装载并动态执行bytecode此时Hello程序将要求我们输入名字之后我们将看到一个问候信息
如果在上面的过程中发生问题请检查下面的地方* 检查命令行 ikvm像java一样需要我们输入正确的类名
* 如果ikvm报告ClassNotFoundException请检查CLASSPATH环境变量是否被设置如果被设置请清除CLASSPATH或者将当前目录加入到CLASSPATH中以使ikvm能够在当前目录中找到类
如果运行jar文件我们可键入
ikvm jar hellojar
提示详细的命令行选项可以参考ikvm手册
将java程序转换为NET程序IKVMNET包含ikvmc这个能够将jar文件转换为NET的dll库文件和exe应用的工具下面我们将学习如何将java应用转换为一个NET执行文件进入IKVMROOT\samples\hello目录输入以下命令
ikvmc hellojar
注意当我们使用Mono时我们需要告诉ikvmc如何找到GNU Classpath dll例如
ikvmc reference/usr/lib/IKVMGNUClasspathdll hellojar
在命令执行完后我们将发现helloexe已被生成在当前目录* 在Windows/NET环境下如果我们得到了FileNotFound的异常请记住检查NET框架希望在当前目录或是全局汇编缓沖区中寻找dll文件我们可以通过上面讲的方法将dll安装到全局汇编缓沖区中或者将dll文件直接复制到当前目录
* 在Linux/Mono环境下我们使用下面的命令执行helloexe
mono helloexe
在java中开发NET应用首先进入IKVMROOT\samples\usenetapi目录找到ShowDirjava文件这个java应用使用了NET API来显示当前目录下的文件列表打开这个文件我们会发现其导入的包名以cli开头这些并不是java API包它们是映射到NET命名空间的伪包需要查看更多信息请看IKVM的开发者手册
第一步生成java存根文件IKVM没有提供java编译器所以我们可以使用标准的java编译器由于java编译器只能编译使用了java API的应用程序而不是使用NET API的应用所以我们在这里需要愚弄一下java编译器使其相信名为cliSystemIO的包是一个真正的java包帮助我们完成这项工作的是ikvmstub程序它从NET dll生成jar文件这个被生成的jar文件包含了与NET类对应的java类和接口但是并不包含真正的代码只包含一些映射信息这样做便会通过java编译器的检查和编译
ikvmstub mscorlibdll
注意在Linux Mono环境下我们必须输入dll文件的完整路径例如
ikvmstub /usr/lib/mscorlibdll
在编译完成后我们将在当前目录下发现一个名为mscorlibjar的文件
第二步编译java源代码现在我们将编译java源代码如果使用javac的话可输入以下命令javac classpath mscorlibjar ShowDirjava
在命令完成后ShowDirclass文件将出现当前目录下
第三步生成NET执行文件最后我们将转换java class文件为NET应用程序正如前面讲的ikvmc ShowDirclass
注意在Linux Mono环境下我们需要使用前面提到的reference选项
ikvmc reference/usr/lib/IKVMGNUClasspathdll ShowDirclass
这时我们便可以看到ShowDirexe出现在当前目录
五参考资源