【问题标题】:Any better options than porting from C# to Java?有比从 C# 移植到 Java 更好的选择吗?
【发布时间】:2011-08-07 02:42:03
【问题描述】:

我有一个用 C# 编写的现有库,它包装了一个低级别 TCP/IP API,并将来自服务器(专有二进制协议)的消息公开为 .NET 事件。我还提供了对对象的方法调用,该对象处理将方便的 .NET 类型(如 System.DateTime)编组为 API 所需的二进制编码和固定长度结构(用于向服务器传出消息)的复杂性。有相当多的现有应用程序(内部应用程序和第三方使用的)构建在这个 .NET 库之上。

最近,有人与我们接触,他们不想自己做所有抽象 TCP/IP 的繁琐工作,但他们的环境严格非 Windows(我假设 *nix,但我不是 100 % 当然),并且他们已经暗示他们的理想是可以从 Java 中调用的东西。

什么是支持他们的要求的最佳方式,而无需我:

  1. 现在将代码移植到 Java(包括我们当前 P/Invoke 用于解压缩的非托管 DLL)
  2. 今后必须维护两个独立的代码库(即两次进行相同的错误修复和功能增强)

我考虑过的一件事是将大部分核心 TCP/IP 功能重写为更跨平台 (C/C++) 的东西,然后将我的 .NET 库更改为在此之上的一个薄层(P/Invoke?),然后在其上也写一个类似的薄 Java 层(JNI?)。

优点:

  • 我大部分时间只花一次时间写东西。

缺点:

  • 现在大部分代码都将不受管理 - 不是世界末日,但从生产力的角度来看并不理想(对我而言)。
  • 更长的开发时间(不能像移植到 Java 一样快地将 C# 套接字代码移植到 C/C++)[这是真的吗?]
  • 此时,底层 API 大部分已封装,库非常稳定,因此可能没有太多新开发 - 仅将当前代码移植到 Java 并偶尔需要做一些可能还不错将来会修复错误或公开两次新字段。
  • 我现有的客户端应用程序可能不稳定,而它们运行的​​版本在它们下面发生了巨大变化。 (我突然想到 32/64 位问题、字节顺序问题以及移植期间可能出现的一般错误等)

我简要考虑过的另一个选择是以某种方式将 Mono 安装到 Java,这样我就可以利用我已经拥有的所有现有 C# 代码。尽管对于必须使用它的 Java 开发人员来说,开发人员的体验有多流畅,但​​我并不太清楚。我很确定大多数代码在 Mono 下应该可以毫无问题地运行(除了解压 P/Invoke,它可能应该只是移植到 C#)。

如果我能提供帮助,我最好不要在我的代码和客户端 Java 应用程序之间添加另一层 TCP/IP、管道等(因此 WCF 到 Java 端的 WS-DeathStar 可能已退出)。我从未使用 Java 进行过任何认真的开发,但我感到自豪的是,该库目前对于第三方开发人员来说是小菜一碟,可以将其集成到他的应用程序中(当然,只要他运行 .NET: )),并且我希望能够为任何想要相同体验的 Java 开发人员保持同样的易用性。

因此,如果有人对我提出的 3 个选项有意见(移植到 Java 并维护两次,移植到 C 并为 .NET 和 Java 编写瘦语言绑定,或者尝试集成 Java 和 Mono),或任何其他我很想听听他们的建议。

谢谢

编辑:在与客户的开发人员直接交谈(即移除损坏的电话 AKA 销售部门)后,要求已经发生了很大变化,以至于这个问题不再适用于我的当前情况。不过,我会留下这个问题,希望我们能提出更多好的建议。

在我的特殊情况下,客户端实际上运行除了 Solaris 之外的 Windows 机器(现在谁不呢?)并且很高兴我们在库之上编写一个应用程序(Windows 服务)并提供更多简化和更小的 TCP/IP API 供他们编写代码。我们会将他们的简单消息翻译成下游系统可以理解的格式,并将传入的响应翻译回给他们使用,以便他们可以继续通过他们的 Java 应用程序与这个下游系统进行交互。

在考虑了几个星期之后回到原来的场景,我确实有更多的 cmets:

  • 如果您事先知道需要支持多种语言/平台,那么基于 C 的可移植库可能会是您的最佳选择。

  • 在 *nix 上,单个进程能否同时托管 Java 运行时和 Mono 运行时?我知道在早期版本的 .NET 中你不能在同一个进程中有两个不同的 .NET 运行时,但我相信他们已经用 .NET 4 解决了这个问题?如果这是可能的,如何在两者之间进行交流?理想情况下,您需要像静态方法调用和委托一样简单的东西来引发响应。

  • 如果在 Java 和 Mono(方法和委托等)之间没有简单的直接接口支持,可以考虑使用带有协议缓冲区的 ZeroMQ 或 Apache Thrift 作为消息格式。由于 ZeroMQ 支持不同的传输,这将在进程内、进程间和网络上工作。

【问题讨论】:

    标签: java .net porting code-reuse


    【解决方案1】:

    如果您真正想要的是能够在 .NET 中编写代码并让它在 JVM 上运行,您可以check out Grasshopper(2015-09:链接可能已失效)。这就是它的设计目的。

    我知道多年来,Mainsoft 的人一直是 Mono 的贡献者。如果我没记错的话,他们为 Mono 编写了 Visual Basic 编译器。

    还有C# to Java converter from Tangible。我听说过好东西,但我自己从未使用过。

    另外,它对你的情况没有多大帮助,但我应该指出Mono for Android

    Mono for Android 并行运行 CLR 和 Dalvik VM。换句话说,您为 Android 编写的 C# 代码可以调用 Java 库(例如 Android UI)并作为单个应用程序执行。您曾询问在同一进程中运行 .NET 和 Java 代码的能力。显然,这是可以做到的。

    【讨论】:

      【解决方案2】:

      如果您需要在 Java 虚拟机上运行但看起来很像 C# 的东西,您应该查看Stab。这对 P/Invoke 等没有帮助,但您可能会发现将 C# 代码移植到 Java 并维护它的工作量较少。

      不过,您应该查看Mono。我希望您的所有 C# 代码都可以不加修改地运行(接触非托管 DLL 的部分除外)。

      我没有使用它,但jni4net 应该允许从 Java 调用 .NET 代码。如果您的客户需要 Java 接口,这可能是一个解决方案。

      我一直在 Linux 和 Mac 上使用 Mono,即使 .NET 兼容性不是优先事项。我喜欢 C# 和 .NET 库,并且更喜欢 CLR 而不是 JVM。 Mono 已获得 MIT/X11 许可,这意味着您可以根据需要在商业上使用它。与其他一些人不同,我认为没有理由在偏爱甲骨文和 IBM 支持的技术的同时回避微软支持的技术。

      使用 Mono 不会帮助您处理非托管位,尽管您仍然可以 P/Invoke 到本机 DLL。您只需要自己移植该 DLL 或找到一些等效的。

      您可能还想查看 Mono Ahead of Time compilation

      【讨论】:

        【解决方案3】:

        我考虑过的一件事是将大部分核心 TCP/IP 功能重写为更跨平台 (C/C++) 的东西,然后将我的 .NET 库更改为在此之上的一个薄层(P/Invoke?),然后在其上也写一个类似的薄 Java 层(JNI?)。

        这是一种可能。在 Java 方面,您应该考虑使用 JNA 而不是 JNI。 (如果使用 JNI,则需要编写 C/C++ 代码以使用 JNI 特定的签名。)

        另一种可能性是用可以与多种编程语言“正常工作”的东西替换专有的二进制协议。这是 CORBA 和类似技术提供良好解决方案的问题空间。

        【讨论】:

          【解决方案4】:

          在您的情况下,这可能不是正确的解决方案,但为了完整性:

          有一些语言可以同时针对 JVM 和 .NET,特别是 Ruby(JRuby 和 IronRuby)和 Python(Jython 和 IronPython)。 Scala 也可能最终实现目标,尽管目前 .NET 版本与 JVM 版本相差甚远。

          无论如何,您可能会用 Ruby 或 Python 重写您的库并同时针对这两个运行时。

          【讨论】:

            【解决方案5】:

            你考虑过单声道吗?它很可能支持您在非 Windows 环境中的现有代码。诀窍是从 java 调用它,但单声道的人也可能有一些帮助你的东西。

            【讨论】:

              【解决方案6】:

              在决定实施之前花更多时间确定需求。在您知道需要什么之前,您没有任何标准来选择设计。

              如果它是一个非 Windows 环境,例如,在其中的任何地方都有 .NET 是没有意义的。

              【讨论】:

              • 我已将您的答案标记为正确,因为我的要求最终确实发生了变化。但是,我对此不是很满意——在广泛的需求分析之后,可能仍然存在需要这种互操作的场景,所以我仍然希望能有更好的答案。
              • 简短回答:不,我认为没有比从 c# 移植到 Java 更好的选择 :) 但考虑到客户需要代码的用途,这可能不是一个合适的解决方案,多少钱他愿意付钱等等。
              猜你喜欢
              • 2012-01-24
              • 1970-01-01
              • 2012-09-11
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多