Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Compatibility, Deprecation, and Migration Plan

 Backward Compatibility

  This change is fully backward compatible:  
  
1. ; existing plugins will work seamlessly with newer Connect runtimes:

  1. Source Compatibility: Existing component implementations are not required to change. They already implement the config()

...

  1. method, which satisfies the new
      interface requirement.

...

...

  1. Binary Compatibility: The change only adds a new interface to the type hierarchy. Existing compiled classes will continue to work without recompilation.

...

...

  1. Behavioral Compatibility: No changes to method signatures, return types, or semantics. All existing code will behave identically.

  Forward Compatibility

  Plugins compiled against newer versions of the Connect API (with ConfigSpecifier) will remain compatible with older Connect runtimes under normal usage
  patterns:

  When a plugin is compiled against the new API, its bytecode stores only direct interface relationships. For example, a class implementing Transformation
  records implements Transformation in its bytecode, but does not record that Transformation extends ConfigSpecifier.

  At runtime, the JVM resolves the complete interface hierarchy by loading interface classes from the runtime's classpath. This means:

  • New plugin on old runtime: The JVM loads the plugin's class (which declares implements Transformation), then loads Transformation from the old runtime
      (which doesn't extend ConfigSpecifier). The hierarchy is resolved using the old runtime's interface definition, so ConfigSpecifier is never referenced.
  • New plugin on new runtime: The same plugin bytecode loads Transformation from the new runtime (which extends ConfigSpecifier), and the full hierarchy
      , including ConfigSpecifier, is available for discovery.

  When Forward Compatibility Breaks

  Forward compatibility is broken only when plugin code directly references the ConfigSpecifier type. Specifically:

  Incompatible patterns (will fail on older runtimes):
 

Code Block
languagejava
titleIncompatible patterns (will fail on older runtimes)
// Field with ConfigSpecifier type
private ConfigSpecifier specifier;

// Method parameter with ConfigSpecifier type
public MyConnector(ConfigSpecifier spec) { ... }

// Local variable with explicit ConfigSpecifier type
ConfigSpecifier spec = this;

// instanceof checks
if (obj instanceof ConfigSpecifier) { ... }

// Explicit cast to ConfigSpecifier
ConfigSpecifier casted = (ConfigSpecifier) obj;

// Explicitly implementing ConfigSpecifier
public class MyPlugin implements Transformation, ConfigSpecifier { ... }


  Any of these patterns causes the ConfigSpecifier class to be referenced in the plugin's bytecode, resulting in NoClassDefFoundError when loading on older runtimes that lack the ConfigSpecifier class.

  

Code Block
languagejava
titleCompatible pattern (works on all runtimes)
// Simply implement existing interfaces as before
public class MyTransformation implements Transformation<Record> {
    @Override
    public ConfigDef config() {
        return new ConfigDef();
    }
    // ... other methods
}

  This pattern never directly references ConfigSpecifier in the plugin bytecode, allowing it to run on both old and new Connect runtimes.

Guidance for Plugin Developers

To maintain compatibility with older Connect runtimes while compiling against newer APIs:

  • Do not explicitly implement ConfigSpecifier in your plugin classes
  • Do not use ConfigSpecifier as a field, parameter, return, or local variable type
  • Do continue implementing the standard component interfaces (Connector, Transformation, Converter, etc.) as you always have, the ConfigSpecifier contract will be satisfied automatically through interface inheritance

In practice, this is unlikely to be an issue as there is no compelling reason for plugin code to directly reference ConfigSpecifier; it exists purely to enable uniform component discovery by tooling and the Connect runtime.

Migration Path    

For Component Developers:  
- No changes required. Existing implementations already satisfy the new interface contract.  
- Optional: Add @Override annotations for clarity and compile-time checking.  
  
For Tool Developers:  
- Can immediately start using ConfigSpecifier to discover components uniformly.  
- Existing type-specific discovery code continues to work and can be gradually migrated.  
- The new interface provides an additive capability without breaking existing approaches.  

...