Это звучит разумно. В [API javadoc для loadClass] [1] говорится:
"Загружает класс с указанным двоичным именем. Реализация этого метода по умолчанию ищет классы в следующем порядке:
Вызвать findLoadedClass (String), чтобы проверить, загружен ли уже класс.
Вызвать метод loadClass в загрузчике родительского класса. Если родительский объект имеет значение null, вместо него используется встроенный в виртуальную машину загрузчик классов.
Вызовите метод findClass (String), чтобы найти класс. "
Если CL1 для MyAPI1, CL2 для MyAPI2, а CL3 для MyLib, звучит так, как будто вы хотите, чтобы они проверялись в следующем порядке: CL3, CL2, CL1. Что из приведенной выше цитаты (поскольку родители проверяются первыми) предполагает, что вы хотите, чтобы CL1 имел родительский CL2, а CL2 - родительский CL3. Поскольку конструктор с родительским загрузчиком классов защищен, вам придется использовать URL-загрузчик классов с правильно установленными родителями.
Что-то вроде
URLCLassLoader cl3 = new URLClassLoader(new URL[]{ path to MyLib});
URLCLassLoader cl2 = new URLClassLoader(new URL[]{ path to API2}, cl3);
URLCLassLoader cl1 = new URLClassLoader(new URL[]{ path to API1}, cl2);
тогда везде используйте cl1.
[1]: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/ClassLoader.html#loadClass(java.lang.String, логическое значение)