GSoC 2017 – Week 1

 

It’s been one hell of a first week.

First, exams got postponed a week because Sri Lanka was hit with the heaviest floods since 2003. The lower part of the country was basically washed off into the sea. Our thoughts and prayers are with those affected. Exams getting postponed meant I need to cover as much work as I can in this week.

Second, a weird error kept coming up out of nowhere. Some errors, you just gotta erase from your code.

Errors, Errors Everywhere

You know the best part of Java Exceptions? It’s how specific they are. You know the worst part? It’s how specific they are.

“You know the best part of Java Exceptions? It’s how specific they are. You know the worst part? It’s how specific they are.”

I was working on checking UI functionality of the Operation Theater module and there were errors as functions didn’t fire up properly. First there was a UI element that was incorrectly configured – a text area was given to be loaded from the EMR module, while it should have been from the UI Commons.
Then I started looking into the unit tests. If a unit test failed, that meant there was a difference between the older dependencies and newer ones. So I ran them, and of course, there they were[1].

The first set of errors all said that they could not autowire some beans of the Serialization Xstream module. I checked the POM files and that module was being loaded properly. But then it hit me – maybe the OT module needs the older APIs of the Xstream module. I had seen multiple APIs of the same module being loaded in a POM when looking through certain OpenMRS modules. So it occurred to me that I should first try loading the older API versions of the Xstream module.

And I did just that. Off went the autowiring issues. In came a different set of Hibernate issues[2]. This time it said this.

GenericJDBCException: could not prepare statement

I looked around for this error and Stack Overflow said it could due to mixing newer and older versions of DB tools. Apparently there was a point in the DB call chain that didn’t work well with the rest of it which was newer. Or so I guess.

I checked to see if we were using HSQLDB but couldn’t find a mention of it. I was looking around when all of a sudden, everything just stopped loading.

Well, it went like this.

Previously, the module could be loaded to the Ref App 2.6 through the web interface. OpenMRS refreshed context and loaded classes without any problem.

But once I shut down the server, restarting it would throw an error saying the following[3]:

... nested exception is java.lang.LinkageError: loader constraint violation: loader (instance of org/openmrs/util/OpenmrsClassLoader) previously initiated loading for a different type with name "org/joda/time/DateTime"

Apparently, the class loader encounters a conflict with multiple Joda time versions. The class loader constraint violation would come up whenever I restarted the server. However, I could delete the module from the server’s folder manually, start the server and then load the module via the web interface for testing.

But now, I could not load the module even in a fresh server. When I try to load it via the web interface, the server would crash while refreshing the context, throwing ^that error. What the $%#*? How come it worked before and now doesn’t? Oh well.

How would I solve it?

I tried a few things.

  • Use Joda Time version mentioned in the other modules and give scope as provided.
  • Give dependency with compile scope.

Neither could put an end to my worry. Next step, ask the community!

Asked about this on the IRC channel but people could not help me. Then I looked at alternatives. Could we replace the whole thing? It’s Joda Time that causes the error. So let’s stop depending on it.

My mentors came to aid. We discussed the issue and I got to know that Joda Time had given trouble before as well. They were more than happy to stop relying on it.

It’s Time to move on.

The new Java 8 time library was in fact co-written by the author of the older Joda Time library. But he decided that some features like Intervals are too specific for a general, built-in library and dropped them when writing java.time. He’s the author of the ThreeTen-Extra library too.
java.time was known as JSR-310 while in development. Notice something here?

JSR-310.
ThreeTen-Extra.
JSR… ThreeTen.

Oh. Riiight.
Yep, he made ThreeTen-Extra as an add-on for the java.time library. In fact, it’s based on the latter.

Java 8 has a new library for Time related concepts, and I looked at comparisons between them[4]. The new library was built-in, but it didn’t have many of the features that Joda Time had. The worst part was that we depended on some exclusive features like intervals. I realized this after I started working on replacing Joda.

Then, I found another library called ThreeTen-Extra[5] that has just what we need – intervals. I asked if the mentors were okay with replacing one dependency with another and got the green light. I’m working on the replacement now, in a new branch.

We also decided that it’s best to bring the OT module to a repository under the OpenMRS org in GitHub. Right now, I’m working on a fork from the original GSoC student’s repo. He doesn’t seem to be active there anymore.

That’s about it for this week. Next one’s gonna be tough. Exams. You can find the discussion with mentors here.

  1. ProcedureDAO Test – https://pastebin.com/c7n7jAMz
  2. SurgeryDAO Test – https://pastebin.com/vzTwcZ5W
  3. Joda Time Error – https://pastebin.com/sDkmDb6K
  4. Joda Time to Java Time – http://blog.joda.org/2014/11/converting-from-joda-time-to-javatime.html
  5. ThreeTen-Extra – http://www.threeten.org/threeten-extra/
  • Nimaz Sheik

    The line about Java exceptions being too specific was just perfect :O

    • Chanuka Wijayakoon

      It’s a hard life for a Java dev :3