天天看點

将java庫轉換為.net庫

【轉載請注明出處】

動機:

    充分利用java陣營衆多的類庫

工具:

IKVM――把java bytecode 轉換成IL程式,并提供大部分J2SE 1.4類的.net實作(IKVM.GNU.Classpath.dll)

winrar――提取jar,打包jar

Java IDE(可選)――閱讀源代碼,浏覽類之間的關系,我用的是eclipse

反編譯工具(可選)――沒源代碼時用,主要也是浏覽類與類之間的關系,java反編譯我用的是DJ Java Decompiler,.net用Reflector。

原理:

java也好,.net也好,其執行無非就是運作時 + 庫,把java彙編指令一條一條轉換為IL彙編指令,就可以實作java程式到.net程式的轉換――你可以通過最純正的.net使用方式來使用這些類庫/程式。ikvm實作的就是這樣一個功能。

如果一個java程式調用一大堆java類庫,那麼必須把這些程式和類庫全部轉換成.net的IL格式,這個程式才能執行。

IKVM安裝:

從www.ikvm.net上下載下傳ikvm,解壓縮後就能開始用。

将jar轉換為dll:

運作:ikvmc -target:library ××××.jar

會将jar檔案自動轉換為 ××××.dll

但是,如果jar中引用的類不存在于××××.jar,也不存在于IKVM.GNU.Classpath.dll之中,則會給出警告資訊,該類也不會轉換。這時,需要引用缺少的類所在的dll,格式如下:

ikvmc -target:library -reference:lib1.dll -reference:lib2.dll -reference:lib3.dll jar1.jar

jar的提取:

jar可以用winrar打開,把你想要的目錄或類解壓縮。

把java class檔案打包為jar:

把目錄壓縮成zip格式,把字尾改成jar,OK。

例子:轉換Geotools的main子產品

下面以Geotools的main子產品為例,說明怎樣将jar檔案轉換為IL檔案。

geotools是有10年曆史的GIS中間件。其main子產品有1000多個類,源代碼檔案大小合計9.74M。jar檔案名為gt2-main.jar,2.34M.

步驟1:分析main子產品依賴的類庫,分析類庫間的依賴關系

geotools-main依賴的類庫有:

rt.jar――java的主要的lib

geoapi.jar――OpenGIS一幫人定義的标準geoapi

jai_codec.jar, jai_core.jar,――Java 2D API

JTS-1.4.jar,――Java 拓撲套件,主要用于拓撲分析,可能依賴

vecmath-1.3.jar――vector數學庫

xalan-2.5.1.jar――xml 轉換lib

opengis-legacy-0.1.jar,――忘了幹什麼的,反正和gis有關

units-0.01.jar――不知道是什麼

batik*.jar――SVG lib

mailapi-1.3.jar

步驟2:轉換類庫

先轉換那些沒依賴的庫,比如vecmath-1.3.jar,......

運作:

ikvmc -target:library vecmath-1.3.jar

結果:

Note: output file is "vecmath-1.3.dll"

Note: automatically adding reference to "f:\ikvm-0.20.0.0\ikvm\bin\ikvm.gnu.classpath.dll"

成功轉換成vecmath-1.3.dll。

如果碰上了依賴的庫沒轉換,比如運作:

ikvmc -target:library jai_codec.jar

結果提示有些類找不到:

Note: output file is "jai_codec.dll"

Warning: class "com.sun.image.codec.jpeg.JPEGCodec" not found

Warning: class "com.sun.image.codec.jpeg.JPEGEncodeParam" not found

Warning: class "com.sun.image.codec.jpeg.JPEGImageEncoder" not found

Warning: class "com.sun.image.codec.jpeg.JPEGDecodeParam" not found

Warning: class "com.sun.image.codec.jpeg.JPEGImageDecoder" not found

Warning: class "com.sun.image.codec.jpeg.ImageFormatException" not found

Warning: class "com.sun.image.codec.jpeg.JPEGQTable" not found

Warning: class "sun.security.action.GetPropertyAction" not found

是以對于有依賴關系的庫,需要從最下面那個,大家都依靠它的那個庫轉換起。在這裡就是rt.jar。

ikvmc -target:library rt.jar

慘!!!ikvm彈出錯誤視窗――不是我無能,是rt.jar太狡猾!

怎麼辦?需要從rt.jar中找出所需要的類,将這些類轉換就行了。

用winrar找出需要的類,比如jai_codec需要com.sun.image.codec.jpeg.JPEGCodec,....等8個類,就從rt.jar中找出這些類出來。注意,這些類可能還依賴于别的類,依賴的類也需要找出來,全部打包成一個新的jar,如little_rt.jar。如果有些類在IKVM.GNU.Classpath.dll中已經有了,可以不用提取。

最慘的情況可能是1個類依賴2個類,2個類又依賴8個類,然後又依賴更多的類,這種情況下與其要把這些類提取出來,不如更改這個類,把對外依賴的東東都去掉,全部return null, return 0什麼的。先轉換成功,然後再用.net把這個類重寫就行了。幸運的是這裡沒碰見這情況。

用把little_rt.jar轉換為little_rt.dll,然後運作:

ikvmc -target:library -reference:little_rt.dll jai_codec.jar

OK!成功!

這樣繼續一個jar一個jar的轉換,這些jar會依賴rt.jar中更多的類,需要都提取出來,放在little_rt.jar中,再轉換為little_rt.dll。

就這樣把geoapi.jar,jai_codec.jar, jai_core.jar, JTS-1.4.jar, vecmath-1.3.jar,xalan-2.5.1.jar,opengis-legacy-0.1.jar, units-0.01.jar都轉換成了dll。mailapi-1.3.jar和batik*.jar沒轉換。這兩個直接轉換都沒成功,batik*.jar是一系列jar,之間的關系比較複雜我也搞不清。憑我對geotools的了解, main子產品裡基本沒用到mail,而SVG是以插件形式提供的,在這裡用的也不多。那就不管這兩個,來轉換gt2-main.jar先。

ikvmc -target:library -reference:jai_codec.dll  -reference:geoapi.dll -reference:xalan-2.5.1.dll -reference:JTS-1.4.dll -reference:vecmath-1.3.dll -reference:units-0.01.dll -reference:opengis-legacy-0.1.dll -reference:little_rt.dll -reference:jai_core.dll gt2-main.jar

Note: output file is "gt2-main.dll"

Warning: class "org.geotools.ct.CoordinateTransformation" not found

Warning: unable to compile class "org.geotools.renderer.lite.InternalTranscoder"

    (missing class "org.apache.batik.transcoder.image.ImageTranscoder")

Warning: class "javax.swing.text.DefaultFormatterFactory" not found

Warning: unable to compile class "org.geotools.ct.CoordinateTransformation$Inverse"

    (missing class "org.geotools.ct.CoordinateTransformation")

Warning: class "org.geotools.renderer.style.InternalTranscoder" not found

Warning: class "org.apache.batik.transcoder.TranscoderInput" not found

Warning: class "org.apache.batik.transcoder.SVGAbstractTranscoder" not found

Warning: class "org.apache.batik.transcoder.TranscodingHints$Key" not found

Warning: class "org.apache.batik.transcoder.TranscoderOutput" not found

Warning: class "org.apache.batik.transcoder.TranscodingHints" not found

Warning: class "org.geotools.renderer.lite.InternalTranscoder" not found

Warning: unable to compile class "org.geotools.data.DataTestCase"

    (missing class "junit.framework.TestCase")

Warning: class "javax.mail.Session" not found

Warning: class "javax.mail.internet.InternetAddress" not found

Warning: class "javax.mail.Address" not found

Warning: class "javax.mail.internet.MimeMessage" not found

Warning: class "javax.mail.Message" not found

Warning: class "javax.mail.Message$RecipientType" not found

Warning: class "javax.mail.Transport" not found

Warning: class "javax.mail.MessagingException" not found

Warning: class "javax.mail.internet.AddressException" not found

可以看見隻有org.geotools.ct.CoordinateTransformation,org.geotools.renderer.lite.InternalTranscoder,org.geotools.data.DataTestCase這三個類沒轉換成功,其中org.geotools.data.DataTestCase是測試用的,可以不管,剩下兩個類要用到batik中的類,可以按照上述思路把batik轉換為dll,也可重寫這兩個類――剩下的1000個類,已經全部轉換成功,可以在.net平台上用了。

檢驗結果:用reflector打開gt2-main.dll

将java庫轉換為.net庫
将java庫轉換為.net庫

說明:

1,rt.jar中sun.*;com.*命名空間中的類,IKVM.GNU.Classpath.dll都沒有

2,進行.net開發時需要引用IKVM.GNU.Classpath.dll

3,ikvm的jar->dll轉換可能存在bug,最好把test case也全部轉換過來,測試測試

4,ikvm的jar->dll轉換可能存在性能問題,需要時可進行重構

5,有少量java 文法産生的指令不能直接轉換,會報錯。這是極少量的,我轉換了好幾M的東西了,隻報了2處這種錯。這時候可能需要改動改動java源代碼

本文轉自xiaotie部落格園部落格,原文連結http://www.cnblogs.com/xiaotie/archive/2005/10/10/251724.html如需轉載請自行聯系原作者

xiaotie 集異璧實驗室(GEBLAB)