2010-01-14 39 views
5

Để sử dụng các tính năng thiết bị được giới thiệu trong JDK 5, bạn có thể sử dụng cờ -javaagent được chuyển đến JVM. Điều này sẽ tiêm một thể hiện của một lớp Instrumentation vào phương thức tĩnh premain. Ví dụ trong một lớp học như thế này:Tôi có thể sử dụng java.lang.instrument như thế nào trong một ứng dụng RCP Eclipse?

public class MyClass { 
    public static Instrumentation inst; 
    public static void premain(String options, Instrumentation inst) { 
     MyClass.inst = inst; 
    } 
} 

Với một file manifest thích hợp, bạn có thể chạy này như sau:

java -javaagent:myfiles.jar SomeClass 

này gọi phương thức premain sau đó main từ SomeClass. Cách tiếp cận này được sử dụng trong các Java.SizeOf Project để đoán ở kích thước gần đúng của một đối tượng Java.

OK, bây giờ trong Eclipse RCP each bundle has its own classloader. Điều này có nghĩa rằng Instrumentation tĩnh mà chúng ta lưu trữ trong MyClass của chúng ta không hiển thị đối với một ứng dụng Eclipse. Các javaagent sử dụng một trình nạp lớp, các gói Eclipse được nạp với một gói khác. Khi chúng tôi truy cập MyClass.inst từ trong plugin, nó là null, dưới dạng rằng lớp không phải là lớp giống với lớp được tải và được gọi là premain.

Các đầu mối khác về giải pháp có thể là this thread trên danh sách gửi thư rcp. Nhưng không có gì kết luận.

Có cách nào để giải quyết vấn đề này không? Các Eclipse-BuddyPolicy ám chỉ trong bài viết eclipsezone âm thanh tốt. Tôi đã thử:

Eclipse-BuddyPolicy: app 

trong plugin mà không gặp may. Tôi cần một cái gì đó như Eclipse-BuddyPolicy: javaagent. Bất kỳ ý tưởng?

+0

Bạn có nhận được bất kỳ exeptions? Một điểm yếu là có lớp agent mà không cần gói. (ví dụ: MyClass có thể không nằm trong gói mặc định). Nó có hoạt động ngoài nhật thực không? – stacker

+0

Đúng, hoạt động tốt bên ngoài Eclipse với các công cụ POJO. Trong thực tế, một "println" trong tiền tố được hiển thị từ Eclipse, nhưng sau đó Công cụ tĩnh là null khi được gọi từ bất kỳ plugin nào. – richq

Trả lời

4

Tôi nghĩ giải pháp đơn giản nhất là sử dụng đối tượng thuộc tính chung. Có cửa hàng trước khi chính đối tượng bị đo đạc như một thuộc tính toàn cầu và sau đó truy cập nó từ khắp mọi nơi (các thuộc tính đối tượng là như nhau trong tất cả các bộ tải lớp):

[Edit: cập nhật]

public class MyClass { 
    private static final String KEY = "my.instrumentation"; 
    public static void premain(String options, Instrumentation inst) { 
     Properties props = System.getProperties(); 
     if(props.get(KEY) == null) 
      props.put(KEY, inst); 
    } 

    public static Instrumentation getInstrumentation() { 
     return System.getProperties().get(KEY); 
    } 
} 
+0

Đó là một ý tưởng hay, nhưng thật đáng buồn là 'setProperty (String, String)' - bạn không thể đặt bất kỳ Object cũ nào trong đó. – richq

+0

Điều này có thể dễ dàng sửa (Xem phiên bản cập nhật của câu trả lời của tôi): System.getProperties() trả về một đối tượng Properties() là một lớp con của Hashtable có API cung cấp thiết lập (String, Object) và nhận (String) trả về một đối tượng. –

+0

Một giải pháp đơn giản như vậy, và nó hoạt động hoàn hảo. Cảm ơn! – richq

Các vấn đề liên quan