Tương tác OSGi và AspectJ
Công ty Vĩnh Cửu tuyển dụng lập trình viên Java

1- Giới thiệu

Tài liệu này được viết dựa trên:
  • Eclipse 4.4 (LUNA)

Lịch sử:
   20-01-2014: Tạo tài liệu hướng dẫn viết dựa trên Eclipse 4.3 (Kepler)
   23-07-2014: Cập nhập lên Eclipse 4.4 (LUNA)

1.1- Gợi ý

Đả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- Tạo ví dụ minh họa

2.1- Download source

2.2- Mô hình ví dụ

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

2.3- Project target-runtime

Tạo một project java thông thường, với tên "target-runtime":
New/Other
Tại thời điểm tôi cập nhập tài liệu này lên Eclipse 4.4, AJDT đang được phát triển từ 4.3 lên 4.4 và nó chưa hoàn thành, chúng ta sử dụng tạm thư viện dev.
  • http://download.eclipse.org/tools/ajdt/44/dev/update/
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.

2.4- Project "osgi-define-aspectj"

Tạo project "osgi-define-aspectj":
  • org.o7planning.tutorial.osgidefineaspectj.Activator
Chuyển đổi project này về 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;

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

public class MathUtils {
    
    public static int sum(int a, int b) {
        return a + b;
    }
}
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 và 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 bundle osgi 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.

2.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
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;
    }   
     
}
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".
  1. Đặt tên cấu hình chạy ứng dụng là "Run affected-osgi project"
  2. Check chọn 2 project của bạn.
  3. Bỏ check toàn bộ Target Platform
  4. Nhấn vào "Add Required Bundles" để Eclipse tự động tính toán các bundle phụ thuộc.
  5. 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 các osgi "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
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.