Kể từ khi cập nhật 9-u175, java cho phép truy cập trái phép theo mặc định, cho phép tất cả các thủ thuật phản chiếu cũ. Hoạt động tốt, ngoại trừ khi nói đến các lớp trong control.skin (có thể những người khác nữa, không kiểm tra) - để tái sản xuất, chạy ví dụ bên dưới, nhấp vào nút và xem cách truy cập thành công cho đến khi dòng cố truy cập riêng tư trong trường ButtonSkin. Stacktrace:Phản chiếu sâu không thành công trong các lớp xxSkin
Exception in thread "JavaFX Application Thread" java.lang.reflect.InaccessibleObjectException:
Unable to make field private final com.sun.javafx.scene.control.behavior.BehaviorBase javafx.scene.control.skin.ButtonSkin.behavior accessible:
module javafx.controls does not "opens javafx.scene.control.skin" to unnamed module @537fb2
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:337)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:281)
at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:176)
at java.base/java.lang.reflect.Field.setAccessible(Field.java:170)
My bối cảnh: jdk9-u175, nhật thực-oxy-R với bản vá cho java9, các quy tắc truy cập trong dự án được thiết lập để cho phép JavaFX/**
Câu hỏi đặt ra là: ai là thủ phạm? FX, Eclipse, ea hoặc ..?
Ví dụ:
import java.lang.reflect.Field;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.SkinBase;
import javafx.scene.control.skin.ButtonSkin;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import com.sun.javafx.scene.control.LambdaMultiplePropertyChangeListenerHandler;
public class AccessFieldFX extends Application {
private Parent getContent() {
Button button = new Button("something to click on");
// okay
Object def = invokeGetFieldValue(Button.class, button, "defaultButton");
button.setOnAction(e -> {
ButtonSkin skin = (ButtonSkin) button.getSkin();
// okay
LambdaMultiplePropertyChangeListenerHandler cl =
(LambdaMultiplePropertyChangeListenerHandler) invokeGetFieldValue(SkinBase.class, skin, "lambdaChangeListenerHandler");
// okay
Object clField = invokeGetFieldValue(LambdaMultiplePropertyChangeListenerHandler.class, cl, "EMPTY_CONSUMER");
// failure
Object beh = invokeGetFieldValue(ButtonSkin.class, skin, "behavior");
});
BorderPane pane = new BorderPane(button);
return pane;
}
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setScene(new Scene(getContent(), 600, 400));
// primaryStage.setTitle(FXUtils.version());
primaryStage.show();
}
public static Object invokeGetFieldValue(Class declaringClass, Object target, String name) {
try {
Field field = declaringClass.getDeclaredField(name);
field.setAccessible(true);
return field.get(target);
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
launch(args);
}
@SuppressWarnings("unused")
private static final Logger LOG = Logger
.getLogger(AccessFieldFX.class.getName());
}
Tôi đã sao chép lỗi trên 9 + 178. Thật vậy, lỗi rất lạ! – ZhekaKozlov