Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

1

Partager

Télécharger pour lire hors ligne

Java 9 модули

Télécharger pour lire hors ligne

Совсем скоро выйдет Java 9, которая готовит нам много новых и интересных вещей, таких как jshell, Process API, методы-фабрики для коллекций, мультирелизные JAR-файлы и др. Но самым главным изменением будет, конечно же, введение модулей. Модуль - это новая единица инкапсуляции, которая позволит указывать явно зависимости между программными компонентами и строго контролировать, какие public-классы доступны для других компонент, а какие нет. В этой презентации мы рассмотрим в подробностях механизм модулей Java 9, в частности, как объявляются модули и как модуляризована сама JDK, а также, какие проблемы могут встретиться при миграции приложения на Java 9.

Livres associés

Gratuit avec un essai de 30 jours de Scribd

Tout voir

Java 9 модули

  1. 1. Java 9 модули Евгений Козлов, 19.05.2017
  2. 2. История версий Java Версия Дата выхода Главные изменения Java 1.4 06.02.2002 assert, NIO Java 1.5 30.09.2004 enum, generics, annotations Java 1.6 11.12.2006 @Override in interfaces, Deque Java 1.7 07.07.2011 invokedynamic, try-with-resources Java 1.8 18.03.2014 lambdas, default methods, Nashorn Java 9 27.07.2017 modules, iface private methods, jshell
  3. 3. JDK 9 JEP 102: Process API Updates JEP 110: HTTP 2 Client JEP 143: Improve Contended Locking JEP 158: Unified JVM Logging JEP 165: Compiler Control JEP 193: Variable Handles JEP 197: Segmented Code Cache JEP 199: Smart Java Compilation, Phase Two JEP 200: The Modular JDK JEP 201: Modular Source Code JEP 211: Elide Deprecation Warnings on Import Statements JEP 212: Resolve Lint and Doclint Warnings JEP 213: Milling Project Coin JEP 214: Remove GC Combinations Deprecated in JDK 8 JEP 215: Tiered Attribution for javac JEP 216: Process Import Statements Correctly JEP 217: Annotations Pipeline 2.0 JEP 219: Datagram Transport Layer Security (DTLS) JEP 220: Modular Run-Time Images JEP 221: Simplified Doclet API JEP 222: jshell: The Java Shell (Read-Eval-Print Loop) JEP 223: New Version-String Scheme JEP 224: HTML5 Javadoc JEP 225: Javadoc Search JEP 226: UTF-8 Property Files JEP 227: Unicode 7.0 JEP 228: Add More Diagnostic Commands JEP 229: Create PKCS12 Keystores by Default JEP 231: Remove Launch-Time JRE Version Selection JEP 232: Improve Secure Application Performance JEP 233: Generate Run-Time Compiler Tests Automatically JEP 235: Test Class-File Attributes Generated by javac JEP 236: Parser API for Nashorn JEP 237: Linux/AArch64 Port JEP 238: Multi-Release JAR Files JEP 240: Remove the JVM TI hprof Agent JEP 241: Remove the jhat Tool JEP 243: Java-Level JVM Compiler Interface JEP 244: TLS Application-Layer Protocol Negotiation Extension JEP 245: Validate JVM Command-Line Flag Arguments JEP 246: Leverage CPU Instructions for GHASH and RSA JEP 247: Compile for Older Platform Versions JEP 248: Make G1 the Default Garbage Collector JEP 249: OCSP Stapling for TLS JEP 250: Store Interned Strings in CDS Archives JEP 251: Multi-Resolution Images JEP 252: Use CLDR Locale Data by Default JEP 253: Prepare JavaFX UI Controls & CSS APIs for Modularization JEP 254: Compact Strings JEP 255: Merge Selected Xerces 2.11.0 Updates into JAXP JEP 256: BeanInfo Annotations JEP 257: Update JavaFX/Media to Newer Version of GStreamer JEP 258: HarfBuzz Font-Layout Engine JEP 259: Stack-Walking API JEP 260: Encapsulate Most Internal APIs JEP 261: Module System JEP 262: TIFF Image I/O JEP 263: HiDPI Graphics on Windows and Linux JEP 264: Platform Logging API and Service JEP 265: Marlin Graphics Renderer JEP 266: More Concurrency Updates JEP 267: Unicode 8.0 JEP 268: XML Catalogs JEP 269: Convenience Factory Methods for Collections JEP 270: Reserved Stack Areas for Critical Sections JEP 271: Unified GC Logging JEP 272: Platform-Specific Desktop Features JEP 273: DRBG-Based SecureRandom Implementations JEP 274: Enhanced Method Handles JEP 275: Modular Java Application Packaging JEP 276: Dynamic Linking of Language-Defined Object Models JEP 277: Enhanced Deprecation JEP 278: Additional Tests for Humongous Objects in G1 JEP 279: Improve Test-Failure Troubleshooting JEP 280: Indify String Concatenation JEP 281: HotSpot C++ Unit-Test Framework JEP 282: jlink: The Java Linker JEP 283: Enable GTK 3 on Linux JEP 284: New HotSpot Build System JEP 285: Spin-Wait Hints JEP 287: SHA-3 Hash Algorithms JEP 288: Disable SHA-1 Certificates JEP 289: Deprecate the Applet API JEP 290: Filter Incoming Serialization Data JEP 291: Deprecate the Concurrent Mark Sweep (CMS) Garbage Collector JEP 292: Implement Selected ECMAScript 6 Features in Nashorn JEP 294: Linux/s390x Port JEP 295: Ahead-of-Time Compilation JEP 297: Unified arm32/arm64 Port JEP 298: Remove Demos and Samples JEP 299: Reorganize Documentation
  4. 4. Проект Jigsaw http://openjdk.java.net/projects/jigsaw
  5. 5. Модуль – новая единица инкапсуляции: • Поля и методы объединяются в классы (class) • Классы объединяются в пакеты (package) • Java 9: Пакеты объединяются в модули (module)
  6. 6. Причины создания Jigsaw • Java “толстеет” со временем • 95% разработчиков не нужны JavaFX, RMI, Corba • Но вынуждены их тащить вместе с JRE, потому что Java в текущем виде – это монолит • Нужно модуляризировать JDK, чтобы пользователи могли выбирать только те компоненты, которые им нужны
  7. 7. Размер JDK, MB 89 183 291 351 0 50 100 150 200 250 300 350 400 JDK 5 JDK 6 JDK 7 JDK 8
  8. 8. Размер JRE, MB 62 105 149 184 0 20 40 60 80 100 120 140 160 180 200 JRE 5 JRE 6 JRE 7 JRE 8
  9. 9. Нужно распиливать Java на компоненты, иначе будет как-то так
  10. 10. Java 8 Java 9 Java 10 Java 11
  11. 11. Причины создания Jigsaw • Java “толстеет” со временем • 95% разработчиков не нужны JavaFX, RMI, Corba • Но вынуждены их тащить вместе с JRE, потому что Java в текущем виде – это монолит • Нужно модуляризировать JDK, чтобы пользователи могли выбирать только те компоненты, которые им нужны • Внутренние API JDK торчат наружу • Нет надёжных механизмов их скрыть (public – значит все думают, что их можно использовать, хотя это не так) • Трудно развивать JDK, боясь сломать обратную совместимость • Нужно инкапсулировать внутренние API
  12. 12. Примеры внутренних API JDK • sun.misc.Unsafe • sun.misc.Signal и sun.misc.SignalHandler • sun.misc.Cleaner • sun.reflect.Reflection.getCallerClass(int) • sun.reflect.ReflectionFactory. newConstructorForSerialization
  13. 13. Модули в каком-то виде всегда были в Java: • jar-файлы • Maven artifacts • OSGi bundles • JBoss modules
  14. 14. Maven
  15. 15. <project> <groupId>com.axmor.java9demo</groupId> <artifactId>java9demo</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>moduleA</module> <module>moduleB</module> </modules> </project> java9demo moduleB moduleA <project> ... <artifactId>moduleA</artifactId> </project> <project> ... <artifactId>moduleB</artifactId> <dependencies> <dependency> <groupId>com.axmor.java9demo</groupId> <artifactId>moduleA</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> </project>
  16. 16. Проблемы модулей Maven: • Существуют только в build-time: • Java runtime ничего не знает про Maven • Если модуль А зависит от модуля В, то модуль В всё равно может обратиться к классам модуля А в рантайме • Не решают проблему инкапсуляции: • Нельзя скрыть пакеты от других модулей • Нельзя закрыть классы для доступа через reflection
  17. 17. OSGi (Open Services Gateway Initiative)
  18. 18. META-INF/MANIFEST.MF: Manifest-Version: 1.0 Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: CDC-1.0/Foundation-1.0,J2SE-1.3 Bundle-SymbolicName: org.eclipse.core.runtime; singleton:=true Bundle-Activator: org.eclipse.core.internal.runtime.PlatformActivator Require-Bundle: org.eclipse.osgi; visibility:=reexport, org.eclipse.equinox.common; visibility:=reexport, org.eclipse.core.jobs; visibility:=reexport, org.eclipse.equinox.registry; visibility:=reexport, org.eclipse.equinox.preferences; visibility:=reexport, org.eclipse.core.contenttype; visibility:=reexport, org.eclipse.core.runtime.compatibility.auth; resolution:=optional, org.eclipse.equinox.app; visibility:=reexport Export-Package: org.eclipse.core.internal.preferences.legacy; x-internal:=true, org.eclipse.core.internal.runtime; x-friends:="org.eclipse.core.runtime.compatibility", org.eclipse.core.runtime
  19. 19. Проблемы OSGI: • Не решает до конца проблему инкапсуляции: • setAccessible(true) по-прежнему работает • Обновления бандлов на лету в реальных сценариях почти никогда не работает: • При апдейте Eclipse всё равно просит делать рестарт • Один бандл <-> один classloader: • Проблемы с загрузкой нескольких версий одного и того же бандла • Циклические зависимости: • Может нарушиться ожидаемый порядок активации бандлов • Eclipse может не запуститься на не HotSpot • С помощью OSGi нельзя модуляризовать саму JDK
  20. 20. OSGi Jigsaw
  21. 21. Пример объявления модуля myapp src org.example.myapp Main.java Class1.java org.example.myapp.impl Class2.java Class3.java module-info.java // module-info.java module org.example.myapp { exports org.example.myapp; requires java.base; requires transitive com.google.common; requires static org.slf4j; }
  22. 22. org.example.myapp com.google.commonjava.base org.slf4j
  23. 23. Уровни видимости в Java 1-8: • private • <package> • protected • public
  24. 24. Уровни видимости в Java 1-8: • private • <package> • protected • public Уровни видимости в Java 9: • private • <package> • protected • public внутри модуля • public для конкретных модулей • public для всех
  25. 25. Запуск Через class path (по старинке): java -cp lib/guava-21.0.jar;myapp.jar org.example.myapp.Main Через module path: java --module-path lib/guava-21.0.jar;myapp.jar -m myapp
  26. 26. Запуск модульного приложения Java runtime гарантирует, что: • Все зависимости найдены • Нет циклических зависимостей • Нету расщеплённых пакетов (split packages)
  27. 27. Запуск по старинке (через -cp) • module-info.class игнорируется • Все ограничения игнорируются • Циклы разрешены • Расщеплённые пакеты разрешены • Линейный поиск
  28. 28. Модульная Java java.activation java.base java.compiler java.corba java.datatransfer java.desktop java.instrument java.jnlp java.logging java.management java.management.rmi java.naming java.prefs java.rmi java.scripting java.se java.se.ee java.security.jgss java.security.sasl java.smartcardio java.sql java.sql.rowset java.transaction java.xml java.xml.bind java.xml.crypto java.xml.ws java.xml.ws.annotation javafx.base javafx.controls javafx.deploy javafx.fxml javafx.graphics javafx.media javafx.swing javafx.web jdk.accessibility jdk.charsets jdk.crypto.cryptoki jdk.crypto.ec jdk.crypto.mscapi jdk.deploy jdk.deploy.controlpanel jdk.dynalink jdk.httpserver jdk.incubator.httpclient jdk.internal.le jdk.internal.vm.ci jdk.javaws jdk.jdwp.agent jdk.jfr jdk.jsobject jdk.localedata jdk.management jdk.management.agent jdk.naming.dns jdk.naming.rmi jdk.net jdk.pack jdk.plugin jdk.plugin.dom jdk.plugin.server jdk.scripting.nashorn jdk.scripting.nashorn.shell jdk.sctp jdk.security.auth jdk.security.jgss jdk.snmp jdk.unsupported jdk.xml.dom jdk.zipfs oracle.desktop oracle.net
  29. 29. module java.rmi { requires java.logging; exports java.rmi; exports java.rmi.activation; exports java.rmi.dgc; exports java.rmi.registry; exports java.rmi.server; exports javax.rmi.ssl; exports com.sun.rmi.rmid to java.base; exports sun.rmi.registry to jdk.management.agent; exports sun.rmi.server to java.management.rmi, jdk.management.agent, jdk.jconsole; exports sun.rmi.transport to java.management.rmi, jdk.management.agent, jdk.jconsole; uses java.rmi.server.RMIClassLoaderSpi; }
  30. 30. Модуль java.se module java.se { requires transitive java.desktop; requires transitive java.security.jgss; requires transitive java.security.sasl; requires transitive java.management; requires transitive java.logging; requires transitive java.datatransfer; requires transitive java.sql.rowset; requires transitive java.compiler; requires transitive java.sql; requires transitive java.naming; requires transitive java.prefs; requires transitive java.rmi; requires transitive java.xml.crypto; requires transitive java.management.rmi; requires transitive java.xml; requires transitive java.scripting; requires transitive java.instrument; }
  31. 31. Можно создать свой образ jlink --module-path %JAVA_HOME%/jmods --add-modules java.base --output myjre
  32. 32. Можно создать свой образ jlink --module-path %JAVA_HOME%/jmods --add-modules java.base --output myjre 35.81 MB!
  33. 33. Миграция
  34. 34. Миграция org.example.myapp java.xmljava.base slf4j-api-1.7.25.jar java.sql org.example.mylib guava-21.0.jar logback-classic-1.2.2.jar logback-core-1.2.2.jar
  35. 35. module org.example.mylib { exports org.example.mylib.package1; exports org.example.mylib.package2; requires java.base; requires java.xml; requires java.sql; requires ???; // guava-21.0.jar requires ???; // slf4j-api-1.7.25.jar }
  36. 36. module org.example.mylib { exports org.example.mylib.package1; exports org.example.mylib.package2; requires java.base; requires java.xml; requires java.sql; requires ???; // guava-21.0.jar requires ???; // slf4j-api-1.7.25.jar }
  37. 37. module org.example.mylib { exports org.example.mylib.package1; exports org.example.mylib.package2; requires java.base; requires java.xml; requires java.sql; requires ???; // guava-21.0.jar requires ???; // slf4j-api-1.7.25.jar }
  38. 38. module org.example.mylib { exports org.example.mylib.package1; exports org.example.mylib.package2; requires java.base; requires java.xml; requires java.sql; requires ???; // guava-21.0.jar requires ???; // slf4j-api-1.7.25.jar }
  39. 39. java.xmljava.base java.sql org.example.myliborg.example.myapp com.google.common logback.classic logback.core slf4j.api Но библиотеки ещё не модуляризованы
  40. 40. Но библиотеки ещё не модуляризованы • Однако их всё равно можно использовать как автоматические модули
  41. 41. module org.example.mylib { exports org.example.mylib.package1; exports org.example.mylib.package2; requires java.base; requires java.xml; requires java.sql; requires guava; // guava-21.0.jar requires slf4j.api; // slf4j-api-1.7.25.jar }
  42. 42. Автоматические модули java.xmljava.base java.sql org.example.myliborg.example.myapp logback.classic slf4j.api logback.core guava
  43. 43. Проблемы миграции
  44. 44. Пример #1
  45. 45. import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import javax.xml.bind.annotation.XmlRootElement; import java.io.File; public class Example { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Dog.class); Marshaller marshaller = jc.createMarshaller(); Dog dog = new Dog(); dog.name = "Doggy"; dog.age = 5; marshaller.marshal(dog, new File("file")); } @XmlRootElement public static class Dog { @XmlElement public String name; @XmlElement public int age; } }
  46. 46. Собираем на Java 8 и запускаем на Java 9 java -cp myapp.jar org.example.Example Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/bind/JAXBContext at org.example.Example.main(Example.java:12) Caused by: java.lang.ClassNotFoundException: javax.xml.bind.JAXBContext at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:553) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:185) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:486) ... 1 more … и получаем:
  47. 47. Решение: --add-modules java -cp myapp.jar --add-modules java.xml.bind org.example.Example или java -cp myapp.jar --add-modules java.se.ee org.example.Example
  48. 48. module java.se.ee { requires transitive java.se; requires transitive java.activation; requires transitive java.transaction; requires transitive java.corba; requires transitive java.xml.bind; requires transitive java.xml.ws; requires transitive java.xml.ws.annotation; }
  49. 49. Пример #2
  50. 50. import com.sun.javafx.collections.ObservableListWrapper; import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; import java.util.ArrayList; public class Example { public static void main(String[] args) throws Exception { ObservableList<Integer> list = new ObservableListWrapper<>(new ArrayList<>()); list.addListener((ListChangeListener<Integer>) change -> { while (change.next()) { System.out.println(change.getAddedSize()); } }); list.add(1); list.addAll(2, 3); list.addAll(4, 5, 6); } }
  51. 51. import com.sun.javafx.collections.ObservableListWrapper; import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; import java.util.ArrayList; public class Example { public static void main(String[] args) throws Exception { ObservableList<Integer> list = new ObservableListWrapper<>(new ArrayList<>()); list.addListener((ListChangeListener<Integer>) change -> { while (change.next()) { System.out.println(change.getAddedSize()); } }); list.add(1); list.addAll(2, 3); list.addAll(4, 5, 6); } }
  52. 52. Собираем на Java 8 и запускаем на Java 9 java -cp myapp.jar org.example.Example Exception in thread "main" java.lang.IllegalAccessError: class org.example.Example (in unnamed module @0x35f983a6) cannot access class com.sun.javafx.collections.ObservableListWrapper (in module javafx.base) because module javafx.base does not export com.sun.javafx.collections to unnamed module @0x35f983a6 at org.example.Example.main(Example.java:14) … и получаем:
  53. 53. Решение: --add-exports java -cp myapp.jar --add-exports javafx.base/com.sun.javafx.collections=ALL-UNNAMED org.example.Example
  54. 54. Пример #3
  55. 55. // Example.java package org.example; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import java.io.File; public class Example { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Dog.class); Marshaller marshaller = jc.createMarshaller(); Dog dog = new Dog(); dog.setName("Doggy"); dog.setAge(5); marshaller.marshal(dog, new File("file")); } } // Dog.java package org.example; import javax.xml.bind.annotation.*; @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class Dog { @XmlElement private String name; @XmlElement private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } // module-info.java module myapp { exports org.example; requires java.se.ee; }
  56. 56. // Example.java package org.example; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import java.io.File; public class Example { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Dog.class); Marshaller marshaller = jc.createMarshaller(); Dog dog = new Dog(); dog.setName("Doggy"); dog.setAge(5); marshaller.marshal(dog, new File("file")); } } // Dog.java package org.example; import javax.xml.bind.annotation.*; @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class Dog { @XmlElement private String name; @XmlElement private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } // module-info.java module myapp { exports org.example; requires java.se.ee; }
  57. 57. // Example.java package org.example; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import java.io.File; public class Example { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Dog.class); Marshaller marshaller = jc.createMarshaller(); Dog dog = new Dog(); dog.setName("Doggy"); dog.setAge(5); marshaller.marshal(dog, new File("file")); } } // Dog.java package org.example; import javax.xml.bind.annotation.*; @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class Dog { @XmlElement private String name; @XmlElement private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } // module-info.java module myapp { exports org.example; requires java.se.ee; }
  58. 58. Собираем и запускаем java --module-path myapp.jar –m myapp/org.example.Example … и получаем: Exception in thread "main" java.lang.reflect.InaccessibleObjectException: Unable to make field private java.lang.String org.example.Dog.name accessible: module myapp does not "opens org.example" to module java.xml.bind at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:337) at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:281) at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:175) at java.base/java.lang.reflect.Field.setAccessible(Field.java:169) at java.xml.bind@9- ea/com.sun.xml.internal.bind.v2.runtime.reflect.Accessor$FieldReflection.<init>(Accessor.java:233)
  59. 59. InaccessibleObjectException • В Java 9 закрытые члены классов недоступны по умолчанию для reflection, т.е. setAccessible(true) больше не работает
  60. 60. // Example.java package org.example; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import java.io.File; public class Example { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Dog.class); Marshaller marshaller = jc.createMarshaller(); Dog dog = new Dog(); dog.setName("Doggy"); dog.setAge(5); marshaller.marshal(dog, new File("file")); } } // Dog.java package org.example; import javax.xml.bind.annotation.*; @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class Dog { @XmlElement private String name; @XmlElement private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } // module-info.java module myapp { exports org.example; opens org.example; requires java.se.ee; }
  61. 61. // Example.java package org.example; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import java.io.File; public class Example { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Dog.class); Marshaller marshaller = jc.createMarshaller(); Dog dog = new Dog(); dog.setName("Doggy"); dog.setAge(5); marshaller.marshal(dog, new File("file")); } } // Dog.java package org.example; import javax.xml.bind.annotation.*; @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class Dog { @XmlElement private String name; @XmlElement private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } // module-info.java open module myapp { exports org.example; requires java.se.ee; }
  62. 62. Из командной строки java --module-path myapp.jar --add-opens myapp/org.example=java.xml.bind –m myapp/org.example.Example
  63. 63. Спасибо за внимание! http://jdk.java.net/9
  • makskoutun

    Aug. 7, 2017

Совсем скоро выйдет Java 9, которая готовит нам много новых и интересных вещей, таких как jshell, Process API, методы-фабрики для коллекций, мультирелизные JAR-файлы и др. Но самым главным изменением будет, конечно же, введение модулей. Модуль - это новая единица инкапсуляции, которая позволит указывать явно зависимости между программными компонентами и строго контролировать, какие public-классы доступны для других компонент, а какие нет. В этой презентации мы рассмотрим в подробностях механизм модулей Java 9, в частности, как объявляются модули и как модуляризована сама JDK, а также, какие проблемы могут встретиться при миграции приложения на Java 9.

Vues

Nombre de vues

653

Sur Slideshare

0

À partir des intégrations

0

Nombre d'intégrations

7

Actions

Téléchargements

3

Partages

0

Commentaires

0

Mentions J'aime

1

×