Search code examples
javaconfluence

Implements an interface dynamically in Java


I'm running into an issue with implementing an interface dynamically and couldn't figure out how to achieve that. Here is my problem:

I'm developing a plugin application for Confluence, I have a class Transformer that implements WebResourceTransformerFactory type which is come from Atlassian Confluence public library with the classpath of com.atlassian.plugin.webresource.transformer.*.

I want to make my plugin application to be compatible with a certain range of versions(8 -> 9) of Confluence, but with the latest version of Confluence changes, the interface type WebResourceTransformerFactory has moved to a new package com.atlassian.webresource.spi.transformer.WebResourceTransformerFactory and it cause my plugin application incompatible with the new version of Confluence.

Transformer.java compatible with old version(Confluence v8)

import com.atlassian.plugin.webresource.transformer.*;

public class Transformer implements WebResourceTransformerFactory {
// Do something...
}

Transformer.java compatible with new version(Confluence v9)

import com.atlassian.webresource.spi.transformer.WebResourceTransformerFactory;

public class Transformer implements WebResourceTransformerFactory {
// Do something...
}

As you can see WebResourceTransformerFactory has different classpath with different runtime environments (Confluence). I'm wondering how to make my class Transformer.java to implement WebResourceTransformerFactory dynamically with different classpath when running on different version of Confluence. Can Java reflection do that? If yes, how?

Appreciate any help and advise!


Solution

  • This isn't about "having different classpaths".

    The point is that

    com.atlassian.plugin.webresource.transformer.WebResourceTransformerFactory

    and

    com.atlassian.webresource.spi.transformer.WebResourceTransformerFactory

    are two different interfaces in Java. And there is no "dynamic" / "reflection based" approach that allows you to work around that.

    You have to understand that class (or interface) names in Java bytecode are always absolute, therefore com.whatever.X can never be "the same" as com.something.else.X.

    In other words: yes, this is a compatibility breaking change, and there is no way "working around" it.