<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The eflow blog &#187; java</title>
	<atom:link href="http://blog.eflow.org/archives/tag/java/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.eflow.org</link>
	<description>Insert some amazingly witty tagline here</description>
	<lastBuildDate>Fri, 09 Dec 2011 18:59:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.3</generator>
		<item>
		<title>Script to Find Unused Message Keys in Message.properties Files</title>
		<link>http://blog.eflow.org/archives/325</link>
		<comments>http://blog.eflow.org/archives/325#comments</comments>
		<pubDate>Thu, 06 Jan 2011 19:55:44 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[babble]]></category>
		<category><![CDATA[openmrs]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[messages]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://blog.eflow.org/?p=325</guid>
		<description><![CDATA[Over time the messages in our Spring message.properties files grow stale. When a developer updates/changes code he/she doesn&#8217;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 [...]]]></description>
			<content:encoded><![CDATA[<p>Over time the messages in our Spring message.properties files grow stale.  When a developer updates/changes code he/she doesn&#8217;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.</p>
<p>I wrote this quick shell script to loop over the file and do a recursive grep for that key.  The key is considered &#8220;used&#8221; 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 + &#8220;.started&#8221;)</p>
<blockquote><p>
#!/bin/sh</p>
<p># Loops over all the keys in the given messages.properties file<br />
# and looks in the current directory for the string in quotes.<br />
# Results are printed to stdout<br />
#<br />
# use: (from the &#8220;web&#8221; dir in openmrs)<br />
# sh ./findunusedmessages.sh WEB-INF/messages.properties</p>
<p>propfile=$1<br />
props=`awk -F= &#8216;{print $1}&#8217; $propfile`<br />
count=0<br />
total=0</p>
<p>echo &#8220;These property keys were not found in the code base:&#8221;<br />
for prop in $props<br />
do<br />
 #echo &#8220;Looking for property: $prop&#8221;<br />
 if [ ! -z "$prop" ];<br />
 then<br />
   total=`expr $total + 1`<br />
   output=`grep &#8211;exclude-dir=&#8221;.svn&#8221; -re &#8220;[\'\"]$prop[\'\"]&#8221; *`<br />
   if [ -z "$output" ];<br />
   then<br />
     echo &#8220;$prop&#8221;<br />
     count=`expr $count + 1`<br />
   fi<br />
 fi<br />
done</p>
<p>echo &#8220;done! Found $count possibly uneeded message keys in $propfile (out of $total total keys)&#8221;
</p></blockquote>
<p>Download the file here: <a href='http://blog.eflow.org/wp-content/uploads/2011/01/findunusedmessages.sh'>findunusedmessages.sh</a><br />
<br/><br />
<br/></p>
 <img src="http://blog.eflow.org/wp-content/plugins/feed-statistics.php?view=1&post_id=325" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://blog.eflow.org/archives/325/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Default MySQL Database to InnoDB Storage Engine</title>
		<link>http://blog.eflow.org/archives/145</link>
		<comments>http://blog.eflow.org/archives/145#comments</comments>
		<pubDate>Tue, 31 Mar 2009 12:13:06 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[babble]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://blog.eflow.org/?p=145</guid>
		<description><![CDATA[Currently tables created in MySQL default to MyISam. This is unacceptable for us at Openmrs. You can set a property in your my.cnf file called &#8220;default-storage-engine&#8221;, but I needed a solution that didn&#8217;t involve implementers having to modify their system config files. I changed the jdbc connection url string to set a session property that [...]]]></description>
			<content:encoded><![CDATA[<p>Currently tables created in <a href="http://mysql.com">MySQL</a> default to MyISam.  This is unacceptable for us at <a href="http://openmrs.org">Openmrs</a>.  You can set a property in your my.cnf file called &#8220;default-storage-engine&#8221;, but I needed a solution that didn&#8217;t involve implementers having to modify their system config files.</p>
<p>I changed the jdbc connection url string to set a session property that sets InnoDB as the default engine:</p>
<blockquote><p>jdbc:mysql://localhost:3306/databasename?autoReconnect=true&amp;sessionVariables=storage_engine=InnoDB</p></blockquote>
<p>NOTE! Requires mysql jdbc connecter version 3.1.18 or greater.  See http://dev.mysql.com/doc/refman/5.0/en/connector-j.html for documentation and then http://dev.mysql.com/downloads/connector/j/ to download.</p>
<p>The error message I was getting before upgrading the mysql jdbc connector was:</p>
<blockquote><p>java.sql.SQLException: Server connection failure during transaction. Due to underlying exception: &#8216;java.sql.SQLException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near &#8221; at line 1&#8242;.</p>
<p>** BEGIN NESTED EXCEPTION **</p>
<p>java.sql.SQLException<br />
MESSAGE: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near &#8221; at line 1</p>
<p>STACKTRACE:</p>
<p>java.sql.SQLException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near &#8221; at line 1<br />
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2921)<br />
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1570)<br />
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1665)<br />
at com.mysql.jdbc.Connection.execSQL(Connection.java:2972)<br />
at com.mysql.jdbc.Connection.execSQL(Connection.java:2902)<br />
at com.mysql.jdbc.Statement.executeUpdate(Statement.java:929)<br />
at com.mysql.jdbc.Connection.setSessionVariables(Connection.java:5077)<br />
at com.mysql.jdbc.Connection.initializePropsFromServer(Connection.java:3680)<br />
at com.mysql.jdbc.Connection.createNewIO(Connection.java:2684)<br />
at com.mysql.jdbc.Connection.&lt;init&gt;(Connection.java:1474)<br />
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:264)<br />
at com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:135)<br />
at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:182)<br />
at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:171)<br />
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:137)<br />
at com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1014)<br />
at com.mchange.v2.resourcepool.BasicResourcePool.access$800(BasicResourcePool.java:32)<br />
at com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.java:1810)<br />
at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)</p></blockquote>
 <img src="http://blog.eflow.org/wp-content/plugins/feed-statistics.php?view=1&post_id=145" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://blog.eflow.org/archives/145/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java URLConnection Redirects Between http and https</title>
		<link>http://blog.eflow.org/archives/174</link>
		<comments>http://blog.eflow.org/archives/174#comments</comments>
		<pubDate>Thu, 26 Mar 2009 03:18:06 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[babble]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[openmrs]]></category>

		<guid isPermaLink="false">http://blog.eflow.org/?p=174</guid>
		<description><![CDATA[For some reason Java doesn&#8217;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 [...]]]></description>
			<content:encoded><![CDATA[<p>For some reason Java doesn&#8217;t like to obey http forwards if the protocol is changing.  It has been this way for a while: <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4620571">http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4620571</a>.  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.</p>
<p>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&#8217;t, I would have had to catch the protocol change and refetch the new url.</p>
<p>It took me a while to find an answer for this because these keywords didn&#8217;t give many results on google: URLConnection HttpURLConnection openConnection() connect() getInputStream() Apache redirectMatch 301 302.</p>
 <img src="http://blog.eflow.org/wp-content/plugins/feed-statistics.php?view=1&post_id=174" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://blog.eflow.org/archives/174/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>OpenMRS Metrics</title>
		<link>http://blog.eflow.org/archives/60</link>
		<comments>http://blog.eflow.org/archives/60#comments</comments>
		<pubDate>Fri, 25 Jul 2008 17:16:57 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[openmrs]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://blog.eflow.org/?p=60</guid>
		<description><![CDATA[I was recently tasked with finding out the number of methods in each class in each package inside of OpenMRS. My first thought was to write a java class to do some reflection. My second thought was to find a java class that someone else had written and use that. My third thought was to [...]]]></description>
			<content:encoded><![CDATA[<p>I was recently tasked with finding out the number of methods in each class in each package inside of OpenMRS.  My first thought was to write a java class to do some reflection.  My second thought was to find a java class that someone <em>else</em> had written and use that.  My third thought was to find a way for Eclipse to do it.</p>
<p>I really should have jumped to that last one first.  Googling for my second thought gave me nothing useful.  However, simply adding &#8220;eclipse&#8221; to my search term brought up the <a href="http://metrics.sourceforge.net/">Metrics plugin</a> as the first result!  The Metrics plugin counts all different types of things.  Lucky for me, &#8220;number of methods&#8221; just happens to be one of them.</p>
<p>To get the counts working for you, follow these easy steps:</p>
<ol>
<li>Add <strong>http://metrics.sourceforge.net/update</strong> to eclipse as a plugin update site</li>
<li>Turn metrics on for your project:
<ol>
<li>Right click on the root of your project in <span style="text-decoration: underline;">Package Explorer</span> view</li>
<li>Choose Properties&#8211;&gt;Metrics&#8211;&gt;Enable Metrics</li>
</ol>
</li>
<li>Do an Eclipse clean rebuild</li>
<li>Click on the root of your project in the Package Explorer</li>
<li>Open the &#8220;Metrics&#8221; view</li>
</ol>
<p>These are the relevant statistics from the OpenMRS project:</p>
<p><a href="http://blog.eflow.org/wp-content/uploads/2008/07/metrics.png"><img class="alignnone size-full wp-image-61" title="metrics" src="http://blog.eflow.org/wp-content/uploads/2008/07/metrics.png" alt="" width="448" height="127" /></a></p>
<p>The second api/web are from the test package.  We have a lot of work to do to catch our total number of unit test methods up with our number of api methods.</p>
<p>I&#8217;ve also uploaded the <a href="http://blog.eflow.org/wp-content/uploads/2008/07/metrics-total.png">entire OpenMRS metrics output</a>.</p>
 <img src="http://blog.eflow.org/wp-content/plugins/feed-statistics.php?view=1&post_id=60" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://blog.eflow.org/archives/60/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bending Connector/J to Our Liking</title>
		<link>http://blog.eflow.org/archives/28</link>
		<comments>http://blog.eflow.org/archives/28#comments</comments>
		<pubDate>Wed, 16 Apr 2008 22:55:40 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[openmrs]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[mysqlconf2008]]></category>

		<guid isPermaLink="false">http://eflow.org/blog/archives/28</guid>
		<description><![CDATA[I attended a session today at the MySQLConf2008 by Mark Matthews on adding extensions to the mysql jdbc connector. There are some exciting implications as an alternative to the BIRT ODA Plugin project. The idea of that project is to create a series of REST calls to only require the end user of the BIRT [...]]]></description>
			<content:encoded><![CDATA[<p>I attended a <a href="http://en.oreilly.com/mysql2008/public/schedule/detail/248">session</a> today at the <a href="http://www.mysqlconf.com">MySQLConf2008</a> by <a href="http://en.oreilly.com/mysql2008/public/schedule/speaker/144">Mark Matthews</a> on adding extensions to the mysql jdbc connector.  There are some exciting implications as an alternative to the <a href="http://openmrs.org/wiki/Projects#Extend_OpenMRS_ODA_Plugin">BIRT ODA Plugin</a> project.  The idea of that project is to create a series of REST calls to only require the end user of the BIRT reporting application to have a high level knowledge of OpenMRS objects (instead of low level knowledge of the OpenMRS data model).</p>
<p>Sometime last year <a href="http://burkeware.com/blog/">Burke</a> laid out his dream BIRT (or other reporting frameworks) connection. It entailed writing a custom jdbc connector that didn&#8217;t act on the database, but instead acted on our API.  The &#8220;available tables&#8221; as the user would see it in BIRT would actually be a subset of our higher level Java objects.</p>
<p>In the session Mark discussed the new intercept-ability of the <a href="http://www.mysql.com/products/connector/j/">MySQL Connector/J</a> (new in version 5.1ga of the connector).  The relevant/interesting addition to the connector is the &#8220;statement interceptor&#8221;.  We could use this to intercept the select calls from BIRT that look like &#8220;SELECT AGE, GENDER, WEIGHT, HEIGHT, LATEST CD4  FROM PATIENT WHERE DATE &gt; 1/1/2008&#8243;.  These calls could be turned into some LogicService calls on AGE, WEIGHT, LATEST CD4, etc to get the ResultSet instead of passing that (unusable) query to mysql.  The LogicService&#8217;s resultSet could then be returned to BIRT for display as a data set.  There isn&#8217;t any documentation on <a href="http://forge.mysql.com">MySQL Forge</a> on how this would work yet.  Mark&#8217;s slides should show up as an option on the <a href="http://forge.mysql.com/wiki/MySQLConf2008WednesdayNotes">mysqlconf&#8217;s wiki</a> soon though.</p>
<p>Side note: The jdbc driver&#8217;s version number does not match with the mysql version numbers.  Version 5.1 of the driver can be used with the current 5.0 of MySQL.</p>
 <img src="http://blog.eflow.org/wp-content/plugins/feed-statistics.php?view=1&post_id=28" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://blog.eflow.org/archives/28/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OpenMRS Hibernate Transactions</title>
		<link>http://blog.eflow.org/archives/24</link>
		<comments>http://blog.eflow.org/archives/24#comments</comments>
		<pubDate>Fri, 18 Jan 2008 18:11:32 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[openmrs]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[transacation annotations]]></category>

		<guid isPermaLink="false">http://eflow.org/blog/archives/24</guid>
		<description><![CDATA[I&#8217;m going to post this here as a reminder to other OpenMRS developers (and myself) and to hopefully save a few hours/days of debugging. The key to getting transactions to work correctly in the webapp is to, well, tell Spring that we&#8217;re in a transaction. You can do this by simply putting an @Transactional annotation [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m going to post this here as a reminder to other OpenMRS developers (and myself) and to hopefully save a few hours/days of debugging.  The key to getting transactions to work correctly in the webapp is to, well, tell Spring that we&#8217;re in a transaction.  You can do this by simply putting an <code>@Transactional</code> annotation in the *Service java interface.</p>
<p>Without that key piece of text, the service and its methods will still work.  However, they&#8217;ll work in a readonly kind of way.  All data written to the database will be rolled back when the body of work has completed.  This little error manifested itself recently after our reporting code-a-thon.  During the event we had to create a new API service, which is only done maybe a few times a year.  The service didn&#8217;t get the @Transactional tag and so therefore all database editing failed that went through the ReportService.  The unit tests set up for the object passed, but that is because a unit test happens all within a single transaction &#8212; the rollback is always done after the completion of the test anyway.</p>
<p>I added a note to http://openmrs.org/wiki/OpenMRS_API about the requirement, but I&#8217;m sure there will be an OpenMRS developer in the future struggling with their object not saving or updating in the database and be completely baffled by it.</p>
 <img src="http://blog.eflow.org/wp-content/plugins/feed-statistics.php?view=1&post_id=24" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://blog.eflow.org/archives/24/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OpenMRS Tomcat Startup Error</title>
		<link>http://blog.eflow.org/archives/25</link>
		<comments>http://blog.eflow.org/archives/25#comments</comments>
		<pubDate>Thu, 17 Jan 2008 18:07:09 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[openmrs]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[tomcat]]></category>

		<guid isPermaLink="false">http://eflow.org/blog/archives/25</guid>
		<description><![CDATA[I recently had a very frustrating error that I want to document here for future Googling&#8217;s sake. After a non-ideal shutdown of Tomcat and/or the jvm I was unable to start the OpenMRS webapp. Tomcat was giving this error in its log file: Failed to read schema document 'http://www.springframework.org/schema/beans/spring-beans.xsd' This is somewhat expected with the [...]]]></description>
			<content:encoded><![CDATA[<p>I recently had a very frustrating error that I want to document here for future Googling&#8217;s sake.  After a non-ideal shutdown of Tomcat and/or the jvm I was unable to start the OpenMRS webapp. Tomcat was giving this error in its log file:</p>
<p><code>Failed to read schema document 'http://www.springframework.org/schema/beans/spring-beans.xsd'</code></p>
<p>This is somewhat expected with the move from Spring 2.0 to 2.5.  As of <a href="http://www.springframework.org/">Spring Framework</a> 2.5 the new url to use in the application context is</p>
<p><code>http://www.springframework.org/schema/beans/spring-beans-2.5.xsd</code></p>
<p>but  even after making this change in the code and redeploying the webapp, Tomcat refused to start giving the same url (with just spring-beans.xsd).</p>
<p>Solution:</p>
<p>A Spring definition file (namely applicationContext-service.xml) was being cached in Tomcat&#8217;s work directory and not being replaced on webapp deploy for some reason.  I uninstalled the webapp and then deleted all files under &lt;tomcathome&gt;/work/localhost.  Upon installing openmrs and starting Tomcat again everything started up as expected.</p>
 <img src="http://blog.eflow.org/wp-content/plugins/feed-statistics.php?view=1&post_id=25" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://blog.eflow.org/archives/25/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Building OpenMRS w/ Ant on CentOS</title>
		<link>http://blog.eflow.org/archives/22</link>
		<comments>http://blog.eflow.org/archives/22#comments</comments>
		<pubDate>Wed, 19 Dec 2007 17:29:49 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[openmrs]]></category>
		<category><![CDATA[ant]]></category>
		<category><![CDATA[centos]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://eflow.org/blog/archives/22</guid>
		<description><![CDATA[I recently had the pleasure of setting up an ant build of OpenMRS on our new servers. After installing ant and the OpenMRS source code I kept getting a never-before-seen error when building: No supported regular expression matcher found I made sure I had jdk 1.6 installed. I tried upgrading to Ant 1.7 (from 1.6.5). [...]]]></description>
			<content:encoded><![CDATA[<p>I recently had the pleasure of setting up an ant build of OpenMRS on our new servers.  After installing ant and the OpenMRS source code I kept getting a never-before-seen error when building:</p>
<blockquote><p>No  supported regular expression matcher found</p></blockquote>
<p>I made sure I had jdk 1.6 installed.  I tried upgrading to Ant 1.7 (from 1.6.5).</p>
<p>I ran an &#8220;ant -diagnostics&#8221;.  It wasn&#8217;t showing the optional ant jars so I dropped all of the jars into the ant home lib directory.  Now the jars were showing up but I was still getting the same error as before.</p>
<p>The solution ended up being that Ant lied to me.  It was actually looking for the jars in /usr/share/java/ant (not in its reported /usr/share/ant).  The puzzling thing is that Ant tells me it finds the jars when running &#8220;ant -diagnostics&#8221;.</p>
<p>I ended up installing the optional ant jars via yum. (or apt-get if you&#8217;re on a debian flavor) Yum didn&#8217;t have the explicit ant-optional package, so I just installed all ant-*.jar files.  Voila!  Successful building via ant is now possible.</p>
 <img src="http://blog.eflow.org/wp-content/plugins/feed-statistics.php?view=1&post_id=22" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://blog.eflow.org/archives/22/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>OpenMRS and Your Memory</title>
		<link>http://blog.eflow.org/archives/6</link>
		<comments>http://blog.eflow.org/archives/6#comments</comments>
		<pubDate>Wed, 31 Oct 2007 18:26:37 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[openmrs]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[memory]]></category>
		<category><![CDATA[tomcat]]></category>

		<guid isPermaLink="false">http://eflow.org/blog/archives/6</guid>
		<description><![CDATA[I just finished poring over OpenMRS with a java memory profiler in an attempt to find where we&#8217;re leaking memory. It appears as though OpenMRS takes up more and more of the server&#8217;s memory as time progresses. However, my final conclusion is that we aren&#8217;t leaking much. I found and fixed what appeared to be [...]]]></description>
			<content:encoded><![CDATA[<p>I just finished poring over OpenMRS with a <a href="http://yourkit.com">java memory profiler</a> in an attempt to find where we&#8217;re leaking memory.  It appears as though OpenMRS takes up more and more of the server&#8217;s memory as time progresses.  However, my final conclusion is that we aren&#8217;t leaking much.  I found and fixed what appeared to be memory bugs, but by and large, I think we just demand a lot of Java objects to be loaded at any given time &#8212; and Tomcat holds onto the total memory its been allocated just in case it needs it again.</p>
<p>A very huge find that came out of this was that we were &#8220;leaking&#8221; Tomcat sessions.  In Eldoret we have about 30 data assistants right now that are filling in Infopath forms for about 8 hours a day.  The average form takes about 5 minutes to fill out, so they are opening and closing Infopath fairly often.  When opened, the taskpane on the side of Infopath is a mini IE browser.  The first action taken by that taskpane browser is a stealing of the user&#8217;s session from their other web browser.  The original session is left hanging around in Tomcat though.  After 30 minutes of inactivity that session is dropped.  Apparently, in our setup at least, either Tomcat or Apache has somewhere around a 250 limit on the number of sessions.  With the DAs entering forms at a rapid pace, it would only take a few hours before the limit was reached &#8212; at which point Apache/Tomcat halted all traffic until some sessions were freed by timing out or Tomcat was restarted.</p>
<p>While trying to find the real cause of the problem, my first solution was to shorten the length of the session timeout.  In &lt;Tomcat Home&gt;/conf/web.xml:</p>
<blockquote><p>&lt;session-config&gt;<br />
&lt;session-timeout&gt;15&lt;/session-timeout&gt;<br />
&lt;/session-config&gt;</p></blockquote>
<p>this obviously only lengthened the time between restarts.</p>
<p>The true solution came in the form of a beautiful one line fix in the formentry module:  when initially loading the taskpane (before the session stealing happens) set the timeout of the current session to 10 seconds. Voila! Success! Our Eldoret server is now much more &#8220;dependable&#8221;!</p>
<p>Now, as far as the memory leak goes, I&#8217;d love to have some input from people who might have a better idea of what they&#8217;re doing.  At times I felt as though I were just clicking randomly through the profiler looking for anything that had &#8216;org.openmrs&#8230;&#8217; in the package name.  If you have any pointers to give me or you have found a few memory leaks yourself, let me know!</p>
 <img src="http://blog.eflow.org/wp-content/plugins/feed-statistics.php?view=1&post_id=6" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://blog.eflow.org/archives/6/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

