Вопрос

Кажется, что у всех была неприятная кисть с Java Service Provider, то, что вы можете сделать с файлом, названным как Meta-Inf/Services/com.example.interface, но никто не использует, кроме как попытка загрузить правильный анализатор XML. Я пытаюсь работать с библиотекой, которая использует API поставщика услуг, и обмануть его, чтобы я мог предоставить несколько классов, расширенных во время выполнения (с использованием CGLIB), которые на самом деле не реализуют интерфейс, но можно сделать так легко.

По сути, я думаю, что шаги, которые мне нужно выполнить, являются:

  1. Создайте пользовательский загрузчик класса, который будет реагировать на GetResources (...) и вернет «дополнительный» URL
  2. Также есть этот класс погрузчик getresourceasstream (...), чтобы вернуть список классов, которые я собираюсь манипулировать с помощью Cglib, когда его попросят «дополнительный» ресурс
  3. Наконец, пусть этот класс загружает эти классы по запросу

Но вот где я заблудился. Например, когда библиотека пытается определить, какие есть исполнители, она вызывает getResources (...), что возвращает кучу URL -адресов. Но GetResourCeasStream (...) не принимает URL -адреса, это требует «имен». Имена, которые кажутся относительными в классе, и, следовательно, одинаковые везде. Итак, Meta-Inf/services/com.example.interface в том же «имя», что и Meta-Inf/services/com.example.interface в их банке, верно? За исключением того, что каким -то образом это работает с этими взорванными XML -анализаторами ...

Конечно, все это предполагает, что они были достаточно умными/добрыми, чтобы назвать classloader.getSystemClassloader (), а не использовал ClassLoader.GetSySteMresources (...), ClassLoader.GetSyStemResourCeasStream (...) и т. Д., Как и в последнем случае. Нет возможности зацепить класс -загрузчик и предоставить фальшивый файл.

Я предполагаю, что в этом случае я мог бы использовать BCEL для манипулирования файлами класса, когда мой код упакован Maven, вместо того, чтобы ждать времени выполнения, чтобы сделать это с CGLIB?

Это было полезно?

Решение

Идея, которую я описал, была на правильном пути. Ошибка, которую я сделал, заключалась в том, чтобы думать, что использование ClassLoader.getResourceAsStream(..) Чтобы получить доступ к содержимому URL. Вместо этого вы должны просто URL.openStream().

Нашел ли я это перед публикацией, java.util.ServiceLoader (@Since 1.6) дает некоторое представление о том, как правильно делать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top