Избранное сообщение

Использование списков для ввода данных в Excel / Office / Excel

Вообще при работе с любой информацией, а уж с управленческой в первую очередь, первоочередное значение имеет ее качество. Она обеспечивае...

Ездил на экскурсию на хлебокомбинат.
Больше я хлеб не ем...
Ездил на экскурсию на мясокомбинат.
Больше я мясо не ем...
Завтра экскурсия на ликеро-водочный завод.
Я не поеду...

пятница, 31 августа 2018 г.

День блога 2018

В 2005 году проворные пользователи LiveJournal заметили в слове blog цифры 3108. Именно тогда и зародилась традиция отмечать День блога 31 августа (31.08).
В этот день люди со всего мира публикуют в своих блогах пять ссылок на другие блоги, которые, как правило, по тематике отличаются от их собственного. Ссылки можно сопровождать небольшими рецензиями — своими впечатлениями о блогах. Делается это для того, чтобы блогер и его читатели смогли открыть для себя что-то новое.




  1. Блог Java программиста. Заметки о программировании на Java и Scala, а также про UML, Android и не только… author: Виталий Лигай (Java EE Architect/Android Developer) http://programador.ru
  2. Освой программирование играючи. Сайт Александра Климова. http://developer.alexanderklimov.ru/
  3. Блог Василия Прохорова "Интернет и программы для всех" https://vellisa.ru/
  4. Блог Виктора Князева. Начинающим пользователям компьютера. http://viktor-knyazev.ru/
  5. Народная медицина. http://narodnayamedicyna.ru/blog/latest

Фото-загадка: найди ящерку

Прогуливаясь по лугу я встретил шуструю маленькую ящерицу, очень умело маскирующуюся на местности. Даже на фото найти ее непросто. А у вас получится?



OpenNews: Google представил криптографическую библиотеку Tink / Криптография, шифрование

Компания Google представила открытую криптографическую библиотеку Tink, нацеленную на предоставление простого для корректного применения криптографического API, при использовании которого трудно допустить ошибки, способные привести к снижению с безопасности. Предоставляется полноценная поддержка языков Java (в том числе для Android), C++ и Obj-C, а также экспериментальная поддержка Go и JavaScript. Код поставляется под лицензией Apache 2.0.
Библиотека подготовлена командой, занимавшейся разработкой инструментария Wycheproof и выявившей более 40 уязвимостей и слабых мест в различных популярных криптографических библиотеках и реализациях алгоритмов шифрования. В результате данной работы родилась идея создания предельно простого API, который не позволял бы совершать ошибки, вызванные недопониманием работы алгоритмов шифрования, и который без риска для безопасности смогли бы использовать разработчики не имеющие опыта в криптографии.
В итоге появился проект Tink, сконцентрированный на сокращении числа потенциальных ошибок, которые могут появиться в результате ненадлежащего применения API, спроектированный с учётом опыта анализа слабых мест в различных реализациях алгоритмов шифрования, написанный с оглядкой на безопасность, прошедший жесткое рецензирование кода и досконально протестированный. В Google Tink уже применяется во многих внутренних проектах, таких как AdMob, Google Pay, Google Assistant, Firebase и Android Search App.
Основу программного интерфейса Tink составляет набор криптографических примитивов, каждый из которых охватывает определённую область без углубления в детали, например, для симметричного шифрования по ключу предлагается примитив AEAD, предоставляющий две операции - шифрование и расшифровка, и не требующий от разработчика выбора конкретных алгоритмов шифрования и определения их параметров (например, векторов инициализации (nonce)). Перед использованием примитива выполняется его регистрация, после чего генерируется или загружается необходимый для операции набор ключей и привязывается к примитиву.
В настоящее время предлагаются следующие примитивы:
  • AEAD (Authenticated Encryption with Associated Data) - симметричное аутентифицированное шифрование по фиксированному ключу с опциональной возможностью прикрепления аутентифицированных, но не зашифрованных, связанных данных. Поддерживается как шифрование блоков, так и потоков данных;
  • MAC (Message Authentication Codes) - коды аутентификации сообщений для обеспечения целостности и аутентификации источника данных;
  • Функции для создания цифровой подписи и её проверки (PublicKeySign и PublicKeyVerify);
  • Функции гибридного шифрования, сочетающие скорость симметричного шифрования с удобством шифрования по открытым ключам;
Каждый примитив поддерживает опции для работы в stateless-режиме (безопасный для многопоточных программ), с использованием безопасных операций копирования (copy-safe) и для применения ключей, длиной как минимум 128 бит. Библиотека автоматически блокирует попытки выполнения потенциально небезопасных операций, таких как попытки загрузки ключей из незашифрованных файлов на диске. Доступен API для ротации ключей и взаимодействия со внешними системами управления ключами, такими как Google Cloud KMS, Amazon KMS, Android Keystore и Apple iOS KeyChain.
Библиотека имеет модульную архитектуру и позволяет подключать свои реализации примитивов и заменять существующие примитивы и компоненты управления ключами, не меняя программный код конечных приложений. Например, в случае выявления уязвимости в каком-то алгоритме шифрования достаточно будет заменить примитив в самой библиотеке и перегенерировать ключи, при этом не трогая код приложений. В текущем виде предлагаемые примитивы базируются на использовании библиотек BoringSSL и Java Cryptography Architecture, которые выступают низкоуровневой основой.
Tink также позволяет исключать из сборки излишнюю функциональность. Например, если в программе используется только проверка цифровой подписи, то разработчик для сокращения размера кода приложения может удалить компоненты симметричного шифрования. 

Источник: http://www.opennet.ru/opennews/art.shtml?num=49202

Смотри также:

Основы криптографии. Часть 0. http://fetisovvs.blogspot.com/2018/03/0.html
Лучшие бесплатные утилиты шифрования файлов и папок. http://fetisovvs.blogspot.com/2015/04/freeware_17.html
Защищённый сервис обмена текстовыми сообщениями. http://fetisovvs.blogspot.com/2017/06/blog-post_96.html
Вехи истории шифрования и борьбы с ним. http://fetisovvs.blogspot.com/2017/06/blog-post_44.html
Немного из истории криптографии СССP: M-105 под кодовым названием Агат. http://fetisovvs.blogspot.com/2017/09/p-m-105-ua-hostingcompany.html

Java EE Concurency API / Программирование на Java

Всем привет!

А мы тут плюшками балуемся запускаем второй поток курса «Разработчик Java Enterprise». Бессменный создатель и преподаватель курса — Виталий Иванов, написал вот по этому поводу статью даже, которая, как надеемся, покажется вам полезной :) 

Так что поехали :)

Данная статья посвящена изучению API к спецификации JavaEE Concurrency (JSR 236), определяющий стандарт выполнения параллельных задач в JavaEE контейнере, используя концепцию управляемых ресурсов. Выход седьмой версии JavaEE сделал возможным запуск параллельных задач в Enterprise-контейнерах, предоставляя разработчику удобные средства и утилиты для работы с многозадачностью. До того самого момента, вся многозадачность отдавалась на откуп конкретной реализации используемого сервера приложений, самостоятельно принимающего решение об оптимизации выполнения задач. Нарушение этого принципа расценивалось как плохая практика построения архитектуры Enterprise-приложений. Вследствие чего, разработчику не рекомендовалось создавать новые потоки, а иногда и запрещалось подобное поведение на уровне контейнера. 



The enterprise bean must not attempt to manage threads. The enterprise bean must not attempt to start, stop, suspend, or resume a thread, or to change a thread’s priority or name. The enterprise bean must not attempt to manage thread groups.

(свободный перевод автора: EJB не должны пытаться управлять потоками, а именно пытаться запускать, останавливать, приостанавливать, а также восстанавливать их выполнение или же менять приоритет или изменять имя потока. Также EJB не должны пытаться управлять группами потоков).


По факту, запретить создание своих собственных потоков в JavaEE-контейнерах достаточно проблематично, однако при таком подходе «фоновые» службы контейнера не могут гарантировать корректность выполнения своей работы. Например, закрытие транзакции по завершению метода EJB потенциально могло бы работать некорректно в случае запуска задач в новом потоке, используя наследников Threads (или имплементаций Runnable) из JavaSE. Также использование базовых интерфейсных типов из поставки Executor API такие, как ExecutorService и ScheduledExecutorService, при создании через статичные методы класса Executors, приводило бы к потенциальным ошибкам и нарушению порядка выполнения служб контейнера.

Из рекомендованных спецификацией JavaEE средств для асинхронного выполнения задач в распоряжении разработчика оставалось использование асинхронных Stateless/Statefull EJB и/или Message Driven бинов, возможностей которых достаточно для определенного круга задач и самое главное, что управление которыми изначально целиком и полностью находится под контролем сервера приложений, а именно EJB-контейнера.

Однако, как уже отмечалось ранее, благодаря JSR 236, появились управляемые контейнером ресурсы, реализующие поддержку многопоточности и асинхронного выполнения задач, расширяя возможности пакета java.util.concurrent из JavaSE. Для стека JavaEE классы управляемых ресурсов располагаются в пакете javax.enterprise.concurrent, при этом доступ к объектам этих классов осуществляется через внедрение ресурса, используя аннотацию@Resource, или через JNDI-контекст (в частности, InitialContext). Вместе с тем, добавились возможности использования привычных для многопоточной среды объектов Future/ScheduledFuture/CompletableFuture внутри приложений JavaEE. 

Итак, довольно лирики и давайте уже подробнее рассмотрим каждый из предоставляемых спецификацией управляемых ресурсов с практической точки зрения, а именно — в разрезе использования в прикладном коде приложения, а также с точки зрения конфигурирования ресурсов на примере сервера приложений Glassfish 5.

Что ж, первым на очереди рассмотрения выбран класс ManagedExecutorService, который (уже понимая из названия) расширяет возможности привычного ExecutorService «из коробки» JavaSE и предназначенного для асинхронного выполнения задач в среде JavaEE. 

Для конфигурирования в рамках сервера приложений Glassfish не только данного типа ExecutorService следует обратиться к конфигурационному файлу domain.xml, расположение которого определяется каталогом ${GLASSFISH_HOME}/domains/<имя_домена>/config. Фрагмент данного файла представлен ниже: 

<domain application-root="${com.sun.aas.instanceRoot}/applications" version="25" log-root="${com.sun.aas.instanceRoot}/logs">
<resources>
<context-service object-type="system-all" jndi-name="concurrent/__defaultContextService" />
<managed-executor-service object-type="system-all" jndi-name="concurrent/__defaultManagedExecutorService" />
<managed-scheduled-executor-service object-type="system-all" jndi-name="concurrent/__defaultManagedScheduledExecutorService" />
<managed-thread-factory object-type="system-all" jndi-name="concurrent/__defaultManagedThreadFactory" />
</resources>
<servers>
<server config-ref="server-config" name="server">
<resource-ref ref="concurrent/__defaultContextService" />
<resource-ref ref="concurrent/__defaultManagedExecutorService" />
<resource-ref ref="concurrent/__defaultManagedScheduledExecutorService" />
<resource-ref ref="concurrent/__defaultManagedThreadFactory" />
</server>
</servers>
</domain>

Заходя в интерфейс администраторской панели Glassfish 5, конфигурирование 

ManagedExecutorService выглядит следующим образом:




В данном разделе допускается создание новых однотипных ресурсов, управление имеющимися, удаление, а также блокировка и разблокировка.

Для любителей консольного администрирования в Glassfish представлена мощная утилита asadmin, используя в которой команду create-managed-executor-service, можно создавать новые ресурсы ManagedExecutorService:



В прикладном коде для получения ссылки на объект созданного ManagedExecutorService удобнее использовать внедрение ресурса, но также можно воспользоваться средствами JNDI, как показано ниже:

@Resource(lookup = "concurrent/OtusExecutorService")
ManagedExecutorService executor;
InitialContext context = new InitialContext();
ManagedExecutorService managedExecutorServiceWithContext =
(ManagedExecutorService) context.lookup(
"concurrent/OtusExecutorService");

Хотелось бы обратить внимание читателя, что для аннотации @Resource параметр lookup является опциональным и если он не определен разработчиком в коде приложения, то контейнер инжектирует умолчательные ресурсы, в имени которых присутствует префикс __default. В таком случае, для разработчика код становится еще лаконичнее:

@Resource
ManagedExecutorService executor;


После получения ссылки на данный объект, используя методы execute() и submit(), можно внутри контейнера запускать задачи, имплементирующие интерфейс Runnable или Callable.


Переходя к примеру, хочется отметить, что среди всего многообразия возможных кейсов, наибольший интерес представляют задачи, выполняемые в распределенной среде JavaEE и в которых важно обеспечить поддержку транзакционности в многопоточной среде. Как известно, в JavaEE разработана спецификация JTA (Java Transaction API), которая позволяет определять границы транзакции, явно начиная её методом begin() и завершая методами commit(), фиксируя изменения, или rollback(), откатывающий произведенные действия.

Рассмотрим пример таска, который возвращает сообщение из некоторого списка, состоящего из ста элементов, по индексу в рамках пользовательской транзакции:

public class TransactionSupportCallableTask implements Callable<String> {
private int messageIndex;
public TransactionSupportCallableTask(int messageId) {
this. messageIndex = messageId;
}
public String call() {
UserTransaction tx = lookupUserTransaction();
String message = null;
try {
tx.begin();
message = getMessage(messageIndex);
tx.commit();
} catch (Exception e) {
e.printStackTrace();
try {
tx.rollback();
} catch (Exception e1) {
e1.printStackTrace();
} }
return message;
}
private void getMessage(int index) { … }
private UserTransaction lookupUserTransaction () { … }
}

Код сервлета, выводящего сообщение из списка по случайно выбранному индексу:

@WebServlet("/task")
public class ManagedExecutorServiceServlet extends HttpServlet {
@Resource(lookup = "concurrent/OtusExecutorService")
ManagedExecutorService executor;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Future<String> futureResult = executor.submit(new TransactionSupportCallableTask(Random.nextInt(100)));
while (!futureResult.isDone()) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
} }
try {
response.getWriter().write("Callable task has received message with following content '" + futureResult.get() + "'");
} catch(Exception e) {
e.printStackTrace();
} }
}

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




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




Для быстрого создания ресурса с типом ManagedScheduledExecutorService утилита asadminобладает командой create-managed-scheduled-executor-service




В прикладном коде по-прежнему используем внедрение ресурса:

@Resource(lookup = "concurrent/OtusScheduledExecutorService")
ManagedScheduledExecutorService scheduledExecutor;


Основными методами выполнения задач для данного типа ExecutorService являются schedule(), принимающий на вход задачи типа Runnable или Callable, и scheduleAtFixedRate(), дополнительно определяющий первоначальную задержку в выполнении задачи и задающего интервал повторений в TimeUnit-ах (секундах, минутах и т.д.).


Предыдущий кейс можно переписать следующим образом:

@WebServlet("/scheduledTask")
public class ManagedScheduledExecutorServiceServlet extends HttpServlet {
@Resource(lookup = "concurrent/OtusScheduledExecutorService")
ManagedScheduledExecutorService scheduledExecutor;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ScheduledFuture<String> futureResult = scheduledExecutor.schedule(
new TransactionSupportCallableTask(Random.nextInt(100)), 5, TimeUnit.SECONDS);
while (!futureResult.isDone()) {
try {
Thread.sleep(50); // Wait
} catch (InterruptedException e) {
e.printStackTrace();
} }
try {
response.getWriter().write("Callable task received message with following content '" + futureResult.get() + "'");
} catch ( Exception e) {
e.printStackTrace();
} }
}

Также в Concurrency API для Enterpise-среды предоставляется возможность создания управляемых потоков. Для этих задач следует пользоваться возможностями управляемой фабрики потоков, реализующей свой функционал через одноименный класс ManagedThreadFactory и доступ к которой также осуществляется через службу JNDI:

@Resource
ManagedThreadFactory factory;

Окно администрирования консоли Glassfish выглядит «по старинке»:



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

В нашем случае, определим класс потока, выводящего информацию о друге, с которым неразрывно связан данный таск, в консоль:

public class SimpleThreadTask implements Runnable {
private String friend;
public SimpleThreadTask(String friend){
this.friend = friend;
}
@Override
public void run() {
System.out.println("Hello, " + friend);
}
}

Пусть сервлет запускает поток и сообщает об этом на выходе:

@WebServlet("/thread")
public class ManagedThreadFactoryServlet extends HttpServlet {
@Resource
ManagedThreadFactory factory;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Thread thread = factory.newThread(new SimpleThreadTask("Otus"));
thread.setName("ManagedThreadFromPool");
thread.setPriority(7);
thread.start();
response.getWriter().write("Custom thread has been running.");
}
}

Переходя к заключительной возможности JavaEE в области многопоточности – Context Services, следует заметить, что благодаря данным сервисам создаются динамические контекстные прокси-объекты. Всем нам прекрасно знакомы возможности динамических прокси из JavaSE (java.lang.reflect.Proxy), позволяющие генерировать динамическую реализацию требуемых интерфейсов, чьи возможности активно используются для задач создания соединений с БД и управления транзакциями, задействуются для всевозможных АОП-перехватчиков и прочее. Более того, для прокси, создаваемых посредством контекстных сервисов JavaEE, предполагается возможность работы в рамках общего JNDI контекста, контекста безопасности и класслоудера контейнера.

Для подключения сервиса достаточно использовать код:

@Resource
ContextService service;
С точки зрения администрирования и конфигурирования данного ресурса все крайне знакомо и схоже с уже рассмотренными типами:



Ниже приведем пример потока, запускающего задачу-прокси в контексте контейнера:

public class SampleProxyTask implements Runnable {
@Override
public void run() {
//контекст контейнера
Subject subject = Subject.getSubject(AccessController.getContext());
logInfo(subject.getPrincipals()); //логируем информацию о принципалах
calculateSmth();
}
private void calculateSmth() { … }
private void logInfo(Set<Principal> subject) { … }
}


EJB-бин без сохранения состояния для создания контекстных прокси:

@Stateless
public class ContextServiceBean {
@Resource
ContextService service;
@Resource
ManagedExecutorService executor;
public void perform(Runnable task) {
Runnable proxy = service.createContextualProxy(task, Runnable.class);
executor.submit(proxy); }
}


И наконец код сервлета, выполняющего задачу:

@WebServlet("/context")
public class ContextServiceServlet extends HttpServlet {
@Inject
ContextServiceBean contextServiceBean;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
contextServiceBean.perform(new SampleProxyTask());
}
}

На этом собственно и заканчиваются возможности разработчика JavaEE для работы в многопоточной среде. Благодаря ним, все процессы и службы, протекающие в контейнере, будут находит под четким контролем сервера, согласовывая свою работу и не нарушая привычный порядок выполнения. Для целевых задач Enterprise-разработчика зачастую этих возможностей хватает и в восьмой версии данный API не претерпел изменений. 

THE END

Как всегда ждём вопросы и комментарии и обязательно загляните к Виталию на открытый урок, там ему тоже можно позадавать вопросы и прослушать\поучаствовать в теме «CDI in action@


Смотри также:

Зачем нужна Java. http://fetisovvs.blogspot.com/2014/07/java.html
Разбор основных концепций параллелизма. http://fetisovvs.blogspot.com/2018/04/java.html
Первый контакт с «var» в Java 10. http://fetisovvs.blogspot.com/2018/01/var-java-10-java.html
JAVA 9. Что нового? http://fetisovvs.blogspot.com/2017/10/java-9-java.html
Руководство по Java 9 для тех, кому приходится работать с legacy-кодом. http://fetisovvs.blogspot.com/2018/08/java-9-legacy-java.html
Концепции объектно-ориентированного программирования — ООП в Java. http://fetisovvs.blogspot.com/2017/01/java-java.html
Анимации в Android по полочкам (Часть 1. Базовые анимации). http://fetisovvs.blogspot.com/2018/02/android-1-java.html
Двести пятьдесят русскоязычных обучающих видео докладов и лекций о Java. http://fetisovvs.blogspot.com/2015/12/java-5-java-java.html
Абстрактные классы и методы. http://fetisovvs.blogspot.com/2017/02/java.html
Полное руководство по Java Reflection API. Рефлексия на примерах. http://fetisovvs.blogspot.com/2017/02/java-reflection-api-java.html
Микросервисы для Java программистов. Практическое введение во фреймворки и контейнеры. http://fetisovvs.blogspot.com/2017/10/java-java.html
Микросервисы для Java программистов. Практическое введение во фреймворки и контейнеры. (Часть 3). http://fetisovvs.blogspot.com/2017/10/java-3-java.html
ТОП-3 способа конвертировать массив в ArrayList. Пример на Java. http://fetisovvs.blogspot.com/2016/09/3-arraylist-java-java.html
Ввод–вывод в Java. http://fetisovvs.blogspot.com/2016/05/java-java_28.html
Enum-Всемогущий. http://fetisovvs.blogspot.com/2017/02/enum-java.html
Массивы в Java. Создание и обработка. http://fetisovvs.blogspot.com/2017/10/java-java_18.html
Arrays, Collections: Алгоритмический минимум. http://fetisovvs.blogspot.com/2017/12/arrays-collections.html
Популярные методы для работы с Java массивами. http://fetisovvs.blogspot.com/2016/09/java-java_29.html
Пример использования метода replace в Java. Как заменить символ в строке? http://fetisovvs.blogspot.com/2017/01/replace-java-java.html
Класс Scanner в Java — описание и пример использования. http://fetisovvs.blogspot.com/2017/01/scanner-java-java.html
Пример использования метода trim в Java: как удалить пробелы в начале и конце строки? http://fetisovvs.blogspot.com/2017/01/trim-java-java.html
Spark — Потрясающий веб-микрофреймворк для Java. http://fetisovvs.blogspot.com/2017/10/spark-java-java.html
Чтение и запись CSV файла с помощью SuperCSV. http://fetisovvs.blogspot.com/2017/01/csv-supercsv-java-java.html
Конструкция try/catch/finally (исключения). http://fetisovvs.blogspot.com/2017/01/trycatchfinally-java.html
1000+ часов видео по Java на русском. http://fetisovvs.blogspot.nl/2017/06/1000-java-java.html
Шпаргалка Java программиста 7.1 Типовые задачи: Оптимальный путь преобразования InputStream в строку. http://fetisovvs.blogspot.com/2016/04/java-71-inputstream-java.html
Шпаргалки Java программиста 10: Lombok. http://fetisovvs.blogspot.nl/2017/12/java-10-lombok-java.html
Шпаргалки Java программиста 9: Java SE — Шпаргалка для собеседований и повторений. http://fetisovvs.blogspot.com/2017/12/java-9-java-se-java.html
Шпаргалка Java программиста 8. Библиотеки для работы с Json (Gson, Fastjson,
LoganSquare, Jackson, JsonPath и другие). http://fetisovvs.blogspot.com/2016/04/java-8-json-gson-fastjson-logansquare.html
Java 8 и паттерн Стратегия. http://fetisovvs.blogspot.com/2018/03/java-8-java.html
Реализация ООП-наследования в классах, работающих с SQL и MS Entity Framework. http://fetisovvs.blogspot.com/2017/02/sql-ms-entity-framework.html
Как установить соединение с СУБД MySQL в IntelliJ IDEA в редакции Community. http://fetisovvs.blogspot.com/2016/04/mysql-intellij-idea-community-java.html
Как с помощью maven работать с библиотеками, которых в maven нет. http://fetisovvs.blogspot.com/2017/03/maven-maven-java.html
Проекты по созданию компиляторов из Java в JavaScript и исполняемые файлы. http://fetisovvs.blogspot.com/2018/01/java-javascript-java.html
Диагностика утечек памяти в Java. http://fetisovvs.blogspot.com/2017/03/java-java_18.html
Spring AOP и JavaConfig в плагинах для Atlassian Jira. http://fetisovvs.blogspot.com/2018/04/spring-aop-javaconfig-atlassian-jira.html
Блеск и нищета Java для настольных систем. http://fetisovvs.blogspot.com/2018/04/java-haulmont-java.html
Разбор задачек от Одноклассников на JPoint 2018. http://fetisovvs.blogspot.com/2018/04/jpoint-2018-java.html
Программируем… выход из лабиринта. http://fetisovvs.blogspot.com/2015/10/java.html
Основы работы с IntelliJ IDEA. Интерфейс программы. http://fetisovvs.blogspot.com/2016/09/intellij-idea-java.html
Ускоряем время сборки и доставки java web приложения. http://fetisovvs.blogspot.com/2018/03/java-web-java.html