Protection annotations
Express intent in your code. Apply it through the private protection service.
Small declarations. Precise control.#
Complexer exposes three protection annotations: @Protection, @PerformanceCritical and @Virtualize. They describe how selected parts of your application should be treated, without placing the transformation engine in your application.
These are CLASS-retained build directives. The desktop client or Maven integration submits the compiled artifact and configuration to the API; the service reads the directives and applies the selected policy. An annotation is metadata, not a network request executed by your application. The distributed annotation library does not contain the private transformers.
@Protection: choose the policy#
Apply @Protection to a class or method. Its value defaults to ProtectionLevel.NORMAL. A class supplies the default for its methods; a method annotation replaces that profile. A class marked NONE remains excluded even if a method requests a stronger profile.
@Protection(value = ProtectionLevel.AGGRESSIVE,
disable = {ProtectionFamily.FLOW})
final class ReleasePolicy {
@Protection(ProtectionLevel.LIGHT)
String displayName() { return "Professional"; }
}- NONE: exclude protection while allowing compatibility work.
- LIGHT: allow GENERAL, STRING, NUMBER, KEY, RENAME and COMPATIBILITY.
- NORMAL: allow every family except VM.
- AGGRESSIVE: allow every family, including VM. This makes a family eligible; it does not enable every transformation or select every method for virtualization.
Protection families#
The enable and disable arrays refine the chosen profile using ProtectionFamily: GENERAL, STRING, NUMBER, KEY, FLOW, EXCEPTION, VM, INDIRECTION, SHAPE, RENAME and COMPATIBILITY. A disabled family takes precedence over an enabled one. The pipeline configuration must still enable the corresponding transformation.
Profiles control selection, not arbitrary increases in cipher rounds or class-file limits. This separates protection intent from the safety constraints that every release must satisfy.
@PerformanceCritical: respect the hot path#
Apply it to a class, method or constructor. STRICT is the default: static transformations remain eligible, while transformations classified as adding runtime work are excluded by this policy. REDUCED permits a bounded amount of lightweight work. maxSites defaults to 1 and limits lightweight arithmetic sites per method in REDUCED mode; STRICT treats it as zero.
A method-level declaration can refine its class policy. Configuration rules may tighten it further. This annotation does not turn on disabled transformations and is not a promise of identical timing: measure your own workload.
@PerformanceCritical
void onTick() { /* application logic */ }
@PerformanceCritical(value = PerformanceCritical.Mode.REDUCED, maxSites = 1)
int calculate(int value) { return value * 31; }@Virtualize: change the representation#
This marker has no parameters. Its declared targets are methods and constructors; the virtualization stage still checks each selected body against its supported JVM subset. It is intended for sensitive logic that runs less frequently. Unsupported code is rejected by default. Enabling the stage alone does not virtualize every method.
Virtualization and performance policies must agree with the configured pipeline. Keep high-frequency paths separate from deliberately virtualized logic, and validate the protected result before release.
@Protection(ProtectionLevel.AGGRESSIVE)
@Virtualize
boolean validatePolicy(int version) {
return version >= 21;
}