Примеры использования OSGi WeavingHook

Есть ли у кого-нибудь примеры использования OSGi 4.3+ Weaving Hook Service? Как насчет AspectJ, ASM, JavaAssist? Кто-нибудь действительно использует OSGi WeavingHooks?

Пример в разделе 56.2 OSGi Core 5.0.0 просто не учитывает фактического ткачества и говорит, что "окончательное плетение остается в качестве упражнения для читателя".

Моя цель:

  • создайте аннотацию (@MyAnnotation), которую я могу разместить в полях (примитивах или объектах).
  • создайте org.osgi.framework.hooks.weaving.WeavingHook, чтобы сплести классы с этой аннотацией
  • использовать временное плетение для pointcut при любой модификации полей с помощью этой аннотации
  • пожаловать события EventAdmin, которые были изменены.
  • динамически обновлять проводку связки от WeavingHook до проводки до пакета EventAdmin.

Моя проблема в основном С# 3.

В настоящее время я пытаюсь использовать AspectJ WeavingAdaptor, чтобы выполнить переплетение, но у меня возникают проблемы с получением моей аспектной библиотеки в нем, поскольку он ожидает, что java.net.URL [] aspectURLs в конструкторе будет либо баночками, либо каталогами, которые он может найти в файловой системе, а не в связках. Кроме того, я не уверен, как обращаться с любыми новыми классами, сгенерированными ткачиком через обратные вызовы методу 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, но я хочу, чтобы это работало для любого пакета, а не только beans, созданного с помощью Spring или Blueprint. Кроме того, Equinox Weaving, похоже, пока не использует опцию привязки OSGi, и я не хочу привязываться к Equinox. У меня нет проблем с утилитой AspectJ, если что-то еще работает лучше.

Ссылка на аналогичный вопрос: Можно ли манипулировать байт-кодом при использовании OSGi?

UPDATE:

Конечный результат: я просто использовал Equinox Aspects и установил его в Karaf. Было 3 пакета, одна библиотека и системное свойство. Я буду использовать его до тех пор, пока они не обновят его для нас OSGi, или я напишу свои собственные перетаскивания OSGi, чтобы использовать код AspectJ, похожий на Equinox Aspects. Мне не нравятся показатели ткачества, необходимые для того, чтобы заставить Equinox Aspects работать, потому что он вводит требуемый пакет/реэкспорт или импортный пакет на AspectJ RT в сплетенном комплекте. Эта зависимость должна быть динамически добавлена ​​и рекомендована вне пакета.

Ответ 1

Посмотрите ProxyWeavingHook из прокси-модуля Apache Aries. Он использует библиотеку ASM напрямую, чтобы изменить байт-код так на более низкий уровень.

Ответ 2

WeavingAdaptor ожидает, что ваш WeavingClassLoader будет получен из URLClassLoader, поэтому оба доступных конструктора в основном делают то же самое в конце. Оформить заказ http://www.slideshare.net/mfrancis/bytecode-weaving, чтобы узнать, как BundleWiring можно использовать для получения доступа к URL-адресам класса. Вы можете добавить пакеты времени исполнения AspectJ в wovenClass.getDynamic'Imports(), чтобы избежать прямых ссылок AspectJ. BundleWiring - это также способ предоставить URL-адреса AspectJ для WeavingAdaptor.

Я думаю, что нет способа поддерживать новые классы, исходящие из acceptClass, потому что переплетение говорит о том, что динамический импорт может использоваться только внутри метода переплетения.