Кажется, что у всех была неприятная кисть с провайдером услуг Java , которую вы можете сделать с файлом с именем, например META-INF / services / com.example.Interface, но никто не использует за исключением попытки загрузить правильный анализатор XML. Я пытаюсь работать с библиотекой, использующей API Service Provider, и обманываю ее, чтобы я мог предоставить некоторые расширенные во время выполнения классы (используя cglib), которые на самом деле не реализуют интерфейс, но могут быть легко сделаны.
В принципе, я думаю, что мне нужно выполнить следующие шаги:
- Создайте пользовательский загрузчик классов, который будет отвечать на getResources (...) и возвращать «дополнительный» URL
- Иметь этот загрузчик классов getResourceAsStream (...), чтобы возвращать список классов, которыми я собираюсь манипулировать с помощью cglib, когда запрашивается «дополнительный» ресурс
- Наконец, загрузчик классов загружает эти классы по запросу
Но вот где я заблудился. Например, когда библиотека пытается определить, какие реализации существуют, она вызывает метод getResources (...), который возвращает несколько URL-адресов. Но getResourceAsStream (...) не берет URL-адреса, он принимает «имена». Имена, которые кажутся относительными к классам и, следовательно, везде одинаковы. Таким образом, META-INF / services / com.example.Interface in имеет то же «имя», что и META-INF / services / com.example.Interface в их JAR, верно? Кроме как-то это работает с этими взорванными парсерами XML ...
Конечно, все это предполагает, что они достаточно умны / добры, чтобы вызывать ClassLoader.getSystemClassLoader (), а не использовать ClassLoader.getSystemResources (...), ClassLoader.getSystemResourceAsStream (...) и т. Д., Как в В последнем случае нет способа перехватить ClassLoader и предоставить поддельный файл.
Полагаю, в этом случае я мог бы использовать BCEL для манипулирования файлами классов, когда мой код упакован в Maven, вместо ожидания времени выполнения, чтобы сделать это с помощью cglib?