2013-03-21 54 views
12

有沒有人使用OSGi 4.3+ Weaving Hook Service的任何示例?怎麼樣與AspectJ,ASM,JavaAssist?有人真的使用OSGi WeavingHooks嗎?OSGi WeavingHook示例

OSGi Core 5.0.0第56.2節中的示例只是略去了實際的編織,並說「最後的編織是作爲練習留給讀者的」。

我的目標是:

  1. 創建註釋(@MyAnnotation),我可以在字段(原語或對象)的地方。
  2. 創建org.osgi.framework.hooks.weaving.WeavingHook編織與註解類
  3. 使用load-time織在字段的任何修改與註釋的切點,現場爲
  4. 火的EventAdmin事件改性。
  5. 動態更新從WeavingHook到捆綁到EventAdmin包的捆綁線。

我的問題主要是#3。

目前我正在嘗試使用AspectJ WeavingAdaptor做編織,但我有讓我的方面庫中,以它的問題,因爲它的期待的java.net.URL [] aspectURLs在構造函數可以是文件系統上可以找到的jar或目錄,而不是捆綁軟件。此外,我不知道如何處理由織工生成的任何新類通過acceptClass(字符串名稱,字節[])方法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,但我想這對任何包的工作,而不是僅僅通過豆Spring或藍圖實例化。另外,Equinox Weaving似乎還沒有使用OSGi編織鉤規格,我也不想被綁定到Equinox上。如果其他方面效果更好,我沒有問題報廢AspectJ。

參考一個類似的問題:Is it possible to do bytecode manipulation when using OSGi?

UPDATE:

最終的結果是我只是用春分方面並安裝它到Karaf。是3捆綁,一個庫和一個系統屬性。我將使用它,直到它們將其更新爲我們的OSGi編織,或者我編寫自己的OSGi編織鉤子以使用類似於Equinox Aspects的AspectJ代碼。我不喜歡使Equinox Aspects正常工作所需的織造指標,因爲它在捆綁的AspectJ RT中引入了需求捆綁/再出口或進口包裝。這種依賴性應該動態添加,並在捆綁之外進行建議。

+0

對於OSGi編織鉤子,您會得到需要修改的類的byte []。您不得嘗試加載突變字節[]。在調用所有的鉤子之後,OSGi框架將完成這個任務。 – 2013-03-21 19:36:34

+0

@BJHargrave是的,那是什麼規範說。問題是,哪些框架或庫與OSGi兼容,並且易於在WeavingHook.weave()方法中保留,我可以使用該方法修改原始類byte [] ...並且是否有任何實際執行此操作的示例? – 2013-03-21 19:52:32

+0

想到ASM或BCEL。 – 2013-03-22 12:39:08

回答

2

查看來自Apache Aries的代理模塊的ProxyWeavingHook。它直接使用ASM庫來修改字節碼,使其更低級別。

+1

你是唯一的答案,它是一個合理的答案。最終結果是我只是使用Equinox Aspects並將其安裝到Karaf中。是3捆綁,一個庫和一個系統屬性。我將使用它,直到它們將其更新爲我們的OSGi編織,或者我編寫自己的OSGi編織鉤子以使用類似於Equinox Aspects的AspectJ代碼。我不喜歡使Equinox Aspects正常工作所需的織造指標,因爲它在捆綁的AspectJ RT中引入了需求捆綁/再出口或進口包裝。這種依賴性應該動態添加,並在捆綁之外進行建議。 – 2013-05-10 20:31:10

0

WeavingAdaptor期望您的WeavingClassLoader是從URLClassLoader派生的,因此兩個可用的構造函數最終都會做同樣的事情。請查看http://www.slideshare.net/mfrancis/bytecode-weaving以瞭解如何使用BundleWiring訪問類路徑URL。您可以將AspectJ運行時包添加到wovenClass.getDynamic'Imports()以避免直接引用AspectJ。 BundleWiring也是爲WeavingAdaptor提供AspectJ url的途徑。

我認爲沒有辦法支持來自acceptClass的新類,因爲編織鉤子指出動態導入只能在織法方法內使用。