Annotation Interface XStreamNotDeserializable


@Documented @Retention(RUNTIME) @Target(FIELD) public @interface XStreamNotDeserializable
Marks a transient field as not participating in XStream deserialization.

By default, RobustReflectionConverter intentionally unmarshals into transient fields (unlike stock XStream) to support data migration: old on-disk XML may contain elements that map to fields that have since been made transient, and their values are consumed, e.g., by readResolve() to migrate to a newer representation.

Some transient fields, however, were fields were never serialized and must not be writable by submitted XML, as doing so can alter the object's identity and bypass access control boundaries.

Apply this annotation to transient fields that:

  • Represent runtime-derived status or context rather than persisted configuration.
  • Were never serialized to disk (so no legitimate on-disk XML contains a corresponding element).
  • Must not be overwritable by user-submitted XML (e.g., via config.xml POST).

Do not use this annotation on transient fields that participate in data migration (i.e., fields that once were non-transient and may still appear in old on-disk XML for consumption, e.g., by readResolve()). For those fields, consider using XStreamDeserializable to explicitly opt in once the default behavior changes.

For compatibility with plugins targeting older cores, the converter matches this annotation by simple name. A plugin may declare its own @XStreamNotDeserializable in any package; the contract above applies regardless. This allows plugins to use this protection mechanism without requiring a recent Jenkins core dependency while this addition is still recent. It is expected that this will change in 2027-2028, so once the plugin's core dependency has this annotation, switch to using it directly.

Since:
2.580
See Also: