0

Okay so I have a bit a conundrum. I have a Qaurtz Cron that I want to use to schedule and run some Java Tests. These task are scheduled through a gui that Uses JavaFX. However, the job itself calls a run tests method. The job forces me to make certain elements static, but by making them static, I get a null pointer exception. I would really appreciate some help here.

So here is the job class that forces things to be static.

public class newJob implements Job{

    public void execute(JobExecutionContext arg0) throws JobExecutionException {
        System.out.println("We are attempting the job now");
        try {
            FXMLDocumentController.runScheduledTests();
        } catch (Throwable e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

Inside my controller I have something like this:

public static void runTests() throws SQLException, IOException {
        // Set running to true. In current form we do not use this bool,
        // however, we may
        // make changes that rely on this.
        running = true;
        FileOutputStream fos = null;
        // Verify that users exist, and there is a url with the word max in it
        int count = DBHelpers.getResults("SELECT * FROM USERS;", new String[] { "ID" }).length();

        // Verify that we have both users and a maximo url to work with.
        if ((!userList.isEmpty() || count > 0) && userMaxListChoice.length() > 5) {

            // Set the proper driver, default to chrome if none is selected
            if (IEbutton.isSelected()) {
                BrowserConfig.setDriver(Browsers.IE());
            } else {
                BrowserConfig.setDriver(Browsers.Chrome());
            }

            // Let's assign maximo. If no one has clicked the use UserList
            // button, assume that the data inside
            // maximo name is good to use
            if (userMaxListChoice != null) {
                BrowserConfig.setMaximo(userMaxListChoice);
                // System.out.println("used maxLIst choice");
            } else {
                // If the user has not selected a name from the maximo list,
                // let's grab whatever
                // they have entered in the maximoName field.
                BrowserConfig.setMaximo(maximoName.getText());
            }

            // Set the system pause based on the interval string
            int pause = Integer.parseInt(interval.getText().toString());
            // Make sure the puase is in miliseconds
            pause = pause * 1000;
            BrowserConfig.setInterval(pause);

Note that the runScheduledTests() methods does some configuring and calls the runTest method. Inside the run test method is where I'm hitting the error specifically this line:

if (IEbutton.isSelected()) {
                BrowserConfig.setDriver(Browsers.IE());
            } else {
                BrowserConfig.setDriver(Browsers.Chrome());
            }

The reason is that above I have this :

@FXML
    public static RadioButton ChromeButton;

    @FXML
    public static RadioButton IEbutton;

As I said this is a bit of an issue, If I don't make them static the job class yells at me for making a non-static reference.

How can I resolve this conflict?

Jrawr
  • 199
  • 2
  • 3
  • 15
  • Why can't you create an instance of your controller instead of using `FXMLDocumentController.runScheduledTests();` ? – ItachiUchiha Nov 24 '16 at 18:51
  • I'm not exactly sure how I would do that. Nor am I sure how that would turn out. I really only want to execute the FXMLDocumentController.runScheduledTests() method from the job anyway. The controller has other methods and logic that I don't want to execute. – Jrawr Nov 24 '16 at 18:53
  • I'm not sure if I can make the FXMLController or the Job Class a singleton. – Jrawr Nov 24 '16 at 18:55
  • From the name of `FXMLDocumentController` I am assuming that it is a controller to an FXML document. If yes, then you could just load the FXML using a [FXMLLoader](https://docs.oracle.com/javase/8/javafx/api/javafx/fxml/FXMLLoader.html) and then fetch the controller instance from it. – ItachiUchiha Nov 24 '16 at 18:55
  • @ItachiUchiha, do you have an example? I am unsure how to do that. Could you post an example of doing that as an answer? – Jrawr Nov 24 '16 at 18:56
  • Sure, but before I do that, can you add a snippet of the FXML that has the `fx:controller` defined in it in the question? – ItachiUchiha Nov 24 '16 at 19:01
  • Just a moment. I will do that. – Jrawr Nov 24 '16 at 19:06

2 Answers2

1

TL;DR : You shouldn't use static on the fields annotated with @FXML.

For more information go through - javafx 8 compatibility issues - FXML static fields

You could load the FXML by using the FXMLLoader and then get an instance of the controller from it. By doing this, you can convert the method runScheduledTests() into a non-static method.

public class newJob implements Job{

    public void execute(JobExecutionContext arg0) throws JobExecutionException {
        try {
            FXMLLoader fxmlLoader = 
                        new FXMLLoader(getClass().getResource("path-to-fxml.fxml"));
            fxmlLoader.load();
            FXMLDocumentController fxmlDocumentController = 
                        (FXMLDocumentController)fxmlLoader.getController();
            fxmlDocumentController.runScheduledTests(); // convert the method to non-static
        } catch (Throwable e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
Community
  • 1
  • 1
ItachiUchiha
  • 36,135
  • 10
  • 122
  • 176
  • I tried this and got an the follow error: org.quartz.ObjectAlreadyExistsException: Unable to store Job : 'nextJob.cronJob', because one already exists with this identification – Jrawr Nov 24 '16 at 20:12
  • I managed to get it two work, but I did have to edit my initialize method to make handle two different calls to initialize since the second call caused some variables to change. – Jrawr Nov 28 '16 at 17:26
0

The problem is you are trying to use static when the controller itself is not static. Take into consideration I recommend taking a look at the difference between static and non-static here. In regards to fixing your code. First make your buttons ChromeButton and IEbutton not static. Then when your application class, something like this:

public class HelloWorld extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        //pass a reference of your stage to job.
    }
}

Then Pass a reference of your buttons or controller into the Job class as a variable. Like this:

public class newJob implements Job{

  private RadioButton chrome;
  private RadioButton ie;

  public newJob(RadioButton chrome, RadioButton ie) {
    this.chrome = chrome;
    this.ie = ie;
  }

    public void execute(JobExecutionContext arg0) throws JobExecutionException {
        System.out.println("We are attempting the job now");
        try {
            FXMLDocumentController.runScheduledTests();
        } catch (Throwable e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

The core of your problem is controller variables CANNOT be static as the controller is dependent on instantiating the class and passing the required information in. The best way to fix this is by passing a reference either to the buttons or the class by using variables in the constructor. Please read the link I sent you to get a better understanding between static and non-static. Also, if you are confused about constructors take a look here as well.

  • could you edit this and show what an example of passing a reference of the stage could look like. I've only been using JavaFX for like 2 weeks. This is still kind of new to me. Otherwise I think this might work. – Jrawr Nov 24 '16 at 19:05
  • Do you have a github for your code? Or could you [gist](https://gist.github.com) your relevant code? – Brandon Barker Nov 24 '16 at 19:09
  • The files are pretty large. the FXMLController is something like 1200 lines. What information would you need to so I can make sure to just share the important stuff and save you time. – Jrawr Nov 24 '16 at 19:12
  • its fine. gist it all. – Brandon Barker Nov 24 '16 at 19:15
  • Here is the gist [link](https://gist.github.com/anonymous/28bb034dc1b0d5a4a0cf987cf7688944) – Jrawr Nov 24 '16 at 20:09
  • It does not. I tried the other solution posted with no luck. – Jrawr Nov 25 '16 at 16:10