Сегодня вышла новая версия джавы — Java/JDK 13. Гонка началась с весеннего выпуска JDK 12, состоявшегося 19 марта, а форк от основной ветки произошел 13 июня. Кого-то мы там по пути потеряли вроде JEP 343: Packaging Tool, но в целом всё норм, и пора пожинать плоды.


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


JEP 351: ZGC: Uncommit Unused Memory


Как вы знаете, в JDK 11 у нас появился новый блестящий GC — ZGC, масштабируемый, быстрый и низкопаузный. Ну или по крайней мере, такова идея. Довольно серьезной проблемой в нем было то, что он вел себя как собака на сене и не отдавал занятую память, даже если она оказалась не нужна. Shenandoah и G1 давным-давно начали делиться, и поведение ZGC выглядело преступно нерукопожатно. Ну что ж, теперь всё починено, сразу после таймаута в -XX:ZUncommitDelay мы получаем свои байтики назад.


JEP 350: Dynamic CDS Archives


Сама фича CDS позволяет складывать загружаемые классы в общий архив, тем самым ускоряя запуск и уменьшая количество растрачиваемой оперативной памяти. К сожалению, раньше было как-то немного тупо, что нужно самому многократно перезапускать приложение, формируя список таких классов, а потом еще и руками дампить по этому списку. Теперь работают роботы, а не человек: когда выставлена опция -XX:ArchiveClassesAtExit, классы сбрасываются в архив автоматически после нормальной остановки приложения.



Stuart Marks — Doctor Deprecator, Consulting Member Of Technical Staff at Oracle + olegchir на Oracle Code One, считаные минуты после анонса Java 13


JEP 353: Reimplement the Legacy Socket API


Во всех (уже устаревших теперь) джавах, net.Socket и java.net.ServerSocket основываются на адской смеси Java и C-кода, от вида которого плачут даже самые закаленные теоретики перформанса. Проблему решили тем, что написали свежую реализацию, использующую ту же внутреннюю инфраструктуру, что и NIO, поэтому ей почти не нужно своего нативного кода. Ну и еще, это не легаси, написали всё красиво и пригодно к переезду на файберы из проекта Loom. Если интересно под капотом, то смотреть нужно класс NioSocketImpl.


JEP 354: Switch Expressions


Продолжаем готовиться к приходу паттерн-матчинга. Switch Expressions — это первью-фича, позволяющая писать код вида:


int j = switch (day) {
    case MONDAY  -> 0;
    case TUESDAY -> 1;
    default      -> {
        int k = day.toString().length();
        int result = f(k);
        yield result;
    }
};

Как видим в примере, со времен JDK 12 у нас есть одно косметическое изменение: break поменяли на yield, теперь всё как у всех нормальных людей.


JEP 355: Text Blocks


JEP 326: Raw String Literals отправился под нож, но дело его живёт! «Передайте товарищу Сталину — произошла чудовищная ошибка». Текстовые блоки — это новая превью-фича, которая позволяет обходиться без экранирования, она сама форматирует строки удобным образом, варит кофе с пенкой и чудесным образом даёт контроль над форматом получившейся строки.


Более приземлённо, теперь любой похапэшник без необходимости изучать JSP может написать что-то вроде:


String html = """
              <html>
                  <body>
                      <p>Hello, world</p>
                  </body>
              </html>
              """;

А начинающий DBA сможет строить карьеру, начав со следующего кода:


String query = """
               SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`
               WHERE `CITY` = 'NEW DEHLI'
               ORDER BY `EMP_ID`, `LAST_NAME`;
               """;


Звучит немного угрожающе


Предупреждение


Обзор JEP-ов — малая часть того, что можно и нужно рассказать про новую Java. Настоящий полный обзор должен включать ещё и всестороннее рассмотрение интересных тактических нововведений и обзор багов в багтрекере. Возможно, кто-то (lany, ау!) сможет продолжить эту работу. Мы с командой сейчас находимся на Oracle Code One — к сожалению, сидя на докладах или опершись о стенд Liberica JDK — довольно сложно написать что-то настолько длинное. В любом случае, это тема для совсем другого хабрапоста.



Брайан Гёц — Architect for the Java Language at Oracle + olegchir на Oracle Code One


А ещё у нас есть конференция Joker, на которой можно обсудить нужность перехода на Java 13, сроки перехода на ZGC, объемы запасов попкорна, необходимых после введения Text Blocks и другие актуальные вопросы. Билеты, как всегда, можно приобрести на официальном сайте.

Комментарии (63)


  1. puyol_dev2
    17.09.2019 20:53
    -22

    Apple внедрила text blocks в Swift 4 уже лет 5 как. Сколько помню, Java всегда в роли догоняющих


    1. avost
      17.09.2019 21:05
      +14

      Свифту 4 всего 2 года, а 5 лет назад в него внедрили, ага.
      Ява, конечно, в догоняющих, но догоняет точно не эпл :).


      1. MaximChistov
        18.09.2019 12:39
        +2

        Это как когда Swift всего год как вышел, а уже были вакансии с требованием опыта на Swift от 5 лет)


        1. striver
          18.09.2019 13:27

          Ну это с той же серии, что в 21 год 5 лет стажа и ВО.


          1. 4ITEP
            22.09.2019 02:18

            Вот здесь не стоит обобщать. У меня учеба вошла в стаж, и в 20 лет в моей трудовой можно было насчитать примерно 5 лет стажа. Если бы учился на заочке, то как раз к 21 получилась бы и вышка в придачу


            1. striver
              22.09.2019 11:33

              Опыт != стаж. Да, я ошибся, нужно было написать опыт работы. На стаж всем плевать, кроме пенсионного фонда.


      1. puyol_dev2
        19.09.2019 19:08
        -3

        2 года это конечно не 5 лет, но и не конец 2019. Java и правда где-то в ж%пе и уже лет N как. Да и Apple как-то потехнологичнее будет Oracle


        1. transcengopher
          19.09.2019 19:24
          +2

          Можно на это смотреть как на «следование в ж%пе». Но с другой стороны — язык, как и полагается старику с огромным количеством легаси, позволяет юношам с горящими взорами (которым нечего терять) кидаться на минное поле первыми. А потом собирает самые удачные остатки.

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


          1. puyol_dev2
            19.09.2019 21:36
            -1

            Очень сомнительное преимущество — поддержка старого кода. Опыт IT показывает, что если тянуть лямку слишком долго, то итог плачевный. Тот же Internet Explorer взять. Поэтому либо ты идёшь вперёд, беря с собой самые современные наработки и отсекая старьё, либо ждёт забвение на свалке истории


            1. transcengopher
              19.09.2019 23:02
              +2

              Вот и Java идёт вперёд — по дорожке, расчищенной более молодыми языками. И при этом имеет возможность тщательно выбрать, какие из модных веяний стоит включить в язык и стандартную библиотеку, а какие — всего лишь веяние, и завтра мода уйдёт, а фича языка останется, и её придётся поддерживать.

              Любая фича в языке интерферирует вообще со всеми другими фичами в языке, причём не только уже существующими, но и теми, что вы захотите добавить потом. Посмотрите на C++. Начиная с определённого порога заканчиваются понятные ключевые слова и синтаксис, и приходится начинать использовать непонятные. Или, как Вы выразились — отсекаем лишнее, и ломаем все программы, потому что до версии X оператор <:~: означал выход из корутины, а на момент выхода версии X + 1 корутины перестали быть модными, их сочли лишними и выкинули из языка, зато теперь оператор <:~: освободился, и его приспособили для атомарной записи в файл — разумеется, с ошибкой компиляции если типы не подошли.

              Я бы посмотрел на Вашего босса, когда Вы ему сообщите, что ETA перехода на версию X + 1 (где присутствует критическая для него заплатка CVE) составляет год, потому что старый код теперь нужно отсечь, а новый писать заново.

              > Тот же Internet Explorer взять.

              Этот опыт на самом деле нас учит не тому, что надо брать всё самое современное, а тому, что типичная для Microsoft тактика EEE иногда даёт слабину, и тогда они сокрушительно теряют позиции. Но и при этом в некоторых организациях до сих пор крутится и жрать не просит какая-нибудь внутренняя система, работающая только на IE, и организацию это полностью устраивает.


            1. striver
              19.09.2019 23:42
              +1

              Ваши предложения, что нужно делать банкам сейчас? Отказаться от текущего бизнеса, закрыться и открыться заново с чистого листа на новом языке? Или же вы предлагаете переписать софт на новый язык, который писался лет 20-30? Кто оплати эти издержки? Да, когда открывается новая компания, то есть смысл брать всё новое и желательно стабильное. Когда стартап перерастает себя и становится бизнесом среднего звена, то ему не помешают наработки за прошлые года. А когда это происходит, то ему вообще не важен новый фреймворк, главное — функционал, на который ушло время и деньги. Бизнес не зарабатывает на том, что для них пишут новый софт. Софт — это сопутствующий инструмент для бизнеса. Не все же крутиться на ММО-гриндилках, когда проект себя иссяк и можно смело закрыть сервак и открывать новый, с новой игрой, на новом движке и софте.
              Да, поэтому Java такая медленная в плане внедрения всего самого нового, потому что энетерпрайз такой.


    1. jreznot
      17.09.2019 21:07
      +6

      А вы кроме Apple не знаете никого? В Scala и Groovy это есть лет 10.


      1. jbaruch
        17.09.2019 21:49
        +14

        В Груви 15, но кто считает.


      1. AlexanderRS
        17.09.2019 22:11
        +4

        Эти блоки являют собой некую киллер фичу? Пол-года пишу на Котлине, где это тоже есть, но какого-то кайфа от появления такого инструмента в своей повседневной работе не испытал. Просто чуть удобнее.


        1. C4ET4uK
          17.09.2019 22:14
          +7

          Тут скорее не кайф от того, что это есть. А боль от того, что этого нет.


        1. sshikov
          18.09.2019 08:21
          +1

          Если они как в скале — то да. С интерполяцией.


        1. poxvuibr
          18.09.2019 18:01
          -1

          Вот надо написать тест, который проверяет, что объект правильно сериализуется в Json. Тогда делаешь текстовый файл, в котором отформатированный json, а потом сравниваешь его содержимое с результатом сериализации. И очень удобно было бы видеть этот отформатированный json прямо в коде теста. Но это в 12 джаве невозможно.


          1. AlexanderRS
            18.09.2019 19:30
            +3

            Положите Json в отдельный файл, не мучайте программистов такими вставками в код


            1. poxvuibr
              19.09.2019 10:33
              +1

              Сейчас я так и делаю, но мне кажется, что открывать отдельный файл ради того, чтобы посмотреть на 5 строк json, которые в нём находятся, гораздо мучительнее, чем посмотреть на текст, который находится в том же самом файле, что и тест.


    1. C4ET4uK
      17.09.2019 22:21
      +10

      Легко внедрить что-то в молодой и модный язык. А когда у тебя лежит на сердце тяжкий груз legacy каждую новую фичу добавляют с большой оглядкой.


      1. gary1
        18.09.2019 11:26
        +1

        Так, а разве у разработчиков Свифта на сердце лежит хоть какой-то тяжести груз легаси? На сколько знаю они не особо к обратной совместимости, просто ломают все при переходе на новую версию и не парятся.


    1. sergey-gornostaev
      18.09.2019 06:46
      +2

      Основной потребитель Java — это корпоративный сектор, а они перемен не любят, в энтерпрайзе до сих пор работает огромное количество кода, написанного в 70-х.


  1. martin_wanderer
    17.09.2019 21:45
    +4

    Первый пример из JEP 355 перепутан: это как раз как есть сейчас — «one dimensional». А должно быть «two dimensional»

    String html = """
                  <html>
                      <body>
                          <p>Hello, world</p>
                      </body>
                  </html>
                  """;
    


    1. olegchir Автор
      17.09.2019 23:52

      Поправил. Сорри, очень непросто на ходу набирать текст на планшете


  1. mad_nazgul
    18.09.2019 07:56

    Джабка со счастливым числом! :-)


    1. CyberSoft
      18.09.2019 13:01
      +1

      Жаль счастливый номер релиза пропустил такую счастливую пятницу...


      1. mad_nazgul
        19.09.2019 06:28

        Ну они старались… :-)


  1. Anton23
    18.09.2019 09:31

    Я как то писал на Хабре про Text Blocks: В Java 13 хотят добавить «текстовые блоки»


  1. dim2r
    18.09.2019 12:04
    -1

    Жду checked arithmetics, coroutines, memory fence


    1. excentro
      18.09.2019 12:10

      Когда ожидается?


  1. usharik
    18.09.2019 12:24
    +1

    Как бы теперь проект с восьмерки перетащить))


  1. koowaah
    18.09.2019 12:46

    Хотелось чтобы в Java внедрили свойства как в Kotlin.


    1. AstarothAst
      18.09.2019 14:24
      +2

      Просто возьмите котлин :)


      1. koowaah
        18.09.2019 14:51
        -2

        Хотелосься чтобы в Java добавили. Но можно использовать Lombok.


  1. koowaah
    18.09.2019 12:46

    Читал, что хотят уменьшить boilreplate код с помощю record, а как с остальными классами. И record которые-то хотят завести, какие-то урезанные. Хотят только readonly. Хотелось, чтобы было как в Kotlin: мутабельные и немутабельные.


    1. transcengopher
      18.09.2019 15:42
      +1

      Весь смысл record Foo {} не в уменьшении boilerplate, а именно в том, что он урезанный. У него не должно быть собственного identity, чтобы не таскать за собой "лишних" данных, заголовков, wait-списков и прочей чепухи, которой никто не пользуется, и иметь возможность инлайнить такие объекты в массив не перемежая их теми самыми заголовками. Именно поэтому они немутабельные — так как нету заголовка, всё состояние описывается значением полей, следовательно "другое значение поля <==> другая запись".


      Но работа над этим ведётся так долго именно от того, что все в округе хотят всего и сразу. Насколько я помню, в недавних докладах уже рассказывали, что из-за public demand пришлось чуть ли не повернуться на 180, и какие-то вещи оставить. Но вот точно могу сказать, что чем больше у вас запросов вида "хочу не урезанных" — тем меньше у вас причин пользоваться записями. Если вы хотите только синтаксис — берите Lombok (ну или Kotlin сразу, чего мелочиться), а та фича про оптимизацию памяти.


      1. koowaah
        18.09.2019 16:29

        Вы имеете в виду

        inline class Foo {}

        или
        record Foo {}


        1. transcengopher
          19.09.2019 16:02

          Признаюсь, я думал, что речь в целом шла про inline class, а record — это прежнее название того же самого, но в прошлом.
          Сейчас перепроверил, и таки нашёл их parent JEP 359 (про который просто преступно мало информации — видимо, все сейчас смотрят на Вальгаллу).
          Тем не менее, штука про отсутствие собственного identity (точнее, логическому равенству между state и identity) и «другие значения <==> другая запись» тут ещё более применимы, это проистекает из самого исходного требования о полном соответствии состояния объекта его identity. Словами автора (в весьма вольном переводе):

          Аргумент против изменяемости записей более сложен [чем против расширяемости], так как, в теории, вполне можно представить примеры когда возможность мутировать не идёт против основной цели создания подобных типов. Однако, изменяемость мешает соответствию между состоянием объекта и API его типа. Например, как правило, будет ошибкой использовать изменяемое состояние в методах equals() и hashCode(), так как это создаёт возможность для подобных элементов, к примеру, «неожиданно исчезать» из HashSet'ов или словарей HashMap. Иными словами, изменяемые поля записей означают, что мы хотим использовать протокол equals/hashCode, отличный от определения состояния; либо же, мы хотим конструировать подобные объекты по-другому (объекты во многих доменах создаются с использованием конструктора по умолчанию, а затем «заполняются» состоянием посредством вызова сеттеров, либо их конструктор принимает только поля их «натурального ключа».) Такие объекты, теряют одно из основных важных отличительных свойств: мы более не сможем выделить их API только лишь из описания их состояния. (И, как только мы введём в рассмотрение изменяемость, нам придётся также думать о потоко-безопасности, а это будет сложно примирить с основными целями введения записей в язык.)

          cr.openjdk.java.net/~briangoetz/amber/datum.html, секция Restrictions/Mutability


  1. DmitryOlkhovoi
    18.09.2019 12:54

    Ну что, кто рискнет деплоить прод с java 13? Китайцы будут ждать 14ю :)


    1. tmteam
      18.09.2019 13:00
      +2

      По пятницам по прежнему нельзя, а в остальные дни — пожалуйста


    1. striver
      18.09.2019 13:29

      А много ли есть энтрепрайза, который отошел даже от 8-й? )


    1. koowaah
      18.09.2019 13:39
      +1

      В продакшине будет использоваться LTS версии. Следующая Java 17, и то после пару лет после выхода и исправления ошибок.


  1. werklop
    18.09.2019 15:30

    Кого-то мы там по пути потеряли вроде JEP 343: Packaging Tool
    а какие есть альтернативы, кто что использует для этого?


    1. CyberSoft
      18.09.2019 16:40

      Например, rpm-maven-plugin для RHEL/CentOS
      Надо полагать, для поддержки всего зоопарка нужно прикручивать и другие плагины. А тут вам на блюдечке будут предлагать готовое решение из коробки и на все случаи жизни. Жду не дождусь, когда добавят


    1. Kipriz
      19.09.2019 12:06

      Им уже можно спокойно пользоваться. Я пробовал делать msi для Windows и pkg/dmg для Мака — всё отлично работает. Да, есть некие опасение, что это всё ещё early access, но кто мешает попробовать и потестировать?
      Доки вполне понятны, если нужна помощь — обращайтесь.


  1. CyberSoft
    18.09.2019 16:39

    del


  1. regent
    18.09.2019 18:48

    А liberica тормозит со сборкой… У них только ea…
    И spring со своим блин перепакованным spring asm'ом…

    Caused by: java.lang.IllegalArgumentException: Unsupported class file major version 57
    at org.springframework.asm.ClassReader.(ClassReader.java:184)


  1. lany
    19.09.2019 10:12

    Возможно, кто-то (lany, ау!) сможет продолжить эту работу

    Вон Саймон уже написал.


    1. olegchir Автор
      22.09.2019 02:21
      +1

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


      1. lany
        23.09.2019 08:51
        +1

        Ну свежие апишечки он в конце перечислил, а это не часть джепов. Просто прямо скажем ничего нового в этой вашей джаве 13 не появилось :-)


  1. Maccimo
    22.09.2019 07:34

    Многострочные строковые литералы до сих пор не внесли в список особо зловонных Code Smells?
    Очень странно.


    1. lany
      23.09.2019 08:52

      В тестах у нас их полно. Мне кажется, в тестах они наиболее оправданны. Некоторые только ради них пишут тест на груви или Котлине.


      1. AstarothAst
        23.09.2019 09:53

        А можно попросить пример? То ли у меня кейсов таких нет, то ли мимо меня прошел удобный трюк…



  1. eliduvid
    23.09.2019 21:10

    А String.formatted() вошёл в тринадцатку? Он был частью jep-а про многострочные стринги но сходу о нём информации не нашлось


    1. transcengopher
      24.09.2019 17:04

      Вошёл, но, пока JEP в Preview, пользоваться в боевом коде им не стоит (как и фичей в целом, само собой).


  1. relgames
    24.09.2019 23:50
    +1

    Смешно — Spring Boot еще 12 не поддерживает, Google Jib поддерживает 8 и 11, а тут уже 13.

    В реальной работе они минимум через год, а то и два появятся — а к тому моменту уже не будут поддерживаться.

    Остается LTS 11.


    1. transcengopher
      25.09.2019 14:23

      Так ведь и не появилось, по сути, ничего такого ни в 12-й версии, ни в 13-й, что требовалось бы специально поддерживать. Ну что там, улучшенный ZGC? CDS-архивы? Как библиотека сможет это поддержать, а главное — зачем? Опять же, поддерживать preview-фичи — себе дороже, всё равно придётся что-то переделывать в итоге.
      Если что-то поддерживает 8 — с этим уже можно удобно работать, если 9 и упаковано в модуль — тем более хорошо. А вот всё остальное это сугубо некритично, в пользовательском коде откликается чем-то вроде мелких улучшений.
      И в официальных заявлениях о поддержке всё очень логично. 11-я версия носит метку LTS — её все и будут официально поддерживать, и это правильно. Когда выйдет следующий LTS-релиз — будут официально поддерживать его. Это вовсе не означает, что промежуточные версии никто не поддерживает, это нужно делать хотя бы потому, что иначе прыжки через несколько релизов будут очень тяжелыми.


    1. olegchir Автор
      25.09.2019 15:48

      Что значит "не поддерживает", какие ваши доказательства?


      1. transcengopher
        25.09.2019 17:34

        Он, возможно, вот про эту страницу:
        docs.spring.io/spring-boot/docs/current/reference/html/getting-started-system-requirements.html
        Хотя там контрастным по менее контрастному написано, что

        up to 12 (Included)
        Так что непонятно, откуда дровишки.

        Вот ContainerTools действительно никто, вроде, не собрал для JDK 12.


        1. relgames
          25.09.2019 22:48

          Java 10 is supported as of Spring Boot 2.0.1.RELEASE. Java 11 is supported as of Spring Boot 2.1.0.M2. The plan is to officially support Java 12 as of Spring Boot 2.2

          github.com/spring-projects/spring-boot/wiki/Spring-Boot-with-Java-9-and-above


          1. transcengopher
            26.09.2019 16:44

            А. Если нужна прямо официальная поддержка, то пока придётся пользоваться LTS. Даже у самой 13-й версии окно официальной поддержки от разработчиков(!) длится ровно до выхода JDK 14, в отличие от 11, у которой поддержка будет вроде даже немного после выхода JDK 17. Но обратную совместимость между 11, 12 и 13 вроде не ломали, так что разрабатывать вполне можно уже сейчас, а тем временем подтянется и соответствующий релиз Boot.

            Java взяла курс на моду и молодёжность, чтобы не выглядеть совсем уж замшело в глазах нынешних программистов, у которых новый любимый фреймворк рождается, делает несколько мажорных релизов без обратной совместимости, и умирает — за время, пока Java всё ещё готовит к релизу очередную версию с кучей плюшек.

            Логически не-LTS релизы JDK теперь, видимо, имеют смысл минорных версий — насколько я помню, они даже @Deprecated(forRemove) будут удалять именно в LTS релизах. Плюс Preview Features, да плюс инкубаторы — разумеется, этот зоопарк не для кровавого интерпрайза, а для экспериментов и смузи.

            Ну да, на острие придётся быть «на свой страх и риск». А где-то и когда-то это разве было не так?

            На нашем родном проекте будут вводить JDK 12/13 из-за внутренних изменений, но вот language target на всём проекте до сих пор 8 (да, кровавый интерпрайз), хотя я бы лично был бы очень рад текстовым блокам, например.


      1. relgames
        25.09.2019 21:33

        Официально будет в Boot 2.2, а он ещё не вышел.