当我们将java应用程序重新编译为本机应用程序时,是否可以“模拟”通过Spring AOP,依赖注入和其他Spring机制完成的动态代码生成? Hibernate和纯java反射怎么样?一些能够将Java转换为本机代码的工具包括GCC和Excelsior编译器,但它们是否提供了可靠的本机代码,它们将以相同的方式工作和Java应用程序一样吗?
目前,我们正面临一个奇怪的工作场景。我们有一个服务器端的Java Web应用程序,它使用Spring及其依赖注入,消息传递,MVC和AOP。该应用程序非常庞大,具有复杂的结构和依赖性,涉及大量第三方,并且具有庞大的代码库。
问题是我们必须针对应该托管上述应用程序的Windows系统(Windows 7嵌入式; Core2 Duo; 4GB RAM)。我们有一些限制(硬件,软件和合法),它们不允许我们在目标硬件上使用纯Java代码。硬件运行Windows操作系统,我们唯一允许的选项是本机可执行文件(EXE)。
因此,我们必须将(一个软字)java服务器应用程序(或其最小子集)转换为设备的本机应用程序。根据互联网上的某些资源,这可能通过某些生成本机(非JAVA)二进制文件的编译器实现。但是,由于动态平台(如Java所示)与本机平台的静态特性之间存在严重差异,因此某些JVM功能将无法使用 - 例如动态编译和代理(根据this页面) 。因此,对于依赖Spring的DI,AOP和事务管理等动态基础技术的应用程序来说,这似乎是一项几乎不可能完成的任务。更不用说我们将Hibernate用作ORM。
我必须说整个应用程序将尽可能地进行修剪,并且只剩下所需的功能(因为它非常独立 - 就不依赖第三方服务而言),但我们仍然不能说告别Spring,Hibernate和AOP等核心概念。因此,我的问题是:它是否可能成功地将此类应用程序转换为本机代码(具有上述属性和有效限制)?是否可以“模拟”通过AOP完成的动态代码生成(比如将代理编写为静态,如果依赖于AOP)和其他Spring机制?提到的一些工具包括GCC和Excelsior编译器。他们用我提到的动态技术提供可靠的结果吗?除了在更加静态的语言(如C / C ++)上重写应用程序之外还有其他选择吗(这对我们的时间框架来说是不可接受的)?我也很感谢支持不这样做的任何论据,因为我们目前正在评估这个机会。任何有争议的拒绝对我来说都是可以接受的,因为我个人从未进行过这样的本机代码转换,也不知道它对软件的全面影响。
答案 0 :(得分:2)
你唯一真正的目标选项是像IKVM和JNBridgePro这样的东西 - 但是,我猜你的.net应用程序不是真的合理,无论你描述你的约束方式,还是取决于应用程序的技术细节IKVM < / p>
在那种情况下,你几乎要求不可能的事情。没有合理的策略可以将java编译为win32本机代码,支持普通企业应用程序工具链的任何重要子集。
从头开始为目标平台重新编写应用程序会更便宜,然后创建基础架构并进行所需的测试,以便将其从目标运行时进行入侵/移植到完全不相关的外部运行时。
更新:有些事情发生了变化:现在graalvm会为您的java代码生成原生图像。这是免费和花哨的,并且很大程度上是OP想要的。
答案 1 :(得分:1)
这是一个非常有趣的问题:编译器如何预先确定动态加载的类?
我看了一下Excelsior文档,它似乎通过混合编译模型来处理它。 JET运行时涉及一个JIT编译器,它可以为动态场景提供支持。我认为将动态Java程序转换为本机程序是一个非常难的问题,在您的特定情况下无法解决。
尽管如此,.NET Team最近展示了一种新的编译时技术,可以满足您对Microsoft托管应用程序的要求(即.NET而非Java)。目前,它仅支持Windows应用商店应用,因此对您的方案无用。但是,您可能需要查看一个博客:http://blogs.msdn.com/b/dotnet/archive/2014/05/20/net-native-deep-dive-dynamic-features-in-static-code.asp以了解他们对这个有趣问题的解决方案。
他们讨论了他们为在静态编译模型中支持动态场景而引入的机制。简而言之,本机.NET编译器会尽力预测应用程序将使用的所有类。对于无法静态预测的类,需要将“提示”提供给编译器。应用程序开发人员和库开发人员指定runTime指令以启用指定类型的动态方案。运行时指令允许为指定类型添加Reflection元数据或序列化支持。在此模型中,没有JIT,因此如果您的类型未由编译器推断或未包含在运行时指令xml文件中,则会遇到运行时异常。