Compatibilité et périmètre de protection

P4JX chiffre les implémentations des méthodes des classes protégées et n’autorise leur lecture en temps de exécution qu’avec le VLX JRE inclus dans le package. Afin de concilier l’efficacité de la protection et la compatibilité avec le framework, il est recommandé de protéger uniquement les implémentations des fonctionnalités métier essentielles; l’entrée du framework, les DTO/entités, les classes qui doivent être générées ou modifiées dynamiquement par le framework, ainsi que les dépendances tierces ne doivent pas faire l’objet de protection.

1. Exécuter d’abord un scan de compatibilité

Seulement un scan, sans sortie:

p4j javaapp app.jar --compat-scan
p4j springboot app.jar --compat-scan
p4j tomcat app.war --compat-scan

Scanner et appliquer des recommandations prudentes:

p4j springboot app.jar dist --compat-apply

Les options explicites de l’utilisateur priment sur les recommandations automatiques. Le scan est une analyse heuristique statique; un rapport “Il est nécessaire de procéder à une révision.” ne signifie pas nécessairement un échec de l’application; l’absence de problème dans le rapport ne remplace pas non plus les tests de régression sur la plateforme cible.

Lorsque les résultats du scan nécessitent des modifications dans le code

Si le rapport GUI affiche Une action est requise. (ACTION REQUIRED pour l’interface en anglais), cela signifie: L’utilisateur doit modifier le code source de l’application.; de tels problèmes ne peuvent pas être résolus en ajustant les paramètres de packaging. Le rapport indiquera les classes et méthodes spécifiques à modifier, ainsi que des recommandations de traitement correspondantes:

  • Lire des fichiers ZIP/JAR depuis la mémoire: Remplacer ByteArrayInputStream par des méthodes de lecture basées sur les fichiers tels que Files.newInputStream(Path), FileInputStream, ZipFile ou JarFile.
  • Définir une classe à partir des octets bruts: Éviter d’appeler directement ClassLoader#defineClass sur les classes protégées; préférer Class.forName() ou ClassLoader.loadClass() afin que le chargement des classes se fasse lors de l’exécution de P4JX.

Après avoir modifié le code source, recompiler le JAR/WAR et effectuer à nouveau un scan de compatibilité; une fois que le rapport ne mentionne plus ce problème, générer alors l’archive de protection.

2. Modèle de protection recommandé

Frontière publique/entrée du framework → facade ordinaire ou interface → Implémentation centrale protégée

Exemple:

--protect 'com.example.service.impl.**' \
--exclude 'com.example.dto.**,com.example.config.**'

3. Classes qui ne devraient généralement pas être protégées

  • Controller, Servlet, Filter, Listener, Advice;
  • Configuration Spring, objets enrichis par AOT/CGLIB;
  • DTO Jackson, record, entité JPA, modèles de sérialisation;
  • Classe de pontage JNI/SWT/native;
  • Classe modifiée ou redéfinie par un Agent, un ORM, un Mock, un hot reload ou un ClassLoader personnalisé;
  • Frameworks tiers et dépendances open source;
  • Classe qui a besoin de lire son propre bytecode de classe réel.

4. Fonctionnalités JVM non prises en charge ou restreintes

Environnement de exécution

  • L’application protégée doit utiliser le VLX JRE fourni avec le paquet;
  • Démarrage selon la méthode JPMS -m et démarrage à partir d’un seul fichier de code source non pris en charge;
  • Les JAR ordinaires présents dans le classepath doivent être enregistrés par l’outil de packaging et ne peuvent pas être ajoutés arbitrairement lors du déploiement;
  • Il ne faut pas utiliser le VLX JRE pour exécuter des applications ordinaires non protégées.

Débogage et Agent

  • JVMTI, les débogueurs JDWP, les analyseurs de performance, les outils de mesure du taux de couverture ainsi que la plupart des agents APM ne sont pas pris en charge;
  • -javaagent, -agentlib, le rechargement en temps réel et la redéfinition de classes ne sont pas pris en charge;
  • Les traitements nécessitant l’insertion de bytecode doivent être effectués avant l’encodage.

Optimisation au démarrage

  • CDS, AppCDS et AOT ne sont pas pris en charge;
  • ZGC et ShenandoahGC ne sont pas pris en charge par le runtime P4JX.

5. Ressources de classe et scanners

Lors de la lecture des ressources .class de classes protégées, seuls des métadonnées sont obtenus: le nom de la classe, la signature et les annotations sont conservés, mais le corps réel des méthodes est absent.

  • Le reflection classique permet de lire les métadonnées, mais il n’est pas possible de restaurer le bytecode d’origine;
  • Les outils d’analyse de ZIP physique ne voient pas par défaut le contenu de P4JX; on peut essayer --zip-overlay scanner ;
  • Des outils de balayage du classpath tels que ClassGraph et Reflections peuvent avoir besoin de --layout fat dans Spring Boot;
  • La lecture de P4JX à partir de la mémoire ou de flux réseau par ZipInputStream/JarInputStream n’est pas prise en charge;
  • La vue zipfs est en lecture seule; il n’est pas possible de modifier l’archive.

6. Comportement d’archivage

  • L’extension .jar ne correspond pas à un JAR ordinaire; le contenu reste P4JX;
  • Les JAR Multi-Release sont dépliés en fonction de la version Java cible lors de l’encodage;
  • La signature du JAR d’origine ainsi que la sémantique du certificat ne sont pas conservées; une signature externe doit être appliquée au produit final si nécessaire;
  • Il ne faut pas modifier, récompresser ou fusionner les fichiers P4JX générés.