• +4

    Потому что основа функционального программирования — это stateless-операции над аргументами функции. Когда мы добавляем внешний изменяемый state в качестве, например, базы данных, то теряется идемпотентность функций, и результат композиции становится непредсказуемым. Чтобы жестко зафиксировать последовательный порядок применений функций, требуется использовать специальную монаду IO, с которой программирование фактически становится императивным. Кроме того, результат вычисления функции — это уже не просто Response, а еще и измененный State. То есть красивая идеальная схема HttpResponse = WebApplication(HttpRequest) уже не работает, и проблема здесь будет не в getCustomerFromDatabase(), а в updateCustomerInDatabase().
    Поэтому для data-driven приложений функциональное программирование не лучший выбор.

    «Паттерны» функционального программирования
  • 0
    Checked исключения — это вариант возвращаемого значения с приятным бонусом в виде неявного завершения блока кода, вместо проверок возвращаемого методом кода (результата) — ловишь исключение.

    И кто вам мешает делать то же самое с unckecked? Разница лишь в том, что вас не обязуют это делать непосредственно в вызывающем методе. Если хотите, unchecked эксепшны — это вариант возвращаемого значения с неявным завершением блока, добавляемый для всех методов по умолчанию. Но основное назначение эксепшнов — это именно раннее завершение блока, а вот как раз бонус — это возвращаемое значение. Кроме того, когда требуется именно возврат определенного осмысленного значения, лучше использовать монады типа Optional или Try — для эксепшнов осмысленное значение редко выходит за рамки типа эксепшна и сообщения со стектрейсом.


    А насчет заворачивания исключений многократно могу лишь сказать так: руки кривые и излишнее проектирование.

    То есть архитектурный леер должен выставлять наружу делати реализации? :) Для самостоятельного осмысления требуется расставить эксепшны в throws:


    interface ConfigReader {
      Properties readConfig() throws ???;
    }
    class SQLConfigReader implements ConfigReader {
      Properties readConfig() throws SQLException;
    }
    class FileConfigReader implements ConfigReader {
      Properties readConfig() throws IOException;
    }
    class URLConfigReader implements ConfigReader {
      Properties readConfig() throws MalFormedURLException, IOException;
    }

    Не каждый уровень бизнес-логики вообще требует какой-либо работы с исключениями.

    Справедливо. Однако Java Api просто пронизан checked-исключениями. То есть либо перехватывайте и обрабатывайте, либо перехватывайте и врапьте, либо извольте отписаться в throws. И если уж затронули тему Java Api, то почему MalformedURLException и ParseException checked, а NumberFormatException unchecked, хотя все они возникают при парсинге текста.


    Вот чего не хватает в Java, так это возможности сказать, что любые исключения в этом методе считать unchecked — как раз избавится от ручного управления списком throws.

    И это будет последним костылем перед тем, как полностью перейти к unchecked.


    Современные IDE и компиляторы вполне умны, что бы понять какое исключение может быть в вызываемом методе и передать его выше.

    class MyService {
      void init(ConfigReader configReader) {
        // configReader -- это интерфейс.
        // В какой конкретный класс смотреть компилятору,
        // чтобы определить, какие исключения тут могут быть выкинуты?
        configReader.readConfig();
      }
    }
    Исправляем 7 распространенных ошибок обработки исключений в Java
  • –1

    Throws приходится пробрасывать через весь стек методов. При движении снизу вверх количество эксепшнов в throws будет только расти. Ну и как правило верхним уровням абсолютно пофиг что за ошибка там возникла — у него как правило стоит один универсальный обработчик на все типы эксепшнов.


    Есть расхожий паттерн о том, что эксепшны низких уровней нужно заворачивать в собственные более внятные: например при чтении конфигурации SQLException или IOException завернуть в свой ConfigurationException. Это плохо, потому как затрудняет абстракциям верхнего уровня получить внятный доступ к причине (в каком из цепочки getCause() он лежит?). В случае же, когда этого не требуется и абстракции верхнего уровня абсолютно пофиг на тип эксепшна, нет никакого смысла в заворачивании.


    Checked должны быть эксепшны, связанные с бизнес-логикой: валидацией данных, некорректным состоянием, etc. Эксепшны, связанные с ресурсами должны быть только unchecked, и это ошибка дизайна Java API.

    Исправляем 7 распространенных ошибок обработки исключений в Java
  • 0

    Ошибка одна — перехват исключений. В подавляющем большинстве случаев его в бизнес-коде вообще не должно быть. Практически всегда обработка исключений — это удел абстракций верхнего уровня, где как правило нет особой необходимости сильно различать тип эксепшна. К сожалению в Java checked exceptions обязуют перехватывать непосредственно в вызывающем методе, хотя практически всегда это не его ответственность. В частности в Java все исключения доступа к ресурсам checked: IOException, SQLException, JMSException, etc… Архитекторы посчитали, что вызывающий метод во что бы то ни стало просто обязан позаботиться о том, что если вдруг что-то пойдет не так. Реально же бизнес-код вообще не должен заботиться об ошибке доступа к ресурсам также как и не должен заботиться об InterruptedException или OutOfMemoryError — это должны компоненты верхнего уровня универсальным способом, например откатить транзакцию.

    Исправляем 7 распространенных ошибок обработки исключений в Java
  • 0
    1. Третье правило настоящего джентльмена — следи за путями.

    Что за треш? Paths.get(".", "log", "service.log") позволит вам навсегда забыть о File.separator.

    7 правил хорошего тона при написании Unit-тестов
  • +2
    Большинство джунов не в состоянии не только написать такой, но и понять зачастую. Поэтому посты типа "я ненавижу..." следует читать с солидной долей скепсиса.

    Это понятно. С другой точки зрения, джун, который мало-мальски в состоянии распарсить файл и запихнуть его в базу данных, при попытке сделать это на Spring Batch наполняется лютой и праведной ненавистью.

    Почему я ненавижу Spring
  • 0

    На мой взгляд основная проблема спринга, превращающая его из фреймворка в книгу заклинаний, состоит в повсеместном использовании аннотаций. Аннотации в java были придуманы для определения метаданных в коде. Но строить на их основе некий расширяемый метаязык для определения контекста приложения — это вкорне неверная идея, аннотации для этого не приспособлены. Расставленные в коде аннотации сематнически никем не контролируются, кроме рантайма: @EnableWebMvc я могу вообще поставить на любой объект, не обязательно на @Configuration — никто меня не ограничит.
    Есть гораздо более удобные, правильные и открытые способы задания конфигурации контекста без аннотаций, например Guice.
    Спринг же пытается всю задачу замести под ковер, оставляя пользователю лишь набор заклинаний и рецептов для описания бизнес логики, которые нужно использовать в определенном порядке, иначе просто не взлетит. Это очень эффектно для демонстраций и презентаций, но в реальных проектах при попытке заглянуть под ковер и что-то там изменить всегда сопряжена с головной болью и геморроем.

    Обратная сторона Spring
  • +7
    1. огромное количество библиотек и реализаций. Попробуйте навелосипедить свой spring-security c каким-нибудь oauth собственнм сервером и клиентом.

    В большинстве случаев это не нужно. Как правило вы используете какую-то одну конкретную технологию и уже готовую библиотеку для нее. Spring же предлагает навороченный абстрактный леер, интеграцию сразу со всеми известными технологиями и толстую книгу рецептов как это все засандалить в ваше приложение. Причем зачастую многие проблемы уже решены на более низком уровне, например тот же Servlet уже содержит простые средства security.


    Альтернативу @Transactional с нетривиальнм двухфазным коммитом (например БД + Очередь в единой транзакции).

    Двухфазный коммит делает не Spring, а стороннияя библиотека-координатор, например Atomikos, Narayana, etc. Spring @Transactional делает лишь наивный автоматический прокси на коммит/роллбэк, который также легко сделать вручную при помощи java.lang.reflect.Proxy, AspectJ или ByteBuddy. В реальных проектах практически всегда требуется вручную контролировать сбои и взависимости от типа ошибки нужно помимо роллбека повторить транзакцию, реинициализировать ресурс, отрапортовать о сбое, собрать метрики… Вот вам и свой @Transactional. Кроме того есть мнение, что XA вообще не рекомендуется использовать...


    но опять же время на изучение и не меньшее время чтобы все это подружить между собой

    Убеждался и продолжаю убеждаться, что гораздо быстрее сделать все самому, чем читать тонны документации, втыкать, стековерфловить и пытаться все это подружить между собой. Кроме того, как это зачастую бывает в спринге: шаг влево-шаг вправо от рецепта — и геморрой обеспечен.


    Представьте, что у вас ушел 1-2 ключевых разработчика, кто делал ваши велосипеды и потом найдите и пофиксите сложный баг.

    Ваши 1-2 разработчика писали когда-нибудь bean postprocessors? Скорей всего они намолотили кучу кривой прикладной магии ввиде специфических @Заклинаний. Разобраться почему не проксируется бин, кто его процессит и в какой последовательности и почему вдруг что-то перестало работать — никто не будет. Девелоперы как правило понавтыкают костылей, чтобы хоть как-то решить требуемую задачу.


    Куча проблем за вас решена

    И на ровном месте создана другая куча. Если все так просто — почему на SO Spring держится в топе? Как правило всегда есть более простое и элегантное решение каждой конкретной проблемы. Spring же пытается влезть без вазелина везде, где это только возможно, вцелом значительно усложняя архитектуру и упрощая лишь какие-то конкретные простые случаи использования. Кроме того, подобное упрощение имеет негативный эффект: куча кодеров, не понимая принципы работы, начинает копипейстить туториалы и SO, допуская архитектурные ошибки. И, столкнувшись с проблемами или с незнанием того, как что-то конкретное сделать на спринге, начинают грязно костылить.


    Сделать достаточно сложный проект на spring-boot для быстрого старта как прототип относительно несложно

    Сделать демку типа "хелло-ворлд" с кучей подключенных технологий. В реальном проекте требуется более полный контроль над кодом, где в итоге все плюсы ввиде средств автоматического бутстрапа превращаются в огромные минусы.

    Почему я ненавижу Spring
  • +3

    Вобщем-то на Java ввиду особенностей языка как раз нельзя написать нормальный DSL. Лямбды немного улучшают ситуацию, но не сильно. В частности, проблемы возникают с описанием иерархической структуры и со ссылками на проперти (которые всегда будут не type-safe). Стандартрый способ — клепать билдеры, но с ними получается очень гормоздко. Поэтому практически всегда для описания структур используют сторонний язык типа XML.


    P.S. В Java 8 идентификатор _ объявлен как deprecated, а Java 9 вообще запрещает его использовать.

    Рано закапывать Java
  • 0

    Те, кто юзают в бэкенде Java и Hibernate знают о такой вещи как JPA 2.1 Entity Graphs. Фактически это та же идея, что и GraphQL.

    GitHub переходит на GraphQL
  • +1

    У нас пострадали в основном крупные компании.
    http://www.elmundo.es/tecnologia/2017/05/12/59158a8ce5fdea194f8b4616.html


    В пятницу их работники получали уведомление отключить все персональные компьютеры до выяснения обстоятельств, что практически парализовало работу многих служб. Вобщем-то это говорит о низком уровне корпоративной политики безопасности.

    Как защищаться от атаки вируса-шифровальщика «WannaCry»
  • +1
    Вы хотите сказать в том же IBM отдельно сидят люди, которые участвуют в JCP и отдельно те, кто пишет софт и причем первые не общаются со вторыми? Не проблема ли это IBM

    Это проблема не только IBM, а всех крупных компаний, где есть жесткое разделение труда. И да, специалисты, участвующие в JCP, возможно не писали реальный бизнес-код уже лет десять или больше.


    Поэтому еще год назад от них были призывы "если вы видите какие-то проблемы у вашей библиотеки/фреймворка при переходе на Jigsaw — напишите нам!".

    Это когда еще мало-мальски стабильной девятки не было? Есть очень много решений, базирующихся на classpath. SLF4J использует classpath для поиска бэкенда для логгинга и настроек. Чтобы это сработало в модульной среде, библиотека должна быть изменена концептуально. И все остальные библиотеки, использующие SLF4J, будут ждать, пока мейнтейнеры соизволят выпустить его модульную версию, а также модульную версию всех своих зависимостей. И так с каждыми библиотеками, фреймворками и тулзами для сборки, тестинга и, наконец, продуктами. Период перехода может затянуться лет на 5 или больше, и все это время придется поддерживать две версии. В итоге экосистема сплитанется на две — модульную и classpath-ную.


    А теперь главный вопрос: в чем реальный профит модульности?

    Выход Java 9 снова отложен
  • +3

    Очевидно, это разные люди — те, кто пишет спецификации и те, кто разрабатывает софт. Когда появился более-менее стабильный кандидат девятки, компании попробовали портировать свой стек под новую платформу и во многом обломались. Я не уверен, что изначально даже был сделан анализ более-менее распространенных библиотек, фрекмворков и тулзов на предмет насколько их затронет изменение и какие могут быть методы решения. В любом случае, выход девятки — это будет глобальный сплит всей экосистемы.

    Выход Java 9 снова отложен
  • 0

    Наконец-то в браузере появятся нормальные лейауты! FlexBox вместе с GridLayout покрывают практически всю необходимость разметки в приложениях.
    А вообще, как-то странно: именно производители "того самого браузера" изначально предложили и пилили спецификацию GridLayout, теперь же хуже всех ее поддерживают.

    CSS Grid Layout. Быстрый старт
  • +6

    Дааа! Респект за упоминание Ultimae Records!!! В свое время они выпускали годную серию сборников псайбиента под названием Fahrenheit Project. Рекомендую всем! Просто офигительное звучание и очень интересные наработки! Из Solar Fields очень нравится его первый альбом Reflective Frequencies. Упомянутые Asura больше работает в стиле Slow Trance, а вот их бывший музыкант Aes Dana делает чистый dark ambient. Также вместе с Solar Fields они запилили неплохой проект H.U.V.A. Networks на том же Ultimae но по мне, так он слишком атмосферный — люблю тяжелые драм секции. Вобщем, лейбл Ultimae Records — номер один для любителей псайбиента.


    Еще тащился от проекта Vibrasphere — в основном они работают в PsyTrance, но у них есть прям сказочные псайбиентные треки. Жаль, что закрылись.

    Влияние ambient-музыки на процесс написания кода
  • 0

    Да, согласен. В этом случае OSGi действительно помогает как единая платформа для деплоя, если имеется большое число более-менее независимых модулей.


    Я сам не большой фанат контейнеров и микросервисов, поскольку в самой Java уже встроены неплохие средства виртуализации. Контейнеры сильно усложняют архитектуру и деплой и должны применяться только там, где это действительно необходимо, а не по зову моды. Также не имеет смысла искусственно дробить приложение на микросервисы, если у него единый функционал и цикл разработки.

    Модульные приложения на Java. Как?
  • 0

    А вот интересно, как вы все это пускаете в devmode? По стандартной схеме build-pack-deploy? Или плагин какой используете?
    И мне кажется, не совсем аргументирована модульность приложения. Внутренне — да, имеет смысл для кода и тестов. Но с точки зрения деплоя лучше иметь единственный артефакт, нежели груду джарников.
    Если необходима модульность, по-моему лучше будет разбить приложение на микросервисы и стартовать каждый в отдельной JVM/контейнере, как это делается сейчас. Единственный сценарий, который приходит на ум — платформа для деплоя различных приложений и микросервисов с разным циклом разработки. Что-то типа ESB или AppServer. Фактически там он в осносном и используется.

    Модульные приложения на Java. Как?
  • +2

    Я не совсем согласен с такой точкой зрения. Иметь свой корпоративный репозиторий в команде это, конечно же, хорошо и правильно. Но я всегда следую принципу, что проект должен уметь собираться всегда и везде, без лишних геморроев. Локальный репозиторий проекта — разумное решение, когда тебе нужен всего лишь какой-нибудь пропиетарный драйвер. Это делает сборку проекта автономной и независимой от окружения. Maven Wrapper при этом еще отлично помогает.

    Как с помощью maven работать с библиотеками, которых в maven нет
  • 0

    Есть одна проблема с локальным репозиторием — для мультимодульного проекта придется корректировать путь к нему в каждом pom.xml, так как project.badedir будет у каждого модуля свой.

    Как с помощью maven работать с библиотеками, которых в maven нет
  • +1

    По поводу IT-рекрутинга в блоге у yegor256 понравилась фраза: "You're Just the Mayonnaise in a Bad Sandwich"

    Открытое письмо рекрутерам IT-сферы
  • +2

    У меня сложилось такое впечатление, что сейчас под трендом "микросервисы" пытаются втюхать Spring Boot, Rest и иногда каким-то образом припаять Docker. И если посмотреть в Google Trends, то собственно так оно и есть. То есть чтобы в мозгу разработчика четко отложилось: java-приложения, оказывается, можно разрабатывать без контейнера, но для этого нужен Spring Boot, который нам даст Rest. И это теперь называется микросервисами.


    Тем не менее, 10 лет назад в эпоху засилия SOA и JavaEE, когдя я писал что-то вроде:


    @WebService
    public class AddService {
        @WebMethod
        public int add(int a, int b) {
            return a+b;
        }
        public static void main(String[] args ){
            Endpoint.publish("http://0.0.0.0:1234/AddService", new AddService());
        }
    }

    не было подходящего названия для этого. Люди недоумевали: если это java-приложение, то где интерфейс с кнопочками? Если это веб-приложение, то где сервер приложений, куда оно должно деплоиться? Здесь даже не было более-менее знакомого слова "Spring". И вплоть до того, что клиенты отказывались принимать работу, поскольку не знали каким словом это назвать (мой клиент все-таки придумал название — "тамагочи"))).


    Теперь же я любое решение, которое не требует контейнера, я с гордосью называю "микросервис" и вопросов не возникает.

    Многократное использование кода в микросервисной архитектуре — на примере SPRING BOOT
  • +2

    Практическая полезность была бы кстати, если бы JVM умела бы делать быстрый hot-restart: прибиваются все треды, освобождаются все системные ресурсы, но при этом оставлялся бы PermGen с классами, сгенеренной статистикой выполнения и предкомпилированным кодом.


    Предлагаю следующий этап эволюции GC и архитектуры приложений: не собирать мусор, пока не заполнится вся память, затем вызвать специальный OutOfMemory-хандлер у тредов, у которых он зарегистрирован, после чего начать полную сборку мусора.


    Что это даст? Процессинговые треды, имеющие OutOfMemory хандлер смогут обработать ситуацию: закрыть ресурсы, вернуть ошибку клиенту, сообщить в кластер, что нода отвалилась, и при необходимости рестартнуть после сборки мусора. Чтобы при вызове хандлеров не было повторного OutOfMemory вся аллокация ведется в отдельно зарезервированной области.


    Таким образом можно реализовать быстрый перезапуск процессинга без реальной необходимости перезапуска системы.

    Новый GC Epsilon. У джавы может не быть сборки мусора. Шок. Сенсация
  • +1

    Де-факто в Java есть проперти. И описаны они в стандарте JavaBeans при помощи геттеров и сеттеров. И многие сторонние фреймворки и библиотеки не привыкли работать напрямую с полями, а вместо этого делают интроспекцию пропертей.


    В общем случае некорректно думать о пропертях как о полях для хранения данных. Пропертя позволяют скрыть логику хранения данных и добавить дополнительный функционал как валидация значений, lazy-инициализации, связанные значения, события, etc. Ну и естественно, сделовать принципам ООП и переопределять поведение при наследовании.


    А в DTO геттеры и сеттеры действительно не нужны. Я по возможности стараюсь их делать immutable со всеми полями public final. Есть неплохой проект на этот счет Immutables.org.

    Начинается разработка OpenJDK 10
  • 0

    Вещь, которая изо дня в день бесит в java — геттеры сеттеры. Пусть сделают человечный property в качестве сахара. Дабы не быть голословным:


    class Test {
      private String vasya;
      public String getVasya() { return this.vasya;}
      public void setVasya(String vasya) { this.vasya = vasya;}
    }

    Итак, для описания одного лишь свойства vasya мы повторили это слово 7 раз в общей сложности затратив 17 слов! Думаете все? Нет. Добавьте еще javadoc-описание свойства к гетеру и продублируете его же в сеттере.


    Хочется некий алиас который бы генерировал для свойства поле, геттер и сеттер, а в интерфейсах только геттер и сеттер, плюс который бы позволял в коде напрямую обращаться к property. При этом бы вся семантика с override сохранялась.

    Начинается разработка OpenJDK 10
  • 0

    В Entity финальное поле, может, и не нужно. А вот при создании immutable-объектов, если используется сериализация отличная от Java, требуется определить пустой конструктор, где нужно инициализировать все final nonnull-поля (кстати, забыл в примере пометить как поле nonnull) дефолтными значениями. Если раньше все прокатывало с null-ами, то теперь требуется определить некие "пустые" объекты для каждого из полей.


    Я считаю, что нарушение контракта — это как раз вставка проверок на nonnull в рантайме, т.к. изначально эта аннотация планировалась исключително для warning-ов при компиляции. И с @SuppressWarnings код должен компилироваться и работать корректно.

    IntelliJ IDEA 2016.3: Java 8 и ES6, улучшенные отладчик и интерфейс, и многое другое
  • 0

    Очень интересно! Как я понял, MavenClassLoader по дефолту автоматически загружает все зависимости в один модуль. Если я хочу изолировать некоторые зависимости в отдельные модули, я их загружаю отдельно, а затем использую вариант с parent-ом — зависимости заново загружаться не будут?

    Модуляризация в JavaSE без OSGI и Jigsaw
  • –2

    Юмор понятен. Но вот реальный способ платить меньше.
    Выдавайте часть зарплаты различными социальными бонусами: карты на обеды, проезд в общественном транспорте, мед. страховка, абонемент в спортзал, etc… Вроде как для работника сумма та же, а вы экономите на налогах (НДС, подоходный).

    Как платить программистам меньше
  • 0

    Не подскажете, кто теперь насильно вставляет проверки на null для @Nonnull параметров? Это компилятор или IDE? Сейчас апдейтнулся и сломалась половина тестов с ошибкой:


    Caused by: java.lang.IllegalArgumentException: Argument for @Nonnull parameter 'correlationId' of services/storage/CorrelationStorage$Correlation. must not be null
    at services.storage.CorrelationStorage$Correlation.$$$reportNull$$$0(CorrelationStorage.java)

    Просто есть куча immutable классов с публичным конструктором и параметрами @Nonnull. Чтобы работали всякие JPA и сериализаторы, добавляю приватный конструктор по умолчанию, который вызывает публичный с нулами:

    class Bean {
    public final String param;
    public Bean(@Nonnull String param) {this.param = param;}
    @SuppressWarnings("all")
    private Bean() {this(null);}
    }

    До 16.3 все работало. Где отключается?

    IntelliJ IDEA 2016.3: Java 8 и ES6, улучшенные отладчик и интерфейс, и многое другое
  • +2
    Оговоримся, что Rabbit MQ у себя в production мы не используем из-за невозможности его работы с XA.

    Вместе с тем вы используете Rest, который вообще как бы не транзакционный. Странная мотивация.


    Данное решение так же устраняет проблему невозможности отката транзакции при работе с внешними сервисами. Никакой вызов не пройдет дважды — обработка начинается именно с того шага, на котором произошел сбой.

    Вопрос на засыпку: что делать, если мой любимый http вернул timeout? Rest обработал изменения или нет?
    В вашей схеме каждый Rest-сервис должен локально записывать транзакции и автоматически игнорировать их при повторном вызове.

    Реализация гарантированной асинхронной доставки сообщений
  • +2

    Знакомо, только в моем случае я пришел очень далеко не Junior-ом, а эти люди без надлежащего профессионального уровня, мне указывали что и как я должен делать.


    Есть три пути: потихоньку неспеша подыскивать новое место, либо втереться в доверие к кому-нибудь из верхушки и лизать ему задницу в надежде, что тебя примут, либо третий вариант — втихаря вкалывать, не гнушаться лишних заданий, проявлять инициативу, пытаться закольцевать как можно кода и решений на себя, помогать своим коллегам, пытаться выходить напрямую на контакт с клиентами. В определенный момент ты увидишь, как к тебе начнут прислушиваться как твои коллеги, так и "сверху". Помни, что ты развиваешься, а твоя "верхушка" нет, и скоро станет балластом.

    Разработчик: подушка безопасности
  • 0
    Более, чем можно себе представить.Если мы хотим при помощи корутин определять долгоиграющие StateMachine-ы, то состояние после suspend-а хотелось бы персистить, а перед resume-ом восстанавливать. Юзкейсов десятки, от всяких WebFlow, BPM до high availability.
    Континуации в Java
  • 0
    Там пока корутины не сериализуемы. Обещают подумать над темой в будущих релизах.
    Континуации в Java
  • 0
    Файберы — это не совсем континуации, это suspendable threads. Для континуаций не нужны никакие экзекьюторы. Весь экзекьютор — это простой цикл:
    Continuation d = Continuation.startWith(new MySuspendable());
    while(d!=null) {
    d = Continuation.continueWith(d);
    }
    т.е. фактически выполняются вручную, что дает полный контроль выполнения, и что как бы и требуется для задачи: при необходимости можно сериализовать и сохранить состояние в БД, при получении внешнего месседжа загрузить континуацию и продолжить.

    А поскольку файберы подобно тредам должны выполняться автоматически, им нужен внешний шедулер, который будет контролировать их выполнение. И чтобы свести случай к предыдущему, нужно писать свой шедулер. А в API квазара это как бы не совсем предусмотрено.
    Континуации в Java
  • +1
    В свое время искал решение для написания логики бизнес процессов на Java, что есть по сути обычная StateMachine. Хотелось бы, чтобы flow был написан натуральными конструкциями, но при этом код был асинхронный. Необходимо было: а) корутины, б) сериализация состояния, в) возможность полного перехватывания после suspend. Ничего не нашел, что бы могло бы на 100% удовлетворить.

    На мой взгляд основное неудобство Quasar в том, что выполнение файберов сильно завязано на FiberScheduler (которых фреймворк предоставляет два: FiberExecutorScheduler и FiberThreadPoolScheduler). Вся магия выполнения лежит в нем. Если я хочу кастомно выполнять файбер после прерывания Continuation.continueWith©, как это делается в javaflow, то придется писать свой Scheduler.

    Другое основное неудобство всех корутинных библиотек на Java — жесткое трюкачество на уровне байткода: требуется настройка тулзов и добавление агентов в рантайм. Все это сильно усложняет архитектуру, дебагинг и тесты.

    Так что лучше подождем, пока официально запилят корутины Kotlin-е.

    P.S. Добавьте еще одну библиотеку, которая на самый момент наиболее продвинутая — https://github.com/offbynull/coroutines
    Работает с Java8. Основной недостаток — приходится въявную таскать во все suspendable-методы объект Continuation.
    Континуации в Java
  • +2
    Приложение собирается при помощи Maven/Gradle и экспортирует все свои зависимости. JRE не таскаем — это уже реквизит клиента.
    Для запуска используем «Yet Another Java Service Wrapper». На Java корректно упавшее приложение в случае исключительной ситуации — это большая редкость. Чаще всего процесс висит, но не обрабатывает запросы. Поэтому всегда приходится делать велосипеды типа Watchdog-ов и интегрировать их с YAJSW.
    Про логи не понял. Однозначно slf4j+logback. Для кластерного приложения лучше поднять logging server и сбрасывать туда.
    Артефакты для деплоя хранятся в центральном репозитории, который есть SVN (не смейтесь) со всеми своими версиями, ветками, экономией места, etc… Деплой делается простой командой svn update. Более того, она иногда стоит в скрипте (пере)запуска.

    Теперь что огорчает:
    — Разрабатываю на Windows. Пускать VirtualBox, чтобы поднять контейнер, чтобы просто сделать билд приложению по-моему накладно. На данный момент билд приложения можно сделать на любой машине с JDK (спасибо Maven wrapper).
    — Упс. А у клиента Solaris :( И вообще они сказали, что это их инфраструктура и они хотят контролировать и мониторить что и как на ней вертится.
    — Меппинг портов из контейнера сильно усложняет использование извне таких API как JMX, и делает невозможным использование RMI. А также усложняет конфигурацию многих распределенных систем, использующих multicast протокол для service discovery.
    — И вообще service discovery в docker — отдельная и достаточно нетривиальная тема. Например уже так просто не запустить в контейнерах приложение с embedded Zookeeper или Hazelcast.

    Так что не все так однозначно.
    Docker in production: «Когда ты это кушаешь, тебе, как минимум, не противно, особенно если знаешь, как готовить»
  • 0

    Я все-равно не услышал убедительной причины для использования Docker с Java. Docker в первую очередь решает проблему с нативными приложениями, которые требуют установки, конфигурирования и кучи зависимостей. Чтобы не возиться со всем этим, приложения изолируют в отдельный контейнер, в котором есть все необходимое. А JVM сама по себе уже достаточно неплохо виртуализирована. Поэтому многие использует Docker только как некое средство упаковки и доставки своих приложений — некий супер-JAR, при этом не имея реальной необходимости в средствах виртуализации.


    Так что призыв паковать свои Java-микросервисы в Docker — это скорей как раз дань моде.

    Docker in production: «Когда ты это кушаешь, тебе, как минимум, не противно, особенно если знаешь, как готовить»
  • +2

    Фреймворк — это набор готовых шаблонов для решения определенного круга задач, который как правило базируется на определенной архитектурной парадигме (DI + IoC, Actors, Reactive, FP, etc...). Фреймворк позволяет девелоперу среднего уровня быстро бутстрапить типовые приложения без вникания в суть дела, просто копипастив код из примеров, а также предотвращает появление в коде слишком бурной фантазии новичка.


    Упрощает ли фреймворк разработку — вопрос неоднозначный. Да, если Вы досконально его изучили, умеете им пользоваться, понимаете как он работает внутри, знаете все его ограничения, и грамотно обходите возможные грабли. Однозначно нет, если Вы находитесь в процессе его изучения, параллельно используя его в своем проекте. В этом случае разработка превращается в постоянное гугление и вопросы на форумах "как сделать как мне надо при помощи этого фреймворка".

    Минимальный набор знаний молодого разработчика
  • 0

    У нас вот очень жесткие требования клиента по стандартизации, поэтому заставляют нас, несчастных, сидеть на голом JEE. Даже завернуть в Spring не дают. За последние 10 лет столько настрадавшись при разработке JEE и всевозможных аккуратно расставленных граблей, что у меня единственное желание — чтоб он поскорее, наконец, сдох, ибо суть тормоз в разработке и зло в чистом виде.

    «Недавно запустили систему онлайн-продаж для BMW»: T-Systems о роли Java и конференций в своей деятельности
  • +1
    Один и тот же код работает на нескольких Java EE 7-серверах без каких-либо дополнительных настроек

    Человек, однако, лукавит, не стесняясь. Все дополнительные настройки (DataSources, JMS Connection Factories, аутентификацию, etc...) придется делать ручками для каждого сервера по-своему. Ну и как бы дополнительные дескрипторы тоже приходится добавлять, начиная от меппинга jndi, если у вас не "hello world". В стандарте задуман только неинтересный джентльменский набор фич, все остальное — vendor-specific расширения. Процесс разработка просто ужасен. Единственно удобоваримый вариант — обернуть весь проект в Spring.

    «Недавно запустили систему онлайн-продаж для BMW»: T-Systems о роли Java и конференций в своей деятельности
  • 0

    Пункт 2 порождает глобальные проблемы в совместимости.


    Во-первых, это должно нарушить работу кучи библиотек и API. Пример:


    JAXBContext jc = JAXBContext.newInstance("com.acme.foo");
    

    JAXBContext лежит модуле в java.xml.bind, но доменные классы в com.acme.foo. То есть классы из com.acme.foo должны быть доступны модулю java.xml.bind, даже если он не импортирует модуль com.acme.foo.


    Во-вторых, не позволяет простым способом "патчить" сторонние библиотеки, просто переписав класс в том же пакете. Не понятно, возможен ли будет по желанию "полный" импорт библиотеки со всеми ее приватными классами.


    В-третьих, ни слова об экспортировании ресурсов: ClassLoader.getResource(). Если ресурсы доступны только текущему модулю, то это сломает огромное количество библиотек, в том числе java.util.ServiceLoader. Кстати, тему сервисов jigsaw вообще обходит стороной, тогда как в OSGi это центральная фишка.


    Ну и в-четвертых, приватные классы модулей могут вылезать наружу как содержимое других объектов. Самый простой пример: exception chain, который в getCause() будет содержать внутренний эксепшн модуля или его транзитивных зависимостей. Как будет контролироваться доступ к этим классам — не понятно.


    Вобщем, вопросов много, а вразумительных ответов по тому как работает модульность в jigsaw нет.

    Проект Jigsaw в Java 9. Модулярное будущее, которого не избежать