Compatibilidad y alcance de la protección
P4JX cifra las implementaciones de los métodos de las clases protegidas y solo deja que las lea, en tiempo de ejecución, el VLX JRE incluido en el paquete. Para que la protección sea sólida sin romper los frameworks, proteja únicamente la lógica de negocio principal y deje fuera los puntos de entrada del framework, los DTO y las entidades, las clases que el framework genera o modifica en tiempo de ejecución y las dependencias de terceros.
1. Ejecute primero un escaneo de compatibilidad
Solo escanear, sin generar nada:
p4j javaapp app.jar --compat-scan
p4j springboot app.jar --compat-scan
p4j tomcat app.war --compat-scan
Escanear y aplicar las recomendaciones conservadoras:
p4j springboot app.jar dist --compat-apply
Las opciones que indique de forma explícita tienen siempre prioridad sobre las recomendaciones automáticas. El escaneo es un análisis heurístico estático: una entrada de «revisión necesaria» no significa que la aplicación vaya a fallar, y un informe limpio no sustituye a las pruebas de regresión en la plataforma de destino.
Cuando el escaneo pide cambiar el código
Si el informe muestra ACTION REQUIRED, hay que modificar el código fuente de la aplicación: ninguna combinación de opciones de empaquetado lo resuelve. El informe indica las clases y los métodos concretos y propone una de estas soluciones:
- Lectura de un ZIP o un JAR desde memoria: sustituya
ByteArrayInputStreampor un método basado en archivos, comoFiles.newInputStream(Path),FileInputStream,ZipFileoJarFile. - Definición de clases a partir de bytes: no llame a
ClassLoader#defineClasssobre una clase protegida. UseClass.forName()oClassLoader.loadClass()y deje que el entorno de ejecución P4JX la cargue.
Tras cambiar el código, vuelva a compilar el JAR o el WAR y repita el escaneo. Genere el paquete protegido solo cuando el informe ya no señale el problema.
2. Modelo de protección recomendado
frontera pública / entrada del framework → fachada o interfaz corriente → implementación principal protegida
Por ejemplo:
--protect 'com.example.service.impl.**' \
--exclude 'com.example.dto.**,com.example.config.**'
3. Clases que normalmente conviene dejar sin proteger
- controladores, servlets, filtros, escuchadores y clases de tipo advice;
- clases de configuración de Spring y objetos ampliados con AOT o CGLIB;
- DTO de Jackson, records, entidades JPA y modelos de serialización;
- clases puente de JNI, SWT y otras interfaces nativas;
- clases que un agente, un ORM, una biblioteca de simulación, una herramienta de recarga en caliente o un ClassLoader propio reescriben o redefinen;
- frameworks de terceros y dependencias de código abierto;
- clases que necesitan leer su propio bytecode real.
4. Funciones de la JVM no admitidas o limitadas
Entorno de ejecución
- La aplicación protegida debe ejecutarse con el VLX JRE que la acompaña.
- No se admite el arranque mediante la forma
-mde JPMS ni desde un único archivo fuente. - Los JAR corrientes del classpath deben estar registrados por el empaquetador y no pueden añadirse libremente al desplegar.
- No use el VLX JRE para ejecutar aplicaciones sin proteger.
Depuración y agentes
- No se admiten JVMTI, los depuradores JDWP, los perfiladores, las herramientas de cobertura ni la mayoría de los agentes APM.
- No se admiten
-javaagent,-agentlib, la recarga en caliente ni la redefinición de clases. - Cualquier tejido de bytecode debe completarse antes de la codificación.
Optimización del arranque
- No se admiten CDS, AppCDS ni AOT.
- ZGC y Shenandoah GC quedan fuera del alcance del entorno de ejecución P4JX.
5. Recursos de clase y escáneres
Al leer el recurso .class de una clase protegida se obtiene un esbozo de metadatos: se conservan el nombre de la clase, las firmas y las anotaciones, pero no los cuerpos reales de los métodos.
- La reflexión corriente puede leer los metadatos, pero no recuperar el bytecode original.
- Las herramientas que analizan el ZIP físico por su cuenta no ven nada dentro de un archivo P4JX; pruebe con
--zip-overlay scanner. - Los escáneres de classpath como ClassGraph y Reflections pueden necesitar
--layout fatcon Spring Boot. - No se admite analizar un archivo P4JX desde un flujo en memoria o de red con
ZipInputStreamoJarInputStream. - La vista zipfs es de solo lectura, así que no permite modificar el archivo.
6. Comportamiento del archivo
- El sufijo
.jarno lo convierte en un JAR corriente: el contenido sigue siendo P4JX. - Los JAR multiversión se aplanan a la versión de Java de destino durante la codificación.
- No se conservan las firmas ni la semántica de certificados del JAR original; firme el resultado final por separado si su distribución lo exige.
- No modifique, recomprima ni combine los archivos P4JX generados.