将java移植到.NET


======================================================
注:本文源代码点此下载
======================================================

前言

在编程武林中,java派成立较久底子雄厚,虽然新掌门oracle准备重现java神威,但镇山之技的java语言已经被后进的新秀.net派的c#压得喘不过气来,甚至有时候ocacle老大还得跑到.net派潜伏学艺。但是百足之虫,死而不僵,一众java派的拥趸们自认虽然java渐渐技不如人,但是java派成立日久,从java演化过来的七十二门绝技绝非武林暴发户.net派所能比拟,其中几大支派如apache,springsource各有绝技,而衍生出的帮会、黑社会等等更是不计其数,.net派望尘莫及。

然而江湖传言有不世神功叫北冥神功,"北冥有鱼,其名为鲲,鲲之大,不知其几千里也……",能够容纳几千里的大鱼必定是非常广阔的海洋,因而北冥神功正是寓含了广大恢宏之意,也体现了神功的威力。"可以吸取他人的内力以供己用,是迅速提升功力的捷径。内力既厚,天下武功无不为我所用,犹如北冥,大舟小舟无不载,大鱼小鱼无不容。"

.net派的几位高人闭关苦练,竟然悟出北冥神功,此神功后曰:ikvm.net.

江湖后辈小子ray linn偶习此神功,得心得一二,不敢自珍,特此记之,以壮大我.net门派,千秋万代,一统江湖。

那日ray偶来到apache支派,却看到apache弟子们各施绝技,好不热闹. ray对apache绝技手痒已久,想来得习ikvm.net已有时日,斗胆上前叫阵。迎战者哪apache派中的小弟子,江湖人称:commons.collection.

二人拳脚来去,ray却懒得与之多动手脚,随即默念真言:

ikvmc?-assembly:commons?-target:library

-version:1.0.0.0?commons-collections-3.2.1.jar

collection陡然萎靡在地,想是一身内功尽被ray所吸去,apache派人等尽皆失色,"我等苦练十余载,内力尽为汝一夕取去",莫敢上前。

ray回转.net派,试练collection的神功,借助ikvm.openjdk.core之神器,神功即成,试演如下:

static?void?main(string[]?args)

{

string?name?=?"tim";

predicate?namejohn?=?new?equalpredicate(?"john"?);

predicate?nametim?=?new?equalpredicate(?"tim"?);

predicate?instancestring?=?new?instanceofpredicate(typeof(string));

predicate?instancedouble?=?new?instanceofpredicate(typeof(double));

console.out.writeline(?"is?name?john?:?"?+?namejohn.evaluate(name?)?);

console.out.writeline("is?name?tim?:?"?+?nametim.evaluate(name));

console.out.writeline(?"is?this?a?string?:?"?+?instancestring.evaluate(?name?)?);

console.out.writeline(?"is?this?a?double?:?"?+?instancedouble.evaluate(?name?)?);

}

相较原有神功:

string?name?=?"tim";

predicate?namejohn?=?new?equalpredicate(?"john"?);

predicate?nametim?=?new?equalpredicate(?"tim"?);

predicate?instancestring?=?new?instanceofpredicate(?string.class?);

predicate?instancedouble?=?new?instanceofpredicate(?double.class?);

//?testing?all?predicates?for?"tim"

system.out.println(?"is?name?john?:?"?+?namejohn.evaluate(?name?)?);

system.out.println(?"is?name?tim?:?"?+?nametim.evaluate(?name?)?);

system.out.println(?"is?this?a?string?:?"?+?instancestring.evaluate(?name?)?);

system.out.println(?"is?this?a?double?:?"?+?instancedouble.evaluate(?name?)?);

竟然绝无二致。

偌大java江湖,从此为我.net所用,哇哈哈。

ikvm.net是一个针对mono和微软.net框架的java实现,其设计目的是在.net平台上运行java程序。本文将比较详细的介绍这个工具的原理、使用入门(如何java应用转换为.net应用、如何在java中开发.net应用),希望能给大家带来惊喜。

介绍

ikvm.net是一个针对mono和微软.net框架的java实现,其设计目的是在.net平台上运行java程序。它包含了以下的组建:

* 一个用.net实现的java虚拟机

* 一个java类库的.net实现

* 致力于在java和.net之间交互的工具

ikvm.net的组件

ikvm.runtime.dll: vm运行时和所有支持代码。它包括以下的功能: byte code jit 编译器和验证器: 使用jit将java byte code编译为cil(c中间语言)。

对象模式映射结构: 将.net中的system.object,system.string,system.exception映射为java代码中的java.lang.object, java.lang.string,java.lang.throwable。

管理本地方法(在classpath中)的.net重新实现。

*ikvm.gnu.classpath.dll: 被编译的gnu classpath版本,它是由自由软件基金会实现的java类库和一些ikvm.net附加代码组成的。注意:这里的gnu classpath不是ikvm.net的一部分,但是前者被用在ik.vm.net中。

ikvm.jni.[mono|clr-win32].dll: 通过实现jni接口管理c++汇编。作为一个可选部分,只在程序使用自己的本地库时才被用到。而对于纯java程序来讲是不会被用到的。

ikvm.exe: 与java.exe很类似的启动执行程序(动态模式)。

ikvmc.exe: 静态编译器,被用来编译java类和jar使其成为.net汇编(静态模式)。

ikvmstub.exe: 一个从.net汇编生成存根类的工具,就如javap一样反编译.net汇编。ikvm.net了解如何存根并用实际的.net类型引用替换对存根的引用。

ikvm.awt.winforms.dll: 非常有限的零散awt实现。

项目状态

此项目目前正在开发,将最大化实现与jdk1.4的兼容,但是仍存在一些漏洞(尤其在classpth api中)。

awt和swing还未有功能。

安全性是ikvm平台的一个大遗漏。此问题将依靠.net平台提供的旧有的、但功能强大的安全模式而被解决。 虽然这样,目前项目已具备能成功运行大型java项目的能力。

ikvm原理

1.如何替换jvm

ikvm应用包含了采用.net实现的java虚拟机。在一些场合,我们可以用它替换掉java。例如: java -jar myapp.jar 将被替换为 ikvm -jar myapp.jar。

2.在.net应用中使用java类库

ikvm.net包含ikvmc,这个在java bytecode与.net中间语言的转换器。如果我们使用一个被用在.net平台的java库的话, 运行ikvmc –target:library mylib.jar(mylib.jar在这里指代我们的jar文件)来生成mylib.dll。例如apache fop项目是一个开源的xsl-fo处理器项目,它使用java语言编写的用于从xml生成pdf文档。使用ikvm.net技术,我们可以将apache fop用在任何的.net应用中。这样在开发.net应用的同时利用ikvm便可以使用java开源项目这个免费的软件仓库。尽管在ikvm.net没有提供在.net中使用的java编译器,但是我们可用开源的jikes编译器将java源代码编译为jvm bytecode,然后使用ikvmc –target:exe myapp.jar来生产.net执行文件。我们甚至可以通过包含ikvmstub应用的方式在我们的java代码中用.net api。

四、ikvm使用入门

1.系统准备

windows平台:microsoft .net framework 1.1 sdk

windows或者linux平台:mono framework 1.0

2.开始安装

在windows和linux平台上安装过程是相同的,在下载二进制发布版后,将文件解压缩。打开命令或者shell窗口,cd进入ikvm\bin目录,执行ikvm。如果我们操作正确的话,我们将看到以下的输出:

usage: ikvm [-options][args...] (to execute a class) or ikvm -jar [-options][args...] (to execute a jar file) ...

为了方便使用,我们可将ikvm\bin目录加入到系统path。现在我们将使用ikvm就像使用jvm一样,并不需要配置。如果我们需要在.net或者mono环境下使用ikvm,请仔细阅读下面的文字说明:

首先下载jikes编译器。如果我们计划开发在java中开发代码 运行于.net环境的话,我们将要一个java编译器。ikvm.net没有提供这个编译器,所以我们需要能生成标准java类文件的编译器。jlikes是一个好选择,它是一个优秀的开源项目,并应用在多种平台。当然sun提供的jdk也很好。

在windows的全局汇编缓冲区中安装ikvm dll。在windows中运行基于ikvm dll的.net应用程序时,.net框架必须定位这些dll的位置。系统首先在全局汇编缓冲区中查找,然后再当前目录中查找。如果我们想不在当前目录中安装这些dll文件的话,我们就要将它们安装在全局汇编缓冲区中:在windows控制面板中访问.net框架配置,增加一个汇编缓冲区。我们至少要安装ikvm.gnu.classpath.dll和ikvm.runtime.dll。

3.设置环境

在我们开始编写代码之前需要准备一下我们的环境,添加以下路径到系统path环境变量中:

包含ikvm执行文件的目录。

包含c#编译器(在windows/mono中为csc)的目录,通常在windows中为c:\windows\microsoft.net\framework\v2.0.5372。

* 包含java编译器(javac或者jikes)的目录。

4.动态执行java应用程序

ikvm.net包括了一个c#实现的java虚拟机。我们可以从一个例子开始——进入ikvmroot\samples\hello目录,编译示例程序:

javac hello jar cfm hello.jar manifest.mf hello.class

现在,在使用javac编译了hello类后,我们使用ikvm运行此类:

ikvm hello

这个命令将启动ikvm,ikvm查找名为hello.class的文件。如果找到,则将其装载并动态执行bytecode。此时hello程序将要求我们输入名字,之后我们将看到一个问候信息。

如果在上面的过程中发生问题,请检查下面的地方:

检查命令行: ikvm像java一样需要我们输入正确的类名。

如果ikvm报告classnotfoundexception,请检查classpath环境变量是否被设置。如果被设置,请清除classpath或者将当前目录加入到classpath中以使ikvm能够在当前目录中找到类。

如果运行jar文件,我们可键入:

ikvm -jar hello.jar

提示:详细的命令行选项可以参考ikvm手册。

5.将java程序转换为.net程序

ikvm.net包含ikvmc这个能够将jar文件转换为.net的dll库文件和exe应用的工具。下面我们将学习如何将java应用转换为一个.net执行文件:

进入ikvmroot\samples\hello目录输入以下命令:

ikvmc hello.jar

注意:当我们使用mono时,我们需要告诉ikvmc如何找到gnu classpath dll,例如:

ikvmc -reference:/usr/lib/ikvm.gnu.classpath.dll hello.jar

在命令执行完后,我们将发现hello.exe已被生成在当前目录:

在windows/.net环境下,如果我们得到了filenotfound的异常,请记住检查.net框架希望在当前目录或是全局汇编缓冲区中寻找dll文件。我们可以通过上面讲的方法将dll安装到全局汇编缓冲区中,或者将dll文件直接复制到当前目录。

在linux/mono环境下,我们使用下面的命令执行hello.exe:

mono hello.exe

6.在java中开发.net应用

首先进入ikvmroot\samples\usenetapi目录,找到showdir.java文件,这个java应用使用了.net api来显示当前目录下的文件列表。打开这个文件,我们会发现其导入的包名以cli开头,这些并不是java api包,它们是映射到.net命名空间的"伪"包。需要查看更多信息请看ikvm

的开发者手册。

第一步:生成java存根文件

ikvm没有提供java编译器,所以我们可以使用标准的java编译器。由于java编译器只能编译使用了java api的应用程序,而不是使用.net api的应用。所以我们在这里需要"愚弄"一下java编译器使其相信名为cli.system.io的包是一个真正的java包。帮助我们完成这项工作的是ikvmstub程序。它从.net dll生成jar文件,这个被生成的jar文件包含了与.net类对应的java类和接口,但是并不包含真正的代码,只包含一些映射信息。这样做便会通过java编译器的检查和编译:

ikvmstub mscorlib.dll

注意:在linux mono环境下,我们必须输入dll文件的完整路径,例如:

ikvmstub /usr/lib/mscorlib.dll

在编译完成后,我们将在当前目录下发现一个名为mscorlib.jar的文件。

第二步:编译java源代码

现在我们将编译java源代码,如果使用javac的话,可输入以下命令:

javac -classpath mscorlib.jar showdir.java

在命令完成后,showdir.class文件将出现当前目录下。

第三步:生成.net执行文件

最后我们将转换java class文件为.net应用程序,正如前面讲的:

ikvmc showdir.class

注意:在linux mono环境下,我们需要使用前面提到的-reference选项:

ikvmc -reference:/usr/lib/ikvm.gnu.classpath.dll showdir.class

这时我们便可以看到showdir.exe出现在当前目录。


======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值