In my spare time I lead the MapStruct project, a code generator for bean to bean mappings.
While Java 9 has reached its end-of-life earlier this week, the Java Platform Module System (JPMS, JSR 376) is here to stay. This means also specifications such as the Java Persistence API or Bean Validation will eventually have to be adjusted to support and take advantage of the module system.
This blog post is the first of a series on exploring JPMS modularity patterns for specification APIs. In this part we’re going to look into how implementations of a specification API can be bootstrapped in a portable way and how such implementations can access the private state of modules of the user of the API. As discussed a while ago, the latter is a common requirement; for instance JPA providers must do so for reading and writing entity state.
The most significant feature in Bean Validation 2.0 (JSR 380) is the support for container element constraints.
I.e. you can now apply constraints to the contents of container types such as
Optional by annotating their type arguments
(which became possible with Java 8):
List<@Future LocalDate> shipmentDates.
In this blog post you’ll learn how to take advantage of that for the validation of custom container types,
Graph from Google’s widely known Guava library.
One of the most exciting features in Java 9 are modular runtime images. Using the new jlink utility, you can create customized distributions which contain your app, its dependencies and just the JDK modules which it needs. For instance, a simple service based on the Undertow web server can be packaged into an image of just 25 MB, batteries included.
While that’s pretty cool already, it gets even nicer, as jlink provides a plug-in mechanism which allows to fine-tune the contents modular runtime images as they are created. There’s a set of jlink plug-ins coming with the JDK, e.g. for compressing image contents or removing debug symbols. But many more use cases may benefit from this API, for instance one could imagine plug-ins for removing un-used code or for performing byte code instrumentation of JPA entities. In the following, we’ll create a plug-in for adding an annotation index to the created image. At runtime, this index can then be used to discover annotations very efficiently, i.e. without loading classes and using reflection.
For sure it does, there’s just one catch: the jlink plug-in API is not a supported part of the JDK as of Java 9.
In fact, its packages are not even exported from the
This means some tricks are required to create custom plug-ins and run the jlink tool with these plug-ins enabled.
The API may change in future Java versions, so any custom plug-in may break.
Nevertheless it’s definitely worth to explore the API and see what it can do. It’s my hope that it’ll be promoted to a public API eventually.
Without doubt, the module system (JPMS) is the most prominent feature of Java 9. But there are many other useful additions to the JDK, which have not been discussed as widely yet.
One of them is the new
ToolProvider SPI, which defines a uniform way to invoke all the tools coming with the JDK (e.g.
jlink etc.) in a programmatic way.
E.g. imagine you’d like to create a JAR archive from within your Java application.
Before Java 9, you had two options to do so:
Start a separate process to run the
Find out which classes are used by the
jarcommand internally and invoke them directly
Neither option is ideal.
The former incurs some overhead for forking an OS level process and it requires a bit of coding to locate the binary to execute in the Java home directory and to correctly capture any output of the forked process.
The second option doesn’t come with the disadvantages of forking a new process, but it requires knowledge about the implementation of the tool to execute.
So for instance in the case of the
jar command, you’d have to know that
java.util.jar.JarOutputStream is used to produce JAR files.
The WildFly application server comes with a patching mechanism which makes it very easy to upgrade existing modules of the server or add new ones. E.g. Hibernate Validator provides patch files which let you upgrade WildFly 10.1 to the preview releases of Bean Validation 2.0.
But you also can use the patching mechanism to add your own custom libraries to WildFly, making them available to deployed applications. Even if you only ever deploy a single application to one WildFly instance, this can be very useful, as it results in a smaller size of your deployment unit (WAR etc.) and thus faster build and deployment times.
How are WildFly patches created, though? Patch files are generally just ZIP files which contain the module(s) to be added or updated as well as some additional metadata. So in theory you could create them by hand, but there’s the patch-gen tool which greatly simplifies this task.
Data-centric libraries often need to access private state of classes provided by the library user.
An example is Hibernate ORM.
@Id annotation is given on a field of an entity, Hibernate will by default directly access fields - as opposed to calling property getters and setters - to read and write the entity’s state.
Usually, such fields are private. Accessing them from outside code has never been a problem, though. The Java reflection API allows to make private members accessible and access them subsequently from other classes. With the advent of the module system in Java 9, rules for this will change a bit, though.
In the following we’ll explore the options authors of a library provided as a Java 9 module have to access private state of classes defined in other modules.
As the Bean Validation 2.0 spec is making good progress, you may want to try out the features of the new spec revision with your existing Java EE applications.
WildFly, as a compatible Java EE 7 implementation, comes with Bean Validation 1.1 and its reference implementation Hibernate Validator 5 out of the box. In the following we’ll show you how easy it is to upgrade the server’s modules to the latest Bean Validation release, using a patch file provided by Hibernate Validator.
Java 9 comes with a new feature very useful to library authors: multi-release JARs (JEP 238).
A multi-release JAR (MR JAR) may contain multiple variants of one and the same class, each targeting a specific Java version. At runtime, the right variant of the class will be loaded automatically, depending on the Java version being used.
This allows library authors to take advantage of new Java versions early on, while keeping compatibility with older versions at the same time.
If for instance your library performs atomic compare-and-set operations on variables, you may currently be doing so using the
Unsafe has never been meant for usage outside the JDK itself,
Java 9 comes with a supported alternative for CAS logics in form of var handles.
By providing your library as an MR JAR, you can benefit from var handles when running on Java 9 while sticking to
Unsafe when running on older platforms.
In the following we’ll discuss how to create an MR JAR using Apache Maven.
If you’ve ever watched the great show "Home Improvement", you’ll know that a fool with a tool is still a fool. At the same time though, the right tool used in the right way can be very effective for solving complex issues.
In this post I’d like to introduce a tool called jQAssistant which I’ve found very useful for running all sorts of analyses of a project’s code base, e.g. for preventing the leakage of internal types in the public API of a library. This is planned to be the first post in a blog series on developer-centric tools we’ve come to value when working on the different libraries of the Hibernate family.
In this post I’ll show you how easy it is to use the latest and greatest version of Hibernate ORM with WildFly 10.
Traditionally, updating Hibernate in WildFly required some good knowledge of the server’s module system and the structure of the ORM modules. It certainly was doable, but it involved search/replace in existing module descriptors and generally wasn’t very convenient.
This has become much simpler with last week’s release of Hibernate ORM 5.2.1!
We now provide a ZIP archive containing all the required modules, making it a breeze to add the latest version of Hibernate to an existing WildFly instance. And what’s best: the version of Hibernate packaged with the application server remains untouched; switching between this and the new version is just a matter of setting one small configuration option, and you can go back at any time.