Что включает в себя модуль lz
Модульность в Java 9
Основным нововведением Java 9 было именно введение модульности. Про эту фичу было много разговоров, дата релиза несколько раз переносилась, чтобы допилить все должным образом. В этом посте речь пойдет о том, что дает механизм модулей, и чего полезного Java 9 принесла в целом. Основой для поста послужил доклад моего коллеги — Сергея Малькевича.
Для реализации модулей в этой версии Java был выделен целый проект — Project Jigsaw — который включает в себя несколько JEP и JSR.
Для любителей официальной документации, ознакомиться более подробно с каждым JEP можно здесь.
Подробнее о Project Jigsaw
Project Jigsaw, который реализует модульность, начал разрабатываться в далеком 2005: сначала вышел JSR 277, а уже в 2008 началась непосредственная работа над проектом. Релиз состоялся только в 2017 году. То есть, для того, чтобы докрутить модули в Java, понадобилось почти 10 лет. Что, собственно, подчеркивает весь масштаб работы и изменений, которые были внесены в ходе реализации модульности.
Какие цели ставили перед собой разработчики:
Чего полезного принесла Java 9
До 9 версии, JDK и JRE были монолитными. Их размер рос с каждым релизом. Java 8 занимала уже сотни мегабайт, и все это разработчикам приходилось “таскать с собой” каждый раз, чтобы иметь возможность запускать Java приложения. Один только rt.jar весит порядка 60 Mb. Ну и сюда еще добавляем медленный старт и высокое потребление памяти. Тут на помощь пришла Java 9.
В JDK 9 было введено разделение на модули, а именно, JDK была разделена на 73 модуля. И с каждой новой версией количество этих модулей растет. В 11 версии это число близится к 100. Это разделение позволило разработчикам создать утилиту JLINK. С помощью JLINK можно создавать кастомные наборы JRE, которые будут включают только «нужные» модули, которые реально необходимы вашему приложению. Таким образом, простое приложение и какой-либо customJRE с минимальным (или небольшим) набором модулей в итоге может уместиться в 20 Mb, что не может не радовать.
Список модулей можно посмотреть здесь.
С приходом Java 9 поменялась структура JDK: теперь она идентична структуре JRE. Если раньше JDK включала папку JRE, где снова имеется bin и дублируются файлы, то теперь все выглядит следующим образом:
Модули
Собственно. что такое модуль? Модуль — это новый уровень агрегации пакетов и ресурсов (ориг. “a uniquely named, reusable group of related packages, as well as resources and a module descriptor”).
Модули поставляются в JAR файлах с пакетами и дескриптором модуля
module-info.java. Файл module-info.java содержит описание модуля:
имя, зависимости, экспортируемые пакеты, потребляемые и предоставляемые сервисы, разрешения для reflection доступа.
Примеры описания дескриптора модуля:
После ключевого слова module у нас идет имя пакета jdk.javadoc, который зависит от другого пакета java.xml и транзитивно зависит от других пакетов.
Давайте подробнее пройдемся по каждому из ключевых слов:
Сначала указываем интерфейс — javax.tools.Tool, после with — реализацию.
Немного о сервисах
Допустим, у нас подключено несколько модулей, которые реализуют абстрактный сервис — MyService. При сборке приложения у нас есть возможность решить, какую реализацию сервиса использовать, “перетащив” нужные нам модули реализации сервиса на —module-path:
Таким образом, возвращенный Iterator содержит список реализаций интерфейса MyService. Фактически, он будет содержать все реализации, найденные в модулях, найденных на —module-path.
Зачем в принципе были введены сервисы? Они нужны для того, чтобы показать, как наш код будет использован. То есть, здесь заключена семантическая роль. Также, модульность — это про инкапсуляцию и безопасность, так как мы можем сделать реализацию private и исключить возможность несанкционированного доступа через reflection.
Также, один из вариантов использования сервисов — это достаточно простая реализация плагинов. Мы можем реализовать интерфейс плагина для нашего приложения и подключать модули для работы с ними.
Вернемся к синтаксису описания модулей:
До 9ки через reflection мы имели доступ практически ко всему и могли делать все, что хотим и с чем хотим. А 9-ая версия, как уже упоминалось, позволяет обезопасить себя от “нелегального” reflection доступа.
Мы можем полностью открыть модуль для reflection доступа, объявив open:
Либо, мы можем указать какие либо пакеты для reflection доступа, объявив opens:
Здесь же есть возможность использовать opens com.my.coolpackage to…, таким образом предоставляя reflection доступ пакету com.my.coolpackage из пакета, который укажем после to.
Типы модулей
Project Jigsaw классифицирует модули следующим образом:
Class-path vs module-path
С появлением модулей появилось новое понятие — module-path. По сути, это тот же class-path, но для модулей.
Запуск модульного приложения выглядит следующим образом:
В обычном режиме запуска мы указываем опции и полный путь к мейн классу. В случае, если мы хотим работать с модулями, мы также указываем опции и параметр -m либо -module, который как раз указывает на то, что мы будем запускать модули. То есть, мы автоматически переводим наше приложение в модульный режим. Далее мы указываем имя модуля и путь к мейн классу из модуля.
Также, если в обычном режиме мы привыкли работать с параметром -cp и —class-path, в режиме модульности мы прописываем новый параметр -p и —module-path, который указывает пути к используемым в приложении модулям.
Часто встречаюсь с тем, что разработчики не переходят на версии 9+, так как считают, что им придется работать с модулями. Хотя на самом деле, мы можем запускать наши приложения в старом режиме, попросту не прописывая параметр и не используя модули, а используя только другие новые фишки.
JAR HELL
Хочу также по диагонали остановится на проблеме Jar Hell.
Что такое Jar Hell в двух словах? Например, у нас есть какое-то наше приложение и оно зависит от библиотеки X и библиотеки Y. При этом, обе эти библиотеки зависят от библиотеки Z, но от разных версий: X зависит от версии 1, Y — от версии 2. Хорошо, если версия 2 обратно совместима с версией 1, тогда никаких проблем не возникнет. А если нет — очевидно, что мы получаем конфликт версий, то есть одна и та же библиотека не может быть загружена в память одним и тем же загрузчиком классов.
Как в этом случае выходят из ситуации? Есть стандартные методы, которые разработчики используют со времен самой первой Java, например, exclude, кто-то использует плагины для Maven, которые переименовывают названия корневых пакетов библиотеки. Либо же, разработчики ищут разные версии библиотеки X, чтобы подобрать совместимый вариант.
К чему это я: первые прототипы Jigsaw подразумевали наличие версии у модуля и позволяли загрузку нескольких версий через разные ClassLoader’ы, но позже от это отказались. В итоге, “серебряной пули”, которую многие ждали, не вышло.
Но, “прямо-из-коробки” нас немного обезопасили от подобных проблем. В Java 9 запрещены Split Packages — пакеты, которые разделены на несколько модулей. То есть, если у нас есть пакет com.my.coolpackage в одном модуле, мы не можем его использовать в другом модуле в рамках одного приложения. При запуске приложения с модулями, содержащими одинаковые пакеты, мы просто упадем. Это небольшое улучшение исключает возможность непредсказуемого поведения в связи с загрузкой Split пакетов.
Также, помимо самих модулей, есть еще механизм слоев или Jigsaw Layers, который также помогает справится с проблемой Jar Hell.
Jigsaw слой можно определить как некоторую локальную модульную систему. И здесь стоит отметить, что Split пакеты, о которых шла речь выше, запрещены только в рамках одного Jigsaw слоя. Модули с одинаковыми пакетами имеют место быть, но они должны принадлежать разным слоям.
Выглядит это следующим образом:
При старте приложения создается слой boot, куда входят модули платформы, загружаемые Bootstrap, добавочные модули платформы, загружаемые платформенным загрузчиком и модули нашего приложения, загружаемые Application загрузчиком.
В любой момент, мы можем создать свои слои и “положить” туда модули разных версий и при этом не упасть.
Есть отличный подробный доклад на YouTube на эту тему: Спасение от Jar Hell с помощью Jigsaw Layers
Заключение
Механизм модулей из Java 9 открывает нам новые возможности, при этом поддержка библиотек на сегодняшний день довольно небольшая. Да, люди запускают Spring, Spring Boot и так далее. Но большинство библиотек так и не перешло на полное использование модулей. Видимо поэтому, все эти изменения были восприняты довольно скептически техничесим сообществом. Модули предоставляют нам новые возможности, но вопрос востребованности остаётся открытым.
Ну и напоследок, предлагаю подборку материалов на эту тему:
Что такое адаптер CI и cam модуль для телевизора
CI-модуль (САМ-модуль CI+) – это слот, расположенный на задней панели устройства. Данная система позволяет пользователю обеспечить доступ к ранее зашифрованному контенту, поставляемому через спутниковое ТВ. Это актуально, когда имеют место недоступные каналы, или имеется некоторая база данных, к которой нужно открыть доступ, к примеру, к фильмам или анимации.
Расшифровывается данная аббревиатура как Conditional Access Module (модуль условного доступа ci cam), сам же модульный элемент вставляется в специальный слот CI (common interface).
Как это работает
Предусматривается размещение в CAM-модуль некоторой смарт-карты для последующего декодирования, которая предоставляется провайдером спутникового или кабельного телевидения.
Смарт карта и кам модуль для телевизора от оператора спутникового тв МТС
Без данной карты работать модуль не будет, учитывая тот факт, что все данные, актуальные для дешифровки, находятся непосредственно на этом элементе. Наличие данной карты представляет собой доступ к платному материалу, предоставленному провайдером услуги.
Все ли ТВ комплектуются кам модулем
Как правило, CAM-модуль входит непосредственно в комплект поставки к телевизору. Но можно отметить, что далеко не все телевизоры оснащаются данным приспособлением.
В том случае, когда модульный элемент отсутствует, его потребуется в дальнейшем приобрести отдельно. Как вариант, поставщики услуг смогут предоставить данное оборудование непосредственно с самим сервисом. Однако, его предлагают зачастую в аренду за весьма небольшие средства.
Как модуль Триколор
Преимущества использования кам модуля для телевизора
Главным достоинством можно назвать то, что когда имеется встроенный cam модуль, то количество необходимого оборудования для трансляции телевидения минимально.
Тогда не потребуется приставка для приема цифрового ТВ, а также тюнер, используемый для трансляции спутникового телевидения.
К преимуществам также стоит отнести:
Как происходит декодирование
Поставка контента в рамках цифрового телевидения выполняется непосредственно в зашифрованном виде. Чтобы разблокировать данный сигнал потребуется код, который изменяется провайдером непосредственно по приведенному алгоритму.
Передача осуществляется с декодирующей смарт-карты, которая выдается провайдером непосредственно при покупке услуги.
Каналы, специально оплаченные, а также входящие в план тарифа будут в дальнейшем разблокированы.
Иные каналы останутся непосредственно закрытыми. Чтобы разблокировать, дополнительно нужно позаботиться о специальных тюнерах.
Осуществляется прием данных сигналов, для кабельного ТВ в стандарте DVB-C/DVB-C2, в то время как для спутникового – DVB-S/DVB-S2.
Как подключить кам модуль к ТВ: установка и настройка
В зависимости от конкретной модели, кам модуль может подключаться непосредственно через слот CI или же через отдельный адаптер, поставляемый непосредственно в комплекте с ТВ.
Устанавливается модульное устройство на задней панели телевизора:
Как и куда правильно вставить cam-модуль на телевизоре
В первом случае потребуется выполнить следующее:
Установка через адаптер CI
Поставляется адаптер в комплекте с ТВ. Если элемент утрачен, можно совершить его покупку в специальном сервисном центре.
Процесс установки выглядит следующим образом:
Как выполняется установка и настройка CAM модуля:
Модули вместо микросервисов
Термин «модуль» (module) взят из статьи Modules vs. microservices. Так же для описания чего-то среднего между микросервисами и монолитами иногда используют термины «микролит» (microlith) или «моносервис» (monoservice). Но, не смотря на то, что термин «модуль» и так уже нагружен общеизвестным смыслом, на мой взгляд он подходит лучше других вариантов. Update: В комментарии lega использовал термин «встроенный микросервис» — он лучше описывает суть подхода, чем «модуль».
Монолит и микросервисы это очень разные подходы, поэтому в любой попытке взять лучшее от обоих критически важен баланс — что взять, а что нет. Иначе получится монстр вроде OSGi.
Я пишу микросервисы с 2009 года, но применять модули вместо микросервисов в реальных проектах пока не пробовал — всё описанное далее это моё предположение о том, каким должен быть вышеупомянутый баланс, и оно нуждается как в теоретической критике так и в проверке практикой.
Что такое модуль
Модуль — это что-то вроде микросервиса, только реализованного внутри единого приложения, состоящего из группы таких модулей и очень небольшой части, которая занимается инициализацией и запуском всех этих модулей.
Хотя формально такое приложение можно назвать монолитом, у этого подхода намного больше общего с микросервисами, поэтому и сравнивать его имеет смысл именно с микросервисным подходом. Как и микросервис, каждый модуль:
В отличие от микросервисов, модуль:
В отличие от обычных библиотек, модуль:
В большинстве случаев модули не нуждаются в каком-либо реестре сервисов — вместо регистрации себя и поиска других модулей они получают необходимые им интерфейсы других модулей при запуске, когда запускающееся приложение вызывает функцию инициализации каждого модуля (в порядке, определяемом зависимостями между модулями). В качестве побочного эффекта это позволит сразу обнаружить циклические зависимости между модулями, если они появятся (и, по возможности, изменить архитектуру так, чтобы от них избавиться).
Где нужны модули
Есть константная добавленная сложность (accidental complexity), одинаковая в каждом микросервисе (регистрация/обнаружение сервисов, подключение и переподключение к ним, авторизация между сервисами, (де)маршалинг и шифрование трафика, использование прерывателей зацикленных запросов, реализация трассировки запросов, etc.). Есть аналогичная константная добавленная операционная сложность (необходимость автоматизации тестирования и выката, реализация детального мониторинга, агрегация логов, использование служебных сервисов для регистрации и поиска сервисов, для хранения конфигурации сервисов, для аудита, etc.). С этим можно смириться, потому что реализовать всё это можно один раз, по мере роста количества микросервисов эта сложность не растёт, а преимущества микросервисов с лихвой компенсируют эти затраты.
Но есть сложность, зависящая от бизнес-логики конкретного приложения и увеличивающаяся по мере развития приложения, от которой хотелось бы избавиться хотя бы в тех приложениях, которым не требуется возможность масштабирования и высокая доступность (или хотя бы той части кода таких приложений, в которой нет явной необходимости взаимодействовать с внешними сервисами):
Правильный модульный подход позволяет сохранить многие преимущества микросервисов (при наличии необходимой поддержки на уровне языка и/или инструментов разработки), но помимо потери ненужных в данном приложении возможностей масштабирования и высокой доступности есть и другие:
Так же у модульного подхода появляются новые достоинства:
Резюме
В общем и целом подход выглядит достаточно соблазнительным — мы получаем возможность писать монолитное приложение в виде кучки по-настоящему хорошо изолированных частей (причём контролировать это будет по большей части язык и/или инструменты, а не внутренняя дисциплина), разрабатываемых в микросервисном стиле (в т.ч. разными командами в разных репо), которые «лёгким движением руки» могут превратиться в настоящие микросервисы если в этом возникнет реальная необходимость… А пока её нет — мы можем использовать обмен сообщениями между модулями внутри приложения как простую и очень быструю замену настоящего RPC, избегая сложностей асинхронности, eventual consistency и обработки сетевых ошибок.
Необходимая поддержка этого подхода в данный момент есть далеко не во всех языках, но в некоторых есть: автор статьи «Modules vs. microservices» писал о поддержке модульности в Java 9, в Go уже пару лет есть поддержка internal-пакетов, в Erlang судя по статье на эту же тему Dawn of the Microlith — Monoservices with Elixir всё хорошо, …. Я не уверен, насколько на скриптовых языках возможно обеспечить реальную изоляцию модулей, но попытки есть: micromono на NodeJS, в комментарии lega ссылка на подход для Python, …
Если у вас есть соображения по теме (а ещё лучше — опыт реального проекта на похожих принципах) или дополнительные ссылки на статьи/проекты по теме — пишите в комментариях, я постараюсь дополнять ими статью.
Что такое модульная форма обучения?
Одной из современных форм обучения является модульная система, которая сегодня становится все популярней в силу своей динамичности и высокой результативности. Мы расскажем обо всех ее особенностях и перечислим все преимущества и недостатки этой системы обучения.
В основе современных систем образования лежат принципы, кардинально отличающиеся от учебных постулатов советских времен. Они чужие для наших родителей и, наверняка, незнакомы бабушкам и дедушкам (ну разве что они работают в сфере образования). Но это отнюдь не приуменьшает их эффективности и удобства. Одной из таких современных форм обучения является модульная система, которая сегодня становится все популярней в силу своей динамичности и высокой результативности. Мы расскажем обо всех ее особенностях и перечислим все преимущества и недостатки этой системы обучения.
Понятие модуля
Понятие «модуль» является одним из новых терминов в современном российском образовании. Это структурированная часть образовательной программы, в рамках которой изучается несколько дисциплин, учебных курсов и разделов наук. Термин «модуль» часто употребляют в качестве синонима рабочей программы дисциплины, цикла дисциплин учебного плана, программы учебного курса.
Сущность модульной формы обучения, прежде всего, заключается в том, что ученик сам изучает дисциплину, а педагог управляет его учебно-познавательной деятельностью: организовывает учебный процесс, а также мотивирует, координирует и контролирует работу ученика.
На сегодняшний день в системе российского образования модуль выполняет функции:
Структура модульной образовательной программы, программы модуля
Образовательный процесс с модульной организацией реализуется на базе утвержденных Министерством образования и наук России учебных планов. Структура образовательной программы может включать в себя несколько модулей, при этом объем их исполнения выражается в кредитах (за академический год может быть освоено не более 60 кредитов).
Каждый модуль имеет в своем составе учебные элементы, конфигурация которых зависит от дидактических целей. Учебный элемент модуля состоит из: цели, списка материалов, пособий, проверки усвоенных знаний. Как правило, каждый модуль содержит 5-8 учебных элементов: введение, учебные цели, базовые проблемы элемента (кейсы), текстовая информация, упражнения, заключения, библиографический список, глоссарий (словарь терминов).
Структура модульной учебной программы | Структура учебной программы модуля |
Цели освоения учебной программы | Цели освоения модуля |
Ожидаемый результат освоения учебной программы | Ожидаемый результат освоения модуля |
Элемент 1 учебной программы | Учебная программа курса 1 |
Элемент 2 учебной программы | Учебная программа курса 2 |
Элемент 3 учебной программы | Учебная программа курса 3 |
Элемент 4 учебной программы | Учебная программа курса 4 |
Аттестация по итогам освоения учебной программы | Аттестация по модулю (экзамен, письменная работа, защита письменной работы) |
Целью модульной программы является организация и реализация учебного процесса, ориентированного на индивидуализм, повышение эффективности и качества подготовки учащихся, а также формирование универсально-профессиональных компетенций. Учащийся должен самостоятельно ее усвоить и достичь поставленных целей в процессе работы над модулем. Учебные модули должны быть структурированы таким образом, чтобы достичь поставленных педагогических целей и ясно, в полном объеме, преподнести информацию учащемуся. Оценка успеваемости происходит через рейтинговую систему оценки знаний.
Модульная система обучения
Модульная система обучения реализуется в формате ECTS – Европейской кредитно-трансферной системы (Болонской системе), которая базируется на объеме учебной нагрузки, выполненных кредитов.
Модульное обучение отличается от классической формы преподавания:
Модульная система обучения это современная педагогическая технология, которая базируется на блочном (модульном) построении материала, который усваивается последовательно и оценивается путем накопления рейтинговых баллов за занятия и самостоятельную работу. Она реализуется в контексте принципов познавательной деятельности, индивидуальной структуризации программы и психологического комфорта. Преподаватель в учебном плане самостоятельно распределяет количество баллов на каждый модуль, за разные виды учебной деятельности, формы контроля знаний.
Формы модульного контроля
В отличие от привычной нам (советской) системы обучения модульная система имеет несколько форм контроля:
Результаты учебы трактуются в контексте количества набранных баллов согласно шкале ЕСТS.
Шкала ECTS | Национальная шкала | Сумма баллов по дисциплине |
A | отлично | 90-100 |
B,C | хорошо | 75-89 |
D,E | удовлетворительно | 60-74 |
FX | неудовлетворительно (но с возможностью пересдачи) | 35-59 |
F | неудовлетворительно (с обязательным повтором курса) | 1-34 |
Преимущества и недостатки модульной формы обучения
Преимущества модульного обучения:
Отметим, что несмотря на некоторые недостатки, модульная система обучения является инновационной педагогической технологией, которая повышает эффективность учебного процесса, делает его более индивидуализированным и динамичным.