domingo, 22 de outubro de 2017

How can cause leaks

If you didn't know this, now you know: calling can cause leaks. This is described by  Yan in his is evil post.

You may think that you develop applications that won't create too much files and does not runs for many hours, but in an application server running for days this may be a real problem.

In this post I just wanted to share how it can quickly grow your heap memory when dealing a lot of files. See the code below:

Notice that the code deletes the reference to the created file object (nullify it) so it can be collected by the garbage collector. At some point the program will explodes with OutOfMemory error probably due the high amount of String created (when running with small heap).

If you increase the heap and use some tool to get a heap dump of your running application you will see memory content on the *static* Linked used in DeleteOnExitHook class. We can do this in runtime by using jvisualvm (a tool that comes with JDK 1.8). This is the first screenshot I took:

After a few hours the memory occupied by LikedHashMap is 30% of all the memory used by the JVM

This memory will only be released after a JVM restart!

If you are scared about the chars[] and String size growing as well, don't worry, this got improved in JDK 9, however, the issue we are discussing here may still happen with Java 9! See below, after @lasombra_br suggestion I was able to get a Java 9 heap dump using jconsole and as you can see the memory use for Strings are now smaller due the use of byte[] instead using char[] and the LikedHashMap (caused by the deleteOnExit call) quickly pass the memory use by Strings:

In another words, avoid calling method!

quarta-feira, 18 de outubro de 2017

JavaFX with Bean Validation and CDI 2.0

When JavaFX 2 was released I remember people looking for frameworks that would make easy to integrate JavaFX with a validation framework, a dependency injection container and other enterprise services. Currently we can integrate CDI 2.0 and Bean Validation 2.0 with a JavaFX application without the need of any external framework. In this post I will show you how to validate your javaFX screen fields using bean validation in a CDI managed application.

Before talking about all these things and JavaFX I recommend you to check the following posts from this blog:

Validating JavaFX controls using Bean Validation

With Bean Validation 2.0 we have the automatic unwrap of JavaFX properties. Which means that if you have a field that is of type of ObservableValue so the validator implementation will be able to retrieve the actual value to perform the validation. However, JavaFX control fields are still not supported, so if you try something like the code below you will have an exception when running the validator against your JavaFX controller:  

This happens because the validator implementation doesn't know how to retrieve values from a JavaFX controller. What we need to do is create a class that implements javax.validation.valueextraction.ValueExtractor. We must use the control type in this class and implement a method that will do the actual value extraction and use the annotation javax.validation.valueextraction.ExtractedValue to set the value type that will be extracted (String, Integer, LocalDate...). To avoid additional steps we use the annotation javax.validation.valueextraction.UnwrapByDefault on our implementation. This is what ValueExtractor for TextField and for DatePicker looks like:

Value Extractor for DatePicket

Value Extractor for TextField

Finally we must register it in within the bean validation framework. There are a couple of ways of doing it, we chose the SPI way, which is create a file named META-INF/services/javax.validation.valueextraction.ValueExtractor with the class name of our ValueExtractors:

Content of file META-INF/services/javax.validation.valueextraction.ValueExtractor

We could have a bean validation extension for JavaFX that should include all the extractors possible for the JavaFX controls. Let me know ff you are doing something like that and I can mention it here!

Showing validation errors to users

You will probably want to show users messages when the value they entered for the fields are not valid. Once you have access to the Validator class in your controller you can simply call validate against your controller itself and set labels values in the view to show users messages. I personally don't like this approach because I think it is intrusive. An easy solution is displaying a tooltip and to do so we must have access to the control which value is invalid. The following code did this in our test application:

Method showValidationErrors gets the control that has an invalid value and set a tooltip for it

To show the tooltip we must have access to the control itself, and to do this we have to make some reflection, hence the field representing the control should be public or make get methods to access it

CDI, Bean Validation and JavaFX

There's nothing to add about CDI from what I have mentioned in Using CDI 2.0 in a JavaFX application post. I just wanted to share that the Hibernate Validator CDI API worked on a JavaFX application and due this I can simply inject the validator on my controller class! A single dependency will make that possible: org.hibernate.validator:hibernate-validator-cdi. See below the application files:

Our maven project and its files

And these are the dependencies I added to pom.xml:

These are all dependencies required to use bean validation and CDI on a JavaFX application

Code of a sample application can be found in github. Below you can see a quick video I made just to show what the validation with tooltips looks like:

Why this is important

Being able to integrate with Java EE (or should I say EE4J already?) is a key feature for users who want to build real world applications with JavaFX, it will bring persistence, validation, injection and more. The main question that remains here is: will it work on a Android application that uses Gluon/ JavaFX Ports?

For more Bean Validation specific examples you may check this Hendrik Ebbers pull request to hibernate validator project.

segunda-feira, 16 de outubro de 2017

Testing Bean Validation 2.0

Bean Validation 2.0 is among all the new Java EE 8 good new features:

In this post I will share a sample application I used to see in action the following Bean Validation 2.0 features:

  •  List items validation
  • Temporal validation using Java 8

Project setup

Hibernate Validator is the RI for Bean Validation 2.0 and the project, being a maven or gradle project, must use the following dependencies (or later versions): org.hibernate:hibernate-validator:6.0.2.Final and you should also add org.glassfish:javax.el:3.0.1-X as a hibernate validator dependency, where X is the build, check the maven repository for more. This is what my pom.xml looks like:

Using bean validation annotations in a bean fields

To test the new annotations I used the following bean:

Notice the new annotations in subscribers and in manufactureDate and expirationDate fields:

  • subscribers: I am validating users emails, all the Strings added to this list should be an email. To do this a simple @Email annotation solved the problem;
  • manufactureDate: The validation is to make sure that the manufactureDate is a past date and to do so a single @Past annotation will make sure that this is correctly validated;
  • expirationDate: The product should expire in future and the @Future annotation solves everything.

Finally I can test this in a main class, see:

When running this only p4 will be valid:

The code is in my github. Feel free to clone it and make more tests on top of this project.

terça-feira, 10 de outubro de 2017

Using CDI 2.0 in a JavaFX application

With the CDI 2.0 release we have a container that can be used in Java SE applications! Previously if you wanted to make use of CDI 1.x in a Java SE application you had to use Weld classes, see FXML & JavaFX—Fueled by CDI & JBoss Weld post.

Adam Bien introduced the SE container in a video, see:

Of course I had to try it with JavaFX so I can use CDI in some personal applications!

Create the Container in a JavaFX Application

By JavaFX application I mean the class that extends javafx.application.Application, which is the entry point for JavaFX apps and where the main stage can be used. To use CDI we should create the SeContainer and make sure that it create all classes managed by CDI. This should be done in the entry point Application class so we manage all the classes created from there.

Once you started the container you have different ways to send the initial stage to the actual Application class, for example, you can have users to implement an interface and then use the CDI container to select a bean that implements the interface, for example:

There's a more elegant way which is by using CDI Observer API. In this case we may create an annotation that will be the qualifier for the event javafx.stage.Stage. CDI will wisely know all classes that observes that event and will select the user classes when we fire it by sending the primary stage. This is similar to what was done in FXML & JavaFX—Fueled by CDI & JBoss Weld post:

Whatever approach you chose, just make sure to not shutdown the container or it may bring inconsistencies (actually I think it will work in most of the cases, but I decided to not shutdown it).

Ok, now you can use CDI in your application! Go ahead and inject stuff in your class. Unless of course if you are using FXML and in this case FXML will create the controllers for you using reflection, and CDI won't work there, unless we use CDI itself to produce a FXMLLoader instance and in this case we can set a callback to create the bean using CDI, so all the injected fields won't be null. The code was taken from  FXML & JavaFX—Fueled by CDI & JBoss Weld post because it didn't have change at all, we are just using Java 8 delicious lambdas,  see:

Finally you can create your own app, but never call FXMLLoader static methods when using CDI, instead, use the injected one:

Remember that you are also able to inject stuff in your controller. In my case I injected a classic Greeter to the controller:

Also, since this a CDI application we should not forget about the empty beans.xml file. This is the structure of the project I used in my tests:

This is the final result with the fact that now the message is coming from a CDI Bean:

The full project can be found in my github.