OSGi WeavingHook Примеры

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

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

Моя цель состоит в том, чтобы:

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

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

В настоящее время я пытаюсь использовать AspectJ WeavingAdaptor для выполнения ткачества, но у меня возникают проблемы с подключением к нему моей библиотеки аспектов, так как ожидается, что java.net.URL[] aspectURLs в конструкторе будет либо jar, либо каталогами он может найти в файловой системе, а не в связках. Кроме того, я не уверен, как обрабатывать какие-либо новые классы, сгенерированные ткачом посредством обратных вызовов к методу 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 Aspect и установил его в Karaf. Было 3 комплекта, одна библиотека и системное свойство. Я буду использовать его до тех пор, пока они не обновят его для нас, ткачество OSGi, или я напишу свои собственные хуки для ткачества OSGi, чтобы использовать код AspectJ, аналогичный аспектам Equinox. Мне не нравятся ткацкие индикаторы, необходимые для работы Аспектов Equinox, потому что они вводят require-bundle/reexport или import-package на AspectJ RT в пакете, который нужно сплести. Эта зависимость должна быть динамически добавлена ​​и рекомендована вне пакета.

2 ответа

Решение

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

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

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

Другие вопросы по тегам