2012-12-28 26 views
9

java.lang.IllegalAccessError: tried to access field ConcreteEntity.instance from class Entityjava.lang.IllegalAccessError: cố truy cập trường ConcreteEntity.instance từ lớp Entity

Ok đây là giao dịch. Tôi đang cố gắng truy cập ConcreteEntity.instance là trường có mặc định kiểu truy cập tồn tại bên trong mặc định ClassLoaderEntity.getInstance là một phương thức tồn tại trong một trẻ ClassLoader.

Bây giờ, hãy nhớ rằng cả hai đều trong cùng một gói, tuy nhiên, IllegalAccessError đang bị ném. Có một giải pháp cho vấn đề này mà không liên quan đến tôi thực sự tải lớp thực thể trong cùng một ClassLoaderConcreteEntity?

0 new #14 <Entity> 
3 dup 
4 aload_0 
5 invokevirtual #18 <Adapter.getInstance> 
8 checkcast #20 <sl> 
11 getfield #24 <sl.d> 
14 invokespecial #25 <Entity.<init>> 
17 areturn 

Bytecode được truy xuất thông qua jclasslib at là ngoại lệ được tạo "Sau khi được biên dịch".

Cảm ơn bạn Gamb đã dọn dẹp bài đăng.

+0

Bạn có thay đổi lớp học của bạn trong thời gian chạy sử dụng một số loại trình biên dịch bytecode? –

+0

Có tôi. Nhưng bytecode được chế tác là hoàn hảo. – Justin

+0

Bạn đang cố gắng truy cập một trường con trong lớp cha? Tôi nghĩ đó là điều không được phép. –

Trả lời

27

Xem my answer-a similar question, ngoại trừ trong trường hợp của bạn rõ ràng là bạn đang đối phó với nhiều classloaders:

JVM coi lớp được nạp từ classloaders khác nhau để được "gói runtime" khác nhau, ngay cả khi họ có cùng tên gói. Trích dẫn từ the jvm spceification, phần 5.3:

At run time, a class or interface is determined not by its name alone, but by a pair: its fully qualified name and its defining class loader. Each such class or interface belongs to a single runtime package. The runtime package of a class or interface is determined by the package name and defining class loader of the class or interface.

Và trong phần 5.4.4:

A field or method R is accessible to a class or interface D if and only if any of the following conditions is true:

...

R is either protected or package private (that is, neither public nor protected nor private), and is declared by a class in the same runtime package as D.

+0

Thực sự rất thú vị. Vì vậy, biết của bất kỳ công việc xung quanh khỏi đỉnh đầu của bạn? Nếu tôi không phải là A) cần thay đổi triển khai của tôi "Đáng buồn mang nó vào một trình nạp lớp đơn" hoặc B) thực hiện một số nghiên cứu khác trong tải lớp JVMSpec – Justin

+0

Bạn có thể đặt trường ở chế độ công khai, nếu 'Entity' là một lớp con của' ConcreteEntity' sau đó được bảo vệ cũng sẽ hoạt động.Tôi không nghĩ rằng có một cách giải quyết vì khái niệm về các gói thời gian chạy là vì lý do bảo mật. –

+0

Tôi đánh giá cao câu trả lời của bạn. Nó làm sáng tỏ những gì đang xảy ra. Nó đã được đánh dấu là được chấp nhận. – Justin

1

Javadoc: Thông thường, lỗi này được trình biên dịch bắt; lỗi này chỉ có thể xảy ra tại thời gian chạy nếu định nghĩa của một lớp đã thay đổi không tương thích.

Khi tôi nghĩ rằng một số thao tác lớp khó khăn đã được thử, có thể đang tải lớp, hãy đầu tư một thời gian vào cách cả hai lớp được tải. (Trong trường hợp hiếm hoi, một serialVersionId rõ ràng có thể giúp ích.)

Nếu các lớp có liên quan (siêu/phân lớp), sau đó cố gắng loại bỏ quan hệ đó bằng giao diện. Có thể sử dụng tiêm. Đó không phải là tham chiếu/tải một lớp hai lần.

Xin lỗi một câu trả lời cụ thể mà tôi không thể đưa ra.

+0

Vâng, đó là vấn đề với kỹ thuật cấp thấp mà tôi cho là vậy. Nhưng nếu tôi không nhầm thì sẽ không có vấn đề gì khi tham chiếu đến trường này trong các tình huống bình thường? Đáng buồn là tôi có thể phải tìm một con đường khác với cách thức obfuscator của tôi hoạt động bên trong một môi trường thử nghiệm. – Justin

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