In good company

In case I didn’t mention this before, learning about OpenMRS is the best thing that could have happened to me in college. I love computer science. Finding myself in this community where doing what I love meets a pressing need in the world AND gives me the privilege of meeting all these incredible people here at the OpenMRS Implementers Meeting (#OMRS12) is the most humbling, inspiring, exciting thing that’s happened in my life to date.

I always figured it would be nice to eventually finish up my GSoC project to handle the things I didn’t get to, things that would make it more usable. I thought that my project was going to be helpful for cleaning up concept dictionaries, but there wasn’t anything urgent or extra special about this module that moves data from one concept id to the next… Then on Friday as the conference was wrapping up, I met Dr. Alvin Marcelo and Patrick, also known as the “Ellen Ball of the Philippines.” Long story short, they are in particular need of a tool for cleaning up concept dictionaries. If my module could be improved to do its thing for their HTML forms, Alvin said that it would be a real life saver because their care providers would have more time to see patients.

This not only gives me a new and interesting problem to work on, but invaluable guidance from the project users who I can now call friends.


Beginner’s Notes

Getting started with OpenMRS was the hardest part. This post is a compilation of some technical notes on the major issues I had getting set up.

Here are my general purpose trouble-shooting tips from the early weeks of GSoC…

  1. Make sure database is working and has a password
  2. Check that subversion is updated to HEAD
    – to see what revision you have, right-click on folder in Eclipse-> Properties -> Subversion
  3. Give Maven extra memory
  4. When in doubt, restart Eclipse and/ or computer
  5. In the event of an, “Error: Unable to connect to the database” I had a few tricks, but I’m not sure any of these would work every time.
    – find and delete the .OpenMRS folder
    – go to Activity Monitor and quit mysqld
    – restart computer, and rebuild OpenMRS

This summer was also the first time I used the command line besides experimenting for no reason.

  • (working on list of helpful OpenMRS commands)

Week 12

Tomorrow is the suggested “Pencils Down” date for writing code, so this week can focus on cleaning up code, documenting everything, and getting tests in order.

I wanted to tackle some interesting issues with my project last week, the much anticipated week 12, but my mentors suggested it might be a little ambitious for the last five days and it would be best not to leave any to-do’s unchecked. I agreed, although it reminded me of the first few weeks of this summer. I was in a hurry to do so many things, but needed to slow down to do them right.

If I had the option leave school and work on projects like this forever, and learn everything I need to know as I go along… I wouldn’t, but it would be tempting. I had to learn more for this project than any CS class I’ve taken in college. It was also more real and meaningful. I can’t imagine graduating without having an experience like GSoC with OpenMRS this summer.

I hope this is the moment when the training wheels get taken away and all of a sudden I realize that I know how to ride a bike.

Hibernate? …but it’s still summer!

OpenMRS uses hibernate (the noun – the “open-source object-relational mapping tool.”) to help objects communicate with the database.

Using the Module Maven Archetype gives you the option to add a service layer. When I was setting up my module I said yes to adding a service layer just in case, and didn’t think much about it until a few weeks ago. The reason I decided to implement a MergeConceptsService was that I wanted a query from the openmrs database that wasn’t directly available using the ObsService.

The Module Maven Archetype option to add a service layer gives a module four files that make up the service layer: DAO, HibernateDAO, Service, and ServiceImpl. DAO and Service are interfaces implemented by HibernateDAO and ServiceImpl. The HibernateDAO is home to the sessionFactory, which actually connects to the database. The ServiceImpl will instantiate a DAO, and then the module controller is free to instantiate a Service.

The hibernate mapping file is unnecessary unless you are using hql to change a table.

Week Eleven

I have yet to mention my thing for double numbers in this space. My grandpa always said they were lucky, or something. I actually didn’t know he said that until after he died. Then double numbers sort of became a family thing. This past week, I worked and accomplished more than any other week this summer. Sitting in my quiet house trying to think about how to sum it all up, I just realized that this successful week was week number 11. Figures. 🙂

I actually started with undoing most of the code I had for converting observations from one concept to another in favor of using a service method instead. I was struggling with unit tests because concepts can have different datatypes and the ObsService rejects saving a “question concept” as an “answer concept.” Good thing I was having trouble – it lead me to a thoughtful conversation about making sure certain aspects of a concept are preserved in a merge, even when an ObsService wouldn’t cause a problem.

This being week number 11 makes next week number 12 out of 12 full weeks of GSoC! How do you express freaking out via blog post? Just kidding. I’m looking forward this last real week. I’m excited and nervous about going back to school and finding out what being involved with OpenMRS will look like when I don’t have two incredible and official mentors…

Thanks for the memory!

This is the story of me trying to make run faster.

My first idea was to allocate any of the extra memory on the server to my web app. I found a settings file called “” and opened it up to find:

export JAVA_OPTS="-server -XX:+UseParallelGC -Xmx1024m -XX:PermSize=
256m -XX:MaxPermSize=512m -Djava.awt.headless=true"root@goose:/usr/

The 1024m basically means that OpenMRS on goose was allowed to have 1GB, or a small flash drive’s worth of memory. Dr. Wierman suggested changing the 256 to 512 and the 512 to 1024, or to keep increasing those values until I broke it. Confused, I wanted to find out how much memory goose even had. So, I did:

root@goose:~# cat /proc/meminfo
MemTotal:        1015836 kB
MemFree:           75104 kB
Buffers:           18084 kB
Cached:            54532 kB
SwapCached:       144048 kB
Active:           396248 kB
Inactive:         494176 kB
Active(anon):     373024 kB
Inactive(anon):   460656 kB
Active(file):      23224 kB
Inactive(file):    33520 kB
Unevictable:           0 kB
Mlocked:               0 kB
HighTotal:        129416 kB
HighFree:           1712 kB
LowTotal:         886420 kB
LowFree:           73392 kB
SwapTotal:       1036284 kB
SwapFree:         377404 kB
Dirty:                32 kB
Writeback:             0 kB
AnonPages:        674820 kB
Mapped:            11600 kB
Shmem:             15864 kB
Slab:              33732 kB
SReclaimable:      21136 kB
SUnreclaim:        12596 kB
KernelStack:        3000 kB
PageTables:         4104 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     1544200 kB
Committed_AS:    1973740 kB
VmallocTotal:     122880 kB
VmallocUsed:       10848 kB
VmallocChunk:     108876 kB
HardwareCorrupted:     0 kB
AnonHugePages:         0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       4096 kB
DirectMap4k:       36856 kB
DirectMap4M:      872448 kB

Simple enough, right? This is how I learned that out of slightly less than 1GB of “MemTotal” about 0.07 GB was “MemFree.” My OpenMRS was already allowed to have more memory than the server had to offer.

Dr. Wierman said he had a bag of memory laying around somewhere, and he would look for some that would work with goose. That sounded funny to me so I asked, “What does memory look like?” My question must have sounded funny to him too because he repeated it smiling and pulled out that previously mentioned bag of memory. Nothing in the bag matched the “MT-M 8810-WCX” sticker on goose, so Dr. Wierman opened up and handed me the 1GB memory from that server… “Here, you can put this in goose.” I took it excitedly down the hall. “Don’t forget to unplug it first!”

Adventures in Pair Programming – Week 10

What about pair programming?[1] Janet and I tried pair programming to start writing unit tests. Before this week I had zero experience, and writing the code together was a quick way to bring me up to speed on the when, where, and why of unit testing. We used some combination of Skype, iChat, and to pair program remotely. I shared my screen and control to observe how Janet set up the class path and used the Eclipse plug-in to generate test cases, and wrote the first few tests, explaining each step as she did. Then I wrote the next few tests.

So what about pair programming? The last time I programmed in a pair was in high school with my friend and the only other girl in my class, Cassidy, on a GridWorld project. Neither of us knew more than you would expect to learn in AP CS, but we had each other to use what we did know to solve problems creatively and check syntax. The whole process then and now did not go perfectly smoothly, which was okay. It reminded me that I’m not the only one who gets stuck. Having a partner in code makes it possible to brainstorm and troubleshoot more effectively, and stay focused.

Now What? Janet and I are going to try pair programming for a couple hours again on Wednesday, this time writing code with Hibernate. *I think* there is also talk around OpenMRS of using pair programming strategies to help, mentor, guide new community members.

[1] From Wikipedia: Pair programming is an agile software development technique in which two programmers work together at one workstation. One, thedriver, writes code while the other, the observer (or navigator), reviews each line of code as it is typed in. The two programmers switch roles frequently.