Over time the messages in our Spring message.properties files grow stale. When a developer updates/changes code he/she doesn’t necessarily go to the messages.properties and remove all the keys that they removed from code. This has not detrimental effect on code, it just means that when translating into a new language the translator is potentially more work than they need to.

I wrote this quick shell script to loop over the file and do a recursive grep for that key. The key is considered “used” if it exists in the current directory with quotes around it (single or double). This WILL NOT find keys if they are only used programmatically. (e.g. VAR + “.started”)


# Loops over all the keys in the given messages.properties file
# and looks in the current directory for the string in quotes.
# Results are printed to stdout
# use: (from the “web” dir in openmrs)
# sh ./findunusedmessages.sh WEB-INF/messages.properties

props=`awk -F= ‘{print $1}’ $propfile`

echo “These property keys were not found in the code base:”
for prop in $props
#echo “Looking for property: $prop”
if [ ! -z “$prop” ];
total=`expr $total + 1`
output=`grep –exclude-dir=”.svn” -re “[\’\”]$prop[\’\”]” *`
if [ -z “$output” ];
echo “$prop”
count=`expr $count + 1`

echo “done! Found $count possibly uneeded message keys in $propfile (out of $total total keys)”

Download the file here: findunusedmessages.sh

This is in the babble, openmrs category tagged as , , , ,

Add a comment »

- 01 Apr 2010 -

We held a training here in Indianapolis in February. Darius Jazayeri and I led the talks that walked through all development aspects of OpenMRS. You can see the agenda here: http://openmrs.org/wiki/OpenMRS_Developer_Training_Week_8-February-2010

Overall I was quite pleased with how the training went. There were more people involved that I expected: 40+ were in attendance physically at the Regenstrief building at some point during the week and another 10-15 that participated via the online web casts! One very positive outcome from the week was that Darius and I created a lot of wiki pages directly from the content we were talking about. This gave us a blueprint from which to talk while preserving the content for future users to see. I am still waiting to hear from Michael about the long-term availability of daily recordings.

I really see these types of trainings being a good long term revenue stream for OpenMRS. Obviously it won’t be able to be the only source, but if we had 3-4 trainings a year at various locations around the globe we would be able to hit a large number of developers. (Doing an implementer-centered training is a whole other matter) We learned a lot through this training: get the word out earlier, give out pre-training required reading, and write the entire week’s lesson plans prior to starting the training!

This is in the openmrs category tagged as , ,

Add a comment »

A programmer here at AMPATH (Gilbert Tuwei) had some issues installing mysql. The error message was very unhelpful and the solution was equally puzzling, so I want to put here to for the mighty google to find.

Tuwei was running v5.0.17 of MySQL. Upgrading to version 5.1.31 made the problem disappear.

WARN – InitializationFilter$InitializationCompletion$1.run(823) |2009-10-02 15:24:21,000| Error while trying to update to the latest database version
org.openmrs.util.DatabaseUpdateException: There was an error while updating the database to the latest. file: liquibase-update-to-latest.xml. Error: Migration failed for change set liquibase-update-to-latest.xml::2::upul:
java.sql.SQLException: Can’t create/write to file ‘C:\WINDOWS\TEMP\#sql_fe4_0.MYI’ (Errcode: 17):
Caused By: Precondition Error
at org.openmrs.util.DatabaseUpdater.executeChangelog(DatabaseUpdater.java:145)
at org.openmrs.web.filter.initialization.InitializationFilter$InitializationCompletion$1.run(InitializationFilter.java:817)
at java.lang.Thread.run(Unknown Source)
Caused by: liquibase.exception.MigrationFailedException: Migration failed for change set liquibase-update-to-latest.xml::2::upul:
java.sql.SQLException: Can’t create/write to file ‘C:\WINDOWS\TEMP\#sql_fe4_0.MYI’ (Errcode: 17):
Caused By: Precondition Error
at liquibase.ChangeSet.execute(ChangeSet.java:204)
at liquibase.parser.visitor.UpdateVisitor.visit(UpdateVisitor.java:26)
at org.openmrs.util.DatabaseUpdater$1OpenmrsUpdateVisitor.visit(DatabaseUpdater.java:177)
at liquibase.parser.ChangeLogIterator.run(ChangeLogIterator.java:41)
at org.openmrs.util.DatabaseUpdater.executeChangelog(DatabaseUpdater.java:201)
at org.openmrs.util.DatabaseUpdater.executeChangelog(DatabaseUpdater.java:142)
… 2 more
Caused by: liquibase.exception.PreconditionErrorException: Precondition Error
at liquibase.preconditions.ForeignKeyExistsPrecondition.check(ForeignKeyExistsPrecondition.java:36)
at liquibase.preconditions.NotPrecondition.check(NotPrecondition.java:18)
at liquibase.preconditions.AndPrecondition.check(AndPrecondition.java:21)
at liquibase.ChangeSet.execute(ChangeSet.java:169)
… 7 more

This is in the babble category tagged as , , ,

Add a comment »

Our method for merging branches back to trunk:

  • branch> svn merge from trunk [rev_last_merged_from_trunk]:[HEAD]
  • branch> (resolve conflicts, deploy, test)
  • branch> commit
    (at this point, the branch should be exactly what trunk has plus all changes done in the branch)

  • trunk> svn merge from branch [rev_first_branched_from_trunk]:[HEAD]

For some reason svn still sees a ton of conflicts when doing that last step. In the past I would have to manually go through each file and just copy what was in the branch on top of trunk and then “mark resolved”. However, now there is a faster way: Using at least SVN v1.5 at command line:

svn resolve -R --accept theirs-full *

Thats it! Its a life saver. Or at least a time saver.

(This can be dangerous. Make sure you have resolved all true conflicts in the branch before doing the “resolve all”)

This is in the babble category tagged as


For some reason Java doesn’t like to obey http forwards if the protocol is changing. It has been this way for a while: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4620571.  So when I was trying to load https://modules.openmrs.org that had an apache redirectMatch to http://modules.openmrs.org, I would get the html for the 301 redirect instead of the source of http://modules.openmrs.org.

I was lucky that I have control over the server and could change the http/https to a simply proxy instead of redirecting.  If I didn’t, I would have had to catch the protocol change and refetch the new url.

It took me a while to find an answer for this because these keywords didn’t give many results on google: URLConnection HttpURLConnection openConnection() connect() getInputStream() Apache redirectMatch 301 302.

This is in the babble category tagged as ,