2015-10-23 15 views
19

Tôi muốn thêm một arrayList vào một phương thức trong quá trình đo đạc. Tôi đã thử nó như đã đề cập trong (Javassist CannotCompileException when trying to add a line to create a Map) nhưng nó ném một ngoại lệ khác với một java.lang.VerifyError.Cách tạo một ArrayList bằng cách sử dụng Javassist

public void createInsertBefore(String scenarioName, String className, CtMethod method, 
            String insertBefore) throws CannotCompileException { 
     method.addLocalVariable("startTime", CtClass.longType); 
     StringBuilder bBuilder = new StringBuilder(); 
     bBuilder.append("startTime = System.nanoTime();"); 
     bBuilder.append("System.out.println(startTime);"); 

     if((insertBefore!=null) && !insertBefore.isEmpty()){ 
      bBuilder.append(insertBefore); 
     } 

     bBuilder.append("java.util.List metadata = new java.util.ArrayList();"); 

     System.out.println(bBuilder.toString()); 
     method.insertBefore(bBuilder.toString()); 
} 

Output nhận được từ báo cáo kết quả in là,

startTime = System.nanoTime(); 
System.out.println(startTime); 
java.util.List metadata = new java.util.ArrayList(); 

Nhưng nó ném ngoại lệ sau đây,

Exception in thread "main" java.lang.reflect.InvocationTargetException 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:606) 
    at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:382) 
    at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:397) 
Caused by: java.lang.VerifyError 
    at sun.instrument.InstrumentationImpl.retransformClasses0(Native Method) 
    at sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:144) 
    at org.wso2.das.javaagent.instrumentation.Agent.premain(Agent.java:57) 
    ... 6 more 
FATAL ERROR in native method: processing of -javaagent failed 
Aborted (core dumped) 

Tình hình là giống như trước đó, nhưng tại sao nó ném một ngoại lệ khác nhau . am i làm gì sai .... một số giúp đỡ xin vui lòng ...

Cập nhật 1

dòng thêm với (Tôi đã xóa một số dòng in), insertBefore,

startTime = System.nanoTime(); 
java.util.List metadata = new java.util.ArrayList(); 

insertAt

System.out.println("prepareStatement is running"); 
java.util.Map/*<String,String>*/ arbitraryMap = new java.util.HashMap/*String,String>*/(); 
arbitraryMap.put("query",$1);System.out.println(arbitraryMap); 

insertAfter

System.out.println(System.nanoTime()-startTime); 
+0

Có vẻ như có lỗi trong mã gốc. – Thomas

+0

Ý của bạn là gì? U có nghĩa là phần còn lại của mã? Tôi nghĩ rằng vấn đề là với tuyên bố đó, bởi vì nếu tôi nhận xét ra rằng dòng, thiết bị đo đạc hoạt động tốt. Vì vậy, tôi nghĩ rằng đó là một cái gì đó sai trái với tuyên bố đó. – udani

+0

Mã của bạn có thể sai nhưng lỗi xảy ra ở đây: 'sun.instrument.InstrumentationImpl.retransformClasses0 (Phương thức Gốc)' tức là mã trong mã gốc. Các JavaDoc trên lỗi bạn nhận được nói: 'Thrown khi" Verifier "phát hiện rằng một tập tin lớp, mặc dù cũng được hình thành, có chứa một số loại nội bộ không thống nhất hoặc vấn đề an ninh.' - nó có thể phụ thuộc vào lớp đang được tăng cường, có thể bạn đang cố gắng chèn hai lần hoặc đã có một biến được gọi là 'startTime',' metadata', v.v. – Thomas

Trả lời

6

Một VerifyError xảy ra khi thông báo VM, rằng một bytecode đã biên soạn là không hợp lệ. Ví dụ, khi bạn cố gắng đọc một biến dài bằng cách sử dụng lệnh tải cho một số nguyên hoặc những thứ tương tự.

Vì vậy, trong trường hợp của bạn, mã biên dịch, javaassist thực hiện phép thuật của nó, nhưng VM không chấp nhận mã. Nó phải là một lỗi trong javassist hoặc một lỗi trong việc sử dụng nó.

Làm thế nào để sửa chữa nó:

1) Theo như tôi biết, bạn chỉ có thể thêm một tuyên bố (không một dòng) vào đầu của một phương pháp sử dụng insertBefore. Nếu bạn muốn thêm nhiều hơn một, bọc chúng trong niềng răng {}, giống như method.insertBefore("{" + bBuilder.toString() + "}");

2) Bạn không thêm siêu dữ liệu như là một biến như bạn đã làm với startTime

X) Nếu đây này hay cách khác lỗi vẫn còn, cố gắng để ghi các file class vào một tập tin trên đĩa (sử dụng toClassFile bạn có thể truy cập tệp lớp đã sửa đổi dưới dạng byte[]). Sau đó, bạn có thể sử dụng các công cụ như javap để xem mã được biên dịch và xem rõ hơn những gì đang diễn ra.

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