Перейти к основному содержимому

Справочник по конфигурациям в Java


Справочник-шпаргалка по конфигурациям в Java — типы, синтаксис, стандартная библиотека, типовые паттерны. Не заменяет пошаговое обучение. Учебный курс: раздел.


Справочные таблицы​

Содержание справочника​


1. JVM-аргументы запуска (java [options] …)​

Все JVM-аргументы подразделяются на три группы:

  • -D<property>=<value> — установка системных свойств;
  • -X — нестандартные опции (non-standard), могут отличаться между реализациями JVM;
  • -XX — экспериментальные и внутренние опции управления поведением JVM.

1.1. Системные свойства (-D)​

Свойства, устанавливаемые при старте JVM через -Dkey=value, становятся доступны через System.getProperty("key"). Некоторые из них влияют на поведение стандартных библиотек или JVM.

СвойствоОписаниеВозможные значенияПример
java.versionВерсия Java Runtime Environment (только для чтения)Строка, например 17.0.12—
java.homeПуть к установке JREАбсолютный путь/usr/lib/jvm/java-17-openjdk
java.class.pathПуть кисходным классам и JAR-файламСписок путей, разделённых : (Unix) или ; (Windows)-cp lib/*:app.jar
java.library.pathПоиск нативных библиотек (.so, .dll, .dylib) при вызове System.loadLibraryСписок путей-Djava.library.path=/opt/native
java.io.tmpdirКаталог временных файловПуть к директории/tmp, C:\Temp
file.encodingКодировка по умолчанию для операций ввода-выводаUTF-8, ISO-8859-1, Windows-1251 и др.-Dfile.encoding=UTF-8
sun.stdout.encoding, sun.stderr.encodingКодировка потоков System.out и System.errТа же, что file.encoding, но можно задать отдельно-Dsun.stdout.encoding=UTF-8
user.language, user.country, user.variantЛокаль по умолчаниюen, ru; US, RU; POSIX, WIN-Duser.language=ru -Duser.country=RU
user.timezoneЧасовой пояс по умолчаниюUTC, Europe/Moscow, Asia/Yekaterinburg-Duser.timezone=Europe/Moscow
http.proxyHost, http.proxyPort, https.proxyHost, https.proxyPortНастройка HTTP/HTTPS-проксиХост и порт-Dhttp.proxyHost=proxy.local -Dhttp.proxyPort=3128
http.nonProxyHostsХосты, к которым прокси не применяетсяСписок имён, разделённых `, возможны *и?`
socksProxyHost, socksProxyPortSOCKS-проксиХост и порт-DsocksProxyHost=127.0.0.1 -DsocksProxyPort=1080
java.net.preferIPv4StackИспользовать IPv4-стек при наличии дуального стекаtrue, false-Djava.net.preferIPv4Stack=true
java.net.preferIPv6AddressesПредпочитать IPv6-адреса при разрешении имёнtrue, false-Djava.net.preferIPv6Addresses=true
networkaddress.cache.ttlTTL кэша DNS-имён (в секундах), положительное число0 (никогда не кэшировать), -1 (кэшировать навсегда), 30, 60, и т.д.-Dnetworkaddress.cache.ttl=30
networkaddress.cache.negative.ttlTTL для отрицательных DNS-ответовто же-Dnetworkaddress.cache.negative.ttl=10
jdk.tls.client.protocols, jdk.tls.server.protocolsРазрешённые TLS-протоколыTLSv1.2, TLSv1.3, TLSv1,TLSv1.1,TLSv1.2-Djdk.tls.client.protocols=TLSv1.2,TLSv1.3
jdk.tls.disabledAlgorithmsАлгоритмы, запрещённые для TLSСписок, как в java.security (см. ниже)-Djdk.tls.disabledAlgorithms=SSLv3, RC4, MD5
javax.net.ssl.trustStore, javax.net.ssl.trustStorePassword, javax.net.ssl.keyStore, javax.net.ssl.keyStorePasswordПути и пароли к хранилищам сертификатовПуть к файлу JKS/PKCS12, пароль-Djavax.net.ssl.trustStore=trust.jks -Djavax.net.ssl.trustStorePassword=changeit
jdk.serialFilterГлобальный фильтр десериализации (Java ≥ 9)Паттерн в формате pattern;pattern;…-Djdk.serialFilter="!*" (запрет всех), com.example.*;maxdepth=5
java.util.concurrent.ForkJoinPool.common.parallelismРазмер пула потоков ForkJoinPool.commonPool()Целое число ≥ 1-Djava.util.concurrent.ForkJoinPool.common.parallelism=4
sun.java2d.openglИспользовать OpenGL для Java2Dtrue, false, True, False-Dsun.java2d.opengl=True
awt.useSystemAAFontSettingsСглаживание шрифтов в AWT/Swingon, off, gasp, lcd, lcd_hrgb, lcd_vrgb-Dawt.useSystemAAFontSettings=lcd
swing.aatextСглаживание шрифтов в Swingtrue, false-Dswing.aatext=true
sun.java.launcher.pidPID родительского процесса-запускателя (только чтение)Целое число—

⚠️ Свойства, начинающиеся с sun.* или com.sun.*, не являются частью официальной спецификации Java SE. Их поведение может меняться между реализациями (OpenJDK, Oracle JDK, Azul, IBM Semeru и др.).


1.2. Нестандартные -X параметры​

Эти параметры реализованы в OpenJDK и совместимых сборках. Часть из них стабильна, часть устарела или удалена в новых версиях.

ПараметрОписаниеЗначения / Примеры
-Xms<size>Начальный размер heap-памяти-Xms256m, -Xms1g, -Xms4096m
-Xmx<size>Максимальный размер heap-памяти-Xmx2g, -Xmx8192m
-Xss<size>Размер стека одного потока-Xss512k, -Xss1m (по умолчанию: ~1 МБ на x64)
-Xmn<size>Размер молодого поколения (young generation)-Xmn1g — эквивалентно -XX:NewSize=1g -XX:MaxNewSize=1g
-XnoclassgcОтключение сборки мусора классов (устаревшее, игнорируется в новых версиях)—
-Xverify:<mode>Проверка байткода (устарело в Java 13+)remote, all, none — но в новых версиях всегда all или none, remote удалён
`-Xshare:autoonoff`
-Xloggc:<file>Логирование GC в файл (устарело в Java 9+, заменено -Xlog:gc*)-Xloggc:gc.log
-XprofВстроенный профайлер (устарело в Java 14, удалено в 15)—
-Xdebug, -XrunjdwpПоддержка JDWP (устарело, заменено -agentlib:jdwp)-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
-Xcomp, -Xint, -XmixedРежим JIT-компиляции-Xcomp — компилировать всё сразу; -Xint — интерпретировать всё; -Xmixed — по умолчанию (гибрид)

1.3. Экспериментальные -XX параметры​

Эти параметры доступны через -XX:+OptionName, -XX:-OptionName, -XX:OptionName=value.


1.3.1. Память и GC​
ПараметрОписаниеЗначения / Примеры
-XX:+UseSerialGCПоследовательный GC (однопоточный)Подходит для малых heap и одноядерных сред
-XX:+UseParallelGCParallel GC ("пропускная способность")По умолчанию в Oracle JDK ≤ 8 и в режиме -server
-XX:+UseParallelOldGCВключает Parallel Old для старшего поколения (актуально только если используется Parallel GC)Включается автоматически при -XX:+UseParallelGC
-XX:+UseConcMarkSweepGCCMS GC (устарело в Java 9, удалено в 14)—
-XX:+UseG1GCG1 GC (Garbage-First)По умолчанию в Java 9–16
-XX:+UseZGCZ Garbage CollectorТребует -XX:+UnlockExperimentalVMOptions до Java 15; начиная с Java 15 — без флага
-XX:+UseShenandoahGCShenandoah GCОбычно требует сборки OpenJDK с поддержкой Shenandoah
-XX:MaxGCPauseMillis=<ms>Целевая максимальная пауза GC (влияет на G1, Z, Shenandoah)-XX:MaxGCPauseMillis=200
-XX:G1HeapRegionSize=<size>Размер региона G11m, 2m, 4m, 8m, 16m, 32m (по умолчанию вычисляется)
-XX:G1NewSizePercent=5, -XX:G1MaxNewSizePercent=60Мин/макс доля heap под молодое поколение в G1Проценты от общей heap
-XX:InitiatingHeapOccupancyPercent=45Порог запуска concurrent cycle в G1Процент заполнения heap
-XX:+AlwaysPreTouchВыделение и "трогание" всей heap при стартеУменьшает фрагментацию, увеличивает время старта
-XX:+UseCompressedOopsИспользование сжатых указателей (64-битный режим)Включено по умолчанию при heap ≤ 32 ГБ
-XX:ObjectAlignmentInBytes=<n>Выравнивание объектов (только с +UseCompressedOops)Степень двойки, ≥ 8, ≤ 256; по умолчанию 8
-XX:+UseLargePagesИспользование huge pages (требует ОС-поддержки)+UseLargePages + настройка vm.nr_hugepages в Linux

1.3.2. JIT и компиляция​
ПараметрОписание
-XX:+TieredCompilationМногоуровневая компиляция (C1 + C2) — по умолчанию с Java 8
-XX:TieredStopAtLevel=1..4Уровень остановки компиляции (1 — интерпретатор + C1 без профилирования, 4 — C2)
-XX:CompileThreshold=10000Кол-во вызовов метода до компиляции C1 (для -XX:-TieredCompilation)
-XX:ReservedCodeCacheSize=240mМакс. размер кэша скомпилированного кода
-XX:+PrintCompilationВывод информации о компиляции в stderr
-XX:+UnlockDiagnosticVMOptionsРазблокировка диагностических опций (для -XX:+PrintAssembly, -XX:+LogCompilation, и др.)
-XX:+PrintAssemblyДизассемблирование скомпилированного кода (требует hsdis библиотеки)
-XX:CICompilerCount=<n>Количество потоков JIT-компилятора
-XX:+BackgroundCompilationФоновая компиляция (по умолчанию включена)

1.3.3. Class Data Sharing (CDS)​
ПараметрОписание
-XX:SharedArchiveFile=<file>Путь к архиву CDS (classes.jsa)
-XX:+UnlockDiagnosticVMOptions -XX:SharedArchiveFile=app.jsa -Xshare:dumpГенерация кастомного архива
-XX:ArchiveClassesAtExit=<file>Автоматическое создание архива при завершении JVM

1.3.4. JFR (Java Flight Recorder)​
ПараметрОписание
-XX:+FlightRecorderВключение JFR (по умолчанию включён в OpenJDK ≥ 11)
-XX:StartFlightRecording=settings=<profile>,filename=<file.jfr>,duration=60sЗапуск записи при старте
-XX:FlightRecorderOptions=repository=<dir>,maxsize=1gНастройка хранилища и лимитов

1.3.5. Отладка и диагностика​
ПараметрОписание
-XX:+HeapDumpOnOutOfMemoryErrorСоздание heap-дампа при OutOfMemoryError
-XX:HeapDumpPath=/path/to/dump.hprofПуть для heap-дампа
-XX:ErrorFile=/path/to/hs_err_pid%p.logЛог ошибок JVM при крахе
-XX:+PrintGC, -XX:+PrintGCDetails, -XX:+PrintGCDateStampsПодробное логирование GC (устарело в Java 9+, заменено -Xlog:gc*)
-XX:+PrintCommandLineFlagsВывод всех нестандартных флагов при старте
-XX:+TraceClassLoading, -XX:+TraceClassUnloadingТрассировка загрузки/выгрузки классов
-XX:+UseGCLogFileRotation, -XX:NumberOfGCLogFiles=5, -XX:GCLogFileSize=10MРотация GC-логов (устарело, заменено -Xlog:gc*:file=gc.log:time,filecount=5,filesize=10M)

1.4. Современное логирование GC и JVM через -Xlog (Java 9+)​

Синтаксис:
-Xlog:[<selectors>][:[output][:[decorators][:output-options]]]

Селекторы (что логировать):

  • gc: сборка мусора
  • gc+age=trace, gc+heap=debug, gc+metaspace=info, jit, class, safepoint, os, jfr, monitorinflation, modules
  • all=trace: всё на уровне trace

Выходы:

  • stdout, stderr, file=filename, file=filename%t (временная метка), file=filename%p (PID)

Декораторы:

  • time, utctime, uptime, timemillis, timenanos, pid, tid, level, tags

Примеры:

-Xlog:gc*:file=gc.log:time,uptime,level,tags:filecount=5,filesize=20M

-Xlog:jit+compilation=info,jit+inlining=debug:file=jit.log

-Xlog:class+load=info,modules=info:stdout

-Xlog:jfr*=trace:stdout

2. Системные свойства среды выполнения​

Системные свойства — это ключ-значение пары, доступные внутри JVM через System.getProperty(String key). Они формируются из нескольких источников и имеют иерархию приоритетов:

  1. Значения по умолчанию, заданные реализацией JVM (например, os.name, java.version);
  2. Параметры -Dkey=value, переданные при запуске;
  3. Программные вызовы System.setProperty(String key, String value) — действуют только после выполнения, не влияют на уже инициализированные подсистемы;
  4. Переменные окружения — не становятся системными свойствами автоматически, но некоторые свойства считывают их значения при инициализации (например, java.home зависит от JAVA_HOME, если JVM запущена через java launcher).

Системные свойства можно разделить по функциональным группам.


2.1. Свойства, описывающие среду выполнения​

Эта группа фиксирована, доступна только для чтения, устанавливается JVM при старте.

СвойствоОписаниеПример значения
java.versionВерсия Java (JRE)17.0.12
java.runtime.versionПолная версия JRE (включая сборку)17.0.12+7-Ubuntu-122.04
java.vm.versionВерсия JVM (HotSpot)17.0.12+7-Ubuntu-122.04
java.vm.vendorПоставщик JVMUbuntu, Eclipse Adoptium, Azul Systems, Inc.
java.vm.nameНазвание JVMOpenJDK 64-Bit Server VM
java.vm.specification.versionВерсия спецификации JVM17
java.specification.versionВерсия спецификации Java SE17
java.specification.vendorПоставщик спецификацииOracle Corporation
java.vendorПоставщик реализации JREEclipse Adoptium
java.vendor.urlСсылка на сайт поставщикаhttps://adoptium.net/
java.homeКорневой каталог JRE/usr/lib/jvm/java-17-openjdk-amd64
java.class.versionВерсия формата .class61.0 (Java 17 → 61, Java 21 → 65)

2.2. Свойства операционной системы и аппаратуры​

СвойствоОписаниеПример значения
os.nameНазвание ОСLinux, Windows 10, Mac OS X
os.versionВерсия ОС5.15.0-101-generic, 10.0, 14.5
os.archАрхитектура процессораamd64, aarch64, x86, ppc64le
sun.arch.Data.modelРазрядность данных (32/64)64
sun.cpu.isalistПоддерживаемые инструкции CPU (x86)sse4.2,aes
sun.cpu.endianПорядок байтовlittle, big

⚠️ sun.* свойства непереносимы — их отсутствие возможно в альтернативных реализациях (например, GraalVM Native Image).


2.3. Пользователь и локаль​

СвойствоОписаниеЗначенияПримечание
user.nameИмя текущего пользователя ОСtimur, AdministratorБерётся из системного вызова getpwuid / GetUserName
user.homeДомашняя директория/home/timur, C:\Users\Timur
user.dirТекущая рабочая директория при запуске/opt/app, D:\projectМеняется при System.setProperty("user.dir", …) не влияет на File без абсолютного пути — поведение не определено
user.languageЯзык локали по умолчаниюen, ru, zhМожет отличаться от Locale.getDefault().getLanguage() после изменения локали
user.country, user.regionСтрана/регионUS, RU, CN
user.variantВариант локалиPOSIX, WIN, EURO
file.separatorРазделитель пути/, \Константа, не меняется
path.separatorРазделитель путей в CLASSPATH:, ;
line.separatorСимвол(ы) конца строки\n, \r\n

2.4. Свойства ввода-вывода и кодировок​

СвойствоОписаниеЗначения по умолчаниюПримечание
file.encodingКодировка по умолчанию для FileReader, FileWriter, PrintStream, PrintWriter без явной кодировкиUTF-8 (Java ≥ 18), ранее ANSI_X3.4-1968 (ASCII) или системнаяВажно: в Java 17 и ранее это могло быть Cp1251 на Windows-локали ru_RU. С Java 18 — всегда UTF-8, если не переопределено через -Dfile.encoding=…
sun.stdout.encoding, sun.stderr.encodingКодировка System.out и System.errТо же, что file.encoding, но может быть переопределено отдельноУчитываются только при создании PrintStream внутри JVM, до первого использования System.out
native.encodingКодировка ОС для нативных вызовов (например, имен файлов)UTF-8, Cp1251, KOI8-RДоступно с Java 17+, используется в Path.of(String) и Files при работе с не-UTF-8 именами
sun.jnu.encodingКодировка для аргументов командной строки и имён файлов в JNIТо же, что native.encoding

2.5. Свойства сети​

Эти свойства влияют на поведение java.net API.

СвойствоОписаниеТипичные значения
http.proxyHostХост HTTP-проксиproxy.company.com, 192.168.1.10
http.proxyPortПорт HTTP-прокси3128, 8080
https.proxyHost, https.proxyPortТо же для HTTPS
http.nonProxyHostsСписок хостов, к которым прокси не применяется`localhost
ftp.proxyHost, ftp.proxyPortFTP-прокси
socksProxyHost, socksProxyPortSOCKS-прокси (версия 5)
java.net.useSystemProxiesИспользовать системные настройки прокси (только на Windows/macOS)true, false
networkaddress.cache.ttlВремя жизни кэша DNS-имён (секунды)-1 — кэшировать вечно, 30 — 30 сек, 0 — не кэшировать
networkaddress.cache.negative.ttlTTL для отрицательных DNS-запросов10 по умолчанию
sun.net.inetaddr.ttlУстаревшее, эквивалентно networkaddress.cache.ttl
java.net.preferIPv4StackИспользовать IPv4 при наличии дуального стекаtrue, false
java.net.preferIPv6AddressesПредпочитать IPv6-адрес при разрешении имёнtrue, false
jdk.net.URLClassPath.disableNonFileURLsЗапрет загрузки классов по не-file URLtrue, false

⚠️ Прокси-настройки применяются только к HttpURLConnection, URL.openConnection(). Клиенты вроде HttpClient (Java 11+) или OkHttp не используют их — требуют явной конфигурации ProxySelector.


2.6. Свойства безопасности​

СвойствоОписание
java.security.managerВключение SecurityManager (устарело в Java 17, удалено в 18)
java.security.policyПуть к файлу политики безопасности (актуально только при наличии SecurityManager)
java.security.auth.login.configФайл конфигурации JAAS
java.security.krb5.confПуть к krb5.conf для Kerberos
javax.net.ssl.trustStore, javax.net.ssl.trustStoreType, javax.net.ssl.trustStorePasswordПараметры доверенного хранилища
javax.net.ssl.keyStore, javax.net.ssl.keyStoreType, javax.net.ssl.keyStorePasswordПараметры клиентского хранилища ключей
javax.net.ssl.keyStoreProviderПровайдер хранилища
javax.net.debugОтладка SSL/TLS соединений

2.7. Свойства локализации и форматирования​

СвойствоОписаниеПример
user.timezoneЧасовой пояс по умолчаниюUTC, Europe/Moscow
java.locale.providersПорядок провайдеров локализации (Java 9+)COMPAT,SPI,CLDR,JRE — приоритет от левого к правому
java.util.PropertyResourceBundle.encodingКодировка .properties файловISO-8859-1 (по умолчанию), UTF-8 (начиная с Java 9, если файл содержит ï"¿ BOM или указано явно)

🔹 Начиная с Java 9, PropertyResourceBundle поддерживает UTF-8 без экранирования, если файл сохранён в UTF-8 с BOM или указано -Djava.util.PropertyResourceBundle.encoding=UTF-8.


2.8. Свойства параллелизма​

СвойствоОписаниеЗначение по умолчанию
java.util.concurrent.ForkJoinPool.common.parallelismРазмер ForkJoinPool.commonPool()Runtime.getRuntime().availableProcessors() - 1, минимум 1
java.util.concurrent.ForkJoinPool.common.exceptionHandlerКласс обработчика исключений (FQCN)—
java.util.concurrent.ForkJoinPool.common.threadFactoryКласс ThreadFactory (FQCN)—

Пример:

-Djava.util.concurrent.ForkJoinPool.common.parallelism=4
-Djava.util.concurrent.ForkJoinPool.common.threadFactory=com.example.CustomThreadFactory

2.9. Свойства GUI (AWT/Swing)​

СвойствоОписаниеПримеры
awt.toolkitКласс AWT Toolkitsun.awt.X11.XToolkit, sun.awt.windows.WToolkit
swing.defaultlafLook-and-Feel по умолчаниюjavax.swing.plaf.metal.MetalLookAndFeel, com.sun.java.swing.plaf.gtk.GTKLookAndFeel
swing.metalThemeТема Metal L&Fsteel, ocean
awt.useSystemAAFontSettingsСглаживание шрифтовon, off, gasp, lcd, lcd_hrgb
swing.aatextВключение сглаживания в Swingtrue, false
sun.java2d.openglИспользовать OpenGL для рендерингаTrue, False
sun.java2d.d3dИспользовать Direct3D (Windows)True, False
sun.java2d.noddrawОтключить DirectDraw (Windows)true, false

🔹 Эти свойства влияют только на приложения с GUI. На серверных JVM (headless) они игнорируются.


2.10. Свойства, управляемые переменными окружения​

Некоторые системные свойства инициализируются на основе переменных окружения при старте JVM:

Переменная окруженияВлияющее свойствоПримечание
JAVA_HOMEjava.homeТолько если java запущен как $JAVA_HOME/bin/java
CLASSPATHjava.class.pathПереопределяется опцией -cp или -classpath
TMPDIR (Unix), TEMP, TMP (Windows)java.io.tmpdirПриоритет: TMPDIR > TEMP > TMP
LANG, LC_ALL, LC_CTYPEuser.language, user.country, file.encoding, sun.jnu.encodingJVM парсит локаль из LANG=en_US.UTF-8 → user.language=en, user.country=US, file.encoding=UTF-8

Пример:

LANG=ru_RU.UTF-8 LC_ALL=ru_RU.UTF-8 java -jar app.jar

2.11. Динамические свойства — System.setProperty​

Метод System.setProperty(String key, String value) изменяет значение свойства во время выполнения. Однако:

  • Не все подсистемы реагируют на изменения после инициализации (например, file.encoding игнорируется после первого создания InputStreamReader);
  • Свойства безопасности (например, java.security.policy) не перечитываются;
  • Изменение user.dir не влияет на поведение new File("file.txt") — относительные пути разрешаются на уровне ОС при вызове open(), а не внутри JVM.

Рекомендуется устанавливать конфигурационные свойства до инициализации зависимых компонентов.


3. Конфигурация безопасности​

Подсистема безопасности Java включает несколько взаимосвязанных компонентов:

  • Java Cryptography Architecture (JCA) — криптографические сервисы;
  • Java Secure Socket Extension (JSSE) — TLS/SSL;
  • Java Authentication and Authorization Service (JAAS) — аутентификация и авторизация;
  • Java Generic Security Services (JGSS) — Kerberos, SPNEGO;
  • Policy-based и Module-based ограничения доступа — управление разрешениями;
  • Security Manager — устаревший механизм контроля доступа (удалён в Java 18);
  • Security Properties — глобальные настройки через java.security.

Все настройки управляются через:

  • файл $JAVA_HOME/conf/security/java.security (ранее $JAVA_HOME/lib/security/java.security);
  • файлы политики: java.policy, java.security.policy, пользовательские .policy;
  • системные свойства (-D…);
  • программные вызовы (Security.addProvider, Policy.setPolicy);
  • параметры запуска (-Djava.security.manager, -Djava.security.policy).

3.1. Файл java.security​

Расположение:

  • $JAVA_HOME/conf/security/java.security (Java ≥ 9)
  • $JAVA_HOME/lib/security/java.security (Java ≤ 8)

Это основной конфигурационный файл JVM. Он содержит директивы вида key=value, комментарии (#), и поддерживает переменные (${java.home}).


3.1.1. Провайдеры криптографии (security.provider.N)​

Порядок провайдеров определяет приоритет при поиске реализации алгоритмов.

security.provider.1=SUN
security.provider.2=SunRsaSign
security.provider.3=SunEC
security.provider.4=SunJSSE
security.provider.5=SunJCE
security.provider.6=SunJGSS
security.provider.7=SunSASL
security.provider.8=XMLDSig
security.provider.9=SunPCSC
security.provider.10=JDKPSS # начиная с Java 11

Наиболее важные провайдеры:

ПровайдерОписание
SUNРеализация MessageDigest (SHA-1, SHA-256), SecureRandom, Signature (SHA1withDSA), KeyStore (JKS), Policy
SunRsaSignПодписи RSA: SHA256withRSA, SHA512withRSA
SunECКриптография на эллиптических кривых: EC, ECDH, ECDSA, secp256r1, secp384r1
SunJSSEРеализация JSSE: SSLContext, KeyManagerFactory, TrustManagerFactory
SunJCEСимметричные алгоритмы: AES, DES, DESede, HmacSHA256, PBE, Cipher (GCM, CBC), KeyGenerator, SecretKeyFactory
SunJGSSGSS-API/Kerberos v5

Добавление стороннего провайдера (например, Bouncy Castle):

security.provider.11=org.bouncycastle.jce.provider.BouncyCastleProvider

Или программно:

Security.insertProviderAt(new BouncyCastleProvider(), 1);

3.1.2. Алгоритмы, отключённые по умолчанию​
ПараметрОписаниеПример значения
jdk.tls.disabledAlgorithmsАлгоритмы, запрещённые в TLSSSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC
jdk.certpath.disabledAlgorithmsАлгоритмы, запрещённые при проверке сертификатовMD2, MD5, SHA1 jdkCA & usage TLSServer, RSA keySize < 1024, DSA keySize < 1024
jdk.jar.disabledAlgorithmsАлгоритмы, запрещённые в подписях JARТо же, что certpath, плюс SHA1 при определённых условиях
jdk.security.provider.preferredПредпочтительные провайдеры для алгоритмовSHA256withRSA:SUN, AES/GCM/NoPadding:SunJCE

Формат значений — список условий через запятую. Поддерживает:

  • keySize < N, keySize > N
  • & usage … — применение (например, & usage TLSServer)
  • & jdkCA — если сертификат выпущен доверенным CA из cacerts

Пример:

jdk.tls.disabledAlgorithms=SSLv3, TLSv1, RC4, DH keySize < 2048, EC keySize < 256

3.1.3. Генератор случайных чисел​
ПараметрОписание
securerandom.sourceИсточник энтропии для SecureRandom.getInstanceStrong()
securerandom.strongAlgorithmsАлгоритмы, считающиеся "сильными"

🔹 new SecureRandom() без аргументов использует NativePRNG (на базе /dev/urandom) — неблокирующий.
🔹 SecureRandom.getInstanceStrong() использует NativePRNGBlocking (на базе /dev/random) — может блокироваться при нехватке энтропии.


3.1.4. Хранилища сертификатов​
ПараметрОписаниеЗначение по умолчанию
javax.net.ssl.trustStoreСистемное хранилище доверенных сертификатов${java.home}/lib/security/cacerts
javax.net.ssl.trustStoreTypeТип хранилищаJKS, PKCS12 (по умолчанию JKS)
javax.net.ssl.trustStoreProviderПровайдер хранилищаSUN
javax.net.ssl.keyStoreКлиентское хранилище ключей—
ssl.KeyManagerFactory.algorithmАлгоритм KeyManagerFactorySunX509, PKIX
ssl.TrustManagerFactory.algorithmАлгоритм TrustManagerFactoryPKIX, SunX509

Файл cacerts содержит корневые сертификаты Let’s Encrypt, DigiCert, GlobalSign и др. Его можно обновить через keytool -importcert.


3.1.5. Политики безопасности​
ПараметрОписание
policy.providerКласс реализации Policy
policy.url.1, policy.url.2, …Список URL файлов политики
policy.allowSystemPropertyРазрешить подстановку системных свойств в .policy
policy.expandPropertiesРазрешить ${…} в путях в .policy

3.1.6. JAAS (аутентификация)​
ПараметрОписание
login.configuration.providerКласс загрузчика конфигурации JAAS
java.security.auth.login.configПуть к jaas.conf

3.1.7. Отладка​
СвойствоЭффект
-Djava.security.debug=…Включает детальное логирование подсистемы
Возможные значения:
accessПроверки SecurityManager (устаревшее)
certpathПостроение и проверка цепочки сертификатов
jarПроверка подписей JAR
logincontextJAAS: логин-модули, callback
configfileЗагрузка jaas.conf
providerРегистрация провайдеров
pkcs11Работа с PKCS#11
allВсё

Пример:

-Djava.security.debug=certpath,logincontext

3.2. Файлы политики (.policy)​

Формат:

grant [CodeSource] [, Principal ...] {
Permission permission_class ["target"] [, "action"] [, signedBy "signer"];
};

3.2.1. Элементы grant​
  • CodeSource: источник кода — codeBase "URL" + опционально signedBy "alias".
    • codeBase "file:/opt/app/" — локальные классы;
    • codeBase "http://example.com/" — удалённые;
    • codeBase "file:${user.home}/" — переменные разрешаются.
  • Principal: субъект (JAAS), например Principal com.sun.security.auth.UnixPrincipal "timur".

3.2.2. Типы разрешений (Permission)​
КлассОписаниеПример
java.io.FilePermissionДоступ к файловой системеnew FilePermission("/tmp/-", "read,write,delete")
java.net.SocketPermissionСетевые соединенияnew SocketPermission("example.com:443", "connect,resolve")
java.lang.RuntimePermissionОперации среды выполненияnew RuntimePermission("exitVM"), "getClassLoader", "setFactory", "accessClassInPackage.sun.misc"
java.lang.reflect.ReflectPermissionРефлексияnew ReflectPermission("suppressAccessChecks")
java.security.SecurityPermissionИзменение подсистемы безопасностиnew SecurityPermission("putProviderProperty.SunJCE")
java.util.PropertyPermissionЧтение/запись системных свойствnew PropertyPermission("file.encoding", "read")
java.net.NetPermissionСетевые настройкиnew NetPermission("specifyStreamHandler"), "getProxySelector"
javax.sound.sampled.AudioPermissionДоступ к аудиоnew AudioPermission("play")
javax.security.auth.AuthPermissionJAAS-операцииnew AuthPermission("createLoginContext.myContext")
java.security.AllPermissionПолный доступ (только для доверенного кода)new AllPermission()

Шаблоны в FilePermission и SocketPermission:

  • /tmp/- — /tmp и все подкаталоги;
  • /tmp/* — только файлы в /tmp, без подкаталогов;
  • "*.example.com:443" — все поддомены на порту 443;
  • "localhost:1024-" — порты ≥ 1024.

3.2.3. Пример файла политики​

Код ITЗагрузка примера кода…

Загрузка:

java -Djava.security.manager -Djava.security.policy==/opt/app/app.policy MyApp

(два = означают только этот файл, один = — добавить к системным).


3.3. JAAS — jaas.conf​

Формат:

AppName {
com.sun.security.auth.module.KeyStoreLoginModule required
keyStoreURL="file:/keystore.jks"
keyStorePassword="secret";

com.sun.security.auth.module.UnixLoginModule sufficient;
};

Типы модулей:

  • required — должен завершиться успешно, но не прерывает цепочку при ошибке;
  • requisite — при ошибке — сразу отказ;
  • sufficient — при успехе — цепочка завершается успешно;
  • optional — игнорируется, если другие модули успешны.

Встроенные модули:

МодульНазначение
KeyStoreLoginModuleАутентификация по ключу из JKS/PKCS12
UnixLoginModuleАутентификация через PAM (Linux/macOS)
NTLoginModuleАутентификация в Active Directory (Windows)
Krb5LoginModuleАутентификация через Kerberos

Пример Kerberos:

KafkaClient {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
keyTab="/etc/security/keytabs/app.keytab"
principal="app/host@REALM"
storeKey=true
useTicketCache=false;
};

3.4. JSSE — TLS/SSL-конфигурация​

3.4.1. Программная настройка SSLContext​
KeyStore trustStore = KeyStore.getInstance("JKS");
try (InputStream in = Files.newInputStream(Paths.get("trust.jks"))) {
trustStore.load(in, "changeit".toCharArray());
}

TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
tmf.init(trustStore);

SSLContext sslContext = SSLContext.getInstance("TLSv1.3");
sslContext.init(null, tmf.getTrustManagers(), null);

3.4.2. Системные свойства для JSSE​
СвойствоОписание
https.protocolsПротоколы для HttpsURLConnection
https.cipherSuitesРазрешённые шифронаборы
jdk.tls.client.protocolsПротоколы для всех клиентских сокетов
jdk.tls.server.protocolsПротоколы для серверных сокетов
jdk.tls.ephemeralDHKeySizeРазмер ключа DH для обмена
jdk.tls.namedGroupsРазрешённые эллиптические кривые

3.4.3. Отладка TLS​
-Djavax.net.debug=ssl:handshake:keygen:verbose

Уровни — ssl, handshake, keygen, session, defaultctx, all.


3.5. Устаревшее — SecurityManager​

  • Включался через -Djava.security.manager (Java ≤ 17);
  • Все проверки checkPermission() вызывали SecurityManager.check…();
  • Удалён в Java 18: вызов System.setSecurityManager() выбрасывает UnsupportedOperationException;
  • Рекомендуемая замена — модульные ограничения (--limit-modules, --add-exports, --add-opens), AccessController.doPrivileged (остался, но без SecurityManager работает как no-op), проверки на уровне приложения/контейнера.

3.6. Криптографические ограничения — JCE Jurisdiction Policy Files​

До Java 8 требовались отдельные US_export_policy.jar, local_policy.jar для неограниченной криптографии.
Начиная с Java 8u161 и Java 9 — неограниченные политики включены по умолчанию. Проверка:

int maxKeyLen = Cipher.getMaxAllowedKeyLength("AES");
System.out.println(maxKeyLen); // 2147483647 → неограничено

4. Логирование​

В Java логирование реализуется через иерархию фасадов и движков. Основные компоненты:

  • API — интерфейсы (Logger, Level, Handler);
  • Фасады — абстракции над движками (SLF4J);
  • Движки — реализации (java.util.logging, Logback, Log4j 2);
  • Мосты — перенаправление вызовов между движками (jul-to-slf4j, log4j-to-slf4j);
  • Форматы и транспорты — PatternLayout, JSON, GELF, syslog, Kafka, HTTP;
  • Контекст — MDC (Mapped Diagnostic Context), NDLC (Nested Diagnostic Logical Context).

4.1. java.util.logging (JUL)​

Встроен в Java SE. Конфигурация — через $JAVA_HOME/conf/logging.properties (Java ≥ 9) или программно.


4.1.1. Иерархия логгеров​
  • Корневой логгер: "" (пустая строка), эквивалентен Logger.getLogger("");
  • Иерархия строится по точкам: com.example.service → родитель com.example → com → "";
  • Уровень логгера наследуется от ближайшего предка с установленным уровнем.

4.1.2. Уровни (Level)​
УровеньЧисловое значениеНазначение
OFFInteger.MAX_VALUEОтключение логирования
SEVERE1000Критические ошибки (исключения, сбои)
WARNING900Предупреждения (потенциально некорректное поведение)
INFO800Информационные сообщения (старт, завершение, ключевые события)
CONFIG700Конфигурационная информация (версии, параметры)
FINE500Отладка уровня сервиса
FINER400Подробная отладка
FINEST300Наиболее детальная отладка
ALLInteger.MIN_VALUEВсё

Программное управление:

Logger logger = Logger.getLogger("com.example");
logger.setLevel(Level.FINE);

4.1.3. Обработчики (Handler)​
КлассОписание
ConsoleHandlerВывод в System.err
FileHandlerЗапись в файл, поддерживает ротацию (%u, %g, %t)
StreamHandlerПроизвольный OutputStream
SocketHandlerОтправка в TCP-сокет (устаревший, без TLS)
MemoryHandlerБуферизация в памяти с триггером сброса
AsyncHandler (Java 19+)Асинхронная обработка (экспериментальный)

Параметры FileHandler:

java.util.logging.FileHandler.pattern = %h/java%u.log
java.util.logging.FileHandler.limit = 5242880 # 5 МБ
java.util.logging.FileHandler.count = 5 # 5 файлов
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.FileHandler.append = true

4.1.4. Форматтеры (Formatter)​
КлассФормат вывода
SimpleFormatterмар 13, 2025 10:05:30 ДП com.example.Main main WARNING: Message
XMLFormatterXML-структура лог-записи
LogRecord.toString()Сырой вывод (для отладки)

Кастомный SimpleFormatter через шаблон (Java 7+):

java.util.logging.SimpleFormatter.format=%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%1$tL %4$-7s [%3$s] %5$s%6$s%n

Где:
%1$t — время (LogRecord.getMillis),
%2$s — имя логгера,
%3$s — имя потока,
%4$s — уровень,
%5$s — сообщение,
%6$s — исключение (если есть),
%n — системный перевод строки.


4.1.5. Фильтры (Filter)​

Интерфейс java.util.logging.Filter:

public boolean isLoggable(LogRecord record) {
return !record.getMessage().contains("password");
}

Устанавливается на логгер или хендлер:

logger.setFilter(filter);
consoleHandler.setFilter(filter);

4.1.6. Глобальная конфигурация — logging.properties​

Расположение: $JAVA_HOME/conf/logging.properties
Пример:

handlers=java.util.logging.ConsoleHandler,java.util.logging.FileHandler
.level=INFO

java.util.logging.ConsoleHandler.level=WARNING
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter

com.example.level=FINE
com.example.handlers=java.util.logging.FileHandler
com.example.useParentHandlers=false

Загрузка альтернативного файла:

-Djava.util.logging.config.file=/opt/app/logging.properties

4.2. SLF4J (Simple Logging Facade for Java)​

Фасад, не реализующий логирование, а делегирующий вызовы движку.


4.2.1. API​
Logger logger = LoggerFactory.getLogger(MyClass.class);

logger.trace("Detailed trace");
logger.debug("Debug info: {}", value);
logger.info("Operation started");
logger.warn("Potential issue: {}", cause);
logger.error("Failure", exception);

Методы:

  • trace(), debug(), info(), warn(), error() — 12 перегрузок на каждый уровень (с объектами, массивами, исключениями);
  • Поддержка параметризации: {} заменяется String.valueOf(arg);
  • Поддержка Supplier<String> (Java 8+): logger.debug(() -> computeExpensiveMessage()).

4.2.2. Привязка к движку​

SLF4J выбирает движок по наличию JAR-файла META-INF/services/org/slf4j/impl/StaticLoggerBinder:

JARДвижок
slf4j-simple-*.jarПростая реализация (вывод в System.err, уровень INFO)
slf4j-jdk14-*.jarПривязка к java.util.logging
logback-classic-*.jarLogback (рекомендуется)
slf4j-log4j12-*.jarLog4j 1.2 (устарело)
log4j-slf4j-impl-*.jarLog4j 2

Только один StaticLoggerBinder должен быть в classpath — иначе ошибка инициализации.


4.2.3. Мосты​
АртефактНазначение
jul-to-slf4jПеренаправление JUL → SLF4J (через SLF4JBridgeHandler)
log4j-over-slf4jЗамена Log4j 1.2 API → SLF4J
jcl-over-slf4jЗамена Jakarta Commons Logging → SLF4J

Активация JUL → SLF4J:

SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();

4.3. Logback​

Реализация SLF4J, разработанная тем же автором (Ceki Gülcü). Конфигурация: logback.xml, logback.groovy, logback-test.xml.


4.3.1. Структура logback.xml​

Код ITЗагрузка примера кода…


4.3.2. Appenders​
КлассОписание
ConsoleAppenderВывод в System.out/System.err
FileAppenderЗапись в файл (без ротации)
RollingFileAppenderФайл с ротацией (требует RollingPolicy)
SMTPAppenderОтправка email при ERROR/WARN
DBAppenderЗапись в БД (таблицы logging_event, logging_event_property, logging_event_exception)
SyslogAppenderОтправка в syslog (RFC 3164/5424)
KafkaAppender (через logback-kafka-appender)Отправка в Kafka
AsyncAppenderОборачивает другие appenders в асинхронную очередь

4.3.3. Rolling Policies​
КлассКритерий ротации
TimeBasedRollingPolicyПо времени (%d{yyyy-MM-dd})
SizeBasedTriggeringPolicyПо размеру (maxFileSize)
SizeAndTimeBasedRollingPolicyПо времени + размеру (%i — индекс внутри дня)
FixedWindowRollingPolicyФиксированные окна (app.log, app.log.1, …)

4.3.4. Encoders​
ТипОписание
PatternLayoutEncoderШаблонный вывод (аналог SimpleFormatter)
JsonEncoder (через logback-json-classic)Вывод в JSON (поля: timestamp, level, logger, message, thread, mdc)

Пример JSON-шаблона:

<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<timestamp/>
<logLevel/>
<loggerName/>
<threadName/>
<message/>
<mdc/>
<stackTrace/>
</providers>
</encoder>

4.3.5. Фильтры​
КлассОписание
ThresholdFilterПропускать записи ≥ уровня
LevelFilterТочный уровень (ACCEPT/NEUTRAL/DENY)
EvaluatorFilter + JaninoEventEvaluatorУсловия на Groovy/Janino:
<expression>logger.contains("service") &amp;&amp; message.contains("timeout")</expression>
MDCFilterФильтр по MDC-ключам

4.3.6. MDC и NDLC​
  • MDC.put("traceId", "abc123") — карта, привязанная к потоку;
  • В шаблоне: %X{traceId};
  • NDLC.push("DB_CALL"), NDLC.pop() — стек для логической вложенности;
  • В шаблоне: %x — вся цепочка через разделитель.

4.4. Log4j 2​

Современный движок, несовместимый с Log4j 1.x. Конфигурация: log4j2.xml, log4j2.json, log4j2.yaml, log4j2.properties.


4.4.1. Структура log4j2.xml​

Код ITЗагрузка примера кода…


4.4.2. Особенности Log4j 2​
ФичаОписание
Async LoggersВысокопроизводительное асинхронное логирование через Disruptor (до 10× быстрее)
LookupsДинамические значения: ${env:HOME}, ${sys:user.name}, ${date:yyyy-MM}, ${docker:containerId}
FiltersBurstFilter, DynamicThresholdFilter, ScriptFilter (JavaScript/Groovy), StructuredDataFilter
ReliabilityFailoverAppender, RoutingAppender (маршрутизация по условию)
JSON Template LayoutГотовые шаблоны: EcsLayout, GelfLayout, JsonTemplateLayout
JFR IntegrationАвтоматическая запись событий логирования в JFR-трассу

Пример асинхронного логгера:

<AsyncLogger name="com.example" level="debug" includeLocation="true"/>

Требует com.lmax:disruptor в classpath.


4.4.3. Безопасное логирование​
  • Masking: через RegexReplacement в PatternLayout:
<PatternLayout>
<pattern>%m%n</pattern>
<regexReplacement regex="password=([^&amp;]*)"
replacement="password=***"/>
</PatternLayout>
  • SensitiveDataFilter (Log4j 2.17+): фильтр по регулярным выражениям для маскировки.

4.5. Сравнение движков​

КритерийJULLogbackLog4j 2
ПроизводительностьНизкаяСредняяВысокая (Async Loggers)
Гибкость конфигурацииОграниченнаяВысокаяОчень высокая
АсинхронностьJava 19+ (AsyncHandler)AsyncAppenderAsyncAppender, AsyncLogger
JSON-поддержкаНетЧерез расширенияВстроенная (JsonTemplateLayout)
JMX-мониторингДаДаДа
JFR-интеграцияНетНетДа
ЛицензияGPL+CEEPL 1.0 / LGPL 2.1Apache 2.0

4.6. Рекомендации по использованию​

  1. Используйте SLF4J как API — обеспечивает независимость от движка.
  2. Выбирайте Logback или Log4j 2 — JUL не подходит для production-сред.
  3. Включайте MDC для трассировки запросов (traceId, spanId).
  4. Избегайте конкатенации строк — используйте параметризованные сообщения.
  5. Логируйте исключения полностью — logger.error("msg", exception), а не logger.error("msg: " + ex.getMessage()).
  6. Маскируйте чувствительные данные на уровне appenders.
  7. Ограничьте уровень логирования в production — INFO для root, WARN/ERROR для внешних библиотек.
  8. Используйте ротацию и сжатие — предотвращает заполнение диска.
  9. Не логируйте в System.out/System.err напрямую — нарушает централизованное управление.

5. Конфигурация модульной системы (JPMS)​

JPMS введён в Java 9 как механизм компоновки на уровне платформы. Основные цели:

  • надёжная инкапсуляция внутренних API;
  • улучшенная производительность запуска и потребления памяти;
  • предсказуемая сборка и развёртывание.

Модуль описывается в файле module-info.java, компилируется в module-info.class, размещается в корне JAR или директории.


5.1. Синтаксис module-info.java​

[open] module <module-name> {
requires [transitive] [static] <module>;
exports <package> [to <module>, …];
opens <package> [to <module>, …];
uses <service-interface>;
provides <service-interface> with <implementation-class>;
}

5.1.1. Объявление модуля​
  • Именованный модуль: имеет module-info.java, имя совпадает с именем JAR-файла (без версии и .jar) или директории.
  • Unnamed module: код без module-info.java — автоматически включает все JAR из classpath, экспортирует все пакеты, требует все модули.
  • Automatic module: JAR без module-info.class, но в --module-path — получает имя по Automatic-Module-Name из MANIFEST.MF или по имени файла (без версии и расширения).

Пример:

module com.example.app {
requires java.base;
requires transitive com.example.core;
requires static org.slf4j;

exports com.example.api;
exports com.example.internal to com.example.test;

opens com.example.config;

uses com.example.spi.DatabaseDriver;
provides com.example.spi.DatabaseDriver with com.example.postgres.PostgresDriver;
}

5.1.2. Директивы​
ДирективаОписаниеПримечания
requires <module>Зависимость от модуляБез transitive — зависимость не наследуется
requires transitive <module>Транзитивная зависимостьПотребители модуля автоматически require этот модуль
requires static <module>Опциональная зависимость (только во время компиляции)Во время выполнения модуль может отсутствовать
exports <package>Публикация пакета для чтения и рефлексииТолько public классы и члены доступны
exports <package> to <module>Ограниченная публикация (qualified export)Доступ только указанному модулю
opens <package>Разрешение рефлексивного доступа к пакетуДля всех модулей (аналог --add-opens)
opens <package> to <module>Ограниченный opensТолько для указанного модуля
open module <name>Все пакеты открыты для рефлексииЭквивалентно opens *
uses <service>Объявление использования сервиса через ServiceLoaderНе требует requires модуля, содержащего интерфейс
provides <service> with <impl>Регистрация реализации сервисаКласс должен реализовывать интерфейс и иметь публичный конструктор без аргументов

🔹 exports не даёт доступ к private/package-private через рефлексию — только через opens.
🔹 opens не даёт доступ к private членам без setAccessible(true).
🔹 provides … with требует, чтобы реализация находилась в том же модуле.


5.2. Параметры запуска JVM для JPMS​

Все параметры начинаются с --.

ПараметрОписаниеПример
--module-path <path>Поиск модулей (JAR с module-info.class или автоматических)--module-path lib:mods
--class-path <path>Поиск классов в unnamed module--class-path legacy/*
-m <module>[/<main-class>], --module <…>Запуск модуля--module com.example.app/com.example.Main
--add-modules <module>,…Явное включение модулей (даже если не требуется)--add-modules java.xml.bind (Java 9–10, удалён в 11)
--add-exports <source-module>/<package>=<target-module>Динамический exports--add-exports java.base/sun.nio.ch=ALL-UNNAMED
--add-opens <source-module>/<package>=<target-module>Динамический opens--add-opens java.base/java.lang=org.mockito
--patch-module <module>=<path>Замена/дополнение содержимого модуля--patch-module java.base=hotfix/
--limit-modules <module>,…Ограничение набора доступных модулей--limit-modules java.base,java.logging
--list-modulesВывод списка всех наблюдаемых модулейТолько в консоли
--describe-module <module>Описание модуля--describe-module java.base
`--illegal-access=denypermitwarn

5.2.1. Специальные значения для --add-exports / --add-opens​
Целевой модульЭффект
ALL-UNNAMEDВсе классы в unnamed module (classpath)
ALL-SYSTEMВсе именованные системные модули
ALL-MODULE-PATHВсе модули из --module-path
java.*, jdk.*Конкретный модуль

Пример для Mockito (требует доступа к private полям):

--add-opens java.base/java.lang=ALL-UNNAMED
--add-opens java.base/java.util=ALL-UNNAMED

5.3. Инструменты JPMS​

5.3.1. jdeps — анализ зависимостей​

Основное применение: выявление модульных зависимостей и непубличных API.

jdeps --module-path lib app.jar

jdeps --check MODULE_PATH --multi-release 17 app.jar

jdeps -R --generate-module-info mods app.jar

jdeps --jdk-internals app.jar

Важные флаги:

  • -cp, --class-path — classpath (для unnamed module);
  • -mp, --module-path — модульный путь;
  • --print-module-deps — список требуемых модулей (для --add-modules);
  • --generate-open-module — генерация open module для legacy-кода.

Генерирует кастомный runtime image с заданными модулями.

jlink \
--module-path $JAVA_HOME/jmods:mods \
--add-modules com.example.app,java.logging,java.xml \
--output myruntime \
--compress 2 \
--strip-debug \
--no-header-files \
--launcher app=com.example.app/com.example.Main

Флаги:

  • --compress=1 (ZIP), =2 (ZIP + удаление отладочной инфо);
  • --strip-debug — удаление отладочных таблиц;
  • --launcher name=module/class — создаёт bin/name и bin/name.bat;
  • --bind-services — включение реализаций provides … with;
  • --ignore-signing-information — игнорирование подписей JAR.

Результат — myruntime/ содержит bin/java, conf/, lib/, release.


5.3.3. jmod — работа с .jmod-файлами​

Формат .jmod — для поставки модулей разработчикам (не для развёртывания).

jmod create \
--class-path classes \
--main-class com.example.Main \
--module-version 1.0 \
--target-platform linux-amd64 \
app.jmod

jmod list app.jmod
jmod describe app.jmod

⚠️ .jmod нельзя использовать в --module-path — только в jlink --module-path ….


5.3.4. jimage — работа с modules-образом​

Внутри $JAVA_HOME/lib/modules — единый образ всех модулей JRE.

jimage list $JAVA_HOME/lib/modules

jimage extract --dir extracted $JAVA_HOME/lib/modules java.base

jimage create --module-path mods --output custom.jimage

5.4. Динамические модули и ModuleLayer​

JPMS поддерживает создание динамических слоёв модулей во время выполнения.

ModuleFinder finder = ModuleFinder.of(Paths.get("mods"));
ModuleLayer parent = ModuleLayer.boot();
Configuration cf = parent.configuration().resolve(finder, ModuleFinder.of(), Set.of("com.example.app"));
ModuleLayer layer = parent.defineModulesWithOneLoader(cf, ClassLoader.getSystemClassLoader());

// Получение ClassLoader модуля
ClassLoader appLoader = layer.findLoader("com.example.app");
Class<?> mainClass = appLoader.loadClass("com.example.Main");

Используется в:

  • плагинных системах;
  • изоляции загрузчиков;
  • тестовых фреймворках (JUnit 5+).

5.5. DIAGNOSTICS — анализ модульной системы​

5.5.1. Через JVM​
java --describe-module java.base

java --list-modules

java -version --show-version

5.5.2. Через API​
Module boot = Object.class.getModule(); // java.base
System.err.println(boot.getDescriptor().name());

// Все наблюдаемые модули
Layer.boot().modules().forEach(m ->
System.out.println(m.getName() + ": " + m.getPackages())
);

5.5.3. Ошибки и их интерпретация​
ОшибкаПричинаРешение
module not found: XМодуль X отсутствует в --module-path или не требуется явноДобавить --add-modules X или включить в requires
package Y is declared in module X, but module Z does not read itZ не requires X, и X не exports Y в ZДобавить requires X или --add-exports X/Y=Z
unable to open Y in module XПопытка рефлексии без opensДобавить opens Y или --add-opens X/Y=Z
provides Z with W, but W is not in this moduleРеализация вне модуляПеренести класс или использовать ServiceLoader.load(Z, layer)

5.6. Совместимость с legacy-кодом​

  1. Classpath и Module-path:

    • Classpath → unnamed module → экспортирует всё, требует всё;
    • Module-path → именованные/автоматические модули.
  2. Split package:
    Один пакет в нескольких модулях — запрещено.
    Решение — --patch-module, объединение JAR, рефакторинг.

  3. Reflection на internal API:
    --add-opens java.base/java.lang=ALL-UNNAMED — временное решение.
    Рекомендуется миграция на публичные API.

  4. ServiceLoader в unnamed module:
    Файл META-INF/services/com.example.Spi в JAR на classpath работает без module-info.java.


6. Конфигурация сборки и развёртывания​

Цель: формирование самодостаточных, безопасных и переносимых артефактов — от JAR до установщиков операционных систем.


6.1. MANIFEST.MF​

Файл META-INF/MANIFEST.MF в JAR-архиве содержит метаданные. Кодировка — UTF-8 (начиная с Java 7), строки не длиннее 72 байт (перенос через пробел в начале строки).


6.1.1. Обязательные атрибуты​
АтрибутОписаниеПример
Manifest-VersionВерсия спецификации манифеста1.0
Created-ByИнструмент создания17.0.12 (Eclipse Adoptium)

6.1.2. Атрибуты запуска​
АтрибутОписаниеПримечание
Main-ClassПолное имя класса с public static void main(String[])Должен быть в корне JAR или в Class-Path
Start-ClassИспользуется Spring Boot — класс с @SpringBootApplicationНе стандартный, обрабатывается JarLauncher
Launcher-ClassДля модульных JAR — модуль/классcom.example.app/com.example.Main

6.1.3. Атрибуты классов и зависимостей​
АтрибутОписаниеПример
Class-PathСписок JAR/директорий (относительно JAR)lib/commons-lang3.jar lib/config/
Multi-ReleaseПоддержка multi-release JARtrue
Automatic-Module-NameИмя модуля для automatic moduleorg.slf4j

⚠️ Class-Path не поддерживает wildcard (*). Каждый JAR указывается явно.


6.1.4. Атрибуты версионирования и поставки​
АтрибутОписание
Implementation-Title, Implementation-Version, Implementation-VendorИдентификация реализации (доступны через Package.getImplementation*())
Specification-Title, Specification-Version, Specification-VendorИдентификация спецификации
SealedЗакрытие JAR: все классы должны быть подписаны и из одного источника
PermissionsУровень прав для Web Start (устарело)

6.1.5. Подпись JAR (JAR Signing)​

Для каждого пакета или файла — отдельная запись:

Name: com/example/
SHA-256-Digest: abc123...

Name: com/example/MyClass.class
SHA-256-Digest: def456...

Генерируется jarsigner на основе MANIFEST.MF и содержимого.


6.2. Multi-Release JAR (MRJAR)​

Позволяет включать разные реализации классов для разных версий Java в один JAR.

Структура:

mylib.jar
├── META-INF/
│ └── MANIFEST.MF ← Multi-Release: true
├── com/example/Util.class ← Java 8+
└── META-INF/versions/
├── 9/com/example/Util.class ← Java 9+
├── 11/com/example/Util.class ← Java 11+
└── 17/com/example/Util.class ← Java 17+

Требования:

  • MANIFEST.MF содержит Multi-Release: true;
  • Классы в versions/N/ должны иметь точно то же полное имя, что и в корне;
  • Нельзя переопределять пакеты — только классы;
  • Поддерживается начиная с Java 9 (JVM выбирает версию ≤ текущей, наибольшую).

Сборка через jar:

jar --create --file mylib.jar \
--main-class com.example.Main \
-C classes8 . \
--release 9 -C classes9 . \
--release 11 -C classes11 . \
--release 17 -C classes17 .

Проверка:

jar --describe-module --file mylib.jar
unzip -l mylib.jar | grep versions

6.3. Sealed JAR​

Запрещает загрузку классов из того же пакета, но из другого JAR или источника.

В MANIFEST.MF:

Name: com/example/internal/
Sealed: true

Эффект:
new URLClassLoader(new URL[]{other.jar}).loadClass("com.example.internal.X") → SecurityException.

Используется для защиты внутренних API.


6.4. jar — утилита управления архивами​

6.4.1. Основные команды​
КомандаОписание
jar --create --file app.jar -C classes .Создание JAR из директории
jar --update --file app.jar -C config application.propertiesДобавление файла
jar --extract --file app.jarРаспаковка
jar --list --file app.jarСписок содержимого
jar --describe-module --file app.jarАнализ модульности
jar --print-module-descriptor --file app.jarВывод module-info

6.4.2. Модульные JAR​
jar --create --file app.jar \
--main-class com.example.Main \
-C build/classes/module-info.class \
-C build/classes .

Требования:

  • module-info.class в корне;
  • имя JAR совпадает с именем модуля (рекомендуется).

6.5. jpackage — сборка native-установщиков​

Генерирует пакеты для ОС: .deb, .rpm, .msi, .pkg, .app, app-image.


6.5.1. Режимы​
РежимОписание
--type app-imageСамодостаточная директория (без установщика)
--type deb/rpm/msi/pkg/app-imageУстановщик или образ

6.5.2. Основные параметры​
ПараметрОписаниеПример
--input <dir>Директория с JAR и зависимостями--input libs
--main-jar <jar>Главный JAR--main-jar app.jar
--main-class <class>Класс main (если не в MANIFEST.MF)--main-class com.example.Main
--name <name>Имя приложения--name MyApp
--app-version <ver>Версия--app-version 1.2.0
--vendor <name>Поставщик--vendor "Example Inc."
--description <text>Описание--description "My Java App"
--icon <file>Иконка (.ico, .png, .icns)--icon app.ico
--linux-shortcut, --win-shortcut, --mac-package-identifierОС-специфичные опции

6.5.3. Сценарий — сборка .deb с runtime​

Код ITЗагрузка примера кода…

Результат: myapp_1.0.0-1_amd64.deb, устанавливаемый через dpkg -i.

⚠️ jpackage требует установленных системных утилит:

  • Linux: dpkg, rpmbuild;
  • Windows: WiX Toolset (3.11+);
  • macOS: pkgbuild, productbuild.

6.6.1. Оптимизация образа​
ФлагДействие
--strip-debugУдаление отладочной информации (line number tables, local variables)
--compress=2Сжатие class-файлов (ZIP + stripping)
--no-header-filesУдаление include/ (заголовки JNI)
--no-man-pagesУдаление man-страниц
--strip-native-commandsУдаление jcmd, jinfo, jmap и др. (остаётся только java)
`--endian littlebig`
`--vm serverclient

6.6.2. Кастомизация release-файла​

Файл release в корне образа содержит:

JAVA_VERSION="17.0.12"
MODULES="java.base java.logging com.example.app"
SOURCE="…"
IMPLEMENTOR="Eclipse Adoptium"

Можно дополнить через --release-info-file custom.properties.


6.7. jdeps — расширенный анализ​

6.7.1. Генерация module-info.java​
jdeps --generate-module-info mods app.jar

Автоматически определяет:

  • requires — по использованию классов;
  • exports — по public классам, используемым извне;
  • opens — если обнаружено использование рефлексии.

6.7.2. Выявление недостающих зависимостей​
jdeps --suggest-missing-deps app.jar

6.7.3. Проверка multi-release-совместимости​
jdeps --multi-release 17 --class-path libs app.jar

6.8. Подпись JAR — jarsigner и keytool​

6.8.1. Генерация ключей​
keytool -genkeypair \
-alias mykey \
-keyalg RSA \
-keysize 4096 \
-sigalg SHA384withRSA \
-dname "CN=Timur Tagirov, O=IT Universe, C=RU" \
-validity 3650 \
-keystore keystore.jks \
-storepass changeit \
-keypass changeit

6.8.2. Подпись​
jarsigner \
-keystore keystore.jks \
-storepass changeit \
-keypass changeit \
-sigalg SHA384withRSA \
-digestalg SHA-384 \
-tsa http://timestamp.digicert.com \
app.jar mykey

Флаги:

  • -tsa — сервер временных меток (требуется для валидности после истечения срока ключа);
  • -verbose — детальный вывод;
  • -certs — включить цепочку сертификатов.

6.8.3. Проверка подписи​
jarsigner -verify -verbose -certs app.jar

Вывод включает:

  • действительность подписи;
  • цепочку сертификатов;
  • наличие временной метки;
  • соответствие политики (jdk.jar.disabledAlgorithms).

6.9. Рекомендации по развёртыванию​

  1. Используйте jlink + jpackage для production-дистрибутивов — уменьшает размер, исключает ненужные модули.
  2. Подписывайте JAR, если требуется проверка целостности (например, в enterprise-средах).
  3. Избегайте Class-Path с абсолютными путями — нарушает переносимость.
  4. Для библиотек — указывайте Automatic-Module-Name в MANIFEST.MF, даже если нет module-info.java.
  5. Multi-release JAR — только при необходимости — усложняет сборку и отладку.
  6. Sealed JAR — для внутренних SDK, где критична изоляция пакетов.

7. Конфигурация инструментов JDK​

Инструменты JDK делятся на:

  • Сборочные — javac, javadoc, jar, jmod;
  • Диагностические — jps, jstat, jmap, jstack, jinfo, jcmd;
  • Интерактивные: jshell;
  • Профилировочные: jfr.

Все они поставляются в $JAVA_HOME/bin/. Начиная с Java 11, отдельный JRE удалён — все инструменты входят в стандартный JDK.


7.1. javac — компилятор Java​

7.1.1. Основные параметры​
ПараметрОписаниеПример
-d <dir>Директория вывода .class-d build/classes
-s <dir>Директория вывода сгенерированных исходников (например, @Generated)-s src/generated
-sourcepath <path>Поиск исходников зависимостей-sourcepath src/main:src/lib
-classpath <path>, -cp <path>Classpath для разрешения ссылок-cp lib/*
--module-path <path>, -p <path>Модульный путь--module-path mods
--module-source-path <path>Исходники модулей (структура modA/src, modB/src)--module-source-path 'modules/*/src'

7.1.2. Целевая совместимость​
ПараметрОписание
--release <N>Компиляция для версии N (от 7 до текущей)
-source <N>, -target <N>Устаревшие (до Java 9); --release предпочтительнее — гарантирует корректные bootstrap-классы
--enable-previewИспользование preview-фич текущей версии

🔹 --release 11 эквивалентно:
-source 11 -target 11 -bootclasspath $JAVA_HOME/jmods/java.base.jar (внутренне).


7.1.3. Предупреждения и линтинг (-Xlint)​
ФлагОписание
-Xlint:allВсе предупреждения
-Xlint:noneОтключить все
-Xlint:deprecationИспользование @Deprecated
-Xlint:uncheckedНебезопасные операции с generic’ами
-Xlint:varargsПроблемы с T... и Object[]
-Xlint:castИзбыточные приведения типов
-Xlint:fallthroughОтсутствие break в switch
-Xlint:finallyreturn в finally
-Xlint:pathНедостижимые пути
-Xlint:serialОтсутствие serialVersionUID в Serializable
-Xlint:moduleПроблемы модульной системы
-WerrorЛюбое предупреждение → ошибка

Пример:

javac -Xlint:unchecked,deprecation -Werror -d bin src/*.java

7.1.4. Аннотации​
ПараметрОписание
-processor <class>Явное указание annotation processor’а
-processorpath <path>Classpath для процессоров
-s <dir>Куда писать сгенерированные исходники
-implicit:noneНе компилировать классы, не указанные явно

7.2. javadoc — генерация документации​

7.2.1. Стандартные теги​
ТегКонтекстОписание
@param <name>Метод/конструкторОписание параметра
@returnМетодВозвращаемое значение
@throws <Exception>МетодИсключение и условие его возникновения
@see <ref>ЛюбойПерекрёстная ссылка
@link <ref>Внутри описанияИнлайновая ссылка
@since <version>ЛюбойВерсия, в которой появилось
@deprecatedЛюбойУстаревшее API
@implSpecИнтерфейс/абстрактный методТребования к реализации
@implNoteЛюбойЗамечание для реализатора

7.2.2. Параметры генерации​
ПараметрОписание
-d <dir>Выходная директория
-sourcepath <path>Поиск исходников
--module-path <path>Модульный путь
--module-source-path <path>Исходники модулей
-public, -protected, -package, -privateУровень видимости
-author, -versionВключать @author, @version
-noindexНе генерировать индекс
-notreeБез иерархии классов
-nohelpБез ссылки на help
-link <url>Внешние javadoc (например, JDK)
-stylesheetfile <css>Кастомный CSS

7.2.3. Модульные отчёты​
javadoc \
--module-path mods \
--module com.example.app \
-d docs \
-author -version

Генерирует:

  • module-summary.html — обзор модуля;
  • package-summary.html — по пакетам;
  • Поддержка module-info.java в навигации.

7.2.4. HTML5 и безопасность​

Начиная с Java 17, javadoc генерирует только HTML5.
Поддержка --allow-script-in-comments удалена — скрипты в комментариях игнорируются.


7.3. jshell — интерактивный REPL​

7.3.1. Запуск и режимы​
КомандаЭффект
jshellИнтерактивный режим
jshell script.jshВыполнение скрипта
jshell --execution-timeout 30sТаймаут выражения
jshell -qТихий режим (без приветствия)
jshell --startup DEFAULT, --startup <file>Загрузка стартовых команд

7.3.2. Встроенные команды (начинаются с /)​
КомандаОписание
/helpСправка
/listСписок всех введённых фрагментов
/list <id>Конкретный фрагмент
/edit <id>Редактирование в external editor (требует $JSHELLEDITOR или --editor)
/drop <id>Удаление фрагмента
/save filenameСохранение сессии
/open filenameЗагрузка сессии
/envТекущее окружение (classpath, modules, feedback)
`/set feedback verboseconcise
/exitВыход

7.3.3. Особенности​
  • Поддержка var, record, switch expressions, текстовых блоков;
  • Автодополнение (Tab);
  • История (↑, ↓);
  • Мультистрочные выражения (ввод до ;);
  • Возможность импорта пакетов: /import java.util.*.

Пример:

jshell> /set feedback verbose
jshell> class Point { int x, y; Point(int x, int y) { this.x = x; this.y = y; } }
| created class Point

jshell> new Point(1, 2)
| — ==> Point@1a2b3c
| x: 1
| y: 2

7.4. jcmd — универсальная управляющая утилита​

Выполняет команды в работающей JVM. Единственный инструмент, поддерживающий все диагностические операции в новых версиях Java (остальные (jstack, jmap) — устаревшие, реализованы через jcmd).


7.4.1. Общая структура​
jcmd [<pid>|<main-class>|0] <command> [arguments]

0 — все локальные JVM.


7.4.2. Основные команды​
КомандаОписание
VM.versionВерсия JVM
VM.command_lineАргументы запуска
VM.flags [-all]Все флаги JVM
VM.set_flag <name> <value>Изменение non-manageable флага (только если manageable = true)
GC.runПринудительный GC (эквивалент System.gc())
GC.run_finalizationЗапуск finalization
Thread.print [-l]Стеки потоков (аналог jstack)
VM.class_hierarchy [-i] [-v]Иерархия классов (требует UnlockDiagnosticVMOptions)
VM.classloader_statsСтатистика загрузчиков
VM.stringtable [-verbose]Интроспекция string pool
VM.symboltableТаблица символов
PerfCounter.printСчётчики производительности
JFR.start [settings=…] [filename=…] [duration=…]Запуск Flight Recorder
JFR.stop [name=…] [filename=…]Остановка и сохранение
JFR.checkСостояние записей
ManagementAgent.start [port=…]Включение JMX (если не был включён при старте)

7.4.3. Примеры​
jcmd -l

jcmd 12345 Thread.print

jcmd 12345 JFR.start name=MyRecording settings=profile duration=60s filename=rec.jfr

jcmd 12345 VM.set_flag MaxGCPauseMillis 200

✅ jcmd — предпочтительный инструмент для production-диагностики.


7.5. jps — список Java-процессов​

ФлагОписание
jpsPID + короткое имя main-class/JAR
jps -lПолный путь к main-class или JAR
jps -vАргументы JVM
jps -mАргументы main-метода
jps -qТолько PID

Пример:

$ jps -lv
12345 /opt/app/app.jar -Xmx2g -Dfile.encoding=UTF-8
12346 org.apache.catalina.startup.Bootstrap start

7.6. jstat — статистика GC и JIT​

КомандаОписание
jstat -gc <pid> [interval] [count]Сборка мусора (Eden, Survivor, Old, Metaspace)
jstat -gccapacity <pid>Ёмкости поколений
jstat -gcutil <pid>% использования поколений
jstat -compiler <pid>Статистика JIT (методы, время компиляции)
jstat -printcompilation <pid>Последние скомпилированные методы

Пример:

jstat -gcutil 12345 1s 5
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.00 98.45 76.32 45.12 95.34 92.11 123 2.345 5 1.234 3.579

Где:
S0/S1 — Survivor 0/1,
E — Eden,
O — Old,
M — Metaspace,
CCS — Compressed Class Space,
YGC/YGCT — Young GC count/time,
FGC/FGCT — Full GC count/time,
GCT — Total GC time.


7.7. jmap — анализ памяти​

КомандаОписание
jmap -heap <pid>Сводка по heap (поколения, GC, capacity)
jmap -histo <pid>Гистограмма классов (экземпляры, байты)
jmap -histo:live <pid>Только живые объекты (запускает GC)
jmap -dump:live,format=b,file=heap.hprof <pid>Heap-дамп в HPROF-формате

⚠️ jmap приостанавливает JVM на время операции. В production используйте jcmd <pid> GC.run_finalization + jcmd <pid> VM.class_histogram, или JFR.


7.8. jstack — дамп стеков потоков​

КомандаОписание
jstack <pid>Стеки всех потоков
jstack -l <pid>+ информация о мониторах и owns
jstack -F <pid>Принудительный дамп (если JVM не отвечает)

Формат вывода:

"main" #1 prio=5 os_prio=0 cpu=123.45ms elapsed=10.00s tid=0x00007f0000000000 nid=0x1234 runnable
java.lang.Thread.State: RUNNABLE
at java.util.HashMap.hash(HashMap.java:339)
at java.util.HashMap.put(HashMap.java:612)
at com.example.Main.main(Main.java:10)

🔹 В Java 8–16 jstack работает напрямую; в Java 17+ — обёртка над jcmd <pid> Thread.print.


7.9. jinfo — конфигурация JVM​

КомандаОписание
jinfo <pid>Все системные свойства и флаги
jinfo -sysprops <pid>Только System.getProperty
jinfo -flags <pid>Только -XX флаги
jinfo -flag <name> <pid>Значение конкретного флага
jinfo -flag +<name> <pid>Включить boolean-флаг (если manageable)

⚠️ Большинство флагов — non-manageable и не могут быть изменены в runtime.


7.10. jfr — работа с Flight Recorder​

КомандаОписание
jfr status <pid>Активные записи
jfr start <pid> [name=…] [settings=…] [duration=…] [filename=…]Запуск записи
jfr stop <pid> [name=…] [filename=…]Остановка и сохранение
jfr dump <pid> [name=…] [filename=…]Дамп текущего буфера без остановки
jfr print <file.jfr>Текстовый вывод событий
jfr metadata <file.jfr>Описание типов событий
jfr extract <file.jfr> --events <type>Извлечение подмножества событий

Форматы settings:

  • default — минимальная нагрузка;
  • profile — полная (методы, allocation, TLAB, monitor, socket);
  • flightrecorder — кастомный (.jfc-файл).

Пример кастомного .jfc:

<configuration version="2.0">
<event name="jdk.CPULoad">
<setting name="enabled">true</setting>
<setting name="period">1 s</setting>
</event>
</configuration>

Загрузка:

jfr start 12345 settings=cpu.jfc filename=cpu.jfr

8. Spring Boot — внешняя конфигурация​

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

Все конфигурационные свойства доступны через Environment и @ConfigurationProperties.


8.1. Иерархия источников конфигурации​

Spring Boot загружает свойства в строго определённом порядке, где более поздние источники переопределяют более ранние:

ПриоритетИсточникОписание
1@TestPropertySourceАннотация на тестах
2Аргументы @SpringBootTest(properties = …)В тестах
3properties атрибут @SpringBootTest, @WebMvcTest и др.
4Аргументы командной строки (--name=value)Через SpringApplication.run(args)
5Свойства из SPRING_APPLICATION_JSON (переменная окружения или системное свойство){"app.port":8081} → app.port=8081
6ServletConfig init-параметрыВ веб-приложениях
7ServletContext init-параметры
8JNDI-атрибуты (java:comp/env/)
9System.getProperties()Системные свойства JVM (-D…)
10Системные переменные окруженияAPP_PORT=8081
11RandomValuePropertySourcerandom.int, random.uuid
12Профильные application-{profile}.properties из упакованного JAR
13application.properties из упакованного JAR (classpath:/)
14Профильные application-{profile}.properties из config/ в текущей директории./config/application-prod.properties
15application.properties из config/ в текущей директории./config/application.properties
16Профильные application-{profile}.properties в текущей директории./application-prod.properties
17application.properties в текущей директории./application.properties
18@PropertySource на @Configuration-классахЗагружается до application.properties, но после системных источников 1–11 — важное исключение из порядка
19Конфиги, загруженные через spring.config.importВыполняются в порядке объявления, после application.properties, но до @PropertySource с @DependsOn

✅ Актуально для Spring Boot 2.4+. До 2.4 порядок @PropertySource был выше.


8.2. Синтаксис application.properties и application.yml​

8.2.1. application.properties​

Код ITЗагрузка примера кода…


8.2.2. application.yml​

Код ITЗагрузка примера кода…

🔹 Spring Boot использует SnakeYAML для парсинга.
🔹 Поддерживаются !!int, !!binary, но не рекомендуются — снижают переносимость.


8.3. Профили (spring.profiles.active)​

8.3.1. Активация​
СпособПример
Системное свойство-Dspring.profiles.active=prod,metrics
Переменная окруженияSPRING_PROFILES_ACTIVE=prod,metrics
application.propertiesspring.profiles.active=dev
application.ymlspring: profiles: active: dev
ПрограммноSpringApplication.setAdditionalProfiles("test")

8.3.2. Условная загрузка​

Код ITЗагрузка примера кода…

🔹 --- — разделитель документов в YAML.
🔹 В properties — отдельные файлы: application-dev.properties, application-prod.properties.


8.3.3. Включение профилей из кода​
@Profile("integration-test")
@Configuration
public class TestDataSourceConfig { … }

8.4. spring.config.import — импорт внешних конфигураций​

Введён в Spring Boot 2.4 для замены spring.config.location (устаревшего). Поддерживает:

ПрефиксИсточникПример
optional:classpath:JAR/classpath (необязательный)optional:classpath:config/external.properties
classpath:JAR/classpath (обязательный)classpath:secrets.properties
optional:file:Файл (необязательный)optional:file:/etc/app/config.properties
file:Файл (обязательный)file:./local.conf
configtree:Дерево файлов как свойстваconfigtree:/etc/secrets/
vault:HashiCorp Vault (через Spring Cloud)vault://secret/data/myapp
consul:Consul KV (Spring Cloud)consul:myapp/config
zookeeper:ZooKeeper (Spring Cloud)zookeeper:/config/myapp

8.4.1. configtree — безопасное хранение секретов​

Структура:

/etc/secrets/
├── db.username
├── db.password
└── api.token

Содержимое файлов — plain text:

admin

В application.properties:

spring.config.import=optional:configtree:/etc/secrets/

Результат:
db.username=admin, db.password=secret, api.token=abc123.

Преимущества:

  • файлы могут иметь chmod 600;
  • не попадают в логи при --debug;
  • не требуют шифрования внутри.

8.5. @ConfigurationProperties — типобезопасная конфигурация​

8.5.1. Объявление​
@ConfigurationProperties(prefix = "app.datasource")
@ConstructorBinding // immutable, требует @EnableConfigurationProperties или @ConfigurationPropertiesScan
public record DataSourceProperties(
String url,
String username,
String password,
Pool pool
) {}

public record Pool(int size, Duration timeout) {}

8.5.2. Активация​
@SpringBootApplication
@EnableConfigurationProperties(DataSourceProperties.class)
public class Application { … }

Или глобально:

@ConfigurationPropertiesScan("com.example.config")
public class Config { … }

8.5.3. Валидация​
@ConfigurationProperties(prefix = "app.datasource")
@Validated
public record DataSourceProperties(
@NotBlank String url,
@NotBlank String username,
@NotBlank String password,
@Valid Pool pool
) {}

public record Pool(
@Min(1) @Max(100) int size,
@NotNull @Positive Duration timeout
) {}

Ошибка приведёт к BindValidationException при старте.


8.5.4. Конвертация типов​

Поддерживаются:

  • Duration ← "30s", "5m", PT30S;
  • DataSize ← "10MB", "2GiB";
  • Charset ← "UTF-8";
  • Resource ← "classpath:app.sql", "file:/tmp/data.txt";
  • List<T>, Set<T>, Map<String, T>;
  • Кастомные Converter<T, R> и @ConfigurationPropertiesBinding.

Пример конвертера:

@Component
@ConfigurationPropertiesBinding
public class PasswordConverter implements Converter<String, EncryptedPassword> {
public EncryptedPassword convert(String source) {
return new EncryptedPassword(AES.encrypt(source, key));
}
}

8.6. @Value и @ConfigurationProperties​

Критерий@Value@ConfigurationProperties
ТипизацияСтрогая привязка к типу, но без вложенных объектовПолная поддержка вложенных структур
ВалидацияТолько через SpEL (#{…}), без @ValidПоддержка Bean Validation
МетаданныеНетГенерирует META-INF/spring-configuration-metadata.json для IDE
ПроизводительностьРазбор SpEL при каждом доступеОднократное связывание при старте
ИммутабельностьТолько через final + конструкторПоддержка @ConstructorBinding и record’ов
ТестированиеТребует @TestPropertySourceЛегко заменяется моком

Рекомендация:
— @ConfigurationProperties — для групп связанных свойств (DAO, клиенты, настройки модуля);
— @Value — для единичных значений (@Value("${app.id}") String id).


8.7. Интеграция с внешними системами​

8.7.1. Spring Cloud Config Server​

bootstrap.yml (загружается до application.*):

spring:
application:
name: myapp
cloud:
config:
uri: http://config-server:8888
username: client
password: secret
fail-fast: true

Конфиг на сервере: myapp-prod.yml:

app:
datasource:
url: jdbc:postgresql://prod-db:5432/mydb

8.7.2. HashiCorp Vault​
spring.config.import=vault://secret/data/myapp
spring.cloud.vault:
host: vault.example.com
port: 8200
scheme: https
authentication: TOKEN
token: s.xxxxx

Данные из secret/data/myapp → app.*.


8.7.3. AWS Secrets Manager​

Через spring.config.import=configtree:/mnt/secrets/, где /mnt/secrets/ — volume с секретами, примонтированными как файлы (ECS/EKS sidecar-паттерн).


8.8. Расширение конфигурационного конвейера​

8.8.1. EnvironmentPostProcessor​

Выполняется до обработки application.properties.

public class CustomEnvPostProcessor implements EnvironmentPostProcessor {
@Override
public void postProcessEnvironment(ConfigurableEnvironment env, SpringApplication app) {
Map<String, Object> map = new HashMap<>();
map.put("app.runtime", "kubernetes");
env.getPropertySources().addFirst(new MapPropertySource("custom", map));
}
}

Регистрация в META-INF/spring.factories:

org.springframework.boot.env.EnvironmentPostProcessor=\
com.example.CustomEnvPostProcessor

8.8.2. ConfigDataLocationResolver + ConfigDataLoader​

Для кастомных префиксов (например, myconf:).

  1. Реализация ConfigDataLocationResolver<MyConfigDataResource>:
@Order(HIGHEST_PRECEDENCE)
public class MyConfigLocationResolver implements ConfigDataLocationResolver<MyConfigDataResource> {
@Override
public boolean isResolvable(ConfigDataLocationResolverContext context, ConfigDataLocation location) {
return location.hasPrefix("myconf:");
}

@Override
public List<MyConfigDataResource> resolve(ConfigDataLocationResolverContext context, ConfigDataLocation location) {
return List.of(new MyConfigDataResource(location.getNonPrefixedValue()));
}
}
  1. Реализация ConfigDataLoader<MyConfigDataResource>:
public class MyConfigDataLoader implements ConfigDataLoader<MyConfigDataResource> {
@Override
public ConfigData load(ConfigDataLoaderContext context, MyConfigDataResource resource) {
Map<String, Object> props = fetchFromCustomSource(resource.getLocation());
return new ConfigData(PropertySource.of("myconf", props));
}
}
  1. Регистрация в spring.factories:
org.springframework.boot.context.config.ConfigDataLocationResolver=\
com.example.MyConfigLocationResolver

org.springframework.boot.context.config.ConfigDataLoader=\
com.example.MyConfigDataLoader

8.9. Безопасность конфигурации​

8.9.1. Шифрование значений​

Jasypt (неофициально, сторонняя библиотека):

app.datasource.password=ENC(G5xJ5s1W3QzK8c9Y1U4aB2vC4nM6lO0p)

Spring Cloud Vault / AWS KMS / Azure Key Vault — предпочтительные production-решения.


8.9.2. Защита от утечек​
  • Запрет логирования @ConfigurationProperties с @Sensitive (кастомная аннотация + PropertySourcesDeducer);
  • Использование configtree вместо application.properties для секретов;
  • spring.main.lazy-initialization=true — уменьшает риск преждевременного связывания.

9. Jakarta EE / MicroProfile Config​

MicroProfile Config — стандарт конфигурации для микросервисов, часть спецификации MicroProfile. Принят в Jakarta EE как основа для jakarta.config (предварительно — MP Config 3.0+).
Реализации — SmallRye Config (Quarkus, WildFly), Helidon Config, Open Liberty, Payara Micro.


9.1. Основные принципы​

  • Декларативность: конфигурация через @ConfigProperty, @Inject Config;
  • Иерархия источников: от высокоуровневых (переменные окружения) к низкоуровневым (файлы);
  • Типобезопасность — автоматическая конвертация в int, Duration, List, Map;
  • Динамичность: поддержка обновления конфигурации без перезапуска (в реализациях);
  • Расширяемость: кастомные ConfigSource, Converter.

9.2. Источники конфигурации и приоритеты​

Приоритет определяется целым числом (ordinal). Чем больше ordinal — тем выше приоритет.

Источникordinal по умолчаниюОписание
Programmatically added ConfigSourceУказывается явноНаивысший приоритет при ordinal > 1000
System properties (-Dkey=value)400System.getProperty()
Environment variables300System.getenv()
.env файл в корне проекта295Поддерживается SmallRye, Helidon
microprofile-config.properties в рабочей директории250./microprofile-config.properties
META-INF/microprofile-config.properties в JAR100Упакованный в артефакт
Custom ConfigSource без ordinal100По умолчанию

🔹 Переменные окружения транслируются в свойства по правилу:
APP_DATASOURCE_URL → app.datasource.url (регистронезависимо, _ → ., __ → _).

Пример:

export APP_DATASOURCE__URL=jdbc:postgresql://prod:5432/mydb

9.3. Формат microprofile-config.properties​

Расположение:

  • META-INF/microprofile-config.properties — в JAR;
  • microprofile-config.properties — в текущей директории (для dev-сред).

Синтаксис:

app.name=MyService
app.version=1.2.0

app.ports=8080,8081,8082
app.features=auth;logging;metrics # разделитель можно задать через Config API

app.timeout=30s
app.delay=5m

app.cache.size=100MB

app.datasource.password=secret

Поддерживаются те же типы, что и в Spring Boot — String, int/Integer, long/Long, boolean/Boolean, Duration, LocalDateTime, URL, URI, Charset, Class, List<T>, Set<T>, Map<String, T>.


9.4. Программное API — Config, ConfigProvider​

9.4.1. Получение Config​
Config config = ConfigProvider.getConfig();
// или через CDI
@Inject
Config config;

9.4.2. Чтение значений​

Код ITЗагрузка примера кода…


9.4.3. Интроспекция источников​
config.getConfigSources().forEach(source -> {
System.out.println(source.getName() + " (ordinal=" + source.getOrdinal() + ")");
});

9.5. CDI-инъекция — @ConfigProperty​

9.5.1. Базовое использование​

Код ITЗагрузка примера кода…


9.5.2. Обработка отсутствующих значений​
  • Без defaultValue — DeploymentException при старте, если свойство не найдено;
  • С defaultValue — используется значение по умолчанию;
  • Optional<T> — безопасное чтение:
@Inject
@ConfigProperty(name = "app.optional.token")
Optional<String> token;

🔹 @ConfigProperty работает только в CDI-биньках (@ApplicationScoped, @RequestScoped и др.).


9.6. Типобезопасная конфигурация — @ConfigProperties (MicroProfile 3.0+)​

Аналог @ConfigurationProperties в Spring Boot.


9.6.1. Объявление​
@ConfigProperties(prefix = "app.datasource")
public interface DataSourceConfig {
String url();
String username();
String password();
PoolConfig pool();

@ConfigProperties(prefix = "pool")
interface PoolConfig {
int size();
Duration timeout();
}
}

Или классом:

@ConfigProperties(prefix = "app.datasource")
public class DataSourceConfig {
private String url;
private String username;
private String password;
private PoolConfig pool;

// геттеры/сеттеры или record-конструктор
}

9.6.2. Инъекция​
@Inject
DataSourceConfig config;

// Использование
DataSource ds = new DataSource(config.url(), config.username(), config.password());

🔹 В SmallRye Config поддерживается @ConfigMapping (альтернативное имя для @ConfigProperties).
🔹 В Quarkus — @ConfigMapping с поддержкой @WithDefault, @WithParentName, @WithName.


9.7. Расширение — кастомные ConfigSource​

9.7.1. Реализация​

Код ITЗагрузка примера кода…


9.7.2. Регистрация​

Через META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource:

com.example.DatabaseConfigSource

Или программно:

Config config = ConfigProviderResolver.instance()
.getBuilder()
.withSources(new DatabaseConfigSource())
.build();
ConfigProviderResolver.instance().registerConfig(config, getClass().getClassLoader());

⚠️ При программной регистрации — только для текущего ClassLoader.


9.8. Кастомные Converter​

9.8.1. Реализация​
@Priority(100) // выше встроенных
public class PasswordConverter implements Converter<String> {
@Override
public String convert(String value) {
return AES.decrypt(value, getKey());
}
}

9.8.2. Регистрация​

Через META-INF/services/org.eclipse.microprofile.config.spi.Converter:

com.example.PasswordConverter

Или для конкретного типа:

public class DurationConverter implements Converter<Duration> {
@Override
public Duration convert(String value) {
return Duration.parse("PT" + value.toUpperCase());
}
}

→ применяется при config.getValue("key", Duration.class).


9.9. Динамическая конфигурация и события​

9.9.1. Поддержка в runtime’ах​
  • Quarkus: @ConfigProperty(reactive = true) + @Observes ConfigValueChangeEvent;
  • SmallRye Config: @Inject @ConfigProperty ConfigValue + ConfigValueObserver;
  • Helidon: Config.onChange(…).

9.9.2. Пример (SmallRye)​
@ApplicationScoped
public class ConfigObserver {

@Inject
@ConfigProperty(name = "app.feature.toggle")
ConfigValue toggle;

void onConfigChange(@Observes ConfigValueChangeEvent event) {
if ("app.feature.toggle".equals(event.getKey())) {
System.out.println("Feature toggle changed to: " + event.getValue());
}
}
}

🔹 Требует mp.config в pom.xml и активной поддержки в runtime.


9.10. Интеграции с runtime’ами​

RuntimeПоддержкаОсобенности
QuarkusПолная (SmallRye Config)application.properties, @ConfigMapping, dev-services, config hot reload в dev mode
HelidonВстроеннаяapplication.yaml, config profiles, programmatic builder
Open LibertyMP Config 3.0+server.xml + microprofile-config.properties, dynamic updates
WildFlySmallRye Configstandalone.xml + META-INF/microprofile-config.properties
Payara MicroMP ConfigПоддержка configsource в payara-micro.properties

9.10.1. Quarkus — расширенные возможности​
  • Profile-specific properties: %prod.app.url=…;
  • Config profiles: -Dquarkus.profile=prod;
  • Secrets via Kubernetes ConfigMap/Secret: автоматическое монтирование как configmap:/ и secret:/;
  • Config encryption: через smallrye-config и внешние провайдеры (Vault, KMS).

Пример application.properties в Quarkus:

%dev.app.url=http://localhost:8080
%prod.app.url=https://api.example.com

quarkus.datasource.db-kind=postgresql
quarkus.datasource.username=${db.user}
quarkus.datasource.password=${db.password}

Переменные db.user, db.password могут поступать из Kubernetes Secret.


9.11. Сравнение с Spring Boot Config​

КритерийMicroProfile ConfigSpring Boot Config
СтандартизацияJakarta EE / MicroProfileProprietary (Pivotal/VMware)
Иерархия источниковordinal-приоритетЖёсткий порядок (17+ уровней)
Типобезопасность@ConfigProperties (MP 3.0+)@ConfigurationProperties (с 1.0)
Динамическая перезагрузкаОпционально (runtime-зависимо)Через Spring Cloud Config + @RefreshScope
CDI-интеграцияВстроеннаяТребует Spring Context
Профили%profile.key=valueapplication-{profile}.properties
КонвертацияВстроенная + ConverterВстроенная + Converter/Formatter

✅ MicroProfile Config легче встраивается в non-Spring среды (Quarkus, Helidon, Open Liberty).
✅ Spring Boot Config богаче в enterprise-интеграциях (Vault, Consul, AWS и др. "из коробки").


10. Конфигурация сетевых и HTTP-клиентов​

Java предоставляет два поколения HTTP-клиентов:

  • Legacy: java.net.URL, URLConnection, HttpURLConnection (Java 1.0+);
  • Modern: java.net.http.HttpClient (Java 11+, incubated в 9–10).

Оба поддерживают HTTPS, прокси, аутентификацию, кастомные заголовки. Современный клиент добавляет HTTP/2, reactive streams, строгую типизацию.


10.1. java.net.http.HttpClient (Java 11+)​

10.1.1. Создание клиента​
HttpClient client = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10))
.followRedirects(HttpClient.Redirect.NORMAL) // NEVER, ALWAYS
.version(HttpClient.Version.HTTP_2) // HTTP_1_1, HTTP_2
.sslContext(sslContext) // кастомный SSLContext
.sslParameters(sslParameters) // кастомные параметры TLS
.executor(executor) // кастомный Executor (по умолчанию ForkJoinPool.commonPool())
.cookieHandler(cookieManager) // управление cookie
.authenticator(authenticator) // HTTP-аутентификация
.proxy(proxySelector) // выбор прокси
.build();

10.1.2. connectTimeout​
  • Применяется к connect() сокета;
  • Не влияет на readTimeout (устанавливается в HttpRequest.Builder);
  • Значение Duration.ZERO — отключает таймаут.

10.1.3. followRedirects​
ЗначениеПоведение
HttpClient.Redirect.NEVERНе следовать за редиректами (3xx)
HttpClient.Redirect.NORMALСледовать за GET/HEAD, не за POST/PUT/DELETE (стандарт RFC 7231)
HttpClient.Redirect.ALWAYSСледовать за всеми (опасно для неидемпотентных методов)

10.1.4. Версии HTTP​
ВерсияПоддержка
HTTP_1_1Всегда доступна
HTTP_2Доступна только при HTTPS и поддержке ALPN на стороне сервера
Авто (null)Попытка HTTP/2 → откат на HTTP/1.1

🔹 HTTP/2 требует TLS 1.2+ и ALPN (Application-Layer Protocol Negotiation).
🔹 В JDK 11+ ALPN встроен в sun.security.ssl.ALPNExtension.


10.1.5. Асинхронные операции​
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/data"))
.timeout(Duration.ofSeconds(30)) // read timeout
.header("User-Agent", "MyApp/1.0")
.GET()
.build();

// Блокирующий вызов
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

// Асинхронный вызов (CompletableFuture)
CompletableFuture<HttpResponse<String>> future = client.sendAsync(request, HttpResponse.BodyHandlers.ofString());

10.1.6. Тела запросов​
ТипМетодПример
СтрокаBodyPublishers.ofString("text")POST("text", BodyPublishers.ofString(body))
ФайлBodyPublishers.ofFile(path)PUT(BodyPublishers.ofFile(Paths.get("data.json")))
ПотокBodyPublishers.ofInputStream(() -> in)POST(BodyPublishers.ofInputStream(() -> new ByteArrayInputStream(bytes)))
ReactiveBodyPublishers.fromPublisher(publisher)Для Flow API

10.1.7. Обработка ответов​
ОбработчикОписание
BodyHandlers.ofString()Строка (по умолчанию UTF-8)
BodyHandlers.ofInputStream()InputStream (ленивая загрузка)
BodyHandlers.ofFile(path)Сохранение в файл
BodyHandlers.discarding()Игнорирование тела
BodyHandlers.ofLines()Stream<String> по строкам
BodyHandlers.fromLineSubscriber(subscriber)Reactive streams

10.2. HttpURLConnection / URLConnection (legacy)​

10.2.1. Базовое использование​
URL url = new URL("https://api.example.com/data");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(10_000);
conn.setReadTimeout(30_000);
conn.setRequestProperty("User-Agent", "MyApp/1.0");

int status = conn.getResponseCode();
String body;
try (InputStream in = conn.getInputStream()) {
body = new String(in.readAllBytes(), StandardCharsets.UTF_8);
}

10.2.2. Настройки подключения​
МетодОписание
setConnectTimeout(int ms)Таймаут установки TCP-соединения
setReadTimeout(int ms)Таймаут между байтами при чтении
setUseCaches(boolean)Использовать кэш (только для GET, если ResponseCache установлен)
setChunkedStreamingMode(int chunklen)Отправка тела чанками (для больших POST)
setFixedLengthStreamingMode(int len)Фиксированная длина тела (Content-Length)
setInstanceFollowRedirects(boolean)Следовать редиректам (по умолчанию true)

10.2.3. Кэширование​
ResponseCache.setDefault(new MyResponseCache());

// MyResponseCache extends ResponseCache
public CacheResponse get(URI uri, String rqstMethod, Map<String, List<String>> rqstHeaders) { … }
public CacheRequest put(URI uri, URLConnection conn) throws IOException { … }

Поддерживается только для GET, HEAD.


10.3. Прокси-настройки​

10.3.1. Глобальные настройки​

Через системные свойства:

-Dhttp.proxyHost=proxy.local -Dhttp.proxyPort=3128
-Dhttps.proxyHost=proxy.local -Dhttps.proxyPort=3128
-Dhttp.nonProxyHosts="localhost|127.0.0.1|*.intranet"

10.3.2. Программные настройки​

Для HttpClient:

ProxySelector proxySelector = ProxySelector.of(new InetSocketAddress("proxy.local", 3128));
HttpClient client = HttpClient.newBuilder()
.proxy(proxySelector)
.build();

Или кастомный:

Код ITЗагрузка примера кода…

Для HttpURLConnection:

Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxy.local", 3128));
HttpURLConnection conn = (HttpURLConnection) new URL("https://example.com").openConnection(proxy);

10.4. TLS/SSL-конфигурация​

10.4.1. Создание SSLContext​
KeyStore trustStore = KeyStore.getInstance("JKS");
try (InputStream in = Files.newInputStream(Paths.get("trust.jks"))) {
trustStore.load(in, "changeit".toCharArray());
}

TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
tmf.init(trustStore);

SSLContext sslContext = SSLContext.getInstance("TLSv1.3");
sslContext.init(null, tmf.getTrustManagers(), null);

10.4.2. SSLParameters​

Код ITЗагрузка примера кода…

🔹 setEndpointIdentificationAlgorithm("HTTPS") — аналог HttpsURLConnection.getDefaultHostnameVerifier().


10.4.3. Отключение проверки сертификатов (только для тестов!)​

Код ITЗагрузка примера кода…

❌ Запрещено в production.


10.5. Аутентификация​

10.5.1. Authenticator (глобальный)​
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
if ("api.example.com".equals(getRequestingHost())) {
return new PasswordAuthentication("user", "pass".toCharArray());
}
return super.getPasswordAuthentication();
}
});

Поддерживает:

  • Basic;
  • Digest;
  • NTLM (на Windows);
  • Negotiate (Kerberos/SPNEGO, если настроен JAAS).

10.5.2. Явные заголовки​
String credentials = Base64.getEncoder().encodeToString("user:pass".getBytes(UTF_8));
HttpRequest request = HttpRequest.newBuilder()
.header("Authorization", "Basic " + credentials)
.GET()
.build();

10.5.3. OAuth2 / Bearer​
HttpRequest request = HttpRequest.newBuilder()
.header("Authorization", "Bearer " + accessToken)
.GET()
.build();

10.6.1. CookieHandler​
CookieManager cookieManager = new CookieManager(
new FileCookieStore(Paths.get("cookies.txt")), // кастомный хранилище
CookiePolicy.ACCEPT_ORIGINAL_SERVER
);

HttpClient client = HttpClient.newBuilder()
.cookieHandler(cookieManager)
.build();

Политики:

  • CookiePolicy.ACCEPT_ALL — принимать все;
  • CookiePolicy.ACCEPT_NONE — игнорировать;
  • CookiePolicy.ACCEPT_ORIGINAL_SERVER — только от исходного домена (без 3rd-party).

10.6.2. Ручное управление​
HttpResponse<String> loginResponse = client.send(loginRequest, BodyHandlers.ofString());
String cookies = loginResponse.headers().firstValue("Set-Cookie").orElse("");

HttpRequest dataRequest = HttpRequest.newBuilder()
.header("Cookie", cookies)
.GET()
.build();

10.7. HTTP/2 и ALPN​

10.7.1. Требования для HTTP/2​
  • HTTPS (TLS 1.2+);
  • Поддержка ALPN на сервере;
  • SSLParameters.setApplicationProtocols(new String[]{"h2", "http/1.1"});
  • JDK ≥ 9 (ALPN встроен).

10.7.2. Проверка версии​
HttpResponse<Void> response = client.send(request, BodyHandlers.discarding());
System.out.println(response.version()); // HTTP_2 или HTTP_1_1

10.7.3. HTTP/3 (QUIC)​
  • В JDK не поддерживается (на 2025 год);
  • Требует сторонних библиотек — AHC (Async HTTP Client), Jetty HttpClient, Netty.

10.8. Безопасность — OCSP, CRL, Hostname Verification​

10.8.1. Включение OCSP stapling​
security.setProperty("ocsp.enable", "true");

10.8.2. Проверка отзыва сертификатов​
System.setProperty("com.sun.net.ssl.checkRevocation", "true");
security.setProperty("jdk.security.certpath.revocationCheck", "PREFER_CRLS");

Возможные значения:

  • PREFER_CRLS — сначала CRL, потом OCSP;
  • PREFER_OCSP — наоборот;
  • NO_FALLBACK — без отката.

10.8.3. Hostname verification​
  • По умолчанию в HttpsURLConnection и HttpClient — включена при setEndpointIdentificationAlgorithm("HTTPS");
  • Проверяет:
    • SubjectAlternativeName (SAN) DNS-имена;
    • при отсутствии SAN — CommonName (CN) в SubjectDN;
    • нечувствительно к регистру;
    • поддерживает wildcard (*.example.com → api.example.com, но не a.b.example.com).

10.9. Диагностика и отладка​

10.9.1. Логирование SSL​
-Djavax.net.debug=ssl:handshake:verbose

10.9.2. Трассировка HTTP​

Код ITЗагрузка примера кода…


10.9.3. Перехват запросов/ответов​

Через HttpClient.Builder.executor() и кастомный Flow.Subscriber, или через прокси (mitmproxy, Charles).


Основа по протоколу

Базовый разбор HTTP и HTTPS находится в отдельной статье — HTTP как основа веб-интеграций.


В подборках​

Статья входит в тематические подборки и блок "С чего начать?" на главной. Соседние шаги того же маршрута:

Справочники — Справочник по Python, Справочник по Java, Справочник по Flask, Документация и инструменты Java (Microsoft), Справочник по модулю Turtle, Справочник по F#.