При решении повседневных задач с интерфейсом настольного приложения, реализованного на JavaFX, приходится в любом случае делать запрос на веб-сервер. После времен J2EE и страшной аббревиатуры RMI многое изменилось, а вызовы на сервер стали более легковесными. Как нельзя кстати для подобной проблемы подходит стандарт веб-сокетов и его обмен простыми текстовыми сообщениями любого содержания. Но проблема корпоративных приложений в том, что разнообразность и количество запросов превращает создание и отслеживание EndPoint-ов при наличии отдельно выделенных бизнес-сервисов в жуткую рутину и добавляет лишних строк кода. А что если взять за основу строго типизированную стратегию с RMI, где между клиентом и сервером существовал стандартный java interface, описывающий методы, аргументы и возвращаемые типы, где добавлялось пару аннотаций, и волшебным образом клиент даже не замечал, что идет вызов по сети? Что если по сети передавать не просто текст, а сериализованные java-объекты? Что если добавить к этой стратегии легкость веб-сокетов и их преимущества возможности push-вызовов клиента со стороны сервера? Что если асинхронность ответов веб-сокета для клиента обуздать в привычный блокирующий вызов, а для отложенного вызова добавить возможность возвращения Future или даже CompletableFuture? Что если добавить возможность подписки клиента на определенные события от сервера? Что если на сервере иметь сессию и подключение к каждому клиенту? Может получиться неплохая прозрачная связка привычная любому java-программисту, так как за интерфейсом будет скрыта магия, а в тестировании интерфейсы легко подменить. Но вот только это все не для нагруженных приложений, обрабатывающих, например, котировки с фондовой биржи.  В корпоративных приложениях из моей практики скорость выполнения sql-запроса и передачи выбираемых данных из СУБД несоизмеримы с накладными расходами на сериализацию и рефлексивные вызовы. Более того страшная трассировка EJB-вызовов, дополняющая длительность выполнения до 4 — 10 мс даже на самый простенький запрос не является проблемой, так как длительность типичных запросов находится в коридоре от 50мс до 250мс. Начнем с самого простого — воспользуемся паттерном Proxy-объект для реализации магии за методами интерфейса. Предположим, что у меня есть метод получения истории переписки пользователя с его оппонентами: Proxy-объект создадим стандартными средствами java, и вызовем на нем нужный метод: Если при этом настроить фабрики, а экземпляр proxy-объекта внедрять по интерфейсу через cdi-инъекцию, то получится магия в чистом виде. При этом открывать/закрывать сокет каждый раз совсем не обязательно. Напротив в моих приложениях сокет постоянно открыт и готов к приему и обработке сообщений. Теперь стоит посмотреть, что такого происходит в RMIoverWebSocketProxyHandler: А вот собственно сам клиентский EndPoint: Таким образом, на вызов любого метода proxy-объекта берем открытую сессию сокета, шлем переданные аргументы и реквизиты метода, который необходимо вызвать на сервере, и wait-имся до получения ответа с указанными ранее в запросе гуидом. При получении ответа проверяем на наличие исключения, и, если все хорошо, то кладем в Request результат ответа и нотифицируем поток, ожидающий ответа в WaitList-е. Реализацию такого WaitList-а приводить не буду, так как она тривиальна. Ожидающий поток в лучшем случае продолжит работать после строки WaitList.putRequest(request, getRequestRunnable(request));. После пробуждения поток проверит наличие задекларированных в секции throws исключений, и выполнит возврат результата через return. Приведенные примеры кода являются выдержкой из библиотеки, которая пока не готова для выкладки на github. Необходимо проработать вопросы лицензирования. Реализацию серверной стороны имеет смысл смотреть уже в самом исходном коде после его опубликования. Но ничего особенного там нет — выполняется поиск ejb-объекта, который реализует указанный интерфейс, в jndi через InitialContext и делается рефлексивный вызов по переданным реквизитам. Там конечно еще много чего интересного, но ни в одну статью такой объем информации не влезет. В самой библиотеке приведенный сценарий блокирующего вызова был реализован в первую очередь, так как является самым простым. Позже была добавлена поддержка неблокирующих вызовов посредством Future и CompletableFuture<>. Библиотека успешно используется во всех продуктах с настольным java-клиентом. Буду рад, если кто-то поделится опытом открытия исходного кода, который линкуется с gnu gpl 2.0 (tyrus-standalone-client). В итоге построить иерархию вызова метода стандартными средствами IDE до самой UI-формы, на которой обработчик кнопки дергает удаленные сервисы, не составляет труда. При этом получаем строгую типизацию и слабую связанность слоя интеграции клиента и сервера. Структура исходного кода приложения делится на клиент, сервер и ядро, которое подключается зависимостью и в клиент, и в сервер. Именно в нем и находятся все удаленные интерфейсы и передаваемые объекты. А рутинная задача разработчика, связанная с запросом в БД, требует нового метода в интерфейсе и его реализации на стороне сервера. На мой взгляд, куда уж проще... javaee/javafx разработчик