title: Keeping compatibility after refactoring without modifying older versions
body: <p>I need to develop a kind of module that will be provided as a JAR that will make 2 products compatible.
  Let's say I have a product called ProductSource and another one called ProductDep.
  The ProductSource is totally independent and ProductDep calls several methods/class and even inherit some class from ProductSource.
  ProductSource (PS) has several versions as does ProductDep (PD). For example, let's say one client use PD_v3 and PS_v3 and another one use PD_V1 and PS_V3.
  Our developpements were somehow nasty and we cannot change any versions, we can only deliver a jar that will be loaded on top of these. The thing is, we developed our PS_v3 only considering PD_v3 consequences, PS_v2 with PD_v2 and PS_v1 with PD_v1. And it's only now that we consider that some of our clients use PS_vY with PD_vX and X!=Y.</p>
  
  <p>Here are the worst cases I need to solve :</p>
  
  <p>PS_v3 class MyClassA :</p>
  
  <pre><code>package com.package.a;
  import com.package.xxx.AClass;
  [...]
  
  /**
   * MyClassA Version 3
   */
  
  public class MyClassA extends AClass
  {
  
      public AType1 method1(AType2 arg1, AType3 arg2){ return null; //or whatever}
      public void method2(AType1 arg1){}
  }
  
  
  public abstract class AClass
  {
  
      public abstract AType1 method1(AType2 arg1, AType3 arg2);
      public abstract void method2(AType1 arg1);
  }
  </code></pre>
  
  <p>And my PD_v2 will use this class but it was developed with PS_v2 which has the same class like this:</p>
  
  <pre><code>package com.some.other.package.a;
  import com.some.other.package.xxx.AClass;
  [...]
  /**
   * MyClassA version 2
   */
  public class MyClassA extends AClass
  {
  
      public AType1 method1(AType2 arg1, AType3 arg2, AType4 arg3){ return null; //or whatever}
      public abstract AType1 method2(){}
  }
  
  
  public abstract class AClass
  {
  
      public abstract AType1 method1(AType2 arg1, AType3 arg2, AType4 arg3);
      public abstract AType1 method2();
  }
  </code></pre>
  
  <p>So if my PD_V2 wants to use my PD_V3 classes he will have some runtime issues.</p>
  
  <p>example :</p>
  
  <pre><code>import com.some.other.package.xxx.AClass; //error on this one because he cannot find the package
  public class MyClassImpl extends AClass
  {
      public AType1 method1(AType2 arg1, AType3 arg2, AType4 arg3){ return null; //or whatever}
      public abstract AType1 method2(){}
  }
  </code></pre>
  
  <p>but he uses V3 package def so he wont find com.package.a.AClass so my idea was to look for every versions and deliver a jar with every possible signatures of the methods.</p>
  
  <p>so my idea was to deliver something like this :</p>
  
  <pre><code>package com.some.other.package.a;
  import com.some.other.package.xxx.AClass;
  [...]
  /**
   * MyClassA version 2
   */
  public class MyClassA extends AClass
  {
  
      public AType1 method1(AType2 arg1, AType3 arg2, AType4 arg3){ 
      try{
          //we try to load our latest version
          //no need to search for the class version in this package it will be loaded automatically if it exists
          Class&lt;?&gt; clazz =  Class.forName("com.package.a.MyClassA");
          clazz.getConstructor(......)
          etc....
      } catch(ClassNotFoundException e){....}
      }
  }
  </code></pre>
  
  <p>My problem is with abstract classes... Or if you have any better solution. Right now I'm pluging in my compatibility folder which will contains all classes used by previous version with all methods that were deleted since the new version (yeah my team don't know the annotation Deprecated T.T) or any method signatures that changed or even classes moved.</p>