days
0
4
hours
1
1
minutes
1
1
seconds
5
6
search
Operating and Experimental use of JavaFX in the Energy Economy

A fresh breeze by Enterprise JavaFX

Andreas Liebelt
Corn field with a windmill image via Shutterstock

Currently consolidation appears in some parts of the energy system transformation in Germany, but even with the expansion and restructuring of the energy system there is still great progress to be determined . One innovation focus currently lies on the more efficient use of the well over a million wind, solar and biomass power plants that have already been built. For this purpose, fresh, new and innovative solutions are needed, and this in an industry that has to be based primarily on established and proven technologies. JavaFX can act as a bridge here. But is it actually possible to create innovative software products with JavaFX that provide the necessary reliability? A water-level and experience report from applied research.

One year and a half has passed since I wrote my last article about JavaFX for the Java Magazin -during this period, the UI framework evolved. Back then, JavaFX had just appeared in version 8, but several updates have since been released and JavaFX is currently (as I am writing this article) available in Version 8u66. JavaFX and many libraries that are JavaFX-based have progressed. ControlsFX should also be mentioned here because from our point of view its layout containers and controls are nearly indispensable additions to JavaFX.

Figure 1 : Power plant cluster view of the control room of the Virtual Combined Power Plant IWES.vpp of Fraunhofer IWES

Figure 1 : Power plant cluster view of the control room of the Virtual Combined Power Plant IWES.vpp of Fraunhofer IWES

Our software has evolved considerably also. It has benefitted countless times from the development of JavaFX, identified shortcomings and sometimes encountered real obstacles. This raises a pertinent question: Can JavaFX be used in enterprise applications? Is it suitable for such an environment? I want to describe this from the perspective of our software “Virtual Combined Power Plant” IWES.vpp (see Figure 1), offer one or two helpful tips from our personal experience and also give a heads up about pitfalls. Below you can learn more about that…

What are virtual combined power plants?

Energy generators based on renewable sources typically have a small power production in contrast with the existing large power stations – and each fluctuates. The advantages of virtual combined power plants (see Figure 2) are on the one hand that the many small producers can reach a large total generation capacity through the virtual interconnection. On the other hand, a kind of passive generation curve smoothing arises (fluctuations balance each other) by using different types of plants (wind, solar, etc.), which are also placed in different locations. Thanks to the energy management of a virtual combined power plant, an active smoothing of the generation curve can be realized by derating or increasing the power of plants, as well as by buffering and retrieving energy into or from storage. In the best-case scenario, the power production can be controlled by the energy management in a way that a required consumption curve is completely fulfilled. Virtual combined power plants are therefore often considered the central tool for the energy system transformation.

Figure 2 : Component diagram of the virtual combined power plant

Figure 2 : Component diagram of the virtual combined power plant

The control of a virtual combined power plant is no different than the one which occurs in a conventional power plant using a control room. In the conventional variant’s control rooms, there is often a variety of analog measurement and control devices, whereas control rooms of virtual combined power plants completely have completely abandoned them and just need computers and monitors. The purpose of the control room has not been changed: The power plant is expected to behave within defined parameters. These parameters depend on the purpose which can be on the one hand profitable marketing at an electricity exchange (in the case of electricity traders), on the other hand to guarantee a stable operation of the electricity network (in the case of grid operators). The objective of the control room is to offer the operator the right and relevant information so that he may decide to intervene in the operation of the virtual combined power plant. This intervention must also be done by using the control room while ensuring that interventions have the desired effect and that incorrect entries are prevented.

When designing a control room software, a special requirement must be considered: the continuous operation stability. The expectation is that a software which should be used in the control room context can ensure a faultless 24/7 operation. Even after weeks, months and actually years, the UI has to work smoothly and without problems. Even if errors occur (e.g. unexpected exceptions), which naturally cannot always be prevented, these may not interfere with the proper operation of the control room. In order to respond to these possible errors, special architectural and algorithmic safety measures should be applied (see “avoid problems”). Since this topic is very extensive, it is not possible to go into more detail here.

General software architecture

For the realization of the control system for our virtual combined power plant IWES.vpp, we use a three-tier architecture. The client is conceived as a rich client based on JavaFX 8 and represents the control room of the virtual combined power plant. The client communicates with the server via a RESTful interface. The exchange data model only makes use of different profiles of IEC CIM 61970, 61968 and 62325 The Common Information Model (CIM) of the International Electrotechnical Commission (IEC) is a data model developed by the energy economy for modeling energy systems. The server processes all inputs which are made using the control room and takes appropriate actions (e.g. gear down a biogas plant).

The search for a suitable architecture for our control room user interface was a time-consuming process because we wanted to find an optimal solution for our demanding challenges. In order to increase the maintainability, performance and stability, as well as to facilitate the joint development of the user interface, we developed different approaches. In the end, we chose afterburner.fx and videos of Adam Bien on JavaFX. The result  is based on the MVP pattern and satisfies our expectations.

The UI architecture in detail

The architecture of the control room (see Figure 3) basically consists of strictly separated graphical modules based on the afterburner.fx framework. The graphical modules are created and assembled at runtime only when needed. Each graphical module is based on the Model-View-Presenter (MVP) “Passive View” design pattern and consists of at least five parts. One part is the view (View), which results from the combination of a CSS stylesheet a FXML file and the resource bundle with the currently selected language and the presenter (presenter), which also has access to the resource bundle and uses repositories (DDD: Domain-driven design) to gain access to the data model. The entire graphical module is based on a file naming convention (CoC: Convention over Configuration) and is assembled by afterburner.fx. Optionally, each graphical module can contain further resources (e.g. images, special helper and working classes, etc.).

Shared resources such as images, CSS or ResourceBundles are most of the times omitted. While this sometimes results in the duplication of resources, every graphical module is usually fully defined by all the resources in its package. Unintentional or unanticipated interactions between the modules are practically excluded this way. The parallel development of a complex user interface is therefore significantly facilitated.

If it makes sense, we deviate from this paradigm. For example, for graphical components which always look the same, we use common CSS style sheets (e.g. Button, ComboBox, CheckBox, etc.). This would not be possible without 8u20 because in this version the @Import reference is processed in stylesheets. Of course we source out presenters’ common code to abstract implementations. Text blocks with translations that do not change regardless of the context (e.g. OK, Cancel, Select one … etc) are provided by a TranslationRepo (see below: repositories).

Figure 3 : Software architecture of the control room of the virtual combined power plant

Figure 3 : Software architecture of the control room of the virtual combined power plant

Here is an example of the inner functionality of a graphic module: The getView () method gives a prospect (the application or another graphic module) a graphical module inherited from the parent class FXMLView (part of the afterburner.fx framework). The prospect interacts with the graphic module exclusively via the API of the presenter. The API is also invoked by the view (JavaFX) via Inversion of Control (IoC). The presenter interacts with the view through view objects (e.g. ComboBox, ListView, etc.), which are injected (DI: Dependency Injection) into the presenter by JavaFX based on the @FXML annotation and the fx:id attribute name mapping.

The data exchange of the graphic modules usually takes place via repositories. For the fundamental principle, we got our inspiration from DataFX’s DataProviders and through the API of the presenter. Listing 1 shows an example of a graphic module’s presenter for displaying the power plants with the ability to select a power plant using a repository or a setter. afterburner.fx injects the PowerPlantRepo as singleton while the repositories access various data sources. This may be a local file or the RESTful interface for example.

The energy management server has been based on JDK 8 since the autumn of 2014, as important frameworks we use are now compatible with JDK 8 (e.g. Spring and Apache Camel). In order to guarantee the highest possible compatibility with our wide (and in some cases, very long-life) software solution portfolio, our data access objects (DAOs) of the control room are solely based on mechanisms that are available in JDK 6. This makes them usable in all of our software solutions, including for example in their integration tests. The data access objects are JDK 6 Observables, which publish the attributes known from JavaFX concurrency (such as message, progress, etc.). To use this from JavaFX comfortably and asynchronously, we use the data access objects with JavaFX Service and Task, and our Task implementation works as Observer and translates the observable attributes of the data access objects into the JavaFX properties.

public class PowerPlantsPresenter implements Initializable {

  // JavaFX-controls (injected by JavaFX)
  @FXML ListView<PowerPlant> listViewPowerPlants;
  @FXML Label labelSelectedPowerPlant;

  // Repositories (injected by afterburner.fx)
  @Inject PowerPlantsRepo powerPlantsRepo; 

  @Override
  public void initialize(URL location, ResourceBundle resources) {
    listViewPowerPlants.setItems(powerPlantsRepo.getData());
    powerPlantsRepo.selectedElement().addListener((powerPlantProperty, oldPowerPlant, newPowerPlant) -> {
        setSelectedPowerPlant(newPowerPlant));
    }
  }

  public void setSelectedPowerPlant(PowerPlant powerPlant) {
    labelSelectedPowerPlant.setText(powerPlant.getName());
  }
}

Optimize mechanisms

The more extensive an application is, the more essential it is to relieve the JavaFX application thread (FX-thread), to use it less frequently or as brief as possible. Otherwise slight operation delays, unsightly “stuttering” or even temporarily freezing will certainly occur. For our purpose, the selected options presented below have been very beneficial.

Parallelization: A good and simple way to carry out operations more quickly overall under appropriate circumstances[1] is the parallelization of list accesses by the streams of Java 8. A further possibility is to process more complex portions of code in additional threads (e.g. JavaFX Service and Task). The FX-thread is thereby relieved. However, this is only useful or possible if the scene graph is not modified within the additional threads, therefore limiting the possible applications. A third option is the asynchronous loading of graphic modules, which is possible with afterburner.fx 1.6.0. This also relieves the FX-thread.

Reactivity: Another way to improve performance is the “targeted non-run” of code. First, background processes can be disabled, which has no effect on the visible user interface content. Therefore, you must implement the visibility detection yourself. However, you can define the maximum repetition rate of execution for certain mechanisms. For example, a value should not be recalculated more than once every 5 seconds, even if the input values are updated in the millisecond range. ReactFX provides an appropriate API for this.

Avoid problems

In order to avoid an unwanted application behavior, you should know that there are limitations in JavaFX. For example, in the case of lambda expressions, they are design-related. In other cases, they occur due to unresolved problems in JavaFX. The following cases were particularly important for our control room because they may interfere with or prevent the proper 24/7 operation.

The lambda expressions significantly shorten and simplify the code, but there is one thing that deserves your attention. When they are used as a substitute for InvalidationListener, ChangeListener or similar to react on the change of observables, this action cannot be undone due to operation of the lambda expressions itself: There is no compile time object reference to the listener, which could be deregistered from the observable. An instance of each listener interface is woven around the code in the lambda expression only at runtime. Lambda-based listeners are always infinite listeners. If listeners should stop their work sometime, they must be built like before as a referenceable object in order to be able to explicitly deregister them later.

An important aspect for the stability of an application is the handling of RuntimeExceptions. JavaFX solves this nicely. Still, there are special cases in which you have to be active yourself to prevent a malfunction, a hang or even a crash of the application. The exception works incorrectly in Run-timeExceptions in the methods setCellFactory (TableView, ListView and ComboBox) and setCellValueFactory (Ta-bleView). If such an exception occurs, nearly all controls stop their work almost completely. This problem is expected to be resolved only with JavaFX 9 (see JDK 8090078 and JDK-8087792). For now, it’s still recommended to use a security pattern to prevent problems of this type (see Listing 2).

listView.setCellFactory(listView -> {
  return new ListCell<String>() {
    @Override
    protected void updateItem(String item, boolean empty) {
      // Safety Pattern (try-catch-Throwable)
      try {
        // Your Code:
        // Update Item
      } catch (Throwable t) {
        // React on Exception
      }
    }
  };
});

tableColumn.setCellValueFactory(value -> {
  // Safety Pattern (try-catch-Throwable)
  try {
    // Your Code:
    // Return Observable Value
  } catch (Throwable t) {
    // React on Exception
  }
});

Front-end tests

Testing user interfaces is a challenge. At best, this is of course automated and with high test coverage. Due to the lack of appropriate frameworks, we had to apply manual testing of the control room during operation. Within the context of research projects, this approach is still feasible. However, the increasing range of functions and the productive use of the control room has made automated testing indispensable.

In the first step, we introduced executable visual tests: There were test cases set up for graphical components, each of them able to run as a standalone application. The necessary data is provided via repositories, which are prepared for the various test cases with the Mockito framework and injected into the tested graphic module using afterburner.fx. However, what changed is that the developer was the one who evaluated the test case based on a visual inspection of the application. This approach reaches its limits quickly due to the increasing number of different tests.

Fortunately, a version of TestFX was published in 2013, which was seamlessly integrated into our test ecosystem of Eclipse, JUnit and Jenkins. Running graphical unit tests is now possible directly from the IDE and is automatically triggered by Jenkins at each Subversion commit. For these tests, we use the root nodes of the manual tests described above. We extended the class GuiTest from TestFX, which enabled a screenshot comparison: to realize this, we captured the screen based on the coordinates of the stage produced by TestFX and compared the result with a stored reference image. For comparison, a limit of the allowed deviation can be adjusted.

Currently there are bottlenecks in the infrastructure when running tests with Jenkins because a computer (Jenkins slave) is required for the front-end tests. More than one test cannot be performed simultaneously per computer because otherwise there might be interferences of window appearance, mouse and keyboard inputs between the tests. Therefore, the front-end tests can be run on one computer and only serially. A parallelization can only be realized through the installation of new computers, including screens, which generates additional costs and requires space. Encapsulation of visualization is possible with “Monocle” but an appropriate solution for the mouse and keyboard interaction should be developed and brought together with Monocle in a testing framework (e.g. TestFX).

Front-end delivery

All our products (including the control room) support the build process of Maven in version 3. In the build process configured by the pom.xml, we use the javafx-maven-plugin in combination with Inno Setup to create a Windows Installer. We almost exclusively deliver self-contained applications (with included JRE), so that our customers don’t need to install Java. Plus, delivering an installation file instead of letting the customers click through Java Web Start dialogues is what should be done in this case.

There is still one big drawback: you can only create an installer for the operating system on which the build process is performed (e.g. Windows / see JDK-8091902). In addition, only that bit version of the installer can be built by a JDK which matches the bit architecture of the JDK (for example, only 32 bit installer with 32 bit JDK / see JDK-8091056). Running the Maven release with a 32-bit JDK means that only a 32-bit installer can be created; running it with a 64-bit JDK only a 64-bit installer can be designed. If you want to deliver an installer for both bit versions, you must release it once withJDK and after that with the other. This way you receive two installers with different application versions.

JavaFX reliability and other little problems

But what is the state of the reliability of JavaFX in general? I want to use a few examples to explain this: It is not possible to migrate from 8u51 8u60 which has (again) to do with a previously functional component that no longer functions correctly after an update (regression). In our case, it relates to the LineChart component which is crucial for our application (see Figure 1). All axes, lines and auxiliary lines have been blurry since 8u60, which is why we cannot use this release. This is not the first time when he were forced to skip an update or write a workaround for a regression in JavaFX.

Another point of criticism that I did not want to leave unmentioned is the tacit introducing (through OpenJDK developers) of wanted changes (“It’s not a bug it’s a feature”). For example, the behavior of buttons changed with 8u20. If you use the Enter key in a window, the default button is always triggered, even if another button is focused. Therefore, you will be (at least as a Windows user) surprised by the following behavior: if one focuses on the Cancel button in a confirmation dialog with the keyboard and presses Enter, the OK button is triggered anyway. That can be very dangerous! There is no (easy) way to get around this. With JDK-8136599, what should be done is to look for a way to make the described behavior adaptable. More detailed release notes for JavaFX would increase the transparency for the developer’s perspective in a meaningful way.

It occasionally happens that you want to implement allegedly simple things with JavaFX components and thereby note that the intention is very complex to implement, or even not at all. Therefore we wanted, for example, to make ListViews with CheckBoxListCells be operated by the keyboard (arrow keys up / down, Spacebar change the selection of the just focused cell): we had to write almost 100 rather cumbersome lines of code to teach the ListViews. On the other hand, the simple hide and show of individual rows and columns is basically impossible with the GridPane.

Conclusion

I wanted to comment on the question regarding the possibility to create innovative software products while obtaining the necessary reliability for enterprise applications:

I would limit my answer to YES.

The mentioned weaknesses are often not so severe that a serious impairment of the development process would be determined. And if you know the current weaknesses, you can usually handle it well. If you look at the development on a larger timeline, it can be stated that in the past year the level of maturity has increased significantly. Many problems have been fixed and new problems have rarely emerged.

While innovative software is highly dependent on the underlying idea, a nice and fast implementation through the used framework plays an important role, I believe. JavaFX has a lot to offer here even if suitable layout containers or controls are not available for all requirements. The current JavaFX version together with the mentioned libraries provide a very broad base of components, with which one can realize a lot of different use cases. But if one wants to exhaust the technology, one should not back off from using the JDK issue tracker. The support of relevant frameworks such as ControlsFX is an advantage.

I am extremely optimistic that the JavaFX ecosystem will continue to grow and mature and will soon be universally appropriate for enterprise application.

Links & Literature:

[1] Java Magazin 10.2015 „Java 8: Stream Performance“

Author
Andreas Liebelt
Andreas Liebelt is OpenJFX-author and works as a scientist at the Fraunhofer Institute for Wind Energy and Energy System Technology IWES at the institute part Energy System Technology in Kassel. He is in charge of the development of energy economy JavaFX applications. Contact: andreas.liebelt@iwes.fraunhofer.de

Comments
comments powered by Disqus