2013-03-21 14 views
12

Hat jemand Beispiele für die Verwendung des OSGi 4.3+ Weaving Hook Service? Was ist mit AspectJ, ASM, JavaAssist? Benutzt jemand tatsächlich OSGi WeavingHooks?OSGi WeavingHook Beispiele

Das Beispiel in OSGi Core 5.0.0 Abschnitt 56.2 lässt einfach das eigentliche Weben aus und sagt "das letzte Weben wird dem Leser als Übung überlassen".

Mein Ziel ist es,

  1. eine Anmerkung erstellen (@MyAnnotation), die ich auf den Feldern (Primitiven oder Objekte) platzieren kann.
  2. ein org.osgi.framework.hooks.weaving.WeavingHook schaffen Klassen zu weben mit dieser Anmerkung
  3. Verwendung der Ladezeit mit dieser Anmerkung
  4. Feuer Eventadmin Ereignisse bei jeder Änderung von Feldern zu Pointcut Weben, das war das Feld geändert.
  5. aktualisieren Sie die Bündelverdrahtung dynamisch von WeavingHook zu Draht zum EventAdmin-Bundle.

Mein Problem ist meistens mit # 3.

ich zur Zeit versucht, die AspectJ WeavingAdaptor zu verwenden, um das Weben zu tun, aber ich habe Probleme, um es meinen Aspekt Bibliothek bekommen, da sie den java.net.URL [] aspectURLs im Konstruktor erwartet entweder jars oder Verzeichnisse sein, die es auf dem Dateisystem finden kann, und nicht Bündel. Außerdem bin ich nicht sicher, wie mit neuen Klassen umzugehen, die vom Weber durch Rückrufe an die acceptClass (String name, bytes []) Methode von GeneratedClassHandler verarbeitet werden.

Vielleicht ist WeavingAdaptor nicht der richtige Ort, um mit dem Weben anzufangen? Oder sollte ich AspectJ nicht benutzen?

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 
    } 
} 

I Frühling AOP verwenden könnte, aber ich mag dies für jedes Bündel arbeiten, nicht nur Bohnen durch Frühling oder Blueprint instanziiert. Außerdem scheint Equinox Weaving die Web-Hook-Spezifikation von OSGi noch nicht zu verwenden und ich möchte nicht an Equinox gebunden sein. Ich habe kein Problem, AspectJ zu verwerfen, wenn etwas anderes besser funktioniert.

Referenz auf eine ähnliche Frage: Is it possible to do bytecode manipulation when using OSGi?

UPDATE:

End Ergebnis habe ich nur Equinox Aspects und installiert es in Karaf. War 3 Bundles, eine Bibliothek und eine Systemeigenschaft.Ich werde es benutzen, bis es entweder OSGi Weben aktualisiert oder ich schreibe meine eigenen OSGi Weben-Hooks, um den AspectJ-Code ähnlich Equinox Aspects zu verwenden. Ich mag die Webindikatoren nicht, die benötigt werden, um Equinox-Aspekte zum Laufen zu bringen, weil es ein Bedarfspaket/Reexport oder ein Importpaket auf dem AspectJ RT in dem zu verwebenden Bündel einführt. Diese Abhängigkeit sollte außerhalb des Bündels dynamisch hinzugefügt und empfohlen werden.

+0

Für die OSGi Weben-Hooks erhalten Sie ein Byte [] der Klasse, die Sie ändern müssen. Sie dürfen nicht versuchen, das mutierte Byte [] zu laden. Dies wird durch den OSGi-Rahmen geschehen, nachdem alle Webhacken aufgerufen wurden. –

+0

@BJHargrave ja, das ist was die Spezifikation sagt. Die Frage ist, welche Frameworks oder Bibliotheken OSGi-kompatibel und leicht in der WeavingHook.weave() -Methode zu halten sind, mit der ich das ursprüngliche Klassenbyte [] ändern kann ... und gibt es irgendwelche Beispiele dafür, dass irgendjemand das tatsächlich tut? –

+0

ASM oder BCEL kommen in den Sinn. –

Antwort

2

Werfen Sie einen Blick auf ProxyWeavingHook von Proxy-Modul von Apache Widder. Es verwendet die ASM-Bibliothek direkt, um den Bytecode so niedriger zu gestalten.

+1

Ihr ist die einzige Antwort und es ist eine vernünftige Antwort. Das Endergebnis ist, dass ich Equinox Aspects nur verwendet und in Karaf installiert habe. War 3 Bundles, eine Bibliothek und eine Systemeigenschaft. Ich werde es benutzen, bis es entweder OSGi Weben aktualisiert oder ich schreibe meine eigenen OSGi Weben-Hooks, um den AspectJ-Code ähnlich Equinox Aspects zu verwenden. Ich mag die Webindikatoren nicht, die benötigt werden, um Equinox-Aspekte zum Laufen zu bringen, weil es ein Bedarfspaket/Reexport oder ein Importpaket auf dem AspectJ RT in dem zu verwebenden Bündel einführt. Diese Abhängigkeit sollte außerhalb des Bündels dynamisch hinzugefügt und empfohlen werden. –

0

WeavingAdaptor erwartet, dass Ihr WeavingClassLoader von URLClassLoader abgeleitet wird, sodass beide verfügbaren Konstruktoren am Ende dasselbe tun. Überprüfen Sie http://www.slideshare.net/mfrancis/bytecode-weaving, um zu erfahren, wie BundleWiring verwendet werden kann, um auf Klassenpfad-URLs zuzugreifen. Sie können AspectJ-Laufzeitpakete zu wovenClass.getDynamic'Imports() hinzufügen, um direkte AspectJ-Referenzen zu vermeiden. Mit BundleWiring können auch AspectJ-URLs für den WeavingAdaptor bereitgestellt werden.

Ich denke, dass es keine Möglichkeit gibt, neue Klassen von acceptClass zu unterstützen, da das Weben von Hooks besagt, dass dynamische Importe nur innerhalb der Webmethode verwendet werden können.