Tương thích và phạm vi bảo vệ

P4JX mã hóa phần cài đặt của các phương thức thuộc lớp được bảo vệ và chỉ cho phép VLX JRE đi kèm gói đọc chúng lúc chạy. Để vừa bảo vệ chắc chắn vừa không phá vỡ các framework, bạn nên chỉ bảo vệ phần lõi nghiệp vụ, còn các điểm vào của framework, DTO và thực thể, những lớp mà framework tạo hoặc sửa lúc chạy, cùng các phụ thuộc bên thứ ba thì để ngoài phạm vi bảo vệ.

1. Hãy chạy quét tương thích trước

Chỉ quét, không tạo đầu ra:

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

Quét rồi áp dụng các khuyến nghị an toàn:

p4j springboot app.jar dist --compat-apply

Những tùy chọn bạn chỉ định rõ luôn được ưu tiên hơn khuyến nghị tự động. Quét chỉ là phân tích tĩnh theo phỏng đoán: mục «cần xem lại» không có nghĩa ứng dụng chắc chắn hỏng, còn báo cáo sạch cũng không thay thế được kiểm thử hồi quy trên nền tảng mục tiêu.

Khi kết quả quét đòi sửa mã nguồn

Nếu báo cáo hiện ACTION REQUIRED, bạn buộc phải sửa mã nguồn ứng dụng; không tổ hợp tùy chọn đóng gói nào giải quyết được. Báo cáo sẽ nêu rõ lớp và phương thức liên quan, kèm một trong các hướng xử lý sau:

  • Đọc ZIP hoặc JAR từ bộ nhớ: thay ByteArrayInputStream bằng cách đọc dựa trên tệp, chẳng hạn Files.newInputStream(Path), FileInputStream, ZipFile hoặc JarFile.
  • Định nghĩa lớp từ byte thô: đừng gọi ClassLoader#defineClass trực tiếp trên lớp được bảo vệ. Hãy dùng Class.forName() hoặc ClassLoader.loadClass() và để môi trường chạy P4JX nạp lớp.

Sau khi sửa mã, hãy dựng lại tệp JAR hoặc WAR rồi quét tương thích lần nữa. Chỉ tạo gói bảo vệ khi báo cáo không còn nêu vấn đề đó.

2. Mô hình bảo vệ được khuyến nghị

ranh giới công khai / điểm vào framework → facade hoặc giao diện thông thường → phần lõi được bảo vệ

Ví dụ:

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

3. Những lớp thường không nên bảo vệ

  • controller, servlet, filter, listener và các lớp advice;
  • lớp cấu hình Spring cùng các đối tượng được AOT hoặc CGLIB bổ sung;
  • DTO của Jackson, record, thực thể JPA và mô hình tuần tự hóa;
  • lớp cầu nối JNI, SWT và các lớp cầu nối gốc khác;
  • lớp bị agent, ORM, thư viện giả lập, công cụ nạp nóng hoặc ClassLoader tự viết ghi đè hay định nghĩa lại;
  • framework bên thứ ba và các phụ thuộc nguồn mở;
  • lớp cần đọc chính bytecode thật của mình.

4. Những khả năng của JVM không hỗ trợ hoặc bị hạn chế

Môi trường chạy

  • Ứng dụng được bảo vệ phải chạy bằng VLX JRE đi kèm.
  • Không hỗ trợ khởi chạy theo dạng -m của JPMS và khởi chạy từ một tệp mã nguồn đơn lẻ.
  • Các JAR thông thường trên classpath phải được trình đóng gói đăng ký, không thể thêm tùy ý lúc triển khai.
  • Đừng dùng VLX JRE để chạy những ứng dụng chưa được bảo vệ.

Gỡ lỗi và agent

  • Không hỗ trợ JVMTI, trình gỡ lỗi JDWP, công cụ đo hiệu năng, công cụ đo độ phủ và phần lớn agent APM.
  • Không hỗ trợ -javaagent, -agentlib, nạp nóng và định nghĩa lại lớp.
  • Mọi thao tác chèn bytecode phải hoàn tất trước khi mã hóa.

Tối ưu khởi động

  • Không hỗ trợ CDS, AppCDS và AOT.
  • ZGC và Shenandoah GC nằm ngoài phạm vi của môi trường chạy P4JX.

5. Tài nguyên lớp và trình quét

Khi đọc tài nguyên .class của một lớp được bảo vệ, bạn nhận về phần khung siêu dữ liệu: tên lớp, chữ ký và chú thích vẫn còn, nhưng không có phần thân thật của phương thức.

  • Phản chiếu thông thường đọc được siêu dữ liệu nhưng không khôi phục được bytecode gốc.
  • Các công cụ tự phân tích tệp ZIP vật lý mặc định không thấy nội dung bên trong kho lưu trữ P4JX; hãy thử --zip-overlay scanner.
  • Trình quét classpath như ClassGraph hay Reflections có thể cần --layout fat khi dùng với Spring Boot.
  • Không hỗ trợ phân tích kho lưu trữ P4JX từ luồng trong bộ nhớ hoặc luồng mạng bằng ZipInputStream hay JarInputStream.
  • Khung nhìn zipfs chỉ đọc, không sửa được kho lưu trữ qua đó.

6. Hành vi của kho lưu trữ

  • Hậu tố .jar không biến nó thành JAR thông thường; nội dung vẫn là P4JX.
  • Các JAR đa phiên bản được làm phẳng về phiên bản Java mục tiêu trong lúc mã hóa.
  • Chữ ký và ngữ nghĩa chứng chỉ của JAR gốc không được giữ lại; nếu khâu phân phối yêu cầu, hãy ký riêng cho sản phẩm cuối.
  • Đừng sửa, nén lại hay gộp các tệp P4JX đã tạo.