Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Иван Крылов — Разговор про Java 9

Moscow JUG
December 15, 2016

Иван Крылов — Разговор про Java 9

В 2017 ожидается выход новой версии Java – Java 9. Пришло время поговорить про то:
- как скоро потребуется переезжать на новую версию;
- чем являются модули и как переводить свои приложения на модульную архитектуру;
- как взаимодействовать с немодульным кодом;
- какие новые API появятся в Java 9.

Доклад является расширенной и значительно обновленной версией доклада на данную тему с конференций Jokerconf 2015 и Geekout 2016.

Moscow JUG

December 15, 2016
Tweet

More Decks by Moscow JUG

Other Decks in Programming

Transcript

  1. Кто такой Иван Крылов 2000 - Магистр Математики - “Политех”

    2004 - К.т.н. - “Бонч” 1999 - 2005 Занимался оптимизацией медиакодеков для DSP 2005 - 2016 Занимаюсь JVM, Java Runtime, OpenCL native compiler, JITs, Compiler Infrastructure 2
  2. 3

  3. Zing: Виртуальная Java-машина для крупного бизнеса • Главная цель -

    улучшение показателей функционирования виртуальной Java-машины для предприятий • Неизменная производительность - не просто быстро, а ВСЕГДА быстро • Сборка мусора больше не влияет на производительность приложений • Широчайшая сфера применения: • от интерактивных приложений до задач, критичных ко времени отклика • от микросервисов до приложений, требующих больших объемов памяти • Устраняет необходимость в большинстве известных "костылей" в вашем коде 3
  4. Zulu Embedded: Когда нужны решения для встроенных систем • 100%

    открытый код - технология, основанная на OpenJDK • Сертифицирована на совместимость и соответствие Java SE • Показатели функционирования, идентичные OpenJDK и Oracle Java SE • Высококлассная поддержка • Релизация для Linux x86, ARM32, ARM64, PPC32, MIPS, а также Windows и Mac OS 4
  5. Про этот JUG • Разговор про Java 9, а не

    тренинг • Это не обучение и я не топ эксперт • Это не реклама девятки • Нам бы пережить • Всё может еще поменяться: • фичи, сроки и т.п. 5
  6. Временные интервалы выхода версий Java JDK 6
 Дек 2006 JDK

    7
 Июль 2011 JDK 8
 Мар 2014 JDK 9
 план. Июль 2017 JDK 6
 Ноя 2012 JDK 7
 Апр 2015 JDK 8
 план. Июль 2018 J2SE 1.4
 Дек 2006 JDK 5
 Окт 2009 6 GA EOL
  7. Что означает наступление дня EOL? Настал день EOL Нужны исправления

    найденных уязвимостей & Подписать Support Contract Перейти на OpenJDK (Zulu, IcedTea, сборку своими силами) Обновиться до следующей версии JDK 7
  8. Вспомним новое в Java 8 • Лямбды • Method references

    • Type аннотации • Повторяющиеся аннотации • Интерфейсные методы 8 • Stream API • Date Time API • Замена PermGen • Nashorn, JavaScript Engine • Новые утилиты (jdeps,jjs,..)
  9. От идей до нового функционала Java JEP предложен JEP принят,

    найден “спонсор” JEP подтвержден для Java версии N JEP реализован 10
  10. Ориентировочное расписание выхода Java 9 Feature complete Zero Bug Bounce

    Rampdown phase 2 Final Release Candidate Май’16 Rampdown Start All Tests Run General Availability Янв ’17 Фев ’17 Фев ’17 Март ’17 Июль ’17 27 Июля ’17 12 Ext. Feature complete Дек’16
  11. Проблемы существующей модели • Java Runtime большой и “тяжелый” и

    будет дальше расти • Профайлы 1, 2, 3 лишь частично решают проблему • Jar / Classpath Hell • Что от чего зависит?.. • Опциональные и транзитивные зависимости • Ленивая загрузка и инициализация классов -> NoClassDefFoundError • Примитивный механизм видимости для кода вне пакетов - только public • Классы из разных загрузчиков классов “видят” друг друга • SecurityManager помогает, но об этом надо знать 15
  12. 16

  13. Wikepedia о Jar-hell • Accidental presence of two different versions

    of a library installed on a system. This will not be considered an error by the system. Rather, the system will load classes from one or the other library. Adding the new library to the list of available libraries instead of replacing it may result in the application still behaving as though the old library is in use, which it may well be. • Multiple libraries or applications require different versions of library foo. If versions of library foo use the same class names, there is no way to load the versions of library foo with the same classloader. • The most complex JAR hell problems arise in circumstances that take advantage of the full complexity of the classloading system. A Java program is not required to use only a single "flat" classloader, but instead may be composed of several (potentially very many) nested, cooperating classloaders. Classes loaded by different classloaders may interact in complex ways not fully comprehended by a developer, leading to errors or bugs that are difficult to analyze, explain, and resolve. 17
  14. Примеры 18 • 01 - Classpath hell • 02 -

    Простейшее модульное приложение • 03 - jimage • 04 - Ошибка “2 модуля экспортируют один пакет в модуль 3” • 05 - Работа с двумя “одинаковыми” классами в разных модулях через рефлекшн
  15. Jigsaw JEP 162: Prepare for Modularization JEP 200: The Modular

    JDK
 JEP 220: Modular Run-Time Images JEP 201: Modular Source Code JEP 260: Encapsulate Most Internal APIs
 JSR 376: Java Platform Module System JEP 261: Module System
 Модулярность JDK Модули в Java 19
  16. Пример 1 src/com.azul.modules.module1/module- info.java module com.azul.modules.module1 { 
 exports com.azul.testpackage1;

    } src/com.azul.modules.module2/module-info.java module com.azul.modules.module2 { requires com.azul.modules.module1; } com.azul.modules.module1/com/azul/testpackage1/A.java package com.azul.testpackage1; public class A { public static void m() { System.out.println("-- I am in path1.com.azul.test.A.m() "); } } com.azul.modules.module2/com/azul/testpackage2/A.java package com.azul.testpackage2; public class A { public static void main(String[] args) { System.out.println("Calling from com.azul.modules.module2.com.azul.testpackage2.A.m() "); com.azul.testpackage1.A.m(); } } 1 2 20
  17. Новые параметры javac/java (1) • # Компиляция • $cd/src •

    $J/javac —-module-source-path . -d target $(find com.azul.modules.module1 -name “*.java") • $J/javac —-module-path target -d target// com.azul.modules.module2 $(find com.azul.modules.module2 -name “*.java”) • # Запуск • $J/java -p target -m mlib/com.azul.modules.module2 21
  18. Новые параметры javac/java (2) 22 • # Упаковка • $J/jar

    --create --file=mlib/module2.jar --main- class=com.azul.testpackage2.A -C target/ com.azul.modules.module2 . • # Запуск • $J/java -p target -m com.azul.modules.module2
  19. Пример 2 ./nashorn/src/jdk.scripting.nashorn/share/classes/module-info.java module jdk.scripting.nashorn { requires java.logging; requires public

    java.scripting; uses jdk.internal.dynalink.linker.GuardingDynamicLinker; uses jdk.nashorn.internal.runtime.CodeStore; provides javax.script.ScriptEngineFactory with jdk.nashorn.api.scripting.NashornScriptEngineFactory; exports jdk.nashorn.api.scripting; exports jdk.nashorn.api.tree; exports jdk.nashorn.internal.runtime to jdk.scripting.nashorn.shell; exports jdk.nashorn.internal.objects to jdk.scripting.nashorn.shell; exports jdk.nashorn.tools to jdk.scripting.nashorn.shell; } META-INF/services 23
  20. Cосуществование cp и mp • Всё, что попало в cp

    считается попавшим в безымянный (unnamed) модуль • Безымянные модули видят все именованные модули (requires *) • Обратное - неверное, надо указать requires unnamed или … • jar файл, который попал в mp автоматически превращается в модуль с названием, совпадающим с названием jar-файла • автомодули становятся мостом для видимости именными модулями классов в безымянным модуле • Типы ищутся безымянном модуле в последнюю очередь 24
  21. Безымянные модули имеют доступ к (почти) всем именованным • Кроме

    следующих модулей:
 java.activation - java.annotations.common - java.corba - java.transaction - java.xml.bind java.xml.ws • Можно поправить, добавив флаг -addmods java.corba` • Подробнее : см. письмо Алана Бейтманаhttp://mail.openjdk.java.net/ pipermail/jdk9-dev/2016-May/004309.html • Спека: http://openjdk.java.net/jeps/261 25
  22. Виды модулей • Именованные • Для которых есть module-info.class •

    Автоматические • jar файлы в module path • Безымянные • Классы в “классическом” classpath 26
  23. 28 jdeps -genmoduleinfo cat /Users/ivan/test/modules/generated/glassfish.corba.omgapi/module-info.java module glassfish.corba.omgapi { requires public

    java.corba; requires public java.desktop; requires public java.rmi; exports com.sun.corba.ee.org.omg.CORBA; exports javax.rmi.CORBA; exports org.omg.CORBA; exports org.omg.CORBA.DynAnyPackage; exports org.omg.CORBA.ORBPackage; exports org.omg.CORBA.TSIdentificationPackage; exports org.omg.CORBA.TypeCodePackage; exports org.omg.CORBA.portable; exports org.omg.CORBA_2_3; exports org.omg.CORBA_2_3.portable; exports org.omg.CosNaming; exports org.omg.CosNaming.NamingContextExtPackage; exports org.omg.CosNaming.NamingContextPackage; exports org.omg.CosTSInteroperation; exports org.omg.CosTSPortability; exports org.omg.CosTransactions; exports org.omg.Dynamic; exports org.omg.DynamicAny; exports org.omg.DynamicAny.DynAnyFactoryPackage; exports org.omg.DynamicAny.DynAnyPackage; exports org.omg.IOP; exports org.omg.IOP.CodecFactoryPackage; exports org.omg.IOP.CodecPackage; exports org.omg.Messaging; exports org.omg.PortableInterceptor; exports org.omg.PortableInterceptor.ORBInitInfoPackage; exports org.omg.PortableServer; exports org.omg.PortableServer.CurrentPackage; exports org.omg.PortableServer.POAManagerPackage; exports org.omg.PortableServer.POAPackage; exports org.omg.SendingContext; exports org.omg.stub.java.rmi; } jdeps -genmoduleinfo ~/test/modules/generated/ 
 glassfish-4.1.1/glassfish/modules/ glassfish-corba-omgapi.jar
  24. 29 jdeps -jdkinternals glassfish-corba-orb.jar -> java.corba com.sun.corba.ee.impl.copyobject.OldReflectObjectCopierImpl (glassfish-corba-orb.jar) -> sun.corba.Bridge

    JDK internal API (java.corba) com.sun.corba.ee.impl.copyobject.OldReflectObjectCopierImpl$1 (glassfish-corba-orb.jar) -> sun.corba.Bridge JDK internal API (java.corba) com.sun.corba.ee.impl.encoding.BufferManagerWriteStream (glassfish-corba-orb.jar) -> sun.corba.Bridge JDK internal API (java.corba) com.sun.corba.ee.impl.io.IIOPInputStream (glassfish-corba-orb.jar) -> sun.corba.Bridge JDK internal API (java.corba) com.sun.corba.ee.impl.io.IIOPInputStream$1 (glassfish-corba-orb.jar) -> sun.corba.Bridge JDK internal API (java.corba) com.sun.corba.ee.impl.io.IIOPOutputStream (glassfish-corba-orb.jar) -> sun.corba.Bridge JDK internal API (java.corba) com.sun.corba.ee.impl.io.IIOPOutputStream$1 (glassfish-corba-orb.jar) -> sun.corba.Bridge JDK internal API (java.corba) com.sun.corba.ee.impl.io.ObjectStreamClass (glassfish-corba-orb.jar) -> sun.corba.Bridge JDK internal API (java.corba) com.sun.corba.ee.impl.io.ObjectStreamClass$1 (glassfish-corba-orb.jar) -> sun.corba.Bridge JDK internal API (java.corba) com.sun.corba.ee.impl.io.ObjectStreamField (glassfish-corba-orb.jar) -> sun.corba.Bridge JDK internal API (java.corba) com.sun.corba.ee.impl.io.ObjectStreamField$1 (glassfish-corba-orb.jar) -> sun.corba.Bridge JDK internal API (java.corba) com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl$1 (glassfish-corba-orb.jar) -> com.sun.jndi.cosnaming.CNCtx JDK internal API (java.corba) com.sun.corba.ee.impl.util.JDKClassLoader (glassfish-corba-orb.jar) -> sun.corba.Bridge JDK internal API (java.corba) com.sun.corba.ee.impl.util.JDKClassLoader$1 (glassfish-corba-orb.jar) -> sun.corba.Bridge JDK internal API (java.corba) jdeps -jdkinternals glassfish/ modules/ glassfish-corba-orb.jar
  25. 33

  26. 33 • Reflection is disallowed from operating on non-exported types,

    even with the use of setAccessible • Jigsaw has only limited support for the dynamic introduction and alteration of modules • Restrictions that make interoperability with alternative modular systems difficult. • Source: http://wildfly.org/news/2016/12/12/Jigsaws-Missing-Pieces Есть мнение, что это fail
  27. (Мои) Выводы про модули в Java 9 • Цель -

    явное обязательное указание зависимостей • Предоставляет новые возможности по оптимизации • Сохранена совместимость с jar/cp (именные м., безымянный м., автомодули) • jigsaw теряет функциональность на пути к финалу • поддержка версий была еще весной 2015, осталась лишь декларация • OSGi и EE Комьюнити волнуются • IDEs EA builds работают с модулями, сложнее с dependency managers 34
  28. Jigsaw - статус, ссылки • Работа продолжается • Статья о

    текущем состоянии (Ноябрь 2016) • http://openjdk.java.net/projects/jigsaw/spec/sotms/ • Доклады с JavaOne (октябрь 2016) и Devoxx 2016 • http://openjdk.java.net/projects/jigsaw/ • Код давно залит в основной репозиторий (С января 2016) • hg.openjdk.java.net/jdk9/jdk9 • А также: http://blog.codefx.org/java/dev/features-project-jigsaw-java-9/ 35
  29. Обновления языка - Milling Project Coin • Приватные методы в

    
 интерфейсах 36 interface I { private void foo(String s); // Error: private method must declare body. private abstract void foo(int i, int j); // Error: private & abstract: bad combo void foo(int x); // OK. private I foo() { return null; } // OK. }
  30. Обновления языка - Milling Project Coin • Effectively-final переменные могут

    использоваться в try-with- resources выражениях 37 public static void main(String... args) { FileReader f = new FileReader("test.txt"); BufferedReader br = new BufferedReader(fr); try (br) { // do something } catch (Exception ex) { } } public static void main(String... args) { FileReader f = new FileReader(“test.txt"); try (br = new BufferedReader(fr)) { // do something } catch (Exception ex) { } }
  31. Обновления языка - Milling Project Coin • Использование @SafeVarargs в

    private методах 38 class VarargsFinalOnly { @SafeVarargs void m(List<String>... args) { } }
  32. В Java 8 ./TypeInferrenceTest.java:7: error: cannot infer type arguments for

    HashMap<K,V> new HashMap<>() ^ reason: cannot use '<>' with anonymous inner classes where K,V are type-variables: K extends Object declared in class HashMap V extends Object declared in class HashMap 1 error Обновления языка - Milling Project Coin • Использование diamond с анонимными классами при возможности определения типа, который подразумевается под diamond 39 public class TypeInferrenceTest { Map<String, String> map = new HashMap<> () { { map.put("key", "value"); } }; }
  33. Обновления языка - Milling Project Coin • Запрет на использование

    _ из всех имен типов, констант и т.п. 40 // key: compiler.warn.underscore.as.identifier // options: -source 8 -Xlint:-options class UnderscoreAsIdentifierWarning { String _ = null; }
  34. Другие обновления языка Надоело писать имя типа в декларации переменной?

    41 var list = new ArrayList<String>(); Local-Variable Type Inference. Это JEP-286. Пока что только “кандидат” var result = processNewCustomerAdded();
  35. Фабричные методы для коллекций Создание неизменных контейнеров 42 Set<String> set

    = new HashSet<>(); set.add("a"); set.add("b"); set = Collections.unmodifiableSet(set); Set<String> set = Collections.unmodifiableSet( new HashSet<>(Arrays.asList("a", "b"))); Set<String> set = Collections.unmodifiableSet( new HashSet<String>() {{ add("a"); add("b"); }}); Set<String> set = Collections.unmodifiableSet( Stream.of("a", “b").collect(toSet()) ); Set<String> set = Set.of("a", "b");
  36. Фабричные методы для коллекций 43 • Set.of(a, b); • List.of(a,

    b); • Map.of(k1, v1); • Map.of(k1, v1, k2, v2); • Map.of(k1, v1, k2, v2, k3, v3); • Map.ofEntries(entry(k1, v1), entry(k2, v2), ….. entry (kn, vn));
  37. JShell • Развивается в рамках проекта Kulla • http://openjdk.java.net/projects/kulla/ •

    Позволяет попробовать синтаксис без написания законченной программы • Помогает обучать языку Java class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } } 44
  38. Garbage First включен по умолчанию • Плюсы • Самый современный

    GC в HotSpot (хоть и разрабатывается уже 10+ лет) • Региональный параллельный одновременный коллектор • Нацелен быть лучшим во всем - Предсказуемые паузы и высокая производительность! • По умолчанию => Больше пользовательская база => Ошибки находятся быстрее => G1 будет доведен до ума очень быстро • Минусы • Эргономика работает по-другому. Могут проявиться ошибки в синхронизации в вашем или библиотечном коде • Жирные минусы • Есть несовместимости с G1 в Cassandra, Elasticsearch, Lucene, и т.п,. А вы уверены в библиотеках, которые используете? • Источник (датировано июлем 2015): https://groups.google.com/forum/#!topic/mechanical-sympathy/JxsuVtIIOaY 50
  39. Как пережить смену default GC, не теряя сон • Если

    до сих пор вас устраивали настройки GC по умолчанию • запаситесь данными эргономики для вашего приложения и среды внедрения • пропишите явным образом флаги настройки GC в деплоймент скриптах • Если вы и ранее явно выбирали GC и флаги GC • Ничего не изменится, старые коллекторы не исчезнут • В обоих случаях - экспериментируйте с G1 • Главное - понимать основные принципы работы GC • Прежде всего - метрики, которыми оценивают алгоритмы GC • Что еще почитать: http://www.infoq.com/minibooks/java-garbage-collection 51
  40. Другие изменения в GC • Deprecate CMS • Deprecate -

    значит запретить, но в будущем (после 9ки) • Создание GC интерфейса • https://bugs.openjdk.java.net/browse/JDK-8163329 • Shenandoah GC (JEP-189) • Первый OpenJDK GC не от Оракла 52
  41. Currency API • Не войдет в Java 9, развивается отдельно

    • прошлых конференция я говорил не так • Поговорим, если останется время - см. backup slides 53
  42. Обновление Process API • JEP 102: Process API Updates •

    Новое: • Получить pid “своей” JVM • Получить список процессов системы • Работа с деревьями процессов Source: http://blog.takipi.com/java-9-the-ultimate-feature-list/ 54 Process proc = Runtime.getRuntime() .exec(new String[]{"/bin/sh", "-c", "echo $PPID"}); if (proc.waitFor()==0) { InputStream in = proc.getInputStream(); int available = in.available(); byte[] outputBytes = new byte[available]; in.read(outputBytes); String pid = new String(outputBytes); System.out.println("Your pid is " + pid) } System.out.println("Your pid is " + ProcessHandle.current().getPid());
  43. 55 Унификация JVM логгинга • Унификация по всем подсистемам jvm

    • 6 уровней + тэги • Вывод в stdout / stderr / файл / зацикленный файл • Побороли проблему некорректного вывода логов • -Xlog:help • 11 декораторов -Xlog:classinit -Xlog:classloaderdata -Xlog:defaultmethods -Xlog:itables -Xlog:monitormismatch -Xlog:safepoint -Xlog:startuptime -Xlog:vmoperation -Xlog:vtables -Xlog:verification -XX:+TraceClassInitialization -XX:+TraceClassLoaderData -XX:+TraceDefaultMethods -XX:+TraceItables -XX:+TraceMonitorMismatch -XX:+TraceSafepoint -XX:+TraceStartupTime -XX:+TraceVMOperation -XX:+PrintVtables -XX:+VerboseVerification java -Xlog:help
  44. (HTTP/2) ISO 7-Layer Reference Model Layer 7: Application - Specifies

    how a particular application uses a network Layer 6: Presentation - Specifies how to represent data Layer 5: Session - Specifies how to establish communication with a remote system Layer 4: Transport - Specifies how to reliably handle data transfer Layer 3: Network - Specifies addressing assignments and how packets are forwarded Layer 2: Data Link - Specifies the organization of data into frames and how to send frames over a network Layer 1: Physical - Specifies the basic network hardware 57
  45. (HTTP/2) ISO 7-Layer Reference Model Layer 7: Application - Specifies

    how a particular application uses a network Layer 6: Presentation - Specifies how to represent data Layer 5: Session - Specifies how to establish communication with a remote system Layer 4: Transport - Specifies how to reliably handle data transfer Layer 3: Network - Specifies addressing assignments and how packets are forwarded Layer 2: Data Link - Specifies the organization of data into frames and how to send frames over a network Layer 1: Physical - Specifies the basic network hardware 57
  46. HTTP -> TCP 58 • HTTP 0.9: The One-Line Protocol

    (1989) • HTTP/1.0 (1996) • HTTP/1.1: Internet Standard (1997) • Keep alive; chunk encodings; byte- range requests, additional caching mechanisms, transfer encodings, and request pipelining • HTTP/2.0 (since 2012) Ref: https://hpbn.co/brief-history-of-http/
  47. Обзор JEP-ов. Графика • 258: HarfBuzz Font-Layout Engine • 263:

    HiDPI Graphics on Windows and Linux • 265: Marlin Graphics Renderer • 262: TIFF Image I/O • 257: Update JavaFX/Media to Newer Version of GStreamer (1.4.4) • 251: Multi-Resolution Images 61
  48. Stack walking API • Было: Throwable::getStackTrace и Thread::getStackTrace StackTraceElement[] stack

    = Thread.currentThread().getStackTrace(); • Стало: StackFrame[] stack =new StackWalker().walk((s) -> s.collect(Collectors.toArray())); • Новый класс StackWalker 62
  49. Обзор JEP-ов. Производительность • 143: Improve Contended Locking • 266:

    More Concurrency Updates • 197: Segmented Code Cache • 165: Compiler Control • 295: Ahead-of-Time Compilation • 243: Java-Level JVM Compiler Interface • 246: Leverage CPU Instructions for GHASH and RSA • 250: Store Interned Strings in CDS Archives • 254: Compact Strings • 280: Indify String Concatenation 64
  50. Обзор JEP-ов. Безопасность • 219: Datagram Transport Layer Security (DTLS)

    • 229: Create PKCS12 Keystores by Default • 244: TLS Application-Layer Protocol Negotiation Extension • 249: OCSP Stapling for TLS 65
  51. Обзор JEP-ов. Что уберут? • 231: Remove Launch-Time JRE Version

    Selection • 240: Remove the JVM TI hprof Agent • 241: Remove the jhat Tool
 
 ——————————— • Последствия подулярности (JEP - 261) • -Xbootclasspath & -Xbootclasspath/p • system property sun.boot.class.path 66