Я думал об этом последние дни, это одна интересная проблема.
Хотя я не думаю, что это вообще возможно, делать то, что вы хотите, но я придумал немного сложное решение, но оно может помочь вам, я надеюсь.
Вы запускаете виртуальную машину со старой версией ваших классов, предоставляя ей методы RMI. Затем из вызывающего Classloader вы запускаете соединения RMI с этой другой виртуальной машиной, чтобы получить наборы данных из старых, которые НЕ являются экземплярами классов, а являются стандартными объектами Java (например, картой).
Затем вы переносите эту карту на сайте абонента в экземпляр нужной вам версии.
Таким образом, у вас нет конфликтующих версий класса в одной виртуальной машине.
При необходимости я могу предоставить вам пример кода, чтобы продемонстрировать, что я имею в виду, но впереди у вас много реализаций:)
Что касается части производительности: если вы достаточно плотно сконструируете интерфейсы взаимодействующих частей RMI, накладные расходы RMI не будут стоить вам дорого, и в каждой виртуальной машине нет больших проблем сериализации.
Веселитесь (и, если вам все равно, оставьте записку о том, как все получилось)