简体   繁体   中英

groovy - javafx - Can't open new window from FXML after using WebLogic InitialContext

This is a very, very weird and specific situation. I made a minimal verifiable example:

File: Main.groovy

public class Main extends Application {


public static void main(String[] args) {
    launch(Main,args);
}


@Override
public void start(Stage primaryStage) {

    Button destroy = new Button("Break the program")
    Button openWindow= new Button("Open new Window")
    destroy.setOnAction(new EventHandler<ActionEvent>() {
        @Override public void handle(ActionEvent e) {
            Hashtable<String, String> env = new Hashtable<String, String>();
            env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
            env.put(Context.PROVIDER_URL, "[IP censored]");

            InitialContext ic = new InitialContext(env);
        }
    });
    openWindow.setOnAction(new EventHandler<ActionEvent>() {
        @Override public void handle(ActionEvent e) {
           FXMLLoader loader = new FXMLLoader();
                loader.setLocation(getClass().getClassLoader().getResource("test.fxml"))
                TestController testController =new TestController()
                loader.setController(testController)
                Parent testWindowRoot = loader.load();
                Scene scene = new Scene(testWindowRoot);


                Stage stage = new Stage()

                stage.setTitle("Test");
                stage.setScene(scene);
                stage.show();
        }
    });
    HBox hbox = new HBox(destroy,openWindow)
    StackPane root = new StackPane();
    root.setPadding(new Insets(5));
    root.getChildren().add(hbox);

    primaryStage.setTitle("JavaFX Test");
    primaryStage.setScene(new Scene(root, 300, 150));
    primaryStage.show();
}
}

File: TestController.groovy

class TestController implements Initializable {


@FXML AnchorPane mainAnchorPane
@FXML Label label



public void initialize(URL arg0, ResourceBundle arg1) {

     label.setText("test 2") //this is line 20

}


}

File: test.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane fx:id="mainAnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <Label fx:id="label" layoutX="240.0" layoutY="192.0" text="Test 1" />
   </children>
</AnchorPane>

So this is a very basic example to reproduce what happens. When I click on the Open Window button, I see a new Window with the text Test 2 because in the initialize() method of TestController there is a call to setText("Test 2") . Then when I click on "Break the Program", it creates a map and populates it with JMS info (sorry I can't give you the IP for the JMS queue) and instantiates InitialContext. After that, any click to the Open Window button crashes the program. No other window opens ever. I see the following stack trace:

 java.lang.NullPointerException: Cannot invoke method setText() on null object
 [...]
 at TestController.initialize(TestController.groovy:20)

Which of course is not true, since he never had a problem opening that window until I tried to connect to WebLogic.

Note: this only happens when I execute JavaFX from Groovy, not from Java, something that has been working for me flawlessly for months.

So, what's the deal? What is the connection between these two things? Why can't I open a FXML window after instantiating InitialContext?

Using jdk1.8.0_181

edit: I HAVE FOUND A WORKAROUND! It only fixes the symptom though. The issue was that the GUI objects were magically set to null after using WL. Well, I can just use the lookup() method to "refresh" the object reference. This is not the perfect solution obviously, but my code works now. I am still extremely curious about the true answer to this questions though.

I think this is because you create the controller like this

TestController testController =new TestController()

Use the loader

 FXMLLoader loader = new FXMLLoader(getClass().getClassLoader().getResource("test.fxml"));
 TestController testController = (TestController) loader.getController();

or

TestController testController =  loader.getController();

Just a wild guess: Maybe initializing WebLogic is messing up the class loader. Try to print out the value of getClass().getClassLoader().getResource("test.fxml") before using it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM