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/

GSoC 2017 – Operation Theater Module Workflow Enhancements

This is the official blog for my Google Summer of Code 2017 project. I am going to be working for OpenMRS, an open source project that supports healthcare delivery around the world. It feels great to have been awarded this opportunity, thank you @Team OpenMRS! 😁

My project is to work on the Operation theater module, which has been made as part of GSoC 2014. It’s used to schedule surgeries and other operation theater activities in multiple theaters. The module was written for an older OpenMRS version, so my first task is to migrate it to the latest platform.

The next steps would be to make enhancements to the workflow. There are 3 stages in any operation theater activity – pre-theater, in-theater and post-theater. The enhancements will focus on the data collection procedures during the entire workflow of an activity.

Coding officially kicks off on the 30th of May. It’s the community bonding period right now, so I’m using this time to learn more about OpenMRS. It’s a wonderful community with people willing to help and share knowledge.

After discussions with my mentor, we decided to start early. So here I’ll be posting on my progress.

Setting Up the Dev Environment

OpenMRS has a nifty tool for working on their projects – the OpenMRS SDK. It allows you to run multiple instances of OpenMRS at the same time. Hence you can easily test something on different OpenMRS versions concurrently.

The original OT module had been written for platform version 1.9.7, and the current version is 2.0.5. I used the SDK to set up the OpenMRS Reference Application 2.6, which is built on that platform and has a slew of modules bundled with it. The idea is to migrate the OT module to the latest stable release first, then provide backward compatibility if and where necessary.

I use IntelliJ IDEA as the IDE as it has great documentation and support both within the OpenMRS community and outside.

Work so far

When submitting the proposal, I had identified database changes as a key point of consideration when migrating the module. So I decided to start with that.

Out of sheer curiosity, I first tried changing just the target platform version of the module and building against that. The module got compiled successfully, but failed some tests written for the older platform. Then I skipped the tests, and imported the built module to the Ref App via the web interface. Just for the kick of it. Well, the error logs weren’t pretty. But they taught me where to look.

Specifically, they taught me that the changes of Hibernate were causing trouble. The OT module was built for Hibernate 3.x, while OpenMRS currently uses Hibernate 4.x. SessionFactory was now used in place of DbSessionFactory.

The next step was changing the module dependencies to the ones included in the latest Reference Application. Reporting, ID Generation and many other modules had come a long way forward from their older versions used in the OT module.

Then I tried building the module again. It wasn’t going to be that easy of course. Tests failed, so I skipped them again. Imported the module again, but as expected, the module couldn’t start. Database errors were all over the place.

I perused the error logs and it seemed the bean definitions in the module application context were causing the errors. Looking into the file, the errors were caused by a set of beans defined for the Appointment Scheduling module, as it apparently didn’t have its own bean definitions at that time. The current version probably does.

So I commented off those beans, and rebuilt the module. Imported the module  to the Ref App and voila! The module started! 😁

Right now the Operation theater module correctly appears in the UI, with scheduling and other functionality. Next step is to verify that it works properly, going through each action one by one. There’ll be lots of errors, lots of bug hunts. I can already feel the thrill of the hunt. Or the dread, you choose.

Next Steps

So yeah, we’re making progress. I plan to use the tests written before to identify the API calls and learn what has changed. The other option is to read the logs when errors come up.

So much to look forward to.

I’ll be sure to keep you updated.

See ya.