Совместимость и область защиты
P4JX шифрует реализации методов защищённых классов и разрешает их чтение только VLX JRE, входящему в пакет, во время выполнения. Для сбалансирования уровня защиты и совместимости с фреймворком рекомендуется защищать только основную логику бизнеса; входы в фреймворк, DTO/сущности, классы, которые должны быть динамически сгенерированы или изменены фреймворком, а также сторонние зависимости не включаются в процесс защиты.
1. Сначала выполнить сканирование совместимости
Только сканирование, без вывода результатов:
p4j javaapp app.jar --compat-scan
p4j springboot app.jar --compat-scan
p4j tomcat app.war --compat-scan
Сканирование с применением консервативных рекомендаций:
p4j springboot app.jar dist --compat-apply
Явные настройки пользователя имеют приоритет над автоматическими рекомендациями. Сканирование представляет собой статический гибридный анализ; наличие проблемы, указанной в отчёте “Необходимо провести повторную проверку.”, не означает обязательной неудачи приложения; отсутствие проблем в отчёте также не заменяет тестирование на целевой платформе.
Когда результаты сканирования требуют изменения кода
Если в отчёте GUI отображается Требуется выполнение операции. (на английской версии интерфейса — ACTION REQUIRED), это означает: Пользователь должен внести изменения в исходный код приложения.; такие проблемы невозможно решить путём корректировки параметров пакетирования. В отчёте указываются конкретные классы и методы, требующие изменений, а также приводятся рекомендации по их устранению.
- Чтение ZIP/JAR из памяти: Замените
ByteArrayInputStreamна способы чтения из файлов, такие какFiles.newInputStream(Path),FileInputStream,ZipFileилиJarFile. - Определение класса на уровне исходных байтов: Не вызывайте
ClassLoader#defineClassнапрямую для защищённых классов; вместо этого используйтеClass.forName()илиClassLoader.loadClass(), чтобы загрузка классов происходила во время выполнения P4JX.
После изменения исходного кода соберите снова JAR/WAR и выполните сканирование на совместимость; только после того, как в отчёте больше не будет указано это проблема, создавайте пакет защиты.
2. Рекомендуемая модель защиты
Открытая граница/вход в фреймворк → обычное facade или интерфейс → защищённая основная реализация
Пример:
--protect 'com.example.service.impl.**' \
--exclude 'com.example.dto.**,com.example.config.**'
3. Классы, которые обычно не следует защищать
- Controller, Servlet, Filter, Listener, Advice;
- Конфигурация Spring, объекты, улучшенные с помощью AOT/CGLIB;
- DTO Jackson, record, JPA Entity, модели сериализации;
- Классы-мосты JNI/SWT/native;
- Классы, переписанные/переопределённые с помощью Agent, ORM, Mock, теплой замены или пользовательского ClassLoader;
- Сторонние фреймворки и open-source зависимости;
- Классы, которым необходимо читать их реальный классовый байткод.
4. Неподдерживаемые или ограниченные возможности JVM
Среда выполнения
- Защищённое приложение должно использовать VLX JRE, поставляемый вместе с пакетом;
- Неподдерживается запуск по способу JPMS
-mи запуск из одного файла с исходным кодом; - Обычные JAR-файлы, находящиеся в классовом пути, должны быть зарегистрированы инструментом пакетирования и не могут быть добавлены в процесс развертывания произвольно;
- Не следует использовать VLX JRE для запуска незащищённых обычных приложений.
Отладка и агенты
- Не поддерживаются отладчики JVMTI и JDWP, инструменты анализа производительности, инструменты измерения уровня покрытия кода и большинство агентов APM;
- Не поддерживаются
-javaagent,-agentlib, теплая перезагрузка и переопределение классов; - Обработка, требующая встраивания байт-кода, должна быть выполнена до кодирования.
Оптимизация запуска
- Не поддерживаются CDS, AppCDS и AOT;
- ZGC и ShenandoahGC не находятся в диапазоне поддержки движка P4JX.
5. Ресурсы классов и сканеры
При чтении ресурса .class класса с защитой получаются только метаданные: сохраняются имя класса, подпись и аннотации, но отсутствует реальное тело методов.
- Обычный механизм рефлексии позволяет читать метаданные, но не восстанавливать исходный байт-код;
- Инструменты для самостоятельной обработки физических ZIP-архивов по умолчанию не видят содержимое P4JX; можно попробовать использовать
--zip-overlay scanner; - Для сканеров classpath, таких как ClassGraph и Reflections, в Spring Boot может потребоваться
--layout fat; - Пара
ZipInputStream/JarInputStreamне поддерживает обработку P4JX из памяти или сетевого потока; - Виджет zipfs является только для чтения — изменить архив невозможно.
6. Поведение архивации
- Суффикс
.jarне означает обычный JAR; содержимое по-прежнему является P4JX; - При кодировании Multi-Release JAR файлы распаковываются в соответствии с целевой версией Java;
- Семантика подписи оригинального JAR и сертификата не сохраняется; при необходимости финальный продукт должен быть подписан внешним способом;
- Не изменяйте, не сжимайте заново и не объединяйте генерируемые файлы P4JX.