openplanning

Tương tác OSGi và AspectJ

  1. Giới thiệu
  2. Mô hình ví dụ
  3. Project target-runtime
  4. Project "osgi-define-aspectj"
  5. Project "affected-osgi"

1. Giới thiệu

Tài liệu này được viết dựa trên:
  • Eclipse 4.7, 4.6 (OXYGEN, NEON)

Đảm bảo rằng Eclipse của bạn đã được cài đặt Ajdt Plugin, nếu bạn chưa cài đặt bạn có thể tham khảo tài liệu sau:

2. Mô hình ví dụ

Mô hình ví dụ bao gồm 3 Project
  • target-runtime
  • osgi-define-aspectj
  • affected-osgi
  • osgi-define-aspectj
    • Là một osgi project vừa là aspectj project, trong đó có định nghĩa một aspectj là SumAspectj.aj
  • affected-osgi
    • Là một osgi project và không phải là aspectj project. Nó phụ thuộc vào osgi-define-aspectj, và chiụ tác dụng của aspectj được định nghĩa trong project trên.

3. Project target-runtime

Tạo một project java thông thường, với tên "target-runtime":
  • File/New/Other
Copy:
  • http://download.eclipse.org/tools/ajdt/47/dev/update/ (Eclipse 4.7 OXYGEN)
  • http://download.eclipse.org/tools/ajdt/46/dev/update/ (Eclipse 4.6 NEON)
Cuối cùng nhấn "Set As Target Runtime" để các thư viện runtime có tác dụng lên toàn bộ các project có trên Workspace.

4. Project "osgi-define-aspectj"

Tạo project "osgi-define-aspectj":
  • File/New/Other..
  • org.o7planning.tutorial.osgidefineaspectj.Activator
Chuyển đổi project này thành Aspectj project:
Kết quả của việc chuyển đổi:
Chúng ta sẽ tạo một số class và một aspectj để có được một kết quả như hình minh họa dưới đây:
Trước hết thêm vào aspectj SumAspecj, trên Eclipse chọn:
  • File/New/Others...
  • Package: org.o7planning.tutorial.osgidefineaspectj
  • Name: SumAspectj
SumAspectj.aj
package org.o7planning.tutorial.osgidefineaspectj;

public aspect SumAspectj {
 
  before() : execution(* *.sum(..)) {
      System.out.println("Before execution sum");
  }
 
}
MathUtils.java
package org.o7planning.tutorial.osgidefineaspectj;

public class MathUtils {
   
   public static int sum(int a, int b) {
       return a + b;
   }
}
TestSumInternal.java
package org.o7planning.tutorial.osgidefineaspectj;

public class TestSumInternal {
   
   public static void main(String[] args) {
       
       int value= MathUtils.sum(10,20);
       System.out.println("Value ="+value);

   }

}
Chạy class TestSumInternal, và kết quả thấy rằng mỗi khi method có tên "sum" được chạy aspectj SumAspectj sẽ hoạt động và nó ghi ra dòng text "Before execution sum".
Tiếp theo chúng ta khai báo 'export package''aspectj' để các osgi khác có thể sử dụng.
Như vậy cho tới lúc này chúng ta đã tạo được một osgi project với sự tham gia của aspectj. Và chạy thành công trong nội bộ của osgi này.

Tuy nhiên mỗi osgi bundle sử dụng riêng một ClassLoader của riêng nó, vì vậy aspectj chỉ có tác dụng trong nội bộ của osgi này. Để nó có tác dụng tới các osgi bundle khác, cần có một số cấu hình. Hãy làm tiếp một project khác để nó chịu ảnh hưởng của aspectj được khai báo trong project trên.

5. Project "affected-osgi"

Tương tự bạn tạo một osgi project khác với tên "affected-osgi".
Khai báo nó phụ thuộc vào osgi "osgi-define-aspectj". Và 2 bundle:
  • org.eclipse.equinox.console
  • org.apache.felix.gogo.shell
Math2Utils.java
package org.o7planning.tutorial.affectedosgi;

public class Math2Utils {
   
   
   public static float sum(float a,float b)  {
       return a+b;
   }
   
   public static int sum(int a, int b)  {
       return a+b;
   }  
   
}
Activator.java
package org.o7planning.tutorial.affectedosgi;

import org.o7planning.tutorial.osgidefineaspectj.MathUtils;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

public class Activator implements BundleActivator {

   private static BundleContext context;

   static BundleContext getContext() {
       return context;
   }

   public void start(BundleContext bundleContext) throws Exception {
       Activator.context = bundleContext;

       this.testSumAspectj();
   }

   private void testSumAspectj() {
       System.out.println("-----------------------");
       int value1 = MathUtils.sum(100, 100);
       System.out.println("Value =" + value1);

       System.out.println("-----------------------");
       int value2 = Math2Utils.sum(100, 100);
       System.out.println("Value =" + value2);

       System.out.println("-----------------------");
       float value3 = Math2Utils.sum(100f, 100f);
       System.out.println("Value =" + value3);
   }

   public void stop(BundleContext bundleContext) throws Exception {
       Activator.context = null;
   }

}
Bây giờ chúng ta sẽ cấu hình để chạy osgi "affected-osgi".
  • Đặt tên cấu hình chạy ứng dụng là "Run affected-osgi project"
  • Check chọn 2 project của bạn.
  • Bỏ check toàn bộ Target Platform
  • Nhấn vào "Add Required Bundles" để Eclipse tự động tính toán các bundle phụ thuộc.
  • Nhấn Apply
Kết quả việc chạy osgi project "affected-osgi" cho kết quả:
Kết quả trên cho thấy aspectj "SumAspectj" định nghĩa trong osgi "osgi-define-aspectj" chưa có ảnh hưởng tới các osgi khác. Tiếp theo chúng ta sẽ cấu hình tiếp để đảm bảo "SumAspectj" sẽ ảnh hưởng tới "affected-osgi".
Khai báo thêm các bundle đòi hỏi cho osgi "affected-osgi".
  • org.eclipse.osgi
  • org.aspectj.weaver
  • org.eclipse.equinox.weaving.aspectj
  • org.eclipse.equinox.weaving.caching
  • org.eclipse.equinox.ds
Khai báo tham số môi trường chạy:
  • -Dosgi.framework.extensions=org.eclipse.equinox.weaving.hook
  • -Daj.weaving.verbose=true
  • -Dorg.aspectj.weaver.showWeaveInfo=true
  • -Dorg.aspectj.osgi.verbose=true
Khai báo mảnh ghép (fragment) mở rộng cho osgi org.eclipse.osgi.
  • -Dosgi.framework.extensions=org.eclipse.equinox.weaving.hook
Các dòng sau đây bạn cũng có thể thêm vào dành cho việc dò lỗi (Debug):
  • -Daj.weaving.verbose=true
  • -Dorg.aspectj.weaver.showWeaveInfo=true
  • -Dorg.aspectj.osgi.verbose=true
Đảm bảo rằng bundle: org.eclipse.equinox.weaving.aspectj được tự động start ở Level 2.
Cuối cùng bạn chạy lại osgi "affected-osgi" và đây là kết quả mà bạn trông đợi.