Class XStreamConverter

java.lang.Object
org.axonframework.conversion.xstream.XStreamConverter
All Implemented Interfaces:
DescribableComponent, Converter

@Deprecated(forRemoval=true, since="5.4.0") public class XStreamConverter extends Object implements Converter
Deprecated, for removal: This API element is subject to removal in a future version.
Only intended to drain Axon Framework 4 XStream-serialized sagas, deadlines, and scheduled events during a migration period. Remove it from an application's configuration once that data no longer exists.
A Converter implementation that uses an application-supplied XStream instance to convert objects into and from the XML format that Axon Framework 4's XStreamSerializer produced.

This Converter exists for exactly one purpose: giving an Axon Framework 5 application time to let deadlines and events that an Axon Framework 4 node scheduled, and sagas it started, run their course, instead of forcing every one of them to fire or complete before the switch to Axon Framework 5. During a rolling upgrade, an Axon Framework 4 node may still pick up and fire a deadline or event an Axon Framework 5 node scheduled, so this Converter must write XStream XML an Axon Framework 4 node can read, not only read it. A saga is no different here, since it keeps handling events until it ends, so its state is both read and written back in XStream for as long as it stays active. In practice that is Axon Framework 4 saga state (the legacy saga stores default to XStreamSerializer when built without one), deadlines scheduled through a DeadlineManager, and events scheduled through an EventScheduler.

Note this Converter implementation is not meant to be used for anything new. It is never registered by default, and it should be removed from an application's configuration as soon as all data it was reading has been drained or rewritten in the application's regular Converter format.

Construction allows "org.axonframework.**" on the given XStream instance, the same baseline Axon Framework 4's XStreamSerializer added by default. XStream deserializes by instantiating arbitrary classes named in the XML it reads, which is unsafe against untrusted input unless the set of types it may instantiate is restricted. This baseline allows every class in every Axon Framework jar on the classpath, unconditionally: unlike Axon Framework 4's XStreamSerializer, this constructor offers no disableAxonTypeSecurity()-style opt-out, so a caller handing in an otherwise fully locked-down XStream instance still gets this baseline widened. Callers remain responsible for allowing their own saga, deadline, and event payload classes themselves, typically with XStream.allowTypesByWildcard(String[]) or XStream.allowTypes(Class[]), before handing the XStream instance to this constructor.

This Converter only ever converts a single payload, metadata map, or scope descriptor at a time; it never sees a whole message envelope. Construction aliases Metadata to the same <meta-data> element Axon Framework 4's MetaData used, and marks UUID as an immutable type aliased to uuid, so that XML produced by an Axon Framework 4 XStreamSerializer round-trips through this Converter unchanged. Ported scope descriptors such as AggregateScopeDescriptor and SagaScopeDescriptor keep their Axon Framework 4 package and class name in this module, so no further aliasing is required for those to resolve against Axon Framework 4-written XML.

Any source type the configured ChainingContentTypeConverter can convert directly to the target type - byte[], String, and InputStream by default - is treated as already-serialized content and skips XStream entirely, unlike Axon Framework 4's XStreamSerializer, which always ran a payload through XStream regardless of its Java type. Converting between two such types is therefore a plain content type conversion around the XML, not a new XStream marshalling pass.

Running on Java 9 or later with reflective access restricted to named modules, XStream may need --add-opens JVM arguments to reflect on types in java.base or other platform modules; see XStream's FAQ.

Construct this Converter with a pre-configured XStream instance. Note that previous installments of Axon Framework used to expose one that automatically aligned with pre-JDK17 reflection support. Given the current JDK version for this project and the JDK's restrictive nature on reflection, this XStream instance is no longer provided out of the box. Hence, it is strongly recommended to declare the XStream instance yourself, including a full allow-list for your own application types. After that, this Converter can be passed to builder methods of a legacy SagaStore or DeadlineManager, for example:


 XStream xStream = new XStream();
 xStream.allowTypesByWildcard(new String[]{"com.example.myapp.**"});
 Converter xStreamConverter = new XStreamConverter(xStream);

 JpaSagaStore sagaStore = JpaSagaStore.builder()
                                      .entityManagerProvider(entityManagerProvider)
                                      .converter(xStreamConverter)
                                      .build();
 
Since:
5.4.0
Author:
Steven van Beelen
  • Constructor Summary

    Constructors
    Constructor
    Description
    XStreamConverter(com.thoughtworks.xstream.XStream xStream)
    Deprecated, for removal: This API element is subject to removal in a future version.
    Constructs an XStreamConverter using the given xStream instance.
    XStreamConverter(com.thoughtworks.xstream.XStream xStream, ChainingContentTypeConverter converter)
    Deprecated, for removal: This API element is subject to removal in a future version.
    Constructs an XStreamConverter using the given xStream instance and converter.
  • Method Summary

    Modifier and Type
    Method
    Description
    <T> @Nullable T
    convert(@Nullable Object input, Type targetType)
    Deprecated, for removal: This API element is subject to removal in a future version.
    Converts the given input object into an object of the given targetType.
    void
    Deprecated, for removal: This API element is subject to removal in a future version.
    Describe the properties of this DescribableComponent with the given descriptor.
    Deprecated, for removal: This API element is subject to removal in a future version.
    Resolves a type name that Axon Framework 4's XStreamSerializer stored next to a serialized object, to the class it names, through the mapper of this converter's XStream instance, as that serializer did.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

    Methods inherited from interface org.axonframework.conversion.Converter

    convert
  • Constructor Details

    • XStreamConverter

      public XStreamConverter(com.thoughtworks.xstream.XStream xStream)
      Deprecated, for removal: This API element is subject to removal in a future version.
      Constructs an XStreamConverter using the given xStream instance.

      This constructor automatically allows "org.axonframework.**" on it, so this module's ported types resolve. The caller remains responsible for allowing their own application types through the given xStream instance.

      Parameters:
      xStream - the XStream instance used to convert objects into and from XML
    • XStreamConverter

      @Internal public XStreamConverter(com.thoughtworks.xstream.XStream xStream, ChainingContentTypeConverter converter)
      Deprecated, for removal: This API element is subject to removal in a future version.
      Constructs an XStreamConverter using the given xStream instance and converter.

      This constructor automatically allows "org.axonframework.**" on it, so this module's ported types resolve. The caller remains responsible for allowing their own application types through the given xStream instance.

      This constructor should only be used when a specific ClassLoader should be given to the ChainingContentTypeConverter, to ensure it loads the right set of ContentTypeConverter ContentTypeConverters.

      Parameters:
      xStream - the XStream instance used to convert objects into and from XML
      converter - the converter used for the byte[]/String/InputStream content type conversions surrounding the XML (de)serialization
  • Method Details

    • convert

      public <T> @Nullable T convert(@Nullable Object input, Type targetType)
      Deprecated, for removal: This API element is subject to removal in a future version.
      Description copied from interface: Converter
      Converts the given input object into an object of the given targetType.
      Specified by:
      convert in interface Converter
      Type Parameters:
      T - The target data type.
      Parameters:
      input - The value to convert.
      targetType - The type to convert the given input into.
      Returns:
      A converted version of the given input into the given targetType.
    • resolveStoredType

      @Internal public Optional<Class<?>> resolveStoredType(String typeName)
      Deprecated, for removal: This API element is subject to removal in a future version.
      Resolves a type name that Axon Framework 4's XStreamSerializer stored next to a serialized object, to the class it names, through the mapper of this converter's XStream instance, as that serializer did.

      Axon Framework 4 stored the name XStream's mapper gives a class: its alias if it has one, such as XStream's built-in uuid, int or long, or one the application registered, and its class name otherwise. Resolving through the same mapper turns either back into the class. A primitive type resolves to its wrapper class, as a stored value is always an object.

      This method is internal, as it only serves the legacy components that store a type name next to the data they convert with this converter, such as the deadline managers.

      Parameters:
      typeName - the stored type name, an alias or a class name
      Returns:
      the class the given typeName names, or an empty Optional if it names none
    • describeTo

      public void describeTo(ComponentDescriptor descriptor)
      Deprecated, for removal: This API element is subject to removal in a future version.
      Description copied from interface: DescribableComponent
      Describe the properties of this DescribableComponent with the given descriptor.

      Components should call the appropriate describeProperty methods on the descriptor to register their properties. The descriptor is responsible for determining how these properties are formatted and structured in the final output.

      Best Practices: As a general rule, all relevant fields of a DescribableComponent implementation should be described in this method. However, developers have discretion to include only the fields that make sense in the context. Not every field may be meaningful for description purposes, especially internal implementation details. Furthermore, components might want to expose different information based on their current state. The final decision on what properties to include lies with the person implementing the describeTo method, who should focus on providing information that is useful for understanding the component's configuration and state.

      Example implementation:

       public void describeTo(ComponentDescriptor descriptor) {
           descriptor.describeProperty("name", this.name);
           descriptor.describeProperty("enabled", this.enabled);
           descriptor.describeProperty("configuration", this.configuration); // A nested component
           descriptor.describeProperty("handlers", this.eventHandlers);      // A collection
       }
       
      Specified by:
      describeTo in interface DescribableComponent
      Parameters:
      descriptor - The component descriptor to describe this DescribableComponentn its properties in.