Есть ли лучшие варианты, чем портирование с C # на Java? - PullRequest
5 голосов
/ 17 апреля 2011

У меня есть существующая библиотека, написанная на C #, которая оборачивает гораздо более низкоуровневый TCP / IP API и предоставляет сообщения, поступающие по проводам с сервера (собственный двоичный протокол), как события .NET.Я также предоставляю вызовы методов для объекта, который обрабатывает сложности маршалинга удобных типов .NET (например, System.DateTime) вплоть до двоичных кодировок и структур фиксированной длины, которые требуются API (для исходящих сообщений на сервер).Существует немало существующих приложений (как внутренних, так и используемых третьими лицами), построенных поверх этой библиотеки .NET.

Недавно к нам обратился человек, который не хочет делать вселегкая работа по абстрагированию самого TCP / IP, но их среда строго не Windows (я полагаю, * nix, но я не уверен на 100%), и они предположили, что их идеал будет чем-то вызываемым из Java.

Каков наилучший способ удовлетворить их требования, без необходимости:

  1. Портировать код на Java сейчас (включая неуправляемую DLL, которую мы в настоящее время используем для распаковки P / Invoke)
  2. Нужно поддерживать две отдельные кодовые базы, идущие вперед (т.е. дважды вносить одинаковые исправления ошибок и улучшения возможностей)

Одна вещь, которую я рассмотрел, - переписать большую частьОсновные функциональные возможности TCP / IP - однажды во что-то более кросс-платформенное (C / C ++), а затем измените мою библиотеку .NET на тонкий слой поверх этого (P / Invoke?), а затемПовторите также тонкий Java-слой поверх него (JNI?).

Плюсы:

  • В основном я пишу вещи только один раз.

Минусы:

  • Большая часть кода теперь будет неуправляемой - не конец света, но не идеальный с точки зрения производительности (для меня).
  • Большевремя разработки (нельзя переносить код сокетов C # на C / C ++ так же быстро, как просто перенос на Java) [Насколько это верно?]
  • На этом этапе основной API в основном упакован, а библиотека оченьстабильный, так что, вероятно, не так уж много новых разработок - может быть не так уж и плохо просто перенести текущий код на Java, а затем придется периодически исправлять ошибки или выставлять новые поля дважды в будущем.
  • Потенциальная нестабильность для моих существующих клиентских приложений, в то время как версия, на которой они работают, резко меняется под ними.(Вдобавок ко всему, я могу вспомнить проблемы с 32/64 битами, проблемы с порядком байтов и общие ошибки, которые могут возникнуть во время порта и т. Д.)

Еще один вариант, который я кратко рассмотрелкаким-то образом настраивает Mono до Java, чтобы я мог использовать весь существующий код C #, который у меня уже есть.Я не слишком осведомлен о том, насколько гладким будет опыт разработчика для разработчиков Java, которые должны его использовать.Я почти уверен, что большая часть кода должна без проблем работать под Mono (за исключением декомпрессии P / Invoke, которая, вероятно, в любом случае должна быть просто портирована на C #).

В идеале я бы не хотел добавлять другой слойTCP / IP, каналы и т. д. между моим кодом и клиентским Java-приложением, если я могу помочь (так что, вероятно, отсутствует WCF для Java-DeathStar на стороне Java).Я никогда не занимался серьезной разработкой с Java, но я горжусь тем, что библиотека в настоящее время является частью процесса интеграции для стороннего разработчика в его приложение (если, конечно, он работает на .NET:)), и я хотел бы иметь возможность сохранить ту же простоту использования для любых разработчиков Java, которые хотят того же опыта.

Так что, если у кого-то есть мнения по поводу трех предложенных мной вариантов (портировать на Java и поддерживать дважды, портировать на C и писать тонкие языковые привязки для .NET и Java или, попробовать и интегрировать Java и Mono), или любые другие предложения, которые я бы хотел услышать.

Спасибо

Редактировать: После разговора непосредственно с разработчиком на клиенте (т.е. удаление сломанного телефона отдела продаж AKA) требования изменились настолько, что этот вопрос уже не очень хорошо подходит для моей непосредственной ситуации. Однако я оставлю вопрос открытым в надежде, что мы сможем выработать еще несколько хороших предложений.

В моем конкретном случае клиент на самом деле работает на машинах с Windows в дополнение к Solaris (а кто нет?) И рад, что мы напишем приложение (служба Windows) поверх библиотеки и предоставим гораздо больше упрощенный и меньший API TCP / IP для них, чтобы кодировать против. Мы переведем их простые сообщения в формат, понятный нисходящей системе, и переведем входящие ответы обратно для их использования, чтобы они могли продолжать взаимодействовать с этой нисходящей системой через приложение Java.

Возвращаясь к исходному сценарию, подумав об этом пару недель, у меня есть еще несколько комментариев:

  • Переносная библиотека на основе C с различными языковыми привязками сверху, вероятно, была бы подходящим вариантом, если бы вы заранее знали, что вам потребуется поддержка нескольких языков / платформ.

  • В * nix, может ли один процесс одновременно выполнять как среду исполнения Java, так и среду Mono? Я знаю, что в более ранних версиях .NET у вас не было двух разных сред выполнения .NET в одном и том же процессе, но я думаю, что они исправили это в .NET 4? Если это возможно, как можно общаться между двумя? В идеале вам нужно что-то такое простое, как статический вызов метода и делегат для получения ответов.

  • Если нет простой прямой поддержки интерфейса между Java и Mono (методы, делегаты и т. Д.), Можно рассмотреть возможность использования чего-то вроде ZeroMQ с буфером протокола или Apache Thrift в качестве формата сообщения. Это будет работать внутри процесса, между процессами и по сети из-за поддержки ZeroMQ различных транспортов.

Ответы [ 6 ]

2 голосов
/ 17 апреля 2011

Если вам нужно что-то, что работает на виртуальной машине Java, но очень похоже на C #, вы должны проверить Stab .Это не поможет вам с P / Invoke и т. П., Но вам может не понадобиться переносить ваш код C # на Java и поддерживать его.

Хотя вам следует изучить Mono .Я ожидаю, что весь ваш код C # будет работать без изменений (кроме частей, которые касаются неуправляемой DLL).

Я не использовал его, но jni4net должен позволять вызывать код .NET из Java,Если вашим клиентам нужен интерфейс Java, это может быть решением.

Я использую Mono в Linux и Mac все время, даже если совместимость с .NET не является приоритетом.Мне нравятся библиотеки C # и .NET, и я предпочитаю CLR JVM.Mono имеет лицензию MIT / X11, что означает, что вы можете использовать его в коммерческих целях, если хотите.В отличие от некоторых других, я не вижу причин избегать технологий, отстаиваемых Microsoft, в то время как предпочитаю технологии, отстаиваемые Oracle и IBM.

Использование Mono не поможет вам с неуправляемыми битами, хотя вы все равно можете использовать P / Invoke в нативномDLL.Вам просто нужно портировать эту DLL самостоятельно или найти какой-нибудь эквивалент.

Вы также можете посмотреть компиляцию Mono Ahead of Time .

2 голосов
/ 17 апреля 2011

Потратьте больше времени на сбор требований, прежде чем принять решение о реализации.Пока вы не знаете, что требуется, у вас нет никаких критериев для выбора между проектами.

Если это не Windows-среда, нет смысла иметь .NET где-нибудь там, например.

1 голос
/ 20 июня 2011

Если вам действительно нужно иметь возможность кодировать в .NET и запускать его на JVM, вы можете проверить Grasshopper (2015-09: ссылка, возможно, не работает). Вот для чего он предназначен.

Я знаю, что ребята из Mainsoft на протяжении многих лет вносили свой вклад в Mono . Если я правильно помню, они написали компилятор Visual Basic для Mono.

Существует также конвертер C # в Java из Tangible . Я слышал хорошие вещи, но я никогда не использовал это сам.

Кроме того, это не очень помогает вашей ситуации, но я должен отметить, Mono для Android .

Mono для Android запускает CLR и Dalvik VM параллельно. Другими словами, код C #, который вы написали для Android, может вызывать библиотеки Java (например, пользовательский интерфейс Android) и выполняться как одно приложение. Вы спрашивали о возможности запуска кода .NET и Java в одном процессе. Понятно, что это можно сделать.

1 голос
/ 17 апреля 2011

Это, вероятно, не правильное решение в вашем случае, но для полноты:

Существует несколько языков, которые могут работать как с JVM, так и с .NET, в частности Ruby (JRuby и IronRuby) и Python (Jython и IronPython). Scala может в конечном итоге тоже туда попасть, хотя сейчас версия .NET сильно отстает от версии JVM.

В любом случае, вы можете переписать свою библиотеку на Ruby или Python и настроить обе среды выполнения.

1 голос
/ 17 апреля 2011

Вы рассматривали моно? Скорее всего, он будет поддерживать ваш существующий код в среде, отличной от Windows. Трюк будет вызывать его из Java, но у моно может быть кое-что, что может вам помочь.

0 голосов
/ 17 апреля 2011

Одна вещь, которую я рассмотрел, состоит в том, чтобы переписать большую часть основных функций TCP / IP один раз в нечто более кросс-платформенное (C / C ++), а затем изменить библиотеку .NET на тонкий слой поверх этого. (P / Invoke?), А затем напишите аналогичный тонкий слой Java поверх него (JNI?).

Это возможно. На стороне Java вы должны рассмотреть возможность использования JNA, а не JNI. (Если вы используете JNI, код C / C ++ должен быть написан для использования специфичных для JNI подписей.)

Другая возможность заключается в замене проприетарного двоичного протокола чем-то, что «просто работает» с несколькими языками программирования. Это тип проблемного пространства, где CORBA и аналогичные технологии обеспечивают хорошее решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...