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.
Модули в Java
Евгений Козлов
Встреча Novosibirsk
Java User Group
24.05.2018
Обо мне
• Программирую на Java 7 лет
• Последние 5 лет в Axmor.
Программирую desktop (Eclipse).
• Веду Telegram-канал, пос...
Обо мне
• Программирую на Java 7 лет
• Последние 5 лет в Axmor.
Программирую desktop (Eclipse).
• Веду Telegram-канал, пос...
История версий Java
Версия Дата выхода Главные изменения
Java 1.4 06.02.2002 assert, NIO
Java 1.5 30.09.2004 enum, generic...
Java 8
5/136
Java 8
6/136
Проблемы монолитной JDK
7/136
Проблемы монолитной JDK
• Большой размер JRE 5
184MB
JRE 7 JRE 8
62MB
105MB
149MB
JRE 6
8/136
Проблемы монолитной JDK
• Большой размер
• Плоская структура (запутанный граф
зависимостей)
rt.jar
links
9/136
Проблемы монолитной JDK
• Большой размер
• Плоская структура (запутанный граф
зависимостей)
• Сложность разработки и подде...
Проблемы монолитной JDK
• Большой размер
• Плоская структура (запутанный граф
зависимостей)
• Сложность разработки и подде...
Проблемы монолитной JDK
• Большой размер
• Плоская структура (запутанный граф
зависимостей)
• Сложность разработки и подде...
Цели
• Разделить JDK на компоненты и сделать платформу
масштабируемой
13/136
Цели
• Разделить JDK на компоненты и сделать платформу
масштабируемой
• Облегчить разработку и поддержку больших систем,
в...
Цели
• Разделить JDK на компоненты и сделать платформу
масштабируемой
• Облегчить разработку и поддержку больших систем,
в...
Цели
• Разделить JDK на компоненты и сделать платформу
масштабируемой
• Облегчить разработку и поддержку больших систем,
в...
История
• Всё началось в 2005 году с JSR 277: Java Module System
17/136
История
• Всё началось в 2005 году с JSR 277: Java Module System
• 2008 год – создание проекта Jigsaw
18/136
История
• Всё началось в 2005 году с JSR 277: Java Module System
• 2008 год – создание проекта Jigsaw
• 2010 год – Jigsaw ...
История
• Всё началось в 2005 году с JSR 277: Java Module System
• 2008 год – создание проекта Jigsaw
• 2010 год – Jigsaw ...
21/136
22/136
История
• Всё началось в 2005 году с JSR 277: Java Module System
• 2008 год – создание проекта Jigsaw
• 2010 год – Jigsaw ...
Проект Jigsaw
• JEP 162: Prepare for Modularization
• JEP 200: The Modular JDK
• JEP 201: Modular Source Code
• JEP 220: M...
Java 8
rt.jar
25/136
Java 8 Java 9+
rt.jar
lib/modules
26/136
Java 8
jdk1.8.0_172
├── bin
| ├── java.exe
| ├── javac.exe
| ├── jar.exe
| └── …
├── jre
| ├── bin
| | ├── java.exe
| | └─...
Java 8
jdk1.8.0_172
├── bin
| ├── java.exe
| ├── javac.exe
| ├── jar.exe
| └── …
├── jre
| ├── bin
| | ├── java.exe
| | └─...
Java 8 Java 9+
jdk1.8.0_172
├── bin
| ├── java.exe
| ├── javac.exe
| ├── jar.exe
| └── …
├── jre
| ├── bin
| | ├── java.ex...
Java 8 Java 9+
jdk1.8.0_172
├── bin
| ├── java.exe
| ├── javac.exe
| ├── jar.exe
| └── …
├── jre
| ├── bin
| | ├── java.ex...
Java 8 Java 9+
jdk1.8.0_172
├── bin
| ├── java.exe
| ├── javac.exe
| ├── jar.exe
| └── …
├── jre
| ├── bin
| | ├── java.ex...
Нахождение системных модулей
32/136
Нахождение системных модулей
FileSystem fs =
FileSystems.getFileSystem(URI.create("jrt:/"));
33/136
Нахождение системных модулей
FileSystem fs =
FileSystems.getFileSystem(URI.create("jrt:/"));
// Получить стрим всех модуле...
Нахождение системных модулей
FileSystem fs =
FileSystems.getFileSystem(URI.create("jrt:/"));
// Получить стрим всех модуле...
Java 9+
jdk10.0.1
├── bin
| ├── java.exe
| ├── javac.exe
| ├── jar.exe
| └── …
├── lib
| ├── modules
| ├── jrt-fs.jar
| ├─...
Терминология
• Static access – обычный доступ к полям и методам:
com.Foo.bar()
37/136
Терминология
• Static access – обычный доступ к полям и методам:
com.Foo.bar()
• Reflective access – рефлективный доступ к...
Терминология
• Static access – обычный доступ к полям и методам:
com.Foo.bar()
• Reflective access – рефлективный доступ к...
Ага, используешь приватный API
40/136
Инкапсуляция внутренних API
• В Java 9/10 нестандартные API стали закрыты во время
компиляции, но открыты в рантайме
41/136
Инкапсуляция внутренних API
• В Java 9/10 нестандартные API стали закрыты во время
компиляции, но открыты в рантайме
• Во ...
А что Unsafe?
43/136
Неинкапсулированные API (пока)
• sun.misc.Unsafe
• sun.misc.Signal и sun.misc.SignalHandler
• sun.reflect.Reflection.getCa...
Использует ли моё приложение
внутренние API?
45/136
Использует ли моё приложение
внутренние API?
> jdeps --jdk-internals hadoop-hdfs-2.2.0.jar
hadoop-hdfs-2.2.0.jar -> java.x...
Пример объявления модуля
mylib
src
org.example.mylib
Main.java
Class1.java
org.example.mylib.impl
Class2.java
Class3.java
...
Пример объявления модуля
mylib
src
org.example.mylib
Main.java
Class1.java
org.example.mylib.impl
Class2.java
Class3.java
...
Пример объявления модуля
mylib
src
org.example.mylib
Main.java
Class1.java
org.example.mylib.impl
Class2.java
Class3.java
...
java.base
requires
requires
transitive
org.example.mylib
requires
static
com.foo com.bar
50/136
module java.rmi {
requires java.logging;
exports java.rmi;
exports java.rmi.activation;
exports java.rmi.dgc;
exports java...
Уровни видимости
в Java 1-8:
• private
• <package>
• protected
• public
52/136
Уровни видимости
в Java 1-8:
• private
• <package>
• protected
• public
Уровни видимости
в Java 9+:
• private
• <package>
...
module jdk.unsupported {
exports com.sun.nio.file;
exports sun.misc;
exports sun.reflect;
opens sun.misc;
opens sun.reflec...
module jdk.unsupported {
exports com.sun.nio.file;
exports sun.misc;
exports sun.reflect;
opens sun.misc;
opens sun.reflec...
Запуск на Java 8
Через class path:
java -cp foo.jar;bar.jar;myapp.jar org.example.myapp.Main
56/136
Запуск на Java 9+
Через class path (по старинке):
java -cp foo.jar;bar.jar;myapp.jar org.example.myapp.Main
Через module p...
Запуск модульного приложения
Java runtime гарантирует, что:
• Все зависимости найдены
58/136
Запуск модульного приложения
Java runtime гарантирует, что:
• Все зависимости найдены
• Нет циклических зависимостей
59/136
Запуск модульного приложения
Java runtime гарантирует, что:
• Все зависимости найдены
• Нет циклических зависимостей
• Нет...
Запуск по старинке (через -cp)
• module-info.class игнорируется
• Все ограничения игнорируются
• Циклы разрешены
• Расщепл...
-cp targetclasses;
libscomgoogleguavaguava25.0-jreguava-25.0-jre.jar;
libsorgcheckerframeworkchecker-compat-
qual2.0.0chec...
63/136
--module-path
-classpath
64/136
Аналоги директив в
опциях VM и runtime
65/136
Аналоги директив в
опциях VM и reflection
module-info.java VM option java.lang.Module
module foo {
requires bar;
}
--add-r...
Аналоги директив в
опциях VM и reflection
module-info.java VM option java.lang.Module
module foo {
requires bar;
}
--add-r...
Аналоги директив в
опциях VM и reflection
module-info.java VM option java.lang.Module
module foo {
requires bar;
}
--add-r...
Граф модулей
java.xml
foo
java.base
baz
quxbar
java.prefs
69/136
java -p foo.jar;bar.jar;qux.jar;baz.jar -m foo
Граф модулей
70/136
Граф модулей
java.xml
foo
java.base
корневой
модуль (root) baz
quxbar
java.prefs
71/136
Граф модулей
java.xml
foo
java.base
корневой
модуль (root) baz
quxbar
java.prefs
72/136
Граф модулей
java.xml
foo
java.base
корневой
модуль (root) baz
quxbar
java.prefs
73/136
java -p foo.jar;bar.jar;qux.jar;baz.jar -m foo
Добавление модулей в корневое
множество
74/136
Добавление модулей в корневое
множество
java -p foo.jar;bar.jar;qux.jar;baz.jar
--add-modules baz -m foo
75/136
Граф модулей
java.xml
foo baz
java.prefs
bar
java.base
qux
корневой
модуль (root)
корневой
модуль (root)
76/136
Виды модулей
Module
77/136
Виды модулей
Module
Unnamed Named
78/136
Виды модулей
Module
Unnamed
Automatic Explicit
Named
79/136
Виды модулей
Module
Unnamed
Automatic Explicit
System
Named
80/136
Кроме того, системные модули
могут быть:
• Aggregator (например, java.se)
81/136
Модуль java.se
module java.se {
requires transitive java.desktop;
requires transitive java.security.jgss;
requires transit...
Кроме того, системные модули
могут быть:
• Aggregator (например, java.se)
• Deprecated и Deprecated for removal (например,...
Модуль java.se.ee
@Deprecated(since="9", forRemoval=true)
module java.se.ee {
requires transitive java.se;
requires transi...
85/136
Кроме того, системные модули
могут быть:
• Aggregator (например, java.se)
• Deprecated и Deprecated for removal (например,...
Кроме того, системные модули
могут быть:
• Aggregator (например, java.se)
• Deprecated и Deprecated for removal (например,...
Миграция
88/136
app1
app3app2
foo-1.0.jar bar-0.0.1.jar
baz-3.17.jar qux-2.1.jar
java.prefsjava.xml
89/136
app1
app3app2
foo-1.0.jar bar-0.0.1.jar
baz-3.17.jar qux-2.1.jar
java.prefsjava.xml
<unnamed>
90/136
foo-1.0.jar bar-0.0.1.jar
baz-3.17.jar qux-2.1.jar
java.prefsjava.xml
app3app2
app1
91/136
foo-1.0.jar bar-0.0.1.jar
baz-3.17.jar qux-2.1.jar
java.prefsjava.xml
requires app3
requires app2
app3app2
app1
92/136
foo-1.0.jar bar-0.0.1.jar
baz-3.17.jar qux-2.1.jar
java.prefsjava.xml
requires app3
requires app2
requires ???
app3app2
ap...
foo-1.0.jar bar-0.0.1.jar
baz-3.17.jar qux-2.1.jar
java.prefsjava.xml
automatic
modules
automatic
modules
requires app3
re...
Automatic module
• Имя выводится из имени jar-файла (или из
атрибута Automatic-Module-Name)
95/136
foo-1.0.jar bar-0.0.1.jar
baz-3.17.jar qux-2.1.jar
java.prefsjava.xml
automatic
modules
automatic
modules
requires app3
re...
Automatic module
• Имя выводится из имени jar-файла (или из
атрибута Automatic-Module-Name)
• Requires all modules
• Expor...
app1
app3app2
foo-1.0.jar bar-0.0.1.jar
baz-3.17.jar qux-2.1.jar
java.prefsjava.xml
98/136
foo-1.0.jar bar-0.0.1.jar
baz-3.17.jar qux-2.1.jar
java.prefsjava.xml
app1
app2 app3
99/136
app1
app3app2
foo-1.0.jar bar-0.0.1.jar
baz-3.17.jar qux-2.1.jar
java.prefsjava.xml
100/136
app1
app3app2
foo-1.0.jar bar-0.0.1.jar
baz-3.17.jar qux-2.2.jar
java.prefsjava.xml
101/136
app1
app3app2
foo-1.0.jar bar-0.0.1.jar
baz-3.18.jar qux-2.2.jar
java.prefsjava.xml
102/136
app1
app3app2
foo-1.1.jar bar-0.0.1.jar
baz-3.18.jar qux-2.2.jar
java.prefsjava.xml
103/136
app1
app3app2
foo-1.0.jar bar-0.0.2.jar
baz-3.17.jar qux-2.2.jar
java.prefsjava.xml
104/136
Сервисы
105/136
Сервисы
• Появились в Java 6
106/136
Сервисы
• Появились в Java 6
• В Java 9 стали намного удобнее и безопаснее
107/136
package com.foo;
public interface Calculator {
int square(int x);
}
module foo {
exports com.foo;
}
108/136
package com.foo;
public interface Calculator {
int square(int x);
}
module foo {
exports com.foo;
}
public class Main {
…
...
package com.foo;
public interface Calculator {
int square(int x);
}
package com.bar;
public class CalculatorImpl
implement...
package com.foo;
public interface Calculator {
int square(int x);
}
package com.bar;
public class CalculatorImpl
implement...
package com.foo;
public interface Calculator {
int square(int x);
static Calculator get() {…}
}
package com.bar;
public cl...
package com.foo;
import java.util.ServiceLoader;
public interface Calculator {
int square(int x);
static Calculator get() ...
package com.foo;
import java.util.ServiceLoader;
public interface Calculator {
int square(int x);
static List<Calculator> ...
java.scripting
ScriptEngineFactory
jdk.scripting.nashorn
NashornScriptEngineFactory
115/136
java.base
ToolProvider
jdk.compiler
JavacToolProvider
jdk.jlink
JlinkToolProvider
jdk.jartool
JarToolProvider
116/136
Optional<ToolProvider> jar = ToolProvider.findFirst("jar");
117/136
Optional<ToolProvider> jar = ToolProvider.findFirst("jar");
jar.get().run(
System.out,
System.err,
"--describe-module",
"-...
Демонстрация
• Java 10 приложение с использованием сервисов
• git clone https://github.com/orionll/services-demo
119/136
Демонстрация
• Java 10 приложение с использованием сервисов
• git clone https://github.com/orionll/services-demo
120/136
Демонстрация
• Java 10 приложение с использованием сервисов
• git clone https://github.com/orionll/services-demo
FigureDes...
Резюме
122/136
Резюме
• Система модулей улучшает архитектуру проекта
123/136
Резюме
• Система модулей улучшает архитектуру проекта
• Делает приложение более безопасным
124/136
Резюме
• Система модулей улучшает архитектуру проекта
• Делает приложение более безопасным
• Предоставляет механизмы для о...
Резюме
• Система модулей улучшает архитектуру проекта
• Делает приложение более безопасным
• Предоставляет механизмы для о...
Недостатки
127/136
Недостатки
Сложность:
• -classpath vs --module-path vs --upgrade-module-path
• non-modular jar vs modular jar vs automatic...
Недостатки
Сложность:
• -classpath vs --module-path vs --upgrade-module-path
• non-modular jar vs modular jar vs automatic...
Нужно ли прямо сейчас
переходить на модули?
130/136
Экосистема ещё довольно плохо готова
к модульности
• Инструменты плохо готовы (IDE, системы сборки,
контейнеры, тест-фрейм...
Экосистема ещё довольно плохо готова
к модульности
• Инструменты плохо готовы (IDE, системы сборки,
контейнеры, тест-фрейм...
Экосистема ещё довольно плохо готова
к модульности
• Инструменты плохо готовы (IDE, системы сборки,
контейнеры, тест-фрейм...
Экосистема ещё довольно плохо готова
к модульности
• Инструменты плохо готовы (IDE, системы сборки,
контейнеры, тест-фрейм...
Полезные ссылки
• Project Jigsaw: http://openjdk.java.net/projects/jigsaw/
• Replacements for deprecated java.se.ee module...
Спасибо за внимание!
Java 10
136/136
Prochain SlideShare
Chargement dans…5
×

1

Partager

Télécharger pour lire hors ligne

Модули в Java

Télécharger pour lire hors ligne

Рассказ о главном новшестве Java 9: проекте Jigsaw и системе модулей.

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

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

Livres associés

Gratuit avec un essai de 30 jours de Scribd

Tout voir

Модули в Java

  1. 1. Модули в Java Евгений Козлов Встреча Novosibirsk Java User Group 24.05.2018
  2. 2. Обо мне • Программирую на Java 7 лет • Последние 5 лет в Axmor. Программирую desktop (Eclipse). • Веду Telegram-канал, посвящённый Java: https://t.me/miniJUG • Интересуюсь функциональным программированием: https://vk.com/lambdansk 2/136
  3. 3. Обо мне • Программирую на Java 7 лет • Последние 5 лет в Axmor. Программирую desktop (Eclipse). • Веду Telegram-канал, посвящённый Java: https://t.me/miniJUG • Интересуюсь функциональным программированием: https://vk.com/lambdansk • Отвечаю на StackOverflow. 3/136
  4. 4. История версий 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 21.09.2017 modules, iface private methods, jshell Java 10 20.03.2018 var, Graal 4/136
  5. 5. Java 8 5/136
  6. 6. Java 8 6/136
  7. 7. Проблемы монолитной JDK 7/136
  8. 8. Проблемы монолитной JDK • Большой размер JRE 5 184MB JRE 7 JRE 8 62MB 105MB 149MB JRE 6 8/136
  9. 9. Проблемы монолитной JDK • Большой размер • Плоская структура (запутанный граф зависимостей) rt.jar links 9/136
  10. 10. Проблемы монолитной JDK • Большой размер • Плоская структура (запутанный граф зависимостей) • Сложность разработки и поддержки 10/136
  11. 11. Проблемы монолитной JDK • Большой размер • Плоская структура (запутанный граф зависимостей) • Сложность разработки и поддержки • Медленный старт и много памяти 11/136
  12. 12. Проблемы монолитной JDK • Большой размер • Плоская структура (запутанный граф зависимостей) • Сложность разработки и поддержки • Медленный старт и много памяти • Внутренние API торчат наружу 12/136
  13. 13. Цели • Разделить JDK на компоненты и сделать платформу масштабируемой 13/136
  14. 14. Цели • Разделить JDK на компоненты и сделать платформу масштабируемой • Облегчить разработку и поддержку больших систем, в том числе самой JDK 14/136
  15. 15. Цели • Разделить JDK на компоненты и сделать платформу масштабируемой • Облегчить разработку и поддержку больших систем, в том числе самой JDK • Улучшить производительность и уменьшить потребление памяти 15/136
  16. 16. Цели • Разделить JDK на компоненты и сделать платформу масштабируемой • Облегчить разработку и поддержку больших систем, в том числе самой JDK • Улучшить производительность и уменьшить потребление памяти • Улучшить безопасность, инкапсулировать внутренние API 16/136
  17. 17. История • Всё началось в 2005 году с JSR 277: Java Module System 17/136
  18. 18. История • Всё началось в 2005 году с JSR 277: Java Module System • 2008 год – создание проекта Jigsaw 18/136
  19. 19. История • Всё началось в 2005 году с JSR 277: Java Module System • 2008 год – создание проекта Jigsaw • 2010 год – Jigsaw перенесён в Java 8 • 2012 год – Jigsaw перенесён в Java 9 19/136
  20. 20. История • Всё началось в 2005 году с JSR 277: Java Module System • 2008 год – создание проекта Jigsaw • 2010 год – Jigsaw перенесён в Java 8 • 2012 год – Jigsaw перенесён в Java 9 • 2014 год – старт фазы активной разработки Jigsaw 20/136
  21. 21. 21/136
  22. 22. 22/136
  23. 23. История • Всё началось в 2005 году с JSR 277: Java Module System • 2008 год – создание проекта Jigsaw • 2010 год – Jigsaw перенесён в Java 8 • 2012 год – Jigsaw перенесён в Java 9 • 2014 год – старт фазы активной разработки Jigsaw • 21.09.2017 – выход Java 9 23/136
  24. 24. Проект Jigsaw • JEP 162: Prepare for Modularization • JEP 200: The Modular JDK • JEP 201: Modular Source Code • JEP 220: Modular Run-Time Images • JEP 260: Encapsulate Most Internal APIs • JEP 261: Module System • JEP 282: jlink: The Java Linker 24/136
  25. 25. Java 8 rt.jar 25/136
  26. 26. Java 8 Java 9+ rt.jar lib/modules 26/136
  27. 27. Java 8 jdk1.8.0_172 ├── bin | ├── java.exe | ├── javac.exe | ├── jar.exe | └── … ├── jre | ├── bin | | ├── java.exe | | └── … | ├── lib | | ├── rt.jar | | └── … | └── … ├── lib | ├── tools.jar | └── … ├── src.zip └── … 27/136
  28. 28. Java 8 jdk1.8.0_172 ├── bin | ├── java.exe | ├── javac.exe | ├── jar.exe | └── … ├── jre | ├── bin | | ├── java.exe | | └── … | ├── lib | | ├── rt.jar | | └── … | └── … ├── lib | ├── tools.jar | └── … ├── src.zip └── … 28/136
  29. 29. Java 8 Java 9+ jdk1.8.0_172 ├── bin | ├── java.exe | ├── javac.exe | ├── jar.exe | └── … ├── jre | ├── bin | | ├── java.exe | | └── … | ├── lib | | ├── rt.jar | | └── … | └── … ├── lib | ├── tools.jar | └── … ├── src.zip └── … jdk10.0.1 ├── bin | ├── java.exe | ├── javac.exe | ├── jar.exe | └── … ├── lib | ├── modules | ├── jrt-fs.jar | ├── src.zip | └── … ├── jmods | ├── java.base.jmod | ├── java.desktop.jmod | ├── java.xml.jmod | └── … └── … 29/136
  30. 30. Java 8 Java 9+ jdk1.8.0_172 ├── bin | ├── java.exe | ├── javac.exe | ├── jar.exe | └── … ├── jre | ├── bin | | ├── java.exe | | └── … | ├── lib | | ├── rt.jar | | └── … | └── … ├── lib | ├── tools.jar | └── … ├── src.zip └── … jdk10.0.1 ├── bin | ├── java.exe | ├── javac.exe | ├── jar.exe | └── … ├── lib | ├── modules | ├── jrt-fs.jar | ├── src.zip | └── … ├── jmods | ├── java.base.jmod | ├── java.desktop.jmod | ├── java.xml.jmod | └── … └── … 30/136
  31. 31. Java 8 Java 9+ jdk1.8.0_172 ├── bin | ├── java.exe | ├── javac.exe | ├── jar.exe | └── … ├── jre | ├── bin | | ├── java.exe | | └── … | ├── lib | | ├── rt.jar | | └── … | └── … ├── lib | ├── tools.jar | └── … ├── src.zip └── … jdk10.0.1 ├── bin | ├── java.exe | ├── javac.exe | ├── jar.exe | └── … ├── lib | ├── modules | ├── jrt-fs.jar | ├── src.zip | └── … ├── jmods | ├── java.base.jmod | ├── java.desktop.jmod | ├── java.xml.jmod | └── … └── … 31/136
  32. 32. Нахождение системных модулей 32/136
  33. 33. Нахождение системных модулей FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 33/136
  34. 34. Нахождение системных модулей FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); // Получить стрим всех модулей: Stream<Path> modules = Files.list(fs.getPath("modules")); 34/136
  35. 35. Нахождение системных модулей FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); // Получить стрим всех модулей: Stream<Path> modules = Files.list(fs.getPath("modules")); // Получить массив байтов файла Object.class: byte[] bytes = Files.readAllBytes(fs.getPath("modules", "java.base", "java/lang/Object.class")); 35/136
  36. 36. Java 9+ jdk10.0.1 ├── bin | ├── java.exe | ├── javac.exe | ├── jar.exe | └── … ├── lib | ├── modules | ├── jrt-fs.jar | ├── src.zip | └── … ├── jmods | ├── java.base.jmod | ├── java.desktop.jmod | ├── java.xml.jmod | └── … └── … 36/136
  37. 37. Терминология • Static access – обычный доступ к полям и методам: com.Foo.bar() 37/136
  38. 38. Терминология • Static access – обычный доступ к полям и методам: com.Foo.bar() • Reflective access – рефлективный доступ к полям и методам: Method m = Class.forName("com.Foo").getDeclaredMethod("bar"); m.invoke(null); 38/136
  39. 39. Терминология • Static access – обычный доступ к полям и методам: com.Foo.bar() • Reflective access – рефлективный доступ к полям и методам: Method m = Class.forName("com.Foo").getDeclaredMethod("bar"); m.invoke(null); • Deep reflective access – приватный рефлективный доступ к полям и методам: Method m = Class.forName("com.Foo").getDeclaredMethod("baz"); m.setAccessible(true); m.invoke(null); 39/136
  40. 40. Ага, используешь приватный API 40/136
  41. 41. Инкапсуляция внутренних API • В Java 9/10 нестандартные API стали закрыты во время компиляции, но открыты в рантайме 41/136
  42. 42. Инкапсуляция внутренних API • В Java 9/10 нестандартные API стали закрыты во время компиляции, но открыты в рантайме • Во время deep reflective access к классам JVM выдаёт предупреждение: Field field = ArrayList.class.getDeclaredField("elementData"); field.setAccessible(true); WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by org.example.Main (…) to field java.util.ArrayList.elementData 42/136
  43. 43. А что Unsafe? 43/136
  44. 44. Неинкапсулированные API (пока) • sun.misc.Unsafe • sun.misc.Signal и sun.misc.SignalHandler • sun.reflect.Reflection.getCallerClass(int) • sun.reflect.ReflectionFactory. newConstructorForSerialization() 44/136
  45. 45. Использует ли моё приложение внутренние API? 45/136
  46. 46. Использует ли моё приложение внутренние API? > jdeps --jdk-internals hadoop-hdfs-2.2.0.jar hadoop-hdfs-2.2.0.jar -> java.xml org.apache.hadoop.hdfs.tools.offlineEditsViewer.XmlEditsVisitor -> com.sun.org.apache.xml.internal.serialize.OutputFormat JDK internal API (java.xml) org.apache.hadoop.hdfs.tools.offlineEditsViewer.XmlEditsVisitor -> com.sun.org.apache.xml.internal.serialize.XMLSerializer JDK internal API (java.xml) Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break your application. Please modify your code to eliminate dependence on any JDK internal APIs. For the most recent update on JDK internal API replacements, please check: https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool 46/136
  47. 47. Пример объявления модуля mylib src org.example.mylib Main.java Class1.java org.example.mylib.impl Class2.java Class3.java 47/136
  48. 48. Пример объявления модуля mylib src org.example.mylib Main.java Class1.java org.example.mylib.impl Class2.java Class3.java module-info.java // module-info.java module org.example.mylib { exports org.example.mylib; requires java.base; requires transitive com.foo; requires static com.bar; } 48/136
  49. 49. Пример объявления модуля mylib src org.example.mylib Main.java Class1.java org.example.mylib.impl Class2.java Class3.java module-info.java // module-info.java module org.example.mylib { exports org.example.mylib; requires java.base; requires transitive com.foo; requires static com.bar; } concealed package 49/136
  50. 50. java.base requires requires transitive org.example.mylib requires static com.foo com.bar 50/136
  51. 51. 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; } qualified export 51/136
  52. 52. Уровни видимости в Java 1-8: • private • <package> • protected • public 52/136
  53. 53. Уровни видимости в Java 1-8: • private • <package> • protected • public Уровни видимости в Java 9+: • private • <package> • protected • public внутри модуля • public для конкретных модулей • public для всех 53/136
  54. 54. module jdk.unsupported { exports com.sun.nio.file; exports sun.misc; exports sun.reflect; opens sun.misc; opens sun.reflect; } Открытые пакеты 54/136
  55. 55. module jdk.unsupported { exports com.sun.nio.file; exports sun.misc; exports sun.reflect; opens sun.misc; opens sun.reflect; } Открытые пакеты открыты для deep reflection 55/136
  56. 56. Запуск на Java 8 Через class path: java -cp foo.jar;bar.jar;myapp.jar org.example.myapp.Main 56/136
  57. 57. Запуск на Java 9+ Через class path (по старинке): java -cp foo.jar;bar.jar;myapp.jar org.example.myapp.Main Через module path: java -p foo.jar;bar.jar;myapp.jar -m org.example.myapp 57/136
  58. 58. Запуск модульного приложения Java runtime гарантирует, что: • Все зависимости найдены 58/136
  59. 59. Запуск модульного приложения Java runtime гарантирует, что: • Все зависимости найдены • Нет циклических зависимостей 59/136
  60. 60. Запуск модульного приложения Java runtime гарантирует, что: • Все зависимости найдены • Нет циклических зависимостей • Нет расщеплённых пакетов (split packages) 60/136
  61. 61. Запуск по старинке (через -cp) • module-info.class игнорируется • Все ограничения игнорируются • Циклы разрешены • Расщеплённые пакеты разрешены • Линейный поиск 61/136
  62. 62. -cp targetclasses; libscomgoogleguavaguava25.0-jreguava-25.0-jre.jar; libsorgcheckerframeworkchecker-compat- qual2.0.0checker-compat-qual-2.0.0.jar; libscomgoogleerrorproneerror_prone_annotations2.1.3 error_prone_annotations-2.1.3.jar; libscomgooglej2objcj2objc-annotations1.1j2objc- annotations-1.1.jar; libsorgcodehausmojoanimal-sniffer- annotations1.14animal-sniffer-annotations-1.14.jar 62/136
  63. 63. 63/136
  64. 64. --module-path -classpath 64/136
  65. 65. Аналоги директив в опциях VM и runtime 65/136
  66. 66. Аналоги директив в опциях VM и reflection module-info.java VM option java.lang.Module module foo { requires bar; } --add-reads foo=bar foo.addReads(bar) 66/136
  67. 67. Аналоги директив в опциях VM и reflection module-info.java VM option java.lang.Module module foo { requires bar; } --add-reads foo=bar foo.addReads(bar) module foo { exports com.foo to bar; } --add-exports foo/com.foo=bar foo.addExports("com.foo", bar) 67/136
  68. 68. Аналоги директив в опциях VM и reflection module-info.java VM option java.lang.Module module foo { requires bar; } --add-reads foo=bar foo.addReads(bar) module foo { exports com.foo to bar; } --add-exports foo/com.foo=bar foo.addExports("com.foo", bar) module foo { opens com.foo to bar; } --add-opens foo/com.foo=bar foo.addOpens("com.foo", bar) 68/136
  69. 69. Граф модулей java.xml foo java.base baz quxbar java.prefs 69/136
  70. 70. java -p foo.jar;bar.jar;qux.jar;baz.jar -m foo Граф модулей 70/136
  71. 71. Граф модулей java.xml foo java.base корневой модуль (root) baz quxbar java.prefs 71/136
  72. 72. Граф модулей java.xml foo java.base корневой модуль (root) baz quxbar java.prefs 72/136
  73. 73. Граф модулей java.xml foo java.base корневой модуль (root) baz quxbar java.prefs 73/136
  74. 74. java -p foo.jar;bar.jar;qux.jar;baz.jar -m foo Добавление модулей в корневое множество 74/136
  75. 75. Добавление модулей в корневое множество java -p foo.jar;bar.jar;qux.jar;baz.jar --add-modules baz -m foo 75/136
  76. 76. Граф модулей java.xml foo baz java.prefs bar java.base qux корневой модуль (root) корневой модуль (root) 76/136
  77. 77. Виды модулей Module 77/136
  78. 78. Виды модулей Module Unnamed Named 78/136
  79. 79. Виды модулей Module Unnamed Automatic Explicit Named 79/136
  80. 80. Виды модулей Module Unnamed Automatic Explicit System Named 80/136
  81. 81. Кроме того, системные модули могут быть: • Aggregator (например, java.se) 81/136
  82. 82. Модуль 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; } 82/136
  83. 83. Кроме того, системные модули могут быть: • Aggregator (например, java.se) • Deprecated и Deprecated for removal (например, java.se.ee) 83/136
  84. 84. Модуль java.se.ee @Deprecated(since="9", forRemoval=true) module java.se.ee { requires transitive java.se; requires transitive java.activation; requires transitive java.corba; requires transitive java.transaction; requires transitive java.xml.bind; requires transitive java.xml.ws; requires transitive java.xml.ws.annotation; } 84/136
  85. 85. 85/136
  86. 86. Кроме того, системные модули могут быть: • Aggregator (например, java.se) • Deprecated и Deprecated for removal (например, java.se.ee) • Upgradeable (например, jdk.internal.vm.compiler) 86/136
  87. 87. Кроме того, системные модули могут быть: • Aggregator (например, java.se) • Deprecated и Deprecated for removal (например, java.se.ee) • Upgradeable (например, jdk.internal.vm.compiler) • Incubating (например, jdk.incubator.httpclient) 87/136
  88. 88. Миграция 88/136
  89. 89. app1 app3app2 foo-1.0.jar bar-0.0.1.jar baz-3.17.jar qux-2.1.jar java.prefsjava.xml 89/136
  90. 90. app1 app3app2 foo-1.0.jar bar-0.0.1.jar baz-3.17.jar qux-2.1.jar java.prefsjava.xml <unnamed> 90/136
  91. 91. foo-1.0.jar bar-0.0.1.jar baz-3.17.jar qux-2.1.jar java.prefsjava.xml app3app2 app1 91/136
  92. 92. foo-1.0.jar bar-0.0.1.jar baz-3.17.jar qux-2.1.jar java.prefsjava.xml requires app3 requires app2 app3app2 app1 92/136
  93. 93. foo-1.0.jar bar-0.0.1.jar baz-3.17.jar qux-2.1.jar java.prefsjava.xml requires app3 requires app2 requires ??? app3app2 app1 requires ??? 93/136
  94. 94. foo-1.0.jar bar-0.0.1.jar baz-3.17.jar qux-2.1.jar java.prefsjava.xml automatic modules automatic modules requires app3 requires app2 requires ??? app3app2 app1 requires ??? 94/136
  95. 95. Automatic module • Имя выводится из имени jar-файла (или из атрибута Automatic-Module-Name) 95/136
  96. 96. foo-1.0.jar bar-0.0.1.jar baz-3.17.jar qux-2.1.jar java.prefsjava.xml automatic modules automatic modules requires app3 requires app2 requires foo app3app2 app1 requires bar 96/136
  97. 97. Automatic module • Имя выводится из имени jar-файла (или из атрибута Automatic-Module-Name) • Requires all modules • Exports all packages • Opens all packages 97/136
  98. 98. app1 app3app2 foo-1.0.jar bar-0.0.1.jar baz-3.17.jar qux-2.1.jar java.prefsjava.xml 98/136
  99. 99. foo-1.0.jar bar-0.0.1.jar baz-3.17.jar qux-2.1.jar java.prefsjava.xml app1 app2 app3 99/136
  100. 100. app1 app3app2 foo-1.0.jar bar-0.0.1.jar baz-3.17.jar qux-2.1.jar java.prefsjava.xml 100/136
  101. 101. app1 app3app2 foo-1.0.jar bar-0.0.1.jar baz-3.17.jar qux-2.2.jar java.prefsjava.xml 101/136
  102. 102. app1 app3app2 foo-1.0.jar bar-0.0.1.jar baz-3.18.jar qux-2.2.jar java.prefsjava.xml 102/136
  103. 103. app1 app3app2 foo-1.1.jar bar-0.0.1.jar baz-3.18.jar qux-2.2.jar java.prefsjava.xml 103/136
  104. 104. app1 app3app2 foo-1.0.jar bar-0.0.2.jar baz-3.17.jar qux-2.2.jar java.prefsjava.xml 104/136
  105. 105. Сервисы 105/136
  106. 106. Сервисы • Появились в Java 6 106/136
  107. 107. Сервисы • Появились в Java 6 • В Java 9 стали намного удобнее и безопаснее 107/136
  108. 108. package com.foo; public interface Calculator { int square(int x); } module foo { exports com.foo; } 108/136
  109. 109. package com.foo; public interface Calculator { int square(int x); } module foo { exports com.foo; } public class Main { … } 109/136
  110. 110. package com.foo; public interface Calculator { int square(int x); } package com.bar; public class CalculatorImpl implements Calculator { @Override public int square(int x) { return x * x; } } module foo { exports com.foo; } module bar { requires foo; } public class Main { … } 110/136
  111. 111. package com.foo; public interface Calculator { int square(int x); } package com.bar; public class CalculatorImpl implements Calculator { @Override public int square(int x) { return x * x; } } module foo { exports com.foo; uses Calculator; } module bar { requires foo; provides Calculator with CalculatorImpl; } public class Main { … } 111/136
  112. 112. package com.foo; public interface Calculator { int square(int x); static Calculator get() {…} } package com.bar; public class CalculatorImpl implements Calculator { @Override public int square(int x) { return x * x; } } module foo { exports com.foo; uses Calculator; } module bar { requires foo; provides Calculator with CalculatorImpl; } public class Main { … } 112/136
  113. 113. package com.foo; import java.util.ServiceLoader; public interface Calculator { int square(int x); static Calculator get() { return ServiceLoader .load(Calculator.class) .findFirst() // Optional<Calculator> .orElseThrow(() -> new RuntimeException( "No Calculator provider found")); } } 113/136
  114. 114. package com.foo; import java.util.ServiceLoader; public interface Calculator { int square(int x); static List<Calculator> get() { return ServiceLoader .load(Calculator.class) .stream() .collect(Collectors.toUnmodifiableList()); } } 114/136
  115. 115. java.scripting ScriptEngineFactory jdk.scripting.nashorn NashornScriptEngineFactory 115/136
  116. 116. java.base ToolProvider jdk.compiler JavacToolProvider jdk.jlink JlinkToolProvider jdk.jartool JarToolProvider 116/136
  117. 117. Optional<ToolProvider> jar = ToolProvider.findFirst("jar"); 117/136
  118. 118. Optional<ToolProvider> jar = ToolProvider.findFirst("jar"); jar.get().run( System.out, System.err, "--describe-module", "--file", "path/to/some/module.jar"); 118/136
  119. 119. Демонстрация • Java 10 приложение с использованием сервисов • git clone https://github.com/orionll/services-demo 119/136
  120. 120. Демонстрация • Java 10 приложение с использованием сервисов • git clone https://github.com/orionll/services-demo 120/136
  121. 121. Демонстрация • Java 10 приложение с использованием сервисов • git clone https://github.com/orionll/services-demo FigureDescriptorProvider BaseFigureDescriptorProvider ExtFigureDescriptorProvider 121/136
  122. 122. Резюме 122/136
  123. 123. Резюме • Система модулей улучшает архитектуру проекта 123/136
  124. 124. Резюме • Система модулей улучшает архитектуру проекта • Делает приложение более безопасным 124/136
  125. 125. Резюме • Система модулей улучшает архитектуру проекта • Делает приложение более безопасным • Предоставляет механизмы для облегчения разработки крупных систем (сервисы, upgradeable modules) 125/136
  126. 126. Резюме • Система модулей улучшает архитектуру проекта • Делает приложение более безопасным • Предоставляет механизмы для облегчения разработки крупных систем (сервисы, upgradeable modules) • Улучшает производительность 126/136
  127. 127. Недостатки 127/136
  128. 128. Недостатки Сложность: • -classpath vs --module-path vs --upgrade-module-path • non-modular jar vs modular jar vs automatic jar • Много новых опций (--add-modules, --add-exports, --patch-module…) • Много новых инструментов (jlink, jimage, jmod, jdeps) 128/136
  129. 129. Недостатки Сложность: • -classpath vs --module-path vs --upgrade-module-path • non-modular jar vs modular jar vs automatic jar • Много новых опций (--add-modules, --add-exports, --patch-module…) • Много новых инструментов (jlink, jimage, jmod, jdeps) Закрытые split-пакеты запрещены. 129/136
  130. 130. Нужно ли прямо сейчас переходить на модули? 130/136
  131. 131. Экосистема ещё довольно плохо готова к модульности • Инструменты плохо готовы (IDE, системы сборки, контейнеры, тест-фреймворки) 131/136
  132. 132. Экосистема ещё довольно плохо готова к модульности • Инструменты плохо готовы (IDE, системы сборки, контейнеры, тест-фреймворки) • Automatic-Module-Name почти нигде нет 132/136
  133. 133. Экосистема ещё довольно плохо готова к модульности • Инструменты плохо готовы (IDE, системы сборки, контейнеры, тест-фреймворки) • Automatic-Module-Name почти нигде нет • Split packages кругом (например, jsr305 и java.xml.ws.annotation) 133/136
  134. 134. Экосистема ещё довольно плохо готова к модульности • Инструменты плохо готовы (IDE, системы сборки, контейнеры, тест-фреймворки) • Automatic-Module-Name почти нигде нет • Split packages кругом (например, jsr305 и java.xml.ws.annotation) • Многие библиотеки используют private API 134/136
  135. 135. Полезные ссылки • Project Jigsaw: http://openjdk.java.net/projects/jigsaw/ • Replacements for deprecated java.se.ee modules: https://stackoverflow.com/questions/48204141/replacements -for-deprecated-jpms-modules-with-java-ee-apis • jdeps: https://docs.oracle.com/javase/10/tools/jdeps.htm • jlink: https://docs.oracle.com/javase/10/tools/jlink.htm • Services Demo: https://github.com/orionll/services-demo 135/136
  136. 136. Спасибо за внимание! Java 10 136/136
  • sgraba

    Oct. 26, 2019

Рассказ о главном новшестве Java 9: проекте Jigsaw и системе модулей. С момента выхода девятки прошёл уже почти год, и за это время даже успела выйти Java 10, но подавляющее большинство всё ещё использует Java 8 и более старые версии. Однако переход на новые версии каждому рано или поздно придётся сделать, поэтому уже сейчас было бы неплохо иметь базовое понимание модульности в Java и подготовиться к будущей миграции. В докладе рассказано об истории появления модулей в JDK, о том, зачем они нужны обычному программисту и как они могут облегчить разработку и поддержку больших систем. Также рассказано, какие типичные проблемы могут возникнуть при миграции старых приложений на модули и как заранее подготовиться, чтобы избежать этих проблем в будущем.

Vues

Nombre de vues

263

Sur Slideshare

0

À partir des intégrations

0

Nombre d'intégrations

2

Actions

Téléchargements

4

Partages

0

Commentaires

0

Mentions J'aime

1

×