java - OSGi WeavingHook 示例

标签 java osgi aop aspectj load-time-weaving

有人有任何使用 OSGi 4.3+ Weaving Hook 服务的示例吗? AspectJ、ASM、JavaAssist 怎么样?有人真的在使用 OSGi WeavingHooks 吗?

OSGi Core 5.0.0 第 56.2 节中的示例只是省略了实际编织并说“最终编织留给读者作为练习”。

我的目标是:

  1. 创建一个我可以放在字段(基元或对象)上的注释 (@MyAnnotation)。
  2. 创建一个 org.osgi.framework.hooks.weaving.WeavingHook 以使用该注释编织类
  3. 使用加载时织入切入带有该注释的字段的任何修改
  4. 触发字段已修改的 EventAdmin 事件。
  5. 动态更新从 WeavingHook 连接到 EventAdmin 包的包连接。

我的问题主要在于#3。

我目前正在尝试使用 AspectJ WeavingAdaptor进行编织,但我在将方面库放入其中时遇到问题,因为它期望构造函数中的 java.net.URL[] aspectURLs 是它可以找到的 jar 或目录在文件系统上,而不是 bundle 。此外,我不确定如何通过回调到 GeneratedClassHandleracceptClass(String name, bytes[]) 方法来处理编织器生成的任何新类。 .

也许 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,但我希望它适用于任何 bundle,而不仅仅是通过 Spring 或 Blueprint 实例化的 beans。此外,Equinox Weaving 似乎还没有使用 OSGi 编织钩子(Hook)规范,我不想被 Equinox 束缚。如果其他方法效果更好,我完全可以放弃 AspectJ。

引用类似问题:Is it possible to do bytecode manipulation when using OSGi?

更新:

最终结果是我刚刚使用了 Equinox Aspects 并将其安装到 Karaf 中。是 3 个包、一个库和一个系统属性。我将使用它,直到他们将其更新为我们的 OSGi 编织或我编写自己的 OSGi 编织 Hook 以使用类似于 Equinox Aspects 的 AspectJ 代码。我不喜欢让 Equinox Aspects 工作所需的编织指示器,因为它在要编织的包中的 AspectJ RT 上引入了一个 require-bundle/reexport 或一个 import-package。这种依赖性应该在包外动态添加和建议。

最佳答案

看看ProxyWeavingHook来自 Apache Aries 的代理模块。它直接使用 ASM 库来修改字节码,使其更底层。

关于java - OSGi WeavingHook 示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15555545/

相关文章:

java - 如何将 Java 网络服务器添加到 OSGI 包中

java - 将 maven-bundle-plugin 包含的资源声明为可选

java - Tycho 无法解决片段对其他片段的依赖

java - 我无法使用 Spring AOP 调用建议的方法

spring - spring中null自动转为空列表

java - 在mysql,java中计算日期范围内的价格

java - 使用jade(pug)创建jsp

c# - 自定义属性在编译时执行

java - JDK 11 与 JDK 13 的性能

java - 将gradle项目导入eclipse出错