Проблема в том, что по какой-то причудливой причине я должен загрузить интерфейс Inter с дочерним ClassLoader и класс реализации Impl с родительским ClassLoader.
Я не могу понять, почему дочерний загрузчик классовдолжен загрузить интерфейс, оставляя родительский загрузчик классов, чтобы загрузить реализацию.Это должно вызывать проблемы, поскольку в механизме загрузки классов, используемом JVM, не имеет механизма для отсрочки загрузки классов в дочерний загрузчик классов .Обычный механизм реализации поведения загрузки классов в JVM определен в документации API класса ClassLoader:
Класс ClassLoader использует модель делегирования для поиска классов и ресурсов.Каждый экземпляр ClassLoader имеет связанный родительский загрузчик классов.При запросе на поиск класса или ресурса экземпляр ClassLoader делегирует поиск класса или ресурса своему загрузчику родительского класса, прежде чем пытаться найти сам класс или ресурс.Встроенный загрузчик классов виртуальной машины, называемый загрузчиком классов начальной загрузки, сам по себе не имеет родителя, но может служить родителем экземпляра ClassLoader.
Можно написать собственный загрузчик классов,расширяя класс ClassLoader и переопределяя метод loadClass () .Расширение этого метода позволяет вам изменить делегирование загрузки класса одним из двух способов:
- Parent-first : Получить родительский загрузчик классов для загрузки класса первым.Обычно это транзитивное поведение - большинство родительских загрузчиков классов будут откладывать загрузку до своих родителей и т. Д., Пока загрузчик загрузчика классов (корень) не будет достигнут в иерархии загрузчиков классов.Если родительский загрузчик классов не может загрузить класс, дочерний элемент пытается загрузить его.Возможная ошибка при загрузке класса должна привести к возникновению исключения ClassNotFoundException.
- Parent-last : Пользовательский загрузчик классов сначала пытается загрузить класс, прежде чем делегировать его родителю.Родительские загрузчики классов используются только в том случае, если дочерний процесс не может загрузить класс.
Большинство загрузчиков классов реализованы как первоклассные загрузчики классов.Это связано с тем, что механизм делегирования может проходить по дереву вверх, но не вниз.
Если вы действительно хотите делегировать загрузку и поиск классов дочерним загрузчикам классов в иерархиивам придется управлять ссылками на них в пользовательском загрузчике классов для родителя.Это непросто, и обычно это вообще не делается, за исключением очень исключительных обстоятельств, поскольку очень легко получить страшные ClassNotFoundException и NoClassDefFoundError, поскольку нужно быть осторожным при загрузке только необходимых классов из дочерних загрузчиков классов, в то время как остальные должнывсегда откладывать на родителя (если я не ошибаюсь, функция разделяемых библиотек в некоторых контейнерах Java EE реализована таким образом).
Сказав это, идеальным решением будет попытка загрузить оба интерфейсаи классы реализации в родительском загрузчике классов и полагаются на механизм делегирования, чтобы гарантировать, что классы видны обоим загрузчикам классов;родитель может «видеть» загруженные классы самостоятельно, а ребенок может «видеть» классы родителя.
PS: не забывайте использовать AccessController.doPrivileged при загрузке и определении классов.