工具箱之 IKVM.NET 项目新进展
在各种群里经常讨论的一个事情是.NET 如何调用 Java 的实现,最常见的场景之一就是在加解密方面Java提供的密钥,C#无法解密, C#中byte范围是[0,255],而Java中的byte范围是[-128,127],由于密码生成器是java所独有的,其它语言都不支持(IOS,ANDROID,C#,.NET等),既然java这么特立独行,我们用上的解决方案那么就是Java 范的。
Java和.NET是目前软件开发的两种主要技术,Java 8虽然是一种较旧的技术,已经完成了大量的工作。因此,当涉及到可重用性时,在.NET中使用在Java中创建的库是一种非常普遍的做法。假设您已经在 Java 中开发了一个库,并且想要在 .NET 项目中使用它,那么 IKVM.NET 有助于在 .NET 中使用 Java 库。
这就是今天我们要引入的主角 IKVM.NET , IKVM.NET 项目的历史非常悠久,早在2006 年我在博客上写了一篇文章 《在.NET平台上运行Java程序-IKVM.NET入门》[1], IKVM.NET和 Mono 一样都是.NET 开源史前的社区项目,IKVM 是一个 Java 到 .NET Framework的编译器,而 Mono 是 .NET Framework的开源、跨平台版本。2017年IKVM.NET作者决定放弃IKVM.NET的开发工作,从此之后社区里有人分叉了IKVM.NET 并继续工作,虽然开发工作不是很积极, 不过从2022年3月份至今开发就非常活跃了(https://github.com/ikvm-revived/ikvm)[2],现在完全可以支持.NET 6了:

IKVM.NET 包括以下三个主要组件:
- 在.NET中实现的Java虚拟机:它有一个使用C#.NET开发的JVM,它提供了字节码转换和验证,类加载等功能,当前支持Java 8,这也是Java 使用最多的版本。
- Java类库的.NET实现:它基本上使用OpenJDK[3]项目来实现JDK库。
- 支持 Java 和 .NET 互操作性的工具:IKVM.NET 包括以下工具:
a) ikvm:Java 虚拟机: 我们可以将其与java.exe(“动态模式”)进行比较。它加载一个类文件并执行其 main 方法,如果我们将类文件名作为参数传递,那么它将在可执行 jar 文件中执行 Java 代码。如果我们将一个jar文件作为参数传递,那么它将执行它。
b) ikvmc:将 Java 字节码编译为 CIL, 用于将 Java 类和 jar 编译为 .NET 程序集(“静态模式”)。此工具将 Java 字节码转换为 .NET DLL 和 exe。它将输入文件中的 Java 字节码转换为 .NET DLL。因此,当我们传递多个jar文件和类文件时,它将将它们组合在一起并生成单个exe或DLL文件。是 exe 还是 DLL 取决于传递的类文件和 jar 文件是否具有 Main 方法。如果他们有一个Main方法,那么它将生成一个exe,否则DLL。
c) ikvmstub:从 .NET 程序集生成 Java 存根类: 它从 .NET 程序集生成存根类文件,以便可以针对 .NET 代码编译 Java 代码。ikvmstub 工具从 .NET 程序集生成 Java 存根。ikvmstub 读取指定的程序集并生成一个包含 Java 接口和存根类的 Java jar 文件。
IKVM.NET 对于各种软件开发方案非常有用。以下是一些可能性的样本。
- 插入式 JVM 发行版中包含的 IKVM 应用程序是 Java 虚拟机的 .NET 实现。在许多情况下,您可以将其用作 Java 的直接替代品。例如,无需键入“java -jar myapp.jar”来运行应用程序,您可以键入:ikvm -jar myapp.jar
- 在 .NET 应用程序中使用 Java 库,IKVM.NET 包括 ikvmc,一个 Java 字节码到 .NET IL 转换器。如果你有一个Java库,你想在.NET应用程序中使用,然后运行“ikvmc -target:library mylib.jar”来创建“mylib.dll”。 例如,Apache FOP项目是一个用Java编写的开源XSL-FO处理器,广泛用于从XML源生成PDF文档。借助 IKVM.NET 技术,Apache FOP可以被任何.NET应用程序使用。
- 用 Java 开发 .NET 应用程序 IKVM 为您提供了一种用 Java 开发 .NET 应用程序的方法。虽然 IKVM.NET 不包括用于.NET的Java编译器,但您可以使用任何Java编译器将Java源代码编译为JVM字节码,然后使用“ikvmc -target:exe myapp.jar”来生成.NET可执行文件。您甚至可以使用包含的 ikvmstub 应用程序在 Java 代码中使用 .NET API。
支持平台
- .NET Framework 4.6.1 及更高版本
- .NET Core 3.1 及更高版本
- .NET 5 及更高版本
- Java SE 8
IkvmReference
IKVM 包括生成时支持将 Java 库转换为 .NET 程序集,这是最近加入的功能特性,具体可以参见 IkvmReference 设计方案[4]。在要引用 Java 库的项目中安装包。使用IkvmReference 来指示您的项目需要哪些 Java 库。
例:
<ItemGroup>
<IkvmReference Include="..\..\ext\helloworld-2.0.jar" />
</ItemGroup>
输出程序集将作为项目生成过程的一部分生成。可以向IkvmReference 其他元数据添加以自定义生成的程序集。
Identity:项目的标识可以是 a) JAR 文件的路径 b) 目录的路径或 c) 其他不重要的名称。IkvmReferenceAssemblyName:默认情况下,使用规范定义的规则生成 。要覆盖此内容,请在此处执行此操作。AssemblyNameAutomatic-Module-NameAssemblyVersion:默认情况下,使用规范定义的规则生成 。要覆盖此内容,请在此处执行此操作。AssemblyVersionAutomatic-Module-NameDisableAutoAssemblyName:如果禁用 检测 。trueAssemblyNameDisableAutoAssemblyVersion:如果禁用 检测 。trueAssemblyVersionFallbackAssemblyName:如果未提供或无法计算,请使用此值。AssemblyNameFallbackAssemblyVersion:如果未提供或无法计算,请使用此值。AssemblyVersionCompile:可选的以分号分隔的 Java 类路径项列表,以编译到程序集中。缺省情况下,如果项目的标识是现有的 JAR 文件或目录(尚不受支持),则此值是项目的值。支持 MSBuild 客户端引用多个 JAR 或.class文件。IdentitySources:在文档生成期间要使用的 Java 源文件的可选分号分隔列表。(尚不支持)References:可选的以分号分隔的其他标识值列表,以指定为对当前标识值的引用。例如,如果依赖于 ,则将两者都作为项包括在内,但在 元数据上指定 的标识。IkvmReferencefoo.jarbar.jarIkvmReferencebar.jarReferencesfoo.jarDebug:指示是否生成调试符号(不可移植)的可选布尔值。默认情况下,这是根据项目的整体设置确定的。- MSBuild 项组定义支持的所有其他元数据。
Reference
IkvmReference不可传递。将其包含在一个项目中并从第二个项目向该项目添加依赖项不会导致在第二个项目上提供相同的引用。而是添加对每个项目的引用。
对于要解析为相同生成的程序集的每个项目,请确保其设置相同。
<ItemGroup>
<IkvmReference Include="helloworld.jar">
<AssemblyVersion>1.0.0.0</AssemblyVersion>
</IkvmReference>
<IkvmReference Include="helloworld-2.jar">
<AssemblyName>helloworld-2</AssemblyName>
<AssemblyVersion>2.0.0.0</AssemblyVersion>
<References>helloworld.jar</References>
<Aliases>helloworld2</Aliases>
</IkvmReference>
</ItemGroup>
相关链接:
[1]在.NET平台上运行Java程序-IKVM.NET入门:https://www.cnblogs.com/shanyou/articles/343118.html
[2]ikvm Github复活仓库: https://github.com/ikvm-revived/ikvm
[3]OpenJDK: http://openjdk.java.net/
[4]IkvmReference 设计方案:https://github.com/ikvm-revived/ikvm/issues/54
工具箱之 IKVM.NET 项目新进展的更多相关文章
- iOS开发实用技巧—项目新特性页面的处理
iOS开发实用技巧篇—项目新特性页面的处理 说明:本文主要说明在项目开发中会涉及到的最最简单的新特性界面(实用UIScrollView展示多张图片的轮播)的处理. 代码示例: 新建一个专门的处理新特性 ...
- iOS中的项目新特性页面的处理
一般项目中都会出现新特性页面,比如第一次使用应用的时候,或者在应用设置里查看新特性的时候会出现. 这里,选择新建一个专门处理项目新特性的控制器,来完成功能. 首先是 NewFeaturesViewCo ...
- 新项目新工作空间新仓库新setting文件
maven项目涉及到仓库,本地jar包存放在本地仓库中,新项目新工作空间新仓库新setting文件,可以避免很多问题,不同项目工程的版本可能不一样,所涉及的jar包版本可能也不一样,不分开会有一些冲 ...
- 组装技术的新进展 New advances in sequence assembly.
组装技术的新进展 1.测序和组装 很难想象今天距离提出测序和组装已经有40年啦.我们回头来看一下这个问题. “With modern fast sequencing techniques and su ...
- Neutron新进展|DragonFlow在Mitaka版本中的Roadmap
OpenStack网络在Mitaka版本中将有哪些新变化?1月11日到12日,DragonFlow的PTL——Eran Gampel,Kuryr的PTL——Gal Sagie,和他们的老大从以色列来到 ...
- maven项目新检出后不编译爬坑记 及 mvn clean package报错 WagonTransporterFactory: java.util.NoSuchElementException 异常【我】
从SVN新检出一个maven项目,配置好后,发现项目无法编译(只有一个test包中的代码显示编译报错,其他所有包中的代码都不编译,也不报错), 先注释掉报错的test包中的所有内容, 用Eclipse ...
- 项目新的需求,网页的自适应交付/响应式交付 Responsive/Adaptive Delivery
网页为什么要做自适应交付,皆因现在移动设备大行其道,现在是移动互联网时代,以IOS及Android为首的各种移动终端已经遍地开花. 当人家用380px的iphone打开你的网页时,你总不能显示个102 ...
- JAVA WEB新进展
哈哈,终于搞来页面来了,丑是丑,但是好的进展. 高手的思路,自己用库建连接池,确实利害. 最关键的一个HELPER代码: package org.smart4j.chapter2.helper; im ...
- idea 切换新项目 新窗口 原窗口
选择 file--setting. 在新打开的窗口中选择 Appearance & Behavior--System Settings 点 Confirm window to open pro ...
随机推荐
- oracle split 以及 简单json解析存储过程
BEGIN; 由于之前工作上需要在oracle中做split功能以及json格分解.然后经过一番google和优化整合,最后整理到一个存储过程包中,易于管理,代码如下: 1.包定义: CREATE O ...
- JS的URIencode方式
BEGIN; 对需要传递的URL参数进行URLencode编码 刚开始浪费了很多时间都没搞出来,不知道怎么用.后面google到了不少解决方案,最终解决.转载下面内容: js对文字进行编码涉及3个函数 ...
- java自带的四种线程池
java预定义的哪四种线程池? newSingleThreadExexcutor:单线程数的线程池(核心线程数=最大线程数=1) newFixedThreadPool:固定线程数的线程池(核心线程数= ...
- 单列集合(Collection-Set)
(部分) Set类特点: "无序"(输入顺序和存储顺序不一样) HashSet 底层是HashMap 关于不能有重复元素/对象 遇到的问题: 解决办法:重新类的相关方法 选择名字和 ...
- Django视图函数:CBV与FBV (ps:补充装饰器)
CBV 基于类的视图 FBV 基于函数的视图 CBV: 1 项目目录下: 2 urlpatterns = [ 3 path('login1/',views.Login.as_view()) #.as ...
- Linux操作系统基本知识
1.Linux开发环境 2.GCC 2.1GCC工作流程 预处理:只运行 C 预编译器. 宏去掉了,注释没有了 汇编 编译 链接 2.2GCC常用参数选择 选项 解释 -ansi 只支持 ANSI 标 ...
- Linux嵌套目录权限的比较探究
在/tmp目录下新建一个嵌套目录,名字分别为test_0.test_1.test_2.在test_2目录下新建普通文件,名为tryme.设置test_0和test_2的权限为777,设置test_1的 ...
- Java泛型类型擦除问题
以前就了解过Java泛型的实现是不完整的,最近在做一些代码重构的时候遇到一些Java泛型类型擦除的问题,简单的来说,Java泛型中所指定的类型在编译时会将其去除,因此List 和 List 在编译成字 ...
- Typora 开始收费,改用好玩的MarkText
收费-- 可以考虑使用:MarkText 简述MarkText MarkText 这个工具侧重于"命令",导航栏都被收起来了.有些小伙伴感觉反而不好用,其实不然,是未了解该工具的强 ...
- leetcode 3. Longest Substring Without Repeating Characters 无重复字符的最长子串
一.题目大意 https://leetcode.cn/problems/longest-substring-without-repeating-characters/ 给定一个字符串 s ,请你找出其 ...