Upgrading To Java 8 For Developers

Recently, we upgraded the required java version to 8 in OpenMRS core, there has been a growing push from the developers in the community to do the upgrade so that they can utilize the new language features that come with java 8.

What do i have to do?

We recommend module developers to start building their modules against java 8, you don't necessarily have to use the new language features especially if you wish to support older versions of OpenMRS.

It is highly probable that the versions of some the dependencies and tools you use in development don't work well with java 8 and need to be upgraded, worst case scenario you might have to fix a few bugs here and there. You can download the latest official JDK and JRE from the oracle website, you should be able to find OpenJDK's  distribution too from their website.

For module developers working on modules that compile against java 7 and older while at the same time you to contribute to openmrs core which requires java 8, most modern IDEs will let you configure a different JDK version for each project and sub project.

For module developers working on modules and wish to support the upcoming release (2.0) of the platform and the older versions via maven  sub modules but you'll still need java 8 to build the whole project, you might also need to add the animal sniffer maven plugin to ensure that you don't mistakenly use classes from the new APIs in java 8.

 

Things you might to pay attention to:

  •  The VM options PermSize and MaxPermSize were removed. Apparently, this implies by default class metadata allocation is only limited by the amount of available native memory. Use the new flag MaxMetaspaceSize to limit the amount of native memory used for class metadata. It is analogous to MaxPermSize.
  • On OSX, when installing java 8, it overwrites your existing java installation and apparently oracle no longer provides downloads for JDK 6. If you wish to fall back or have multiple JREs,  apple provides java 6 downloads here. Another work-around could be to create another a copy of the previous java installation directory before installing java 8, that way you can point other projects that require older versions to that directory or point the JAVA_HOME to it when necessary.
  • Transient dependencies are handled a little differently in some cases, take an example where you have 3 different projects A, B and C where C depends on B, B in turn depends on A and C doesn't directly reference any class from A. Apparently with java 8, it requires that project A is available at compile time in order to build project C which was never the case with older java versions.

 

 

 

 

 

 

there is definitely going to be some annoyances to developers working on other projects other than openmrs core master. Below are some we are ware of:

- Devs are going to find themselves having to keep switching between JDKs whenever they are going to work on 1.10.x and 1.11.x branches, this also applies when working on modules that support older JDKs. Most modern IDEs will let you configure a different JDK for each run configuration so if you are not using the command line this will be less of an issue when working on module projects. We are trying to find ways to minimize the pain from this issue but we haven't yet come up with a solution therefore we are welcoming any ideas from the community, it might involve writing some sort of script that can set set JAVA_HOME to the appropriate JDK at the beginning of each maven build, but am not 100% sure if this is actually possible or if it can be done via a plugin.

- It is possible for a module developer to mistakenly code against new APIs in java 8, compile and test functionality on java 8, i would think of this as being careless but i think it can happen.

- Java 8 is also very strict in some ways when it comes to transient dependencies as i mentioned on TRUNK-4583 in the comment on 2015-05-14 19:01:00, so DEVs might find their code failing to compile because of this. In summary, if i have projects A, B and C where B depends on A, C depends on B and C doesn't directly reference any class from A, java 8 requires project A to be on the classpath when compiling C which is not the case for older JDKs.