Featured Post

Applying Email Validation to a JavaFX TextField Using Binding

This example uses the same controller as in a previous post but adds a use case to support email validation.  A Commons Validator object is ...

Sunday, February 15, 2015

Dynamic FX Application Modules - Part 4 - Bootstrap

This is the fourth part of a six part series on dynamic Java FX application modules.  This post describes a bootstrap mode whereby the application can come up to module-less state.  Although missing the essential functionality provided by modules, it verifies that the initialization of common data, security, and personalization services can work in a performant and reliable manner.




Startup Parameters

This post describes how a standalone main() can be used to start the FX application.  Alternatively, the app can be started from JNLP.  I'm looking for the presence of a "bootstrap=true" argument to determine whether or not to start up in bootstrap mode.  I'm using the lowest common denominator of raw arguments to provide a switch that will work for both standalone and JNLP deployments.

The Main class used in this demo app is presented in its entirety.

public class MultiStageMain extends Application {

    private Logger logger = LoggerFactory.getLogger(MultiStageMain.class);

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

    @Override    public void start(Stage primaryStage) throws Exception {

        if( logger.isInfoEnabled() ) {
            logger.info("Starting application");
        }

        FXMLLoader loader = new FXMLLoader();
        loader.setLocation( MultiStageMain.class.getResource("app_core/homeScreen.fxml") );
        Parent p = loader.load();

        HomeScreenController c = (HomeScreenController)loader.getController();

        Application.Parameters parameters = getParameters();
        if( parameters.getRaw().contains("bootstrap=true") ) {
            if( logger.isDebugEnabled() ) {
                logger.debug("[START] running in bootstrap mode");
            }
        } else {
            if( logger.isDebugEnabled() ) {
                logger.debug("[START] running in full mode");
            }
            c.initializeSubApps();
        }

        Scene scene = new Scene( p );
        primaryStage.setTitle( "Core" );
        primaryStage.setScene( scene );
        primaryStage.show();

    }
}

For the lowest common denominator approach, I'm scanning the raw parameters for "bootstrap=true" as in "> java.exe MultiStageMain bootstrap=true.

Note that this is all plain FX code except for the initializeSubApps() call.  Even though HomeScreenController is responsible for the SubApps, I can't change the initialize() method behavior with a bootstrapMode flag.  I have to wait until the Controller object is created after the load() call to apply a second stage of initialization.

Here is a class diagram showing the classes that are involved in bootstrap mode.


Bootstrapped Classes
MultiStageMain creates the HomeScreenController object through FXMLLoader.  The FXMLLoader process creates the main Injector which creates the CoreModule.  The child Injectors described in Part 2 of this series are not created.  So, this is a great way to see how CoreModule behaves and performs.  Although it contains a single small ServiceObject class now, it would likely contain many such classes as it is the way in which the application can provide shared resources.

As expected, here's what the application looks like when started in bootstrap mode.

The App in Bootstrap Mode without SubApp Buttons

When you're adding new features, bootstrap mode is a great way to continually verify that the platform is stable.  On an app following this design, you'll both add new features using the dynamic module design and also add common services to cut down on repeated initialization, RAM, and redundancy.  If you wake up one morning and find the app running slowly, starting it up in bootstrap mode can quickly determine if the problem is with a newly-added module or the platform itself.

Click Dynamic FX Application Modules - Part 5 - Common Services and Views for the next part of the series.


No comments:

Post a Comment