Compatibilidade e escopo de proteção

O P4JX criptografa as implementações dos métodos das classes protegidas e permite que apenas o VLX JRE incluído no pacote as leia em tempo de execução. Para equilibrar a proteção com a compatibilidade com o framework, recomenda-se proteger apenas as implementações de negócios essenciais; a entrada do framework, DTOs/entidades, classes que precisam ser geradas ou modificadas dinamicamente pelo framework, bem como dependências de terceiros, não devem ser incluídas na proteção.

1. Execute primeiro a varredura de compatibilidade

Apenas varrer, sem gerar saída:

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

Varrer e aplicar recomendações conservadoras:

p4j springboot app.jar dist --compat-apply

As opções explícitas do usuário têm prioridade sobre as recomendações automáticas. A varredura é uma análise heurística estática; um relatório “É necessário realizar uma revisão.” não significa necessariamente que a aplicação falhará; a ausência de problemas também não substitui os testes de regressão na plataforma-alvo.

Quando os resultados da varredura exigem alterações no código

Se o relatório da GUI exibir É necessária uma ação. (na interface em inglês, ACTION REQUIRED), isso indica: O usuário precisa modificar o código-fonte do aplicativo.; esse tipo de problema não pode ser resolvido ajustando os parâmetros de empacotamento. O relatório listará as classes e métodos específicos que precisam ser modificados e fornecerá sugestões de tratamento para cada um deles:

  • Leitura de ZIP/JAR da memória: Substitua ByteArrayInputStream por métodos de leitura baseados em arquivos, como Files.newInputStream(Path), FileInputStream, ZipFile ou JarFile.
  • Definir a classe a partir dos bytes originais: Não chame diretamente ClassLoader#defineClass em classes protegidas; utilize Class.forName() ou ClassLoader.loadClass() em vez disso, para que o P4JX realize o carregamento da classe durante a execução.

Após modificar o código-fonte, reconstrua o JAR/WAR e execute novamente a varredura de compatibilidade; somente após o relatório indicar que o problema foi resolvido é que se deve gerar o pacote de proteção.

2. Modelo de proteção recomendado

Entrada de boundary/frame público → facade comum ou interface → Implementação central protegida

Exemplo:

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

3. Classes que normalmente não devem ser protegidas

  • Controller, Servlet, Filter, Listener, Advice;
  • Configurações do Spring, objetos aprimorados por AOT/CGLIB;
  • DTOs do Jackson, records, entidades JPA, modelos de serialização;
  • Clases de ponte JNI/SWT/native;
  • Clases reescritas ou redefinidas por Agent, ORM, Mock, hot reload ou ClassLoader personalizado;
  • Frameworks de terceiros e dependências open source;
  • Clases que precisam ler o bytecode de classe real em si.

4. Recursos JVM não suportados ou limitados

Ambiente de execução

  • A aplicação protegida deve utilizar o VLX JRE incluso no pacote;
  • Não é suportado o início pelo método JPMS -m nem o início a partir de um único arquivo de código-fonte;
  • Os JAR comuns no classpath devem ser registrados pelo empacotador e não podem ser adicionados arbitrariamente durante a implantação;
  • Aplicativos comuns não protegidos não devem ser executados usando o VLX JRE.

Depuração e Agentes

  • Não há suporte para depuradores JVMTI, JDWP, analisadores de desempenho, ferramentas de cobertura de código e a maioria dos agentes APM;
  • Não há suporte para -javaagent, -agentlib, recarregamento em tempo quente e redefinição de classes;
  • O processamento que requer inserção de bytecode deve ser concluído antes da codificação.

Otimização de inicialização

  • Não há suporte para CDS, AppCDS e AOT;
  • ZGC e ShenandoahGC não estão dentro do escopo de proteção do runtime P4JX.

5. Recursos de classe e scanners

Ao ler os recursos .class de classes protegidas, são obtidos apenas metadados: o nome da classe, a assinatura e os comentários são mantidos, mas o corpo real dos métodos não está incluído.

  • O reflexo comum consegue ler metadados, mas não é possível restaurar o bytecode original;
  • Ferramentas que analisam ZIPs fisicamente por conta própria normalmente não conseguem visualizar o conteúdo do P4JX; tente usar --zip-overlay scanner;
  • Scanners de classpath como ClassGraph e Reflections podem precisar de --layout fat em ambientes Spring Boot;
  • A análise de P4JX a partir da memória ou de fluxos de rede por meio de ZipInputStream/JarInputStream não é suportada;
  • A visão do zipfs é somente de leitura; não é possível modificar o arquivo compactado.

6. Comportamento de arquivamento

  • O sufixo .jar não indica um JAR comum; o conteúdo continua sendo P4JX;
  • Os Multi-Release JAR são descompactados de acordo com a versão do Java alvo durante a codificação;
  • A assinatura original do JAR e a semântica do certificado não são mantidas; quando necessário, deve-se realizar uma assinatura externa no produto final para distribuição;
  • Não modifique, recomprima ou combine os arquivos P4JX gerados.