Есть ли у кого-нибудь примеры использования OSGi 4.3+ Weaving Hook Service? А как насчет AspectJ, ASM, JavaAssist? Кто-нибудь на самом деле использует OSGi WeavingHooks?
Пример в OSGi Core 5.0.0, раздел 56.2, просто не учитывает фактическое плетение и говорит, что «окончательное плетение оставляется читателю в качестве упражнения».
Моя цель:
- создать аннотацию (@MyAnnotation), которую я могу разместить на полях (примитивах или объектах).
- создайте org.osgi.framework.hooks.weaving.WeavingHook для создания классов с этой аннотацией
- использовать переплетение во время загрузки, чтобы указать на любую модификацию полей с этой аннотацией
- запускать события EventAdmin о том, что поле было изменено.
- динамически обновлять проводку пакета от WeavingHook для подключения к пакету EventAdmin.
У меня проблема в основном с номером 3.
В настоящее время я пытаюсь использовать AspectJ WeavingAdaptor, чтобы выполнить переплетение, но у меня возникли проблемы с подключением к нему моей библиотеки аспектов, поскольку он ожидает, что java.net.URL[] aspectURL в конструкторе будут либо jar или каталоги, которые он может найти в файловой системе, а не пакеты. Кроме того, я не уверен, как обрабатывать любые новые классы, созданные Weaver через обратные вызовы метода acceptClass(String name, bytes[]) в GeneratedClassHandler.
Может быть, WeavingAdaptor — не самое подходящее место для начала плетения? Или, может быть, мне не следует использовать AspectJ?
MyAnnotation.java
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
}
MyWeavingHook.java
public class MyWeavingHook implements WeavingHook {
public class MyWeavingClassloader implements WeavingClassLoader {
private Bundle b;
public MyWeavingClassLoader(Bundle b) {
this.b = b;
}
void acceptClass(java.lang.String name, byte[] bytes) {
//no way to get this back into the woven classes bundle classloader?
}
URL[] getAspectURLs() {
//how do I get a handle to my aspect library that AspectJ can understand?
}
}
public void weave(WovenClass myclass) {
Bundle b = Framework.getBundle(MyWeavingHook.class);
WeavingClassLoader wc = new WeavingClassLoader(b);
WeavingAdaptor w = new WeavingAdaptor(wc);
if (shouldWeave(myclass))
myclass.setBytes(w.weave(myClass.getBytes()));
//should catch exceptions
}
private boolean shouldWeave(WovenClass myclass) {
//not sure of the best logic to pick which classes to weave yet
}
}
MyAspect.aj
privileged aspect MyAspect {
after() : set(* *) && @annotation(MyAnnotation) {
//send EventAdmin event
}
}
MyTestClass.java
public class MyTestClass {
@MyAnnotation
private int myField;
public void doSomething() {
//do stuff with myField
}
}
Я мог бы использовать Spring AOP, но я хочу, чтобы это работало для любого пакета, а не только для bean-компонентов, созданных с помощью Spring или Blueprint. Кроме того, Equinox Weaving, похоже, еще не использует спецификацию ткацкого крючка OSGi, и я не хочу быть привязанным к Equinox. У меня нет проблем с отказом от AspectJ, если что-то другое работает лучше.
Ссылка на аналогичный вопрос: Можно ли сделать байт-код манипуляции при использовании OSGi?
ОБНОВИТЬ:
Конечным результатом является то, что я просто использовал Equinox Aspects и установил его в Karaf. Было 3 бандла, одна библиотека и системное свойство. Я буду использовать его до тех пор, пока они либо не обновят его до OSGi weaving, либо я не напишу свои собственные OSGi weaving hooks, чтобы использовать код AspectJ, аналогичный Equinox Aspects. Мне не нравятся индикаторы переплетения, необходимые для работы Equinox Aspects, потому что они вводят пакет require-bundle/reexport или import-package в AspectJ RT в связке, которую нужно сплести. Эта зависимость должна быть динамически добавлена и рекомендована вне пакета.