A Dance of Flags
First things that need correcting are the start-up JVM flags. Some changed names, other simply disappeared. A good thing that the JVM helps us with explicit error messages.In my case, I had to remove the -XX :+PrintGCDetails and -X :++PrintGCDateStamps flags, which do not exist anymore with the G1 garbage collector. I also had to replace the -Xloggc :gc.log with that one: -Xlog:gc:gc.log.
BootClassPath no more
My first surprise came from the disappearance of the BootClassPath. Of course, I heard about it, and I felt lucky that we migrated a couple of years ago from Orbix, a CORBA implementation (yes, this technology is still in use in 2017…) that installs its libraries in the BootClassPath, to JacOrb. But even without any hint of a BootClassPath in the command line, it still managed to bite me.When we start our application, we display useful pieces of information about the environment in the log file. You can find there the command line, for instance, or the classpath. And of course, the famed BootClassPath. It turned out that the method we use for retrieving it, RuntimeMXBean.getBootClassPath(), is now throwing an UnsupportedOperationException.
What Java version again?
One try/catch later, I stumbled into the change of version number. We are moving from java version ‘1.8.0_111’ to version ‘9’. Once again, in spite of being well aware of this change, it still got me. I had commented out beforehand the part of our code that was forbidding our program to run with anything else than Java 8 (internal politics…), telling myself that I would go back to it later and try to use the all new java.lang.Runtime.Version class.However, the problem came from an external library called Docking Frame. It tried for some reason to discover with which java version the application is running. I found myself facing an ArrayIndexOutOfBoundsException. Fortunately, someone else already solved this bug in the library's latest release. I only had to update its version.
The Forbidden Packages
Now, Java 9 forbids us to access any class coming from the sun.* or com.sun.* packages. And we are using 2 such classes in our application. The first case was easy to fix. I replaced this code:if (UIManager.getLookAndFeel() instanceof WindowsClassicLookAndFeel)
With that one :
if ("Windows Classic".equals(UIManager.getLookAndFeel().getName()))
The second case was harder to fix. We are using the ToolkitImage class for its quite practical getBufferedImage() method. I found a replacement in the javax.imageio package.
Modules put to rest
All this was just a warm up. My next hurdle came in the shape of a NoClassDefFoundError for a class that is actually inside the JDK, more precisely in the java.corba package. As it turned out, some Modules are never loaded at start-up, probably because they are deemed as rare, or too “JEE”. And CORBA falls into that category. To solve that problem, I needed to add a ‘--add-modules java.corba’ flag to the command line.In fact, we are using other such Modules, such as java.xml.bind or java.activation. So I decided, against all good practice described in the Java 9 Migration Guide (https://docs.oracle.com/javase/9/migrate/toc.htm), to use the ‘--add-modules ALL-SYSTEM’ flag. Of course, this is only a temporary solution…
Module Patching
Great! We have now CORBA Modules loaded, but JacOrb doesn’t seem happy. It looks for several classes in the omg.corba package, which belongs to Java, but those classes are nowhere in sight. The explanation is to be found in the omg-jacorb.jar library, bundled with JacOrb release, and that declares some of its classes in the Java package. Of course, now, this is all forbidden. You cannot declare anymore classes in a package that does not belong to you.But you can patch a Module. This is easy, you just add a new flag to the runtime: --patch-module java.corba=omg-jacorb.jar.
Invisible Packages
Unfortunately, patching a Module is not quite enough. Indeed, many packages are not exported in the java.corba Module, because they are for internal use only. But accessing internal classes is actually the reason why JacOrb reverts to declaring its classes in the omg.corba package. So I have to declare, one by one, all the sub-packages to which it need access.That is quite a long and painful process, where I’d add a flag, start the application, check the next exception, then add a flag again… At the end, I had to declare around ten packages with flags similar to this one: --add-exports java.corba/org.omg.GIOP=ALL-UNNAMED. It translates to: « Dear Java, could you kindly make the org.omb.GIOP package from the java.corba module visible to all the classes loaded by the classpath? »
No comments:
Post a Comment