Skip to main content

Annotation Processor

The OptIn annotation processor and javac plugin provide compile-time checks for opt-in requirements. Using it is strongly recommended when working with OptIn.

For correctness, it is strictly necessary to use both.

Usage

The recommended approach to using the annotation processor is using the respective build tool plugin for Gradle or Maven. These plugins automatically take care of managing the required dependencies and offer safety for configuring OptIn verification.

When working with an unsupported build tool or using the command-line, the annotation processor and plugin can be used as usual with --processor-path or --processor-module-path and -Xplugin respectively. It is crucial for correctness that these two are used together and use the same configuration.

Configuration

When using the annotation processor and javac plugin, it is crucial that the same configuration is used for both.

The available options have keys and a format for their values.

In general:

  • Multiple semicolon-separated values may be specified.
  • Values must be URL-encoded (percent-encoded).

Annotation Processor Configuration

Options are passed to the annotation processor as standard annotation processor arguments using the -A flag:

-A<key>=<url-encoded-value>[,<url-encoded-value>]*

For example, to register a global opt-in:

-Acom.osmerion.optin.OptIn=com.example.MyMarker

Compiler Plugin Configuration

Options are passed to the javac compiler plugin via -Xplugin. The plugin name is optIn, followed by space-separated key=value pairs:

-Xplugin:optIn [<key>=<url-encoded-value>[,<url-encoded-value>]*]*

For example, to register a global opt-in:

-Xplugin:optIn com.osmerion.optin.OptIn=com.example.MyMarker
info

Important: Both the annotation processor argument (via -A) and the compiler plugin argument (via -Xplugin) must be provided with identical values. Mismatches between the two will result in incorrect behaviour.

Options

Global Opt-ins

Key: com.osmerion.optin.OptIn
Value Format: <fqName>

Registers a global opt-in for the marker with the given canonical class name (fqName). Any declaration requiring that marker will be considered opted into for the entire compilation, without requiring an explicit @OptIn annotation at each usage site.

Example - Opting into two markers globally:

# Annotation processor
-Acom.osmerion.optin.OptIn=com.example.MarkerA;com.example.MarkerB

# Compiler plugin
-Xplugin:optIn com.osmerion.optin.OptIn=com.example.Marker;com.example.MarkerB

Extra Opt-in Requirements

Key: com.osmerion.optin.RequiresOptIn
Value Format: <fqName>(,<level>(,<message>)?)?

Instructs the verifier to treat the annotation with the given fully qualified name (fqName) as requirement marker. If the level is given, it must be one of ERROR or WARNING. Otherwise, the level is ERROR by default. If a message is given, it may not contain a semicolon (;). Otherwise, a generic default message is generated by the verifier.

Example - Treating com.example.ExperimentalApi as an ERROR-level opt-in requirement with a custom message:

# Annotation processor
-Acom.osmerion.optin.RequiresOptIn=com.example.ExperimentalApi%2CERROR%2CMust+opt+in+to+use+experimental+APIs.

# Compiler plugin
-Xplugin:optIn com.osmerion.optin.RequiresOptIn=com.example.ExperimentalApi%2CERROR%2CMust+opt+in+to+use+experimental+APIs.

Extra Subtyping Opt-In Requirements

Key: com.osmerion.optin.SubtypingRequiresOptIn
Value Format: <fqName>(,<level>(,<message>)?)?

Instructs the verifier to treat the annotation with the given fully qualified name (fqName) as requirement marker for subtyping only. If the level is given, it must be one of ERROR or WARNING. Otherwise, the level is ERROR by default. If a message is given, it may not contain a semicolon (;). Otherwise, a generic default message is generated by the verifier.

Example - Treating com.example.UnstableApi as a WARNING-level subtyping opt-in requirement:

# Annotation processor
-Acom.osmerion.optin.SubtypingRequiresOptIn=com.example.UnstableApi%2CWARNING

# Compiler plugin
-Xplugin:optIn com.osmerion.optin.SubtypingRequiresOptIn=com.example.UnstableApi%2CWARNING