<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6214277125099466960</id><updated>2026-01-05T17:21:29.394-05:00</updated><category term="openmrs"/><category term="reporting"/><category term="usability"/><category term="gsoc"/><category term="backup"/><category term="clonezilla"/><category term="Eclipse"/><category term="acronis"/><category term="clone"/><category term="cloning"/><category term="junit"/><category term="mom"/><category term="ms"/><category term="multiple sclerosis"/><category term="pih"/><category term="tomcat"/><category term="Troubleshooting"/><category term="ant"/><category term="api"/><category term="aspiration"/><category term="bacon"/><category term="blackberry"/><category term="bob ross"/><category term="code-a-thon"/><category term="coffee"/><category term="dataset"/><category term="extending"/><category term="features"/><category term="feedback"/><category term="fun"/><category term="gtd"/><category term="hotswap"/><category term="image"/><category term="java"/><category term="javac"/><category term="jira"/><category term="jrebel"/><category term="mockup"/><category term="modern"/><category term="mysql"/><category term="openmrs eclipse svn subversion subclipse"/><category term="openmrs hotswap tomcat jrebel"/><category term="openmrs mysql"/><category term="openmrs svn subversion bestpractice convention"/><category term="openmrs tomcat mac osx"/><category term="openmrs training developers"/><category term="quartz"/><category term="rtm"/><category term="scheduler"/><category term="tasks"/><category term="tasque"/><category term="test-a-thon"/><category term="todo"/><category term="trac"/><title type='text'>in the midst of modern</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.justinmiranda.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://blog.justinmiranda.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Justin Miranda</name><uri>http://www.blogger.com/profile/12794947822953373298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5AqKjeUVRaa2MOuWom3QvHZQDyyE6OPva7awOh5s6XMNh20agcuIoSFrRCkOKJxlNTuX1K85Lqolaaj9Tey0FhGtIO0VGfwOVEiDtrX9e89b6-sjCy-6ARG2xZSp89Do/s220/5493_128868133104_8302049_n+%28copy%29.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>44</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6214277125099466960.post-3424542437970926075</id><published>2014-09-18T15:47:00.003-04:00</published><updated>2014-09-18T16:13:00.180-04:00</updated><title type='text'>Upgrading IntelliJ on Ubuntu</title><content type='html'>Whenever I receive an &quot;upgrade to the latest version&quot; notification from IntelliJ IDEA I usually click the &quot;Remind Me Later&quot; button because I always forget the steps required to make the new version work with Unity Launcher. &amp;nbsp;So today I&#39;m going to save myself some trouble and document those steps to help streamline the process in the future. &amp;nbsp;The biggest annoyance is always in creating the Unity Launcher file for the new version, so that&#39;s what I&#39;m going to focus on.&lt;br /&gt;
&lt;br /&gt;
So here goes ...&lt;br /&gt;
&lt;h4&gt;
How to upgrade to the latest version of Intellij IDEA&lt;/h4&gt;
1. Download the latest version of IDEA&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaT5WrHfy4KGwpnzDyvtTPHFZ9Z5ehiOPYNZkmxn1tpVrXqUlP9rhWEPztLdZkjibT7Y_kUwy1tCUiiyYDgW03ssVYELDI9X03iAnLNQZNtmPNWvUYKTojm4-y-b8TFaOaDcv_wIUdh7NQ/s1600/Screenshot+from+2014-09-18+12:37:50.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaT5WrHfy4KGwpnzDyvtTPHFZ9Z5ehiOPYNZkmxn1tpVrXqUlP9rhWEPztLdZkjibT7Y_kUwy1tCUiiyYDgW03ssVYELDI9X03iAnLNQZNtmPNWvUYKTojm4-y-b8TFaOaDcv_wIUdh7NQ/s1600/Screenshot+from+2014-09-18+12:37:50.png&quot; height=&quot;95&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
2. Extract contents to a temporary location (e.g. ~/Desktop)&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0WlcVgHyKB23IMmvHfqZv9JC_cdDuvbFzst6McGR-ixRhMqqOLoVuCRvuUQk1g1N7SO9pVvXVvSJrz79r73dlRdV-5jyisJOJ6uapapkViXpkX77Uo4JGhtR3frDQOcMQZobIYm_8W7gL/s1600/Screenshot+from+2014-09-18+12:41:52.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0WlcVgHyKB23IMmvHfqZv9JC_cdDuvbFzst6McGR-ixRhMqqOLoVuCRvuUQk1g1N7SO9pVvXVvSJrz79r73dlRdV-5jyisJOJ6uapapkViXpkX77Uo4JGhtR3frDQOcMQZobIYm_8W7gL/s1600/Screenshot+from+2014-09-18+12:41:52.png&quot; height=&quot;107&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
3. Move the extracted &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;idea&lt;/span&gt; directory to the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;/opt&lt;/span&gt; directory&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;background: rgb(240, 240, 240); border: 1px dashed rgb(204, 204, 204); font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; width: 646.462524414063px;&quot;&gt;&lt;code style=&quot;word-wrap: normal;&quot;&gt;$ cd ~/Desktop
$ sudo mv idea-IU-135.1230 /opt/
&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;code style=&quot;word-wrap: normal;&quot;&gt;&lt;br /&gt;&lt;/code&gt;&lt;/div&gt;
4. Create a new or update an existing Unity Launcher (.desktop file)&lt;br /&gt;
&lt;pre style=&quot;background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_YfEPUdtGHSOwTF2xrjvFmgRaXrdw2YB_0gUVOiUS8J8qYjnsZCXNWpvaPLoL79UOxJUl6rV4UM3dCNThQJbq1Y6hH7w48IWj9eQPPnbKZWaLJJY8CURmkkr900wwAex01g0Ka4vDeSX8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;&quot;&gt;&lt;code style=&quot;color: black; word-wrap: normal;&quot;&gt;$ sudo vi&amp;nbsp;/usr/share/applications/jetbrains-idea.desktop&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
5. If you are updating an existing .desktop file, simply replace the&amp;nbsp;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Icon&lt;/span&gt; and &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Exec&lt;/span&gt;&amp;nbsp;attributes with the paths to the new logo and &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;idea.sh&lt;/span&gt; script.&lt;br /&gt;
&lt;br /&gt;
For example, make yours ...&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_YfEPUdtGHSOwTF2xrjvFmgRaXrdw2YB_0gUVOiUS8J8qYjnsZCXNWpvaPLoL79UOxJUl6rV4UM3dCNThQJbq1Y6hH7w48IWj9eQPPnbKZWaLJJY8CURmkkr900wwAex01g0Ka4vDeSX8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;&quot;&gt;&lt;code style=&quot;color: black; word-wrap: normal;&quot;&gt;[Desktop Entry]
Version=1.0
Type=Application
Name=IntelliJ IDEA
&lt;b&gt;Icon=/opt/idea-IU-133.696/bin/idea.png&lt;/b&gt;
&lt;b&gt;Exec=&quot;/opt/idea-IU-133.696/bin/idea.sh&quot; %f&lt;/b&gt;
Comment=Develop with pleasure!
Categories=Development;IDE;
Terminal=false
StartupWMClass=jetbrains-idea
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
look like mine ...&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_YfEPUdtGHSOwTF2xrjvFmgRaXrdw2YB_0gUVOiUS8J8qYjnsZCXNWpvaPLoL79UOxJUl6rV4UM3dCNThQJbq1Y6hH7w48IWj9eQPPnbKZWaLJJY8CURmkkr900wwAex01g0Ka4vDeSX8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;&quot;&gt;&lt;code style=&quot;color: black; word-wrap: normal;&quot;&gt;[Desktop Entry]
Version=1.0
Type=Application
Name=IntelliJ IDEA
&lt;b&gt;Icon=/opt/idea-IU-135.1230/bin/idea.png
Exec=&quot;/opt/idea-IU-135.1230/bin/idea.sh&quot; %f&lt;/b&gt;
Comment=Develop with pleasure!
Categories=Development;IDE;
Terminal=false
StartupWMClass=jetbrains-idea
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;h4&gt;
How to future-proof this solution&lt;/h4&gt;
In order to make this easier in the future, I&#39;ve added a symlink to the current IDEA directory (e.g. &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;/opt/idea-IU-135.1230&lt;/span&gt;) so that we can simply extract the .tar.gz file contents to the /opt directory and change the symlink to point to the latest version! &amp;nbsp;So just make a simple change to the .desktop file and you&#39;ll never have to do it again.&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_YfEPUdtGHSOwTF2xrjvFmgRaXrdw2YB_0gUVOiUS8J8qYjnsZCXNWpvaPLoL79UOxJUl6rV4UM3dCNThQJbq1Y6hH7w48IWj9eQPPnbKZWaLJJY8CURmkkr900wwAex01g0Ka4vDeSX8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;&quot;&gt;&lt;code style=&quot;color: black; word-wrap: normal;&quot;&gt;[Desktop Entry]
Version=1.0
Type=Application
Name=IntelliJ IDEA
&lt;b&gt;Icon=/opt/idea/bin/idea.png
Exec=&quot;/opt/idea/bin/idea.sh&quot; %f&lt;/b&gt;
Comment=Develop with pleasure!
Categories=Development;IDE;
Terminal=false
StartupWMClass=jetbrains-idea
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
So whenever there&#39;s a new version you just need to download / extract the .tar.gz and update the symlink. &lt;br /&gt;
&lt;br /&gt;
1. Download latest version&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaT5WrHfy4KGwpnzDyvtTPHFZ9Z5ehiOPYNZkmxn1tpVrXqUlP9rhWEPztLdZkjibT7Y_kUwy1tCUiiyYDgW03ssVYELDI9X03iAnLNQZNtmPNWvUYKTojm4-y-b8TFaOaDcv_wIUdh7NQ/s1600/Screenshot+from+2014-09-18+12:37:50.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaT5WrHfy4KGwpnzDyvtTPHFZ9Z5ehiOPYNZkmxn1tpVrXqUlP9rhWEPztLdZkjibT7Y_kUwy1tCUiiyYDgW03ssVYELDI9X03iAnLNQZNtmPNWvUYKTojm4-y-b8TFaOaDcv_wIUdh7NQ/s1600/Screenshot+from+2014-09-18+12:37:50.png&quot; height=&quot;95&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
2. Extract contents to /opt&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0WlcVgHyKB23IMmvHfqZv9JC_cdDuvbFzst6McGR-ixRhMqqOLoVuCRvuUQk1g1N7SO9pVvXVvSJrz79r73dlRdV-5jyisJOJ6uapapkViXpkX77Uo4JGhtR3frDQOcMQZobIYm_8W7gL/s1600/Screenshot+from+2014-09-18+12:41:52.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0WlcVgHyKB23IMmvHfqZv9JC_cdDuvbFzst6McGR-ixRhMqqOLoVuCRvuUQk1g1N7SO9pVvXVvSJrz79r73dlRdV-5jyisJOJ6uapapkViXpkX77Uo4JGhtR3frDQOcMQZobIYm_8W7gL/s1600/Screenshot+from+2014-09-18+12:41:52.png&quot; height=&quot;107&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
3. Create symlink to the latest directory&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_YfEPUdtGHSOwTF2xrjvFmgRaXrdw2YB_0gUVOiUS8J8qYjnsZCXNWpvaPLoL79UOxJUl6rV4UM3dCNThQJbq1Y6hH7w48IWj9eQPPnbKZWaLJJY8CURmkkr900wwAex01g0Ka4vDeSX8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;&quot;&gt;&lt;code style=&quot;color: black; word-wrap: normal;&quot;&gt;$ ln -s /opt/idea-IU-135.1230 /opt/idea&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
4. Boom.&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.justinmiranda.com/feeds/3424542437970926075/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/6214277125099466960/3424542437970926075' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/3424542437970926075'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/3424542437970926075'/><link rel='alternate' type='text/html' href='http://blog.justinmiranda.com/2014/09/upgrading-intellij-on-ubuntu.html' title='Upgrading IntelliJ on Ubuntu'/><author><name>Justin Miranda</name><uri>http://www.blogger.com/profile/12794947822953373298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5AqKjeUVRaa2MOuWom3QvHZQDyyE6OPva7awOh5s6XMNh20agcuIoSFrRCkOKJxlNTuX1K85Lqolaaj9Tey0FhGtIO0VGfwOVEiDtrX9e89b6-sjCy-6ARG2xZSp89Do/s220/5493_128868133104_8302049_n+%28copy%29.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaT5WrHfy4KGwpnzDyvtTPHFZ9Z5ehiOPYNZkmxn1tpVrXqUlP9rhWEPztLdZkjibT7Y_kUwy1tCUiiyYDgW03ssVYELDI9X03iAnLNQZNtmPNWvUYKTojm4-y-b8TFaOaDcv_wIUdh7NQ/s72-c/Screenshot+from+2014-09-18+12:37:50.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6214277125099466960.post-7336292971614103376</id><published>2014-05-31T11:43:00.002-04:00</published><updated>2014-05-31T11:51:17.964-04:00</updated><title type='text'>Tomcat 7.0.52 stalls during startup</title><content type='html'>Last night, I created a new server instance on HP Cloud and punched a hole in the firewall for port 8080. &amp;nbsp;I became puzzled when I couldn&#39;t reach the Tomcat test page (http://server.ip.address:8080). &amp;nbsp;I waited for a few minutes and the server still hadn&#39;t responded. &amp;nbsp;I checked the logs and noticed that Tomcat seemed to be stuck at the point of deploying the default ROOT webapp. &lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;May 31, 2014 7:43:15 AM org.apache.catalina.startup.ClassLoaderFactory validateFile&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;WARNING: Problem with directory [/usr/share/tomcat7/common/classes], exists: [false], isDirectory: [false], canRead: [false]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;May 31, 2014 7:43:15 AM org.apache.catalina.startup.ClassLoaderFactory validateFile&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;WARNING: Problem with directory [/usr/share/tomcat7/common], exists: [false], isDirectory: [false], canRead: [false]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;May 31, 2014 7:43:16 AM org.apache.catalina.startup.ClassLoaderFactory validateFile&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;WARNING: Problem with directory [/usr/share/tomcat7/server/classes], exists: [false], isDirectory: [false], canRead: [false]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;May 31, 2014 7:43:16 AM org.apache.catalina.startup.ClassLoaderFactory validateFile&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;WARNING: Problem with directory [/usr/share/tomcat7/server], exists: [false], isDirectory: [false], canRead: [false]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;May 31, 2014 7:43:16 AM org.apache.catalina.startup.ClassLoaderFactory validateFile&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;WARNING: Problem with directory [/usr/share/tomcat7/shared/classes], exists: [false], isDirectory: [false], canRead: [false]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;May 31, 2014 7:43:16 AM org.apache.catalina.startup.ClassLoaderFactory validateFile&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;WARNING: Problem with directory [/usr/share/tomcat7/shared], exists: [false], isDirectory: [false], canRead: [false]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;May 31, 2014 7:43:22 AM org.apache.coyote.AbstractProtocol init&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;INFO: Initializing ProtocolHandler [&quot;http-bio-8080&quot;]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;May 31, 2014 7:43:22 AM org.apache.catalina.startup.Catalina load&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;INFO: Initialization processed in 5612 ms&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;May 31, 2014 7:43:22 AM org.apache.catalina.core.StandardService startInternal&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;INFO: Starting service Catalina&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;May 31, 2014 7:43:22 AM org.apache.catalina.core.StandardEngine startInternal&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;INFO: Starting Servlet Engine: Apache Tomcat/7.0.52 (Ubuntu)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;May 31, 2014 7:43:22 AM org.apache.catalina.startup.HostConfig deployDirectory&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;INFO: Deploying web application directory /var/lib/tomcat7/webapps/ROOT&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I was looking for the following line, but it never came.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;INFO: Server startup in 3908 ms&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I checked and re-checked the firewall settings in HP Cloud - just in case - and they seemed to be correct. &amp;nbsp;It was 4am EST so I decided to head to bed. &amp;nbsp;This morning, I woke up to check if Tomcat had eventually started. &amp;nbsp;I made a request to the Tomcat test page and received the expected response. &amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Weird.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I tried to restart Tomcat to see if it was just a network hiccup, but Tomcat continued to stall at the same place in the log file. &amp;nbsp;So I went back through the log from the night before and noticed the last four lines below:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;May 31, 2014 7:43:22 AM org.apache.catalina.core.StandardEngine startInternal&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;INFO: Starting Servlet Engine: Apache Tomcat/7.0.52 (Ubuntu)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;May 31, 2014 7:43:22 AM org.apache.catalina.startup.HostConfig deployDirectory&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;INFO: Deploying web application directory /var/lib/tomcat7/webapps/ROOT&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;May 31, 2014 9:03:02 AM org.apache.catalina.util.SessionIdGenerator createSecureRandom&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;&lt;b&gt;INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [4,772,515] milliseconds.&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;&lt;b&gt;May 31, 2014 9:03:02 AM org.apache.coyote.AbstractProtocol start&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;&lt;b&gt;INFO: Starting ProtocolHandler [&quot;http-bio-8080&quot;]&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;&lt;b&gt;May 31, 2014 9:03:02 AM org.apache.catalina.startup.Catalina start&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;&lt;b&gt;INFO: Server startup in 4780082 ms&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Looks like it took 4.8 million ms (about 80 minutes) to create the SecureRandom instance (this is used by Tomcat to generate unique session IDs and other random values). &amp;nbsp;I haven&#39;t looked into why that might be the case, but I found a workaround here (http://wiki.apache.org/tomcat/HowTo/FasterStartUp) that uses a non-blocking entropy source. &amp;nbsp;The wiki page mentions that the non-blocking entropy source (/dev/urandom) is less secure than the blocking entropy source (/dev/random) because the non-blocking option generates less-random data. &amp;nbsp;However, given that this is a completely unacceptable startup delay, I figured I could live with the workaround until I&#39;ve had some time to read up on different entropy sources. &amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
In any case, I just needed to add the following system property to Tomcat&#39;s startup routine.&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;background-color: white; font-size: 13px;&quot;&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;background-color: white; font-size: 13px;&quot;&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;-Djava.security.egd=file:/dev/./urandom&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
On Ubuntu, I generally add command-line properties like this to the setenv.sh script that is called by catalina.sh or startup.sh&amp;nbsp;&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;(/usr/share/tomcat7/bin/setenv.sh).&amp;nbsp;&lt;/span&gt;That might be different for Windows or Mac, so you may need to look around to figure out the correct place for this setting -- adding it to Tomcat&#39;s start script is generally a bad idea.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;export CATALINA_OPTS=&quot;-Xms256m -Xmx512m -XX:MaxPermSize=128m -Duser.timezone=EST -Djava.security.egd=file:/dev/./urandom&quot;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I&#39;ll try to update this blog entry once I&#39;ve figured out the best way to resolve this issue for good.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Software versions&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
Ubuntu 14.04&lt;/div&gt;
&lt;div&gt;
Tomcat 7.0.52&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
Java version &quot;1.7.0_55&quot;&lt;/div&gt;
&lt;div&gt;
OpenJDK Runtime Environment (IcedTea 2.4.7) (7u55-2.4.7-1ubuntu1)&lt;/div&gt;
&lt;div&gt;
OpenJDK 64-Bit Server VM (build 24.51-b03, mixed mode)&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://blog.justinmiranda.com/feeds/7336292971614103376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/6214277125099466960/7336292971614103376' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/7336292971614103376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/7336292971614103376'/><link rel='alternate' type='text/html' href='http://blog.justinmiranda.com/2014/05/tomcat-7052-stalls-during-startup.html' title='Tomcat 7.0.52 stalls during startup'/><author><name>Justin Miranda</name><uri>http://www.blogger.com/profile/12794947822953373298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5AqKjeUVRaa2MOuWom3QvHZQDyyE6OPva7awOh5s6XMNh20agcuIoSFrRCkOKJxlNTuX1K85Lqolaaj9Tey0FhGtIO0VGfwOVEiDtrX9e89b6-sjCy-6ARG2xZSp89Do/s220/5493_128868133104_8302049_n+%28copy%29.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6214277125099466960.post-7677585212083080289</id><published>2013-12-14T23:35:00.000-05:00</published><updated>2013-12-14T23:35:29.129-05:00</updated><title type='text'>Grails 2.3.2 &gt; IllegalArgumentException: No enum constant org.springframework.http.HttpMethod.</title><content type='html'>I just encountered a pretty benign error that ended up taking me about an hour to resolve. &amp;nbsp;Since I didn&#39;t find any Q&amp;amp;As about this on stackoverflow.com, I figured I should document it in case anyone else runs into it.&lt;br /&gt;
&lt;br /&gt;
So I wrote a simple Spock test for my AccountController. &lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;@TestFor(AccountController)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;@Mock([Account])&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;class AccountControllerSpec extends Specification {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; void &quot;should return account with given identfier&quot;() {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; when:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; def account = new Account(firstName: &quot;Justin&quot;, lastName: &quot;Miranda&quot;, age: 35).save(flush:true)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; params.id = account.id&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; controller.show()&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; then:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; response.json.id == account.id&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; response.json.firstName == account.firstName&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; response.json.lastName == account.lastName&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Next, I wrote a simple controller with just a show method.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;class AccountController {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; static allowedMethods = [show:&quot;GET&quot;]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; def show(Account account) {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (account == null) {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; render status:404&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; render account as JSON&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
Then I ran the unit test and received the following error.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;grails&amp;gt; test-app unit: AccountController --verbose --stacktrace&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;| Running 1 unit test... 1 of 1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;ID: 1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;| Failure: &amp;nbsp;should return account with given identfier(com.kinectus.AccountControllerSpec)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;| &amp;nbsp;java.lang.IllegalArgumentException: No enum constant org.springframework.http.HttpMethod.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;at java.lang.Enum.valueOf(Enum.java:236)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;at org.springframework.http.HttpMethod.valueOf(HttpMethod.java:27)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;at org.codehaus.groovy.grails.plugins.web.api.ControllersApi.initializeCommandObject(ControllersApi.java:436)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;at com.kinectus.AccountControllerSpec.should return account with given identfier(AccountControllerSpec.groovy:24)&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
Now that I know the solution, the error message is a little more helpful than I originally thought. &amp;nbsp;The period&amp;nbsp;(.)&amp;nbsp;&amp;nbsp;after &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;HttpMethod&lt;/span&gt; is not the end of the sentence ... it&#39;s actually a hint to the answer. &amp;nbsp;It&#39;s saying &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;No enum constant org.springframework.http.HttpMethod.SOMEVALUE&lt;/span&gt;. &amp;nbsp; It really should have only taken a few seconds to figure this out, but I had just spent a good deal of time working with &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;HttpStatus&lt;/span&gt;, so I thought the issue was with &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;HttpStatus&lt;/span&gt; for some reason.&lt;br /&gt;
&lt;br /&gt;
Anyway, the solution is to add a request method to the test before calling the show controller action.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;@TestFor(AccountController)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;@Mock([Account])&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;class AccountControllerSpec extends Specification {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; void &quot;should return account with given identfier&quot;() {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; when:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; def account = new Account(firstName: &quot;Justin&quot;, lastName: &quot;Miranda&quot;, age: 35).save(flush:true)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; params.id = account.id&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;b&gt;request.method = &quot;GET&quot;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; controller.show()&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; then:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; response.json.id == account.id&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; response.json.firstName == account.firstName&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; response.json.lastName == account.lastName&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
And that&#39;s it.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://blog.justinmiranda.com/feeds/7677585212083080289/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/6214277125099466960/7677585212083080289' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/7677585212083080289'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/7677585212083080289'/><link rel='alternate' type='text/html' href='http://blog.justinmiranda.com/2013/12/grails-232-illegalargumentexception-no.html' title='Grails 2.3.2 &gt; IllegalArgumentException: No enum constant org.springframework.http.HttpMethod.'/><author><name>Justin Miranda</name><uri>http://www.blogger.com/profile/12794947822953373298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5AqKjeUVRaa2MOuWom3QvHZQDyyE6OPva7awOh5s6XMNh20agcuIoSFrRCkOKJxlNTuX1K85Lqolaaj9Tey0FhGtIO0VGfwOVEiDtrX9e89b6-sjCy-6ARG2xZSp89Do/s220/5493_128868133104_8302049_n+%28copy%29.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6214277125099466960.post-2285213034860239715</id><published>2013-11-14T09:34:00.004-05:00</published><updated>2013-11-14T09:34:51.813-05:00</updated><title type='text'></title><content type='html'>&lt;h2&gt;
How to add a Unity Launcher for Intellij IDEA&lt;/h2&gt;
This has been annoying me for the past two days. &amp;nbsp;I couldn&#39;t figure out how to edit the Intellij IDEA launcher after upgrading to the latest version of IDEA. &amp;nbsp;After playing around a bit and getting things working, I figured I&#39;d post this so that I remember for the next upgrade (i.e. IDEA 13 is right around the corner). &lt;br /&gt;
&lt;h3&gt;
Fire up Intellij IDEA&lt;/h3&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$ ~/apps/idea-IU-129.1359/bin/idea.sh&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Create desktop entry (I always forget about this option)&lt;/h3&gt;
Tools &amp;gt; Create desktop entry ...&lt;br /&gt;
(check the &quot;Create entry for all users&quot; checkbox so that the .desktop file is saved to /usr/share/applications)&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvGD8gylC4XLhn_HSYTKPCrta3wd2cDyIhvmxwDkZb5knrthLxDErLXn_GVZMs1VSCwAM6mQvWrV_KokISPah6HysVrfufW_W_yfa8oHJIr0BvxoxK4s8AAGePG8Dd205_Evu_h3sTfZZj/s1600/create-intellij-idea-launcher.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;97&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvGD8gylC4XLhn_HSYTKPCrta3wd2cDyIhvmxwDkZb5knrthLxDErLXn_GVZMs1VSCwAM6mQvWrV_KokISPah6HysVrfufW_W_yfa8oHJIr0BvxoxK4s8AAGePG8Dd205_Evu_h3sTfZZj/s320/create-intellij-idea-launcher.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h3&gt;
Update .desktop file when you upgrade to a new version of Intellij IDEA&lt;/h3&gt;
Different versions of IDEA create launchers with different names, so your file might have been saved as something else. &amp;nbsp;But for Intellij IDEA 12.1.6 Build 129.1359 the new desktop file is called jetbrains-idea.desktop.&lt;br /&gt;
&lt;br /&gt;
If you ever lose that launcher or need to upgrade to a new version of Intellij IDEA, you can edit&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$ sudo gedit /usr/share/applications/jetbrains-idea.desktop&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
&lt;b&gt;/usr/share/applications/jetbrains-idea.desktop&lt;/b&gt;&lt;/h4&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;[Desktop Entry]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Version=1.0&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Type=Application&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Name=IntelliJ IDEA&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Icon=/home/jmiranda/apps/idea-IU-129.1359/bin/idea.png&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Exec=&quot;/home/jmiranda/apps/idea-IU-129.1359/bin/idea.sh&quot; %f&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Comment=Develop with pleasure!&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Categories=Development;IDE;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Terminal=false&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;StartupNotify=true&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;StartupWMClass=jetbrains-idea&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
If, for some reason, you click on the launcher and it doesn&#39;t launch, you may need to make the .desktop file executable.&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$ sudo chmod +x /usr/share/applications/jetbrains-idea.desktop&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.justinmiranda.com/feeds/2285213034860239715/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/6214277125099466960/2285213034860239715' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/2285213034860239715'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/2285213034860239715'/><link rel='alternate' type='text/html' href='http://blog.justinmiranda.com/2013/11/how-to-add-unity-launcher-for-intellij.html' title=''/><author><name>Justin Miranda</name><uri>http://www.blogger.com/profile/12794947822953373298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5AqKjeUVRaa2MOuWom3QvHZQDyyE6OPva7awOh5s6XMNh20agcuIoSFrRCkOKJxlNTuX1K85Lqolaaj9Tey0FhGtIO0VGfwOVEiDtrX9e89b6-sjCy-6ARG2xZSp89Do/s220/5493_128868133104_8302049_n+%28copy%29.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvGD8gylC4XLhn_HSYTKPCrta3wd2cDyIhvmxwDkZb5knrthLxDErLXn_GVZMs1VSCwAM6mQvWrV_KokISPah6HysVrfufW_W_yfa8oHJIr0BvxoxK4s8AAGePG8Dd205_Evu_h3sTfZZj/s72-c/create-intellij-idea-launcher.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6214277125099466960.post-928385765832578677</id><published>2013-11-11T10:56:00.001-05:00</published><updated>2013-11-11T10:56:21.788-05:00</updated><title type='text'></title><content type='html'>How to disable a service in Ubuntu ...&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$ sudo update-rc.d tomcat7 disable&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;update-rc.d: warning: tomcat7 start runlevel arguments (none) do not match LSB Default-Start values (2 3 4 5)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;update-rc.d: warning: tomcat7 stop runlevel arguments (none) do not match LSB Default-Stop values (0 1 6)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp;Disabling system startup links for /etc/init.d/tomcat7 ...&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp;Removing any system startup links for /etc/init.d/tomcat7 ...&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;/etc/rc0.d/K08tomcat7&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;/etc/rc1.d/K08tomcat7&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;/etc/rc2.d/S92tomcat7&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;/etc/rc3.d/S92tomcat7&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;/etc/rc4.d/S92tomcat7&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;/etc/rc5.d/S92tomcat7&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;/etc/rc6.d/K08tomcat7&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp;Adding system startup for /etc/init.d/tomcat7 ...&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;/etc/rc0.d/K08tomcat7 -&amp;gt; ../init.d/tomcat7&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;/etc/rc1.d/K08tomcat7 -&amp;gt; ../init.d/tomcat7&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;/etc/rc6.d/K08tomcat7 -&amp;gt; ../init.d/tomcat7&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;/etc/rc2.d/K08tomcat7 -&amp;gt; ../init.d/tomcat7&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;/etc/rc3.d/K08tomcat7 -&amp;gt; ../init.d/tomcat7&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;/etc/rc4.d/K08tomcat7 -&amp;gt; ../init.d/tomcat7&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;/etc/rc5.d/K08tomcat7 -&amp;gt; ../init.d/tomcat7&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://blog.justinmiranda.com/feeds/928385765832578677/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/6214277125099466960/928385765832578677' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/928385765832578677'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/928385765832578677'/><link rel='alternate' type='text/html' href='http://blog.justinmiranda.com/2013/11/how-to-disable-service-in-ubuntu.html' title=''/><author><name>Justin Miranda</name><uri>http://www.blogger.com/profile/12794947822953373298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5AqKjeUVRaa2MOuWom3QvHZQDyyE6OPva7awOh5s6XMNh20agcuIoSFrRCkOKJxlNTuX1K85Lqolaaj9Tey0FhGtIO0VGfwOVEiDtrX9e89b6-sjCy-6ARG2xZSp89Do/s220/5493_128868133104_8302049_n+%28copy%29.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6214277125099466960.post-252412472014274592</id><published>2012-08-09T13:01:00.003-04:00</published><updated>2012-08-09T13:01:46.232-04:00</updated><title type='text'>Disabling Ubuntu services (like Jenkins) during startup</title><content type='html'>&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;sudo sh -c &quot;echo &#39;manual&#39; &amp;gt; /etc/init/jenkins.override&quot;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.justinmiranda.com/feeds/252412472014274592/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/6214277125099466960/252412472014274592' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/252412472014274592'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/252412472014274592'/><link rel='alternate' type='text/html' href='http://blog.justinmiranda.com/2012/08/disabling-ubuntu-services-like-jenkins.html' title='Disabling Ubuntu services (like Jenkins) during startup'/><author><name>Justin Miranda</name><uri>http://www.blogger.com/profile/12794947822953373298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5AqKjeUVRaa2MOuWom3QvHZQDyyE6OPva7awOh5s6XMNh20agcuIoSFrRCkOKJxlNTuX1K85Lqolaaj9Tey0FhGtIO0VGfwOVEiDtrX9e89b6-sjCy-6ARG2xZSp89Do/s220/5493_128868133104_8302049_n+%28copy%29.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6214277125099466960.post-1086239389807594763</id><published>2012-07-23T13:13:00.002-04:00</published><updated>2012-07-24T13:15:57.910-04:00</updated><title type='text'>Using SSH with hostname tab completion</title><content type='html'>I&#39;ve always hated typing the fully qualified hostname for a server that I wanted to SSH into. &amp;nbsp;I just learned how to configure Ubuntu to use tab completion with the SSH command. &amp;nbsp;Just run the following command and you can start using tab completion (NOTE: this might require a restart of your terminal session):&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;$ complete -W &quot;$(echo $(grep &#39;^ssh &#39; .bash_history | sort -u | sed &#39;s/^ssh //&#39;))&quot; ssh&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;$ ssh [TAB]&lt;tab&gt;&lt;/tab&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
See the following article for more details:&lt;br /&gt;
&lt;a href=&quot;http://www.commandlinefu.com/commands/view/2759/ssh-autocomplete&quot;&gt;http://www.commandlinefu.com/commands/view/2759/ssh-autocomplete&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Update:&lt;/b&gt; &amp;nbsp;I just realized this morning that there&#39;s one more thing you need to do to get this working properly. &amp;nbsp;Somehow you need to source your custom&amp;nbsp;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;complete&lt;/span&gt;&amp;nbsp;commands when you open a new terminal. &amp;nbsp;I use bash, so I &lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;vi&lt;/span&gt;&#39;d my &lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;.bashrc&lt;/span&gt; file and added my custom completion commands. &amp;nbsp;There&#39;s also a directory called &lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;/etc/bash_completion.d&lt;/span&gt; for these scripts, but I felt a little squeamish putting my custom ones there.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;# enable programmable completion features (you don&#39;t need to&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;#&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: white; font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;enable&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: white; font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;this, if it&#39;s already enabled in /etc/bash.bashrc&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;# and /etc/profile&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: white; font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;sources /etc/bash.bashrc).&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;if [ -f /etc/bash_completion ] &amp;amp;&amp;amp; ! shopt -oq posix; then&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; . /etc/bash_completion&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; # custom completions&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; complete -W &quot;$(echo $(grep &#39;^ssh &#39; .bash_history | sort -u | sed &#39;s/^ssh //&#39;))&quot; ssh&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;fi&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.justinmiranda.com/feeds/1086239389807594763/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/6214277125099466960/1086239389807594763' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/1086239389807594763'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/1086239389807594763'/><link rel='alternate' type='text/html' href='http://blog.justinmiranda.com/2012/07/using-ssh-with-hostname-tab-completion.html' title='Using SSH with hostname tab completion'/><author><name>Justin Miranda</name><uri>http://www.blogger.com/profile/12794947822953373298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5AqKjeUVRaa2MOuWom3QvHZQDyyE6OPva7awOh5s6XMNh20agcuIoSFrRCkOKJxlNTuX1K85Lqolaaj9Tey0FhGtIO0VGfwOVEiDtrX9e89b6-sjCy-6ARG2xZSp89Do/s220/5493_128868133104_8302049_n+%28copy%29.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6214277125099466960.post-5247313704346592016</id><published>2010-03-08T22:21:00.005-05:00</published><updated>2010-03-08T22:32:13.473-05:00</updated><title type='text'>[SOLVED] RSA host key has changed</title><content type='html'>I&#39;ve run into the &quot;RSA host key for &lt;server&gt; has changed&quot; issue is a couple times in the past few months as we have a few servers whose IP addresses have changed. &lt;br /&gt;&lt;blockquote style=&quot;font-family: courier new;&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;jmiranda@jmiranda-laptop:~$ ssh www.example.com&lt;br /&gt;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&lt;br /&gt;@       WARNING: POSSIBLE DNS SPOOFING DETECTED!        &lt;br /&gt;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&lt;br /&gt;The RSA host key for www.example.com has changed,&lt;br /&gt;and the key for the corresponding IP address 12.34.56.78&lt;br /&gt;is unknown. This could either mean that&lt;br /&gt;DNS SPOOFING is happening or the IP address for the host&lt;br /&gt;and its host key have changed at the same time.&lt;br /&gt;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&lt;br /&gt;@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!   &lt;br /&gt;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&lt;br /&gt;IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!&lt;br /&gt;Someone could be eavesdropping on you right now (man-in-the-middle attack)!&lt;br /&gt;It is also possible that the RSA host key has just been changed.&lt;br /&gt;The fingerprint for the RSA key sent by the remote host is&lt;br /&gt;aa:bb:cc:dd:ee:ff:11:22:33:44:55:66:77:88:99:00.&lt;br /&gt;Please contact your system administrator.&lt;br /&gt;Add correct host key in /home/jmiranda/.ssh/known_hosts to get rid of this message.&lt;br /&gt;Offending key in /home/jmiranda/.ssh/known_hosts:2&lt;br /&gt;RSA host key for www.example.com has changed and you have requested strict checking.&lt;br /&gt;Host key verification failed.&lt;/span&gt;&lt;/blockquote&gt;I&#39;ve wasted a few minutes Googling the solution each time, so I&#39;m adding a blog entry for it now so that I have a reference to the solution next time it happens.&lt;br /&gt;&lt;blockquote style=&quot;font-family: courier new;&quot;&gt;&lt;span style=&quot;font-size:85%;&quot;&gt;jmiranda@jmiranda-laptop:~$ ssh-keygen -R www.example.com&lt;br /&gt;/home/jmiranda/.ssh/known_hosts updated.&lt;br /&gt;Original contents retained as /home/jmiranda/.ssh/known_hosts.old&lt;/span&gt;&lt;/blockquote&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.justinmiranda.com/feeds/5247313704346592016/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/6214277125099466960/5247313704346592016' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/5247313704346592016'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/5247313704346592016'/><link rel='alternate' type='text/html' href='http://blog.justinmiranda.com/2010/03/solved-rsa-host-key-has-changed.html' title='[SOLVED] RSA host key has changed'/><author><name>Justin Miranda</name><uri>http://www.blogger.com/profile/12794947822953373298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5AqKjeUVRaa2MOuWom3QvHZQDyyE6OPva7awOh5s6XMNh20agcuIoSFrRCkOKJxlNTuX1K85Lqolaaj9Tey0FhGtIO0VGfwOVEiDtrX9e89b6-sjCy-6ARG2xZSp89Do/s220/5493_128868133104_8302049_n+%28copy%29.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6214277125099466960.post-7145252744203537628</id><published>2010-02-15T15:40:00.002-05:00</published><updated>2010-02-15T15:41:01.569-05:00</updated><title type='text'>Syntax Highlighter</title><content type='html'>&lt;pre class=&quot;brush: java;&quot;&gt;&lt;br /&gt;function test() : String&lt;br /&gt;{&lt;br /&gt; return 10;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.justinmiranda.com/feeds/7145252744203537628/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/6214277125099466960/7145252744203537628' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/7145252744203537628'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/7145252744203537628'/><link rel='alternate' type='text/html' href='http://blog.justinmiranda.com/2010/02/syntax-highlighter.html' title='Syntax Highlighter'/><author><name>Justin Miranda</name><uri>http://www.blogger.com/profile/12794947822953373298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5AqKjeUVRaa2MOuWom3QvHZQDyyE6OPva7awOh5s6XMNh20agcuIoSFrRCkOKJxlNTuX1K85Lqolaaj9Tey0FhGtIO0VGfwOVEiDtrX9e89b6-sjCy-6ARG2xZSp89Do/s220/5493_128868133104_8302049_n+%28copy%29.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6214277125099466960.post-3195297134238428781</id><published>2010-02-15T14:26:00.025-05:00</published><updated>2010-02-18T20:01:10.050-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="hotswap"/><category scheme="http://www.blogger.com/atom/ns#" term="jrebel"/><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><category scheme="http://www.blogger.com/atom/ns#" term="tomcat"/><title type='text'>Hotswap This!</title><content type='html'>&lt;span style=&quot;font-style: italic; font-weight: bold;&quot;&gt;Update:  February 18, 2010&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;I just fixed the last two configuration issues and can now hotswap most classes, jsps, and other resources for both OpenMRS core and OpenMRS modules!  See the instructions below.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-style: italic; font-weight: bold;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-style: italic; font-weight: bold;&quot;&gt;Update:  February 17, 2010&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;This is AWESOME!  With the JRebel configuration (see below), I am now able to hotswap the following resources:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;web classes (e.g. modify existing controllers)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;api classes (e.g. create a new api class called Regimen)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;JSPs under WEB-INF (e.g. add or modify&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Controllers (e.g. create annotated controllers and JSPs)&lt;/li&gt;&lt;li&gt;messages.properties (e.g. change i18n properties on the fly)&lt;/li&gt;&lt;li&gt;Spring-managed objects get reloaded on the fly when you change any classes referenced in spring configuration files&lt;/li&gt;&lt;li&gt;module classes&lt;br /&gt;&lt;/li&gt;&lt;li&gt;module web resources like JSPs&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;I&#39;m still in the process of configuring/testing whether changes to the following resources:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;openmrs-servlet.xml (does not seem to hotswap these changes?)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;web.xml (does not seem to hotswap these changes by default?)&lt;/li&gt;&lt;li&gt;applicationContext-*.xml (?)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;dwr.xml (?)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;hibernate mapping files (supposed to be available in JRebel 3.0)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;hr /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Update:  February 15, 2010&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;This is still a work in progress, but I&#39;ve managed to configure JRebel, Tomcat, and Eclipse to hotswap classes within the core openmrs webapp as well as the reporting module.  This took a bit of work because of our custom classloaders and module framework as well as the fact that we&#39;ve adopted some pretty unconventional mechanisms within our current Ant build process and project structure.&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Overview&lt;/span&gt;&lt;br /&gt;Here&#39;s a brief summary of how JRebel works taken from the &lt;a style=&quot;font-weight: bold;&quot; href=&quot;http://www.zeroturnaround.com/jrebel/&quot;&gt;Zero Turnaround website&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;How does JRebel work?&lt;br /&gt;&lt;/span&gt;JRebel maps your project workspace directly to your running application. When you change any class or resource in your IDE, you can immediately see the change in your application, skipping the build and redeploy phases and reducing the 3-7 weeks your team wastes each year.&lt;br /&gt;&lt;/blockquote&gt;You can simply follow the instructions on the JRebel blog or the Reference Manaul included in the JRebel installation zipfile.  Here are a few of the resources that were used throughout the process:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://www.zeroturnaround.com/blog/how-to-install-and-use-jrebel-formerly-javarebel-in-tomcat-with-the-eclipse-ide/&quot;&gt;HOWTO Install and use JRebel with Tomcat and Eclipse&lt;br /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://www.zeroturnaround.com/reference-manual/&quot;&gt;Reference Manual&lt;br /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://www.zeroturnaround.com/jrebel/installation/&quot;&gt;Installation Guide&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://www.zeroturnaround.com/jrebel/configuration/&quot;&gt;Configuration Guide&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Here&#39;s the basic procedure that we need to follow:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Install JRebel&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Install the JRebel Eclipse plugin (optional)&lt;/li&gt;&lt;li&gt;Configure Eclipse&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Configure Tomcat&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Configure your application&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt; &lt;span style=&quot;font-weight: bold;&quot;&gt;Step 1 - Install JRebel&lt;/span&gt;&lt;br /&gt;Follow the instructions from the HOWTO guide above.  I installed JRebel to &lt;span style=&quot;font-weight: bold;&quot;&gt;/var/lib/jrebel&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Step 2 - Install the JRebel Eclipse&lt;/span&gt;&lt;br /&gt;Again, just follow the instructions in the HOWTO Guide.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Step 3 - Configure Eclipse &lt;/span&gt;&lt;br /&gt;Simply set the path to the JRebel JAR under &lt;span style=&quot;font-weight: bold;&quot;&gt;Window&lt;/span&gt; &gt; &lt;span style=&quot;font-weight: bold;&quot;&gt;Preferences&lt;/span&gt; &gt; &lt;span style=&quot;font-weight: bold;&quot;&gt;JRebel&lt;/span&gt; to &lt;span style=&quot;font-weight: bold;&quot;&gt;/var/lib/jrebel/jrebel.jar&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Step 4 - Configure Tomcat&lt;/span&gt;&lt;br /&gt;If you&#39;re running Tomcat on Windows/Mac you need to figure out how to add command-line options to the Tomcat start script or Tomcat Manager utility that eventually calls &lt;span style=&quot;font-weight: bold;&quot;&gt;java&lt;/span&gt; to start the Tomcat threads.  For Ubuntu users, locate the tomcat startup script (e.g. &lt;span style=&quot;font-weight: bold;&quot;&gt;/etc/init.d/tomcat5.5&lt;/span&gt;) and add the following &lt;span style=&quot;font-weight: bold;&quot;&gt;-noverify&lt;/span&gt; and &lt;span style=&quot;font-weight: bold;&quot;&gt;-javaagent&lt;/span&gt; options to the script&#39;s JAVA_OPTS value.&lt;br /&gt;&lt;br /&gt;I actually added the following three options to JAVA_OPTS:&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;-Xverify:none&lt;/span&gt;&lt;br /&gt;I still don&#39;t have a very clear idea of what this option does, but it seems to disable class verification and might have something to do with modification to constructors (see the Troubleshooting section below).&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;-javaagent:/var/lib/jrebel/jrebel.jar=org.openmrs.util.OpenmrsClassLoader,org.openmrs.module.ModuleClassLoader &lt;/span&gt;&lt;br /&gt;The java agent option is required to configure the JRebel JAR that is responsible for monitoring/reloading files when they are modified.  Note that we had to add the &lt;span style=&quot;font-weight: bold;&quot;&gt;OpenmrsClassLoader&lt;/span&gt; and &lt;span style=&quot;font-weight: bold;&quot;&gt;ModuleClassLoader&lt;/span&gt; classes to let JRebel know where to locate/reload classes.&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;br /&gt;-Drebel.log=true&lt;br /&gt;&lt;/span&gt;Included for debugging purposes only.&lt;br /&gt;&lt;br /&gt;Your JAVA_OPTS variable should/might look similar to mine (displayed below):&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: plain;&quot;&gt;JAVA_OPTS=&quot;-noverify -javaagent:/var/lib/jrebel/jrebel.jar=org.openmrs.util.OpenmrsClassLoader,org.openmrs.module.ModuleClassLoader -Drebel.log=true $JAVA_OPTS -Xmx512m -Xms512m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:NewSize=128m -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5000&quot;&lt;br /&gt;&lt;/pre&gt; More options can be found in the JRebel &lt;a href=&quot;http://www.zeroturnaround.com/jrebel/configuration/&quot;&gt;Configuration Guide&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Step 5 - Configure your application&lt;/span&gt;&lt;br /&gt;Now here&#39;s the part that needs to be Create a rebel.xml file and place this under TOMCAT_HOME/webapps/openmrs/WEB-INF/classes.  Eventually, this file could be included within the OpenMRS source and deployed within the WAR file on it&#39;s initial deployment, but unfortunately our WEB-INF source directory is a little &quot;crazy&quot; at the moment and getting the file into WEB-INF/classes would require some changes to the Ant build.xml file.  For now, it would be better if we required developers to configure JRebel on their own.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;rebel.xml&lt;/span&gt;&lt;br /&gt;&lt;pre class=&quot;brush: xml;&quot;&gt;&lt;br /&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;br /&gt;&amp;lt;application&lt;br /&gt;xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&lt;br /&gt;xmlns=&quot;http://www.zeroturnaround.com&quot;&lt;br /&gt;xsi:schemaLocation=&quot;http://www.zeroturnaround.com http://www.zeroturnaround.com/alderaan/rebel-2_0.xsd&quot;&amp;gt;&lt;br /&gt;&amp;lt;classpath&amp;gt;&lt;br /&gt;&amp;lt;dir name=&quot;/home/jmiranda/Workspace/openmrs-1.6.x-trunk/build&quot;&amp;gt;&amp;lt;/dir&amp;gt;&lt;br /&gt;&amp;lt;dir name=&quot;/home/jmiranda/Workspace/module-reporting-trunk/build&quot;&amp;gt;&amp;lt;/dir&amp;gt;&lt;br /&gt;&amp;lt;dir name=&quot;/home/jmiranda/Workspace/module-serialization.xstream/build&quot;&amp;gt;&amp;lt;/dir&amp;gt;&lt;br /&gt;&amp;lt;dir name=&quot;/home/jmiranda/Workspace/module-htmlwidgets/build&quot;&amp;gt;&amp;lt;/dir&amp;gt;&lt;br /&gt;&amp;lt;/classpath&amp;gt;&lt;br /&gt;&amp;lt;web&amp;gt;&lt;br /&gt;&amp;lt;link target=&quot;WEB-INF/&quot;&amp;gt;&lt;br /&gt;  &amp;lt;dir name=&quot;/home/jmiranda/Workspace/openmrs-1.6.x-trunk/web/WEB-INF&quot;&amp;gt;&lt;br /&gt;     &amp;lt;exclude name=&quot;**/*.xml&quot;/&amp;gt;&lt;br /&gt;  &amp;lt;/dir&amp;gt;&lt;br /&gt;&amp;lt;/link&amp;gt;&lt;br /&gt;&amp;lt;/web&amp;gt;&lt;br /&gt;&amp;lt;web&amp;gt;&lt;br /&gt;&amp;lt;link target=&quot;WEB-INF/view/module/reporting/&quot;&amp;gt;&lt;br /&gt;  &amp;lt;dir name=&quot;/home/jmiranda/Workspace/module-reporting-trunk/web/module&quot;&amp;gt;&lt;br /&gt;      &amp;lt;exclude name=&quot;**/*.xml&quot;/&amp;gt;&lt;br /&gt;  &amp;lt;/dir&amp;gt;&lt;br /&gt;&amp;lt;/link&amp;gt;&lt;br /&gt;&amp;lt;/web&amp;gt;&lt;br /&gt;&amp;lt;/application&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Step 6 - Restart Tomcat&lt;/span&gt;&lt;br /&gt;Any time you make a change to the rebel.xml file, you should restart Tomcat.  For me, after playing around with JRebel and the rebel.xml file for a little while, hotswapping of web classes started working.  Now I need to test whether the service layer is&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Next Steps &lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Configure with Eclipse IDE using WTP Server Integration with Tomcat, Glassfish&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Troubleshooting&lt;/span&gt;&lt;br /&gt;I ran into a couple of issues while working on this little project.  These are all sort of fixed at this point, but I&#39;m not entirely thrilled with the solutions so suggestions would be much appreciated.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;[SOLVED] &lt;/span&gt;Invalid option -noverify&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;[SOLVED] &lt;/span&gt;JspRemovedException&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;[WORKAROUND] &lt;/span&gt;I/O failure during classpath scanning&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;[SOLVED] &lt;/span&gt;Unable to refresh JSPs on save&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;[SOLVED]&lt;/span&gt; BeanCurrentlyInCreationException: Error creating bean with name &#39;sessionFactory&#39;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;[SOLVED] Invalid option -noverify&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Problem&lt;/span&gt;&lt;br /&gt;Unfortunately, when I include the &lt;span style=&quot;font-weight: bold;&quot;&gt;-noverify&lt;/span&gt; option within the &lt;span style=&quot;font-weight: bold;&quot;&gt;JAVA_OPTS&lt;/span&gt; variable, I get an error (see below) during Tomcat 5.5 startup.  I&lt;br /&gt;need to do a little more research on this one, but for now I just&lt;br /&gt;remove the -noverify option.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Invalid option -noverify&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Cannot parse command line arguments&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;  &lt;span style=&quot;font-style: italic;&quot;&gt;Workaround&lt;/span&gt;&lt;br /&gt;Remove the -noverify option.  However, when starting Tomcat 5.5 with the &quot;-noverify&quot; option removed, I get the following warning in the JRebel log.  I can live with not being able to hotswap classes that have changes to their constructor, but if anyone can figure this out, please let me know.  I&#39;m hoping this does not prevent hotswapping of newly defined classes.&lt;br /&gt;&lt;blockquote style=&quot;font-style: italic;&quot;&gt;JRebel: &#39;-noverify&#39; missing, changing/adding/removing constructors will not be enabled!&lt;br /&gt;&lt;/blockquote&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Solution&lt;/span&gt;&lt;br /&gt;Thanks to Jevgeni (from ZeroTurnaround - it&#39;s even true with blog comments) we resolved this issue by using the alternative syntax (&lt;span style=&quot;font-weight: bold;&quot;&gt;Xverify:none&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;[SOLVED] JspRemovedException&lt;/span&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;&lt;br /&gt;Problem&lt;/span&gt;&lt;br /&gt;&lt;pre class=&quot;brush: plain;&quot;&gt;ERROR - ApplicationDispatcher.invoke(711) |2010-02-13 12:33:48,206| Servlet.service() for servlet jsp threw exception&lt;br /&gt;org.zeroturnaround.javarebel.integration.jasper.JspRemovedException: /WEB-INF/view/module/reporting/reports/manageReportDesigns.jsp&lt;br /&gt;at org.apache.jasper.compiler.Compiler.isOutDated(Compiler.java)&lt;br /&gt;at org.apache.jasper.compiler.Compiler.isOutDated(Compiler.java:333)&lt;br /&gt;at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:561)&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Solution&lt;/span&gt;&lt;br /&gt;I believe this was before I added support for the /openmrs/module/reporting &quot;web&quot; resources to the JRebel configuration.  This exception was probably caused by the fact that JRebel was resolving all JSP/class files to the /openmrs &quot;web&quot;.  Therefore, by adding in another &quot;web&quot; element for the reporting module, JRebel is able to resolve the module&#39;s files correctly.  However, this means that we need to manually add a &quot;web&quot; element for each new module that we deploy.  Not a big deal, but it would be nice to find a way to include a rebel.xml within each module and allow that file to be picked up by JRebel at deployment time.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;[WORKAROUND] FileNotFoundException: I/O failure during classpath scanning&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;&lt;br /&gt;Problem&lt;/span&gt;&lt;br /&gt;&lt;pre class=&quot;brush: plain&quot;&gt;ERROR - ContextLoader.initWebApplicationContext(215) |2010-02-13 02:40:39,394| Context initialization failed&lt;br /&gt;org.springframework.beans.factory.BeanDefinitionStoreException: I/O failure during classpath scanning; nested exception is java.io.FileNotFoundException: class path resource [org/springframework/test/context&lt;br /&gt;/support/AbstractTestExecutionListener.class] cannot be opened because it does not exist&lt;br /&gt;at org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.findCandidateComponents(ClassPathScanningCandidateComponentProvider.java:222)&lt;br /&gt;at org.springframework.context.annotation.ClassPathBeanDefinitionScanner.doScan(ClassPathBeanDefinitionScanner.java:201)&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Solution (temporary)&lt;/span&gt;&lt;br /&gt;I temporarily fixed this by adding the spring-test.jar to TOMCAT_HOME/webapps/openmrs/WEB-INF/lib.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;[SOLVED] Unable to refresh JSPs on save&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Problem&lt;/span&gt;&lt;br /&gt;This would appear to be the easiest thing to get working, but I&#39;ve only spent a few minutes trying to configure it to work.  We can still use the &lt;span style=&quot;font-weight: bold;&quot;&gt;deploy-web&lt;/span&gt; target within our Ant build.xml for the time being, but it would awesome to get all classes/web resources being hotswapped when they are modified within Eclipse.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Solution&lt;/span&gt;&lt;br /&gt;This was solved by making sure to specify the correct &lt;span style=&quot;font-weight: bold;&quot;&gt;web &gt; link target&lt;/span&gt; in the rebel.xml configuration.  I was incorrectly using the webapp context (e.g. &lt;span style=&quot;font-weight: bold;&quot;&gt;/openmrs&lt;/span&gt;) instead of the webapp root config directory &lt;span style=&quot;font-weight: bold;&quot;&gt;(e.g. WEB-INF).  &lt;/span&gt;I still need to make sure to incorporate all resources above WEB-INF including openmrs.css, openmrs.js, and others.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;[SOLVED] BeanCurrentlyInCreationException: Error creating bean with name &#39;sessionFactory&#39;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Problem&lt;/span&gt;&lt;br /&gt;&lt;pre class=&quot;brush: plain;&quot;&gt;&lt;br /&gt;Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name &#39;hL7ServiceTarget&#39; defined in class path resource [applicationContext-service.xml]: Cannot resolve reference to bean &#39;hL7DAO&#39; while setting bean property &#39;HL7DAO&#39;; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name &#39;hL7DAO&#39; defined in class path resource [applicationContext-service.xml]: Cannot resolve reference to bean &#39;sessionFactory&#39; while setting bean property &#39;sessionFactory&#39;; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name &#39;sessionFactory&#39;: FactoryBean which is currently in creation returned null from getObject&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Solution&lt;/span&gt;&lt;br /&gt;This was solved by adding in an exclude element into the web &gt; link &gt; dir compoment.  This prevents the Spring configuration files from being read multiple times (JRebel already appears to be handling it through its Spring plugin).&lt;br /&gt;&lt;pre class=&quot;brush: xml;&quot;&gt;&lt;br /&gt; &amp;lt;web&amp;gt;&lt;br /&gt;   &amp;lt;link target=&quot;WEB-INF/&quot;&amp;gt;&lt;br /&gt;     &amp;lt;dir name=&quot;/home/jmiranda/Workspace/openmrs-1.6.x-trunk/web/WEB-INF&quot;&amp;gt;&lt;br /&gt;        &amp;lt;exclude name=&quot;**/*.xml&quot;/&amp;gt;&lt;br /&gt;     &amp;lt;/dir&amp;gt;&lt;br /&gt;   &amp;lt;/link&amp;gt;&lt;br /&gt; &amp;lt;/web&amp;gt;&lt;br /&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.justinmiranda.com/feeds/3195297134238428781/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/6214277125099466960/3195297134238428781' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/3195297134238428781'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/3195297134238428781'/><link rel='alternate' type='text/html' href='http://blog.justinmiranda.com/2010/02/hotswap-this.html' title='Hotswap This!'/><author><name>Justin Miranda</name><uri>http://www.blogger.com/profile/12794947822953373298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5AqKjeUVRaa2MOuWom3QvHZQDyyE6OPva7awOh5s6XMNh20agcuIoSFrRCkOKJxlNTuX1K85Lqolaaj9Tey0FhGtIO0VGfwOVEiDtrX9e89b6-sjCy-6ARG2xZSp89Do/s220/5493_128868133104_8302049_n+%28copy%29.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6214277125099466960.post-5523305616960844932</id><published>2010-02-13T12:54:00.008-05:00</published><updated>2010-02-13T13:06:35.812-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="openmrs hotswap tomcat jrebel"/><title type='text'>HOWTO Hotswap OpenMRS webapp and modules (without redeploying)</title><content type='html'>First of all, JRebel is amazing.   In an effort to reduce development time, I ran across JRebel (thanks Christian), a tool that allows you to reload a webapp (jsps, classes, jars) without the need to redeploy the entire application.&lt;br /&gt;&lt;br /&gt;So far, I&#39;ve been able to configure Eclipse/Tomcat to hotswap classes from OpenMRS core and modules without the need for redeploying the entire webapp.  I&#39;m currently working on getting the JSPs to be reloaded on save from within Eclipse, rather than requiring us to run deploy-web.&lt;br /&gt;&lt;br /&gt;Download JRebel from the ZeroTurnaround site&lt;br /&gt;http://www.zeroturnaround.com/&lt;br /&gt;&lt;br /&gt;Very exciting.  More details about how to configure JRebel coming soon ...</content><link rel='replies' type='application/atom+xml' href='http://blog.justinmiranda.com/feeds/5523305616960844932/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/6214277125099466960/5523305616960844932' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/5523305616960844932'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/5523305616960844932'/><link rel='alternate' type='text/html' href='http://blog.justinmiranda.com/2010/02/howto-reloading-openmrs-classes-without.html' title='HOWTO Hotswap OpenMRS webapp and modules (without redeploying)'/><author><name>Justin Miranda</name><uri>http://www.blogger.com/profile/12794947822953373298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5AqKjeUVRaa2MOuWom3QvHZQDyyE6OPva7awOh5s6XMNh20agcuIoSFrRCkOKJxlNTuX1K85Lqolaaj9Tey0FhGtIO0VGfwOVEiDtrX9e89b6-sjCy-6ARG2xZSp89Do/s220/5493_128868133104_8302049_n+%28copy%29.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6214277125099466960.post-8649100259914169426</id><published>2009-12-17T16:08:00.003-05:00</published><updated>2009-12-17T16:22:48.107-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mysql"/><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><title type='text'>On backing up and restoring large mysql databases</title><content type='html'>In order to improve the performance of mysql when dealing with large databases, there&#39;s a couple of settings that can be tweaked in your my.cnf file (or through a MySQL administration tool).  The following line has proven to be the most useful. &lt;br /&gt;&lt;br /&gt;innodb_buffer_pool_size  = 1G&lt;br /&gt;&lt;br /&gt;I&#39;ve been meaning to write about this improvement for the last few weeks, but I wanted to test it myself first.  So far I&#39;m very pleased with the performance improvement (database restore time is down from about 3 hours to about 45 minutes on a ~1.2G database).  I haven&#39;t tested how this setting affects MySQL during normal execution, but it certainly helps improve performance during backups and restores.  So if you find yourself backing up and restoring large MySQL databases, you should test this out.  You should (obviously) not set innodb_buffer_pool_size to a value greater than the available memory on your machine.   &lt;br /&gt;&lt;br /&gt;Thanks to Marc Harrison for the tip. &lt;br /&gt;&lt;br /&gt;If you want to read some more about this configuration, I found a couple of blog entries from a few years ago  Enjoy!&lt;br /&gt;&lt;br /&gt;http://www.mysqlperformanceblog.com/2007/11/01/innodb-performance-optimization-basics/&lt;br /&gt;http://www.mysqlperformanceblog.com/2007/11/03/choosing-innodb_buffer_pool_size/</content><link rel='replies' type='application/atom+xml' href='http://blog.justinmiranda.com/feeds/8649100259914169426/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/6214277125099466960/8649100259914169426' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/8649100259914169426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/8649100259914169426'/><link rel='alternate' type='text/html' href='http://blog.justinmiranda.com/2009/12/on-backing-up-and-restoring-large-mysql.html' title='On backing up and restoring large mysql databases'/><author><name>Justin Miranda</name><uri>http://www.blogger.com/profile/12794947822953373298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5AqKjeUVRaa2MOuWom3QvHZQDyyE6OPva7awOh5s6XMNh20agcuIoSFrRCkOKJxlNTuX1K85Lqolaaj9Tey0FhGtIO0VGfwOVEiDtrX9e89b6-sjCy-6ARG2xZSp89Do/s220/5493_128868133104_8302049_n+%28copy%29.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6214277125099466960.post-4866695369837497956</id><published>2009-12-16T01:23:00.006-05:00</published><updated>2009-12-16T01:50:32.062-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="openmrs tomcat mac osx"/><title type='text'>On setting up a development environment in Mac OS X 10.6 Snow Leopard</title><content type='html'>&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;http://www.prepressure.com/images/prepress_history_macplus.jpg&quot;&gt;&lt;img style=&quot;margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 205px; height: 195px;&quot; src=&quot;http://www.prepressure.com/images/prepress_history_macplus.jpg&quot; alt=&quot;&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;I just bought the new &lt;a href=&quot;http://www.apple.com/macmini/&quot;&gt;Mac Mini&lt;/a&gt; from Apple.  It&#39;s my first Mac since the &lt;a href=&quot;http://en.wikipedia.org/wiki/Macintosh_Plus&quot;&gt;Mac Plus&lt;/a&gt; of the early 90&#39;s and I have to say ... it feels good to be back.  I still love doing development on Ubuntu, but Mac OS X is easy to get used to and a lot of fun to play around with.  Nothing compares to &quot;apt-get install ...&quot; (on Ubuntu) when getting a development environment set up, but &lt;a href=&quot;http://www.malisphoto.com/tips/tomcatonosx.html&quot;&gt;this tutorial for Tomcat 6&lt;/a&gt; probably saved me a couple of hours of agony of going it alone.</content><link rel='replies' type='application/atom+xml' href='http://blog.justinmiranda.com/feeds/4866695369837497956/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/6214277125099466960/4866695369837497956' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/4866695369837497956'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/4866695369837497956'/><link rel='alternate' type='text/html' href='http://blog.justinmiranda.com/2009/12/on-setting-up-development-environment.html' title='On setting up a development environment in Mac OS X 10.6 Snow Leopard'/><author><name>Justin Miranda</name><uri>http://www.blogger.com/profile/12794947822953373298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5AqKjeUVRaa2MOuWom3QvHZQDyyE6OPva7awOh5s6XMNh20agcuIoSFrRCkOKJxlNTuX1K85Lqolaaj9Tey0FhGtIO0VGfwOVEiDtrX9e89b6-sjCy-6ARG2xZSp89Do/s220/5493_128868133104_8302049_n+%28copy%29.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6214277125099466960.post-869713946409818668</id><published>2009-12-03T15:24:00.010-05:00</published><updated>2009-12-03T15:35:14.869-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="openmrs svn subversion bestpractice convention"/><title type='text'>Fixing an existing subversion project to migrate to the trunk/branches/tags convention</title><content type='html'>Here&#39;s the procedure I used to move an existing &quot;dumb&quot; subversion project to one that follows the subversion convention (trunk/branches/svn).  It&#39;s a combination of the two ideas presented in the articles below.  More steps then I was hoping for, but it&#39;s a pretty simple-to-follow solution and much less aggravating than the Eclipse approach.&lt;br /&gt;&lt;br /&gt;(this procedure assumes that you are using &lt;span style=&quot;font-weight: bold;&quot;&gt;Linux&lt;/span&gt;, but the process would be similar on Windows or Mac)&lt;br /&gt;&lt;br /&gt;  // 1. Checkout a fresh copy of your project&lt;br /&gt;$ svn co &lt;a class=&quot;moz-txt-link-freetext&quot; href=&quot;http://svn.openmrs.org/openmrs-modules/serialization.xstream&quot;&gt;http://svn.myproject.com/myproject&lt;/a&gt; myproject&lt;br /&gt; &lt;br /&gt;// 2. Change directories to make it easier perform svn operations&lt;br /&gt;$ cd myproject&lt;br /&gt; &lt;br /&gt;// 3. Add the new trunk directory&lt;br /&gt;$ svn mkdir trunk&lt;br /&gt; &lt;br /&gt;// 4. Locate all files/dirs in the current directory and svn move them to the trunk directory&lt;br /&gt;$ find . -maxdepth 1 ! -name trunk -exec svn mv &#39;{}&#39; trunk \;&lt;br /&gt; &lt;br /&gt;// 5. Double check that all files have been svn move&#39;d (.classpath, .project, build.xml, etc)&lt;br /&gt;$ ls -la trunk&lt;br /&gt; &lt;br /&gt;// 6. Commit all changes&lt;br /&gt;$ svn ci -m &quot;myproject: moving all files from myproject into myproject/trunk&quot;&lt;br /&gt; &lt;br /&gt;// 7. Switch your local copy of the module to&lt;br /&gt;$ svn switch &lt;a class=&quot;moz-txt-link-freetext&quot; href=&quot;http://svn.openmrs.org/openmrs-modules/serialization.xstream/trunk&quot;&gt;http://svn.myproject.com/myproject/trunk&lt;/a&gt; myproject&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Resources:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a send=&quot;true&quot; href=&quot;http://www.ramblingengineer.com/2009/08/03/fixing-subversion-branch-and-trunk-directories/&quot;&gt;http://www.ramblingengineer.com/2009/08/03/fixing-subversion-branch-and-trunk-directories&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a class=&quot;moz-txt-link-freetext&quot; href=&quot;http://stackoverflow.com/questions/345683/svn-creating-trunk-directory-on-existing-repository&quot;&gt;http://stackoverflow.com/questions/345683/svn-creating-trunk-directory-on-existing-repository&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.justinmiranda.com/feeds/869713946409818668/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/6214277125099466960/869713946409818668' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/869713946409818668'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/869713946409818668'/><link rel='alternate' type='text/html' href='http://blog.justinmiranda.com/2009/12/fixing-existing-subversion-project-to.html' title='Fixing an existing subversion project to migrate to the trunk/branches/tags convention'/><author><name>Justin Miranda</name><uri>http://www.blogger.com/profile/12794947822953373298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5AqKjeUVRaa2MOuWom3QvHZQDyyE6OPva7awOh5s6XMNh20agcuIoSFrRCkOKJxlNTuX1K85Lqolaaj9Tey0FhGtIO0VGfwOVEiDtrX9e89b6-sjCy-6ARG2xZSp89Do/s220/5493_128868133104_8302049_n+%28copy%29.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6214277125099466960.post-4711619309992433433</id><published>2009-10-29T11:22:00.002-04:00</published><updated>2009-12-03T15:22:44.063-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="openmrs training developers"/><title type='text'>OpenMRS Developers Conference (Oct 2009)</title><content type='html'>&lt;span style=&quot;font-size:100%;&quot;&gt;OpenMRS Developers Conference in Latin America&lt;br /&gt;&lt;br /&gt;The following document was used by the developers/trainers at the OpenMRS Developer&#39;s Conference in Lima, Peru.  We kept track of the agenda and topics we discussed during the week in order to possible create a curriculum for future training sessions.  I&#39;d be glad to discuss this with anyone who is looking to create training manuals for both short and long-term training sessions on OpenMRS-related technologies.&lt;br /&gt;&lt;br /&gt;This document is still pretty raw, but feel free to use bits and pieces if you find them useful.&lt;br /&gt;&lt;/span&gt;http://docs.google.com/View?id=dnc9s5q_10gb5qb4dn</content><link rel='replies' type='application/atom+xml' href='http://blog.justinmiranda.com/feeds/4711619309992433433/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/6214277125099466960/4711619309992433433' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/4711619309992433433'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/4711619309992433433'/><link rel='alternate' type='text/html' href='http://blog.justinmiranda.com/2009/10/openmrs-conference-developers.html' title='OpenMRS Developers Conference (Oct 2009)'/><author><name>Justin Miranda</name><uri>http://www.blogger.com/profile/12794947822953373298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5AqKjeUVRaa2MOuWom3QvHZQDyyE6OPva7awOh5s6XMNh20agcuIoSFrRCkOKJxlNTuX1K85Lqolaaj9Tey0FhGtIO0VGfwOVEiDtrX9e89b6-sjCy-6ARG2xZSp89Do/s220/5493_128868133104_8302049_n+%28copy%29.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6214277125099466960.post-8334186703244974140</id><published>2009-09-21T10:27:00.012-04:00</published><updated>2009-10-27T10:52:00.428-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="api"/><category scheme="http://www.blogger.com/atom/ns#" term="extending"/><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><category scheme="http://www.blogger.com/atom/ns#" term="reporting"/><title type='text'>Extending the OpenMRS Reporting API:  Cohort Queries</title><content type='html'>&lt;span style=&quot;font-size:130%;&quot;&gt;Introduction&lt;/span&gt;&lt;br /&gt;At the Cape Town meeting last week, we demo&#39;d (if you could call it that) the new reporting framework and some of the early versions of tools that we&#39;ve built on top of it.  Some of those tools have been described in recent entries and others are still undocumented.  That will change soon.  The UI and tool set for the reporting framework is still immature, but we&#39;re happy with what we&#39;ve come up with from an API standpoint.  As a developer, you *should* be able to do most of what you need with what exists.  However, there will be instances where you need to extend the framework to do what you want.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;NOTE:  If anyone knows a good plugin to include code snippets in Blogger, please let me know.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size:100%;&quot;&gt;&lt;span style=&quot;font-size:130%;&quot;&gt;Extending the Cohort Query&lt;/span&gt; &lt;/span&gt;&lt;br /&gt;Here&#39;s a quick example of how to use the API to evaluate a cohort definition.  This will return you a list of patients that can be used as input into another piece of code.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// Define the cohort definition&lt;br /&gt;GenderCohortDefinition gcd = new GenderCohortDefinition();&lt;br /&gt;gcd.setGender(&quot;M&quot;);&lt;br /&gt;&lt;br /&gt;// Evaluate the cohort definition&lt;br /&gt;Cohort males = Context.getService(CohortDefinitionService.class).evaluate(gcd, new EvaluationContext());&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This is a pretty trivial example, but there are lots of cohort definitions in the system that will allow you to do more complex queries.  With that said, there will likely be a time when you need to implement a cohort query that is not currently supported within the framework.&lt;br /&gt;&lt;br /&gt;For instance, let&#39;s say that the Ministry of Health within the country you work calls your mobile and says &quot;Hey, Justin ... we need to report on the number of patients that have had the XYZ form completed on a certain date or in the past month/year&quot;.&lt;br /&gt;&lt;br /&gt;In order to extend the system to support this query, we need to do three things:  (1) write a new cohort definition to define this query, (2) write the evaluator to evaluate the cohort definition and return a cohort.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size:100%;&quot;&gt;&lt;span style=&quot;font-size:130%;&quot;&gt;0)  Write a JUnit test that tests what your new cohort definition should do &lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class FormCohortDefinitionEvaluatorTest extends BaseModuleContextSensitiveTest {&lt;br /&gt;&lt;br /&gt; private Log log = LogFactory.getLog(this.getClass());&lt;br /&gt;&lt;br /&gt; @Test&lt;br /&gt; public void evaluate_shouldReturnPatientsWhoHadFormCompletedOnDate() throws Exception {&lt;br /&gt;     FormCohortDefinition fcd = new FormCohortDefinition();&lt;br /&gt;     fcd.setForms(Context.getFormService().getAllForms());    &lt;br /&gt;     Calendar newYears = Calendar.getInstance();&lt;br /&gt;     newYears.set(2009, 0, 1);    &lt;br /&gt;     EvaluationContext evalContext = new EvaluationContext();&lt;br /&gt;     evalContext.addParameterValue(&quot;sinceDate&quot;, newYears.getTime());&lt;br /&gt;     evalContext.addParameterValue(&quot;untilDate&quot;, newYears.getTime());    &lt;br /&gt; &lt;br /&gt;     Cohort cohort = Context.getService(CohortDefinitionService.class).evaluate(fcd, evalContext);&lt;br /&gt;     Assert.assertEquals(1, cohort.getSize());&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size:130%;&quot;&gt;1) Write the cohort definition&lt;br /&gt;&lt;/span&gt;So the first step is to define the cohort definition.  We just need to extend the DateRangeCohortDefinition to allow dates to be specified as properties or parameters and add a &quot;forms&quot; property that will be used to allow a user to select forms in the system.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class FormCohortDefinition extends DateRangeCohortDefinition {&lt;br /&gt;&lt;br /&gt; private static final long serialVersionUID = 1L;&lt;br /&gt;&lt;br /&gt; @ConfigurationProperty(required=false)&lt;br /&gt; private List&amp;lt;Form&amp;gt; forms;&lt;br /&gt;&lt;br /&gt; public FormCohortDefinition() {&lt;br /&gt;     super();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public List&amp;lt;Form&amp;gt; getForms() {&lt;br /&gt;     return forms;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void setForms(List&amp;lt;Form&amp;gt; forms) {&lt;br /&gt;     this.forms = forms;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size:130%;&quot;&gt;2)  Write the cohort definition evaluator&lt;br /&gt;&lt;/span&gt;&lt;pre&gt;&lt;br /&gt;@Handler(supports={FormCohortDefinition.class})&lt;br /&gt;public class FormCohortDefinitionEvaluator implements CohortDefinitionEvaluator {&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Default Constructor&lt;br /&gt;  */&lt;br /&gt; public FormCohortDefinitionEvaluator() {}&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * @see CohortDefinitionEvaluator#evaluateCohort(CohortDefinition, EvaluationContext)&lt;br /&gt;  */&lt;br /&gt; public Cohort evaluate(CohortDefinition cohortDefinition, EvaluationContext context) {&lt;br /&gt;     FormCohortDefinition fcd = (FormCohortDefinition) cohortDefinition;&lt;br /&gt;     Date fromDate = fcd.getCalculatedFromDate(context);&lt;br /&gt;     Date toDate = fcd.getCalculatedToDate(context);&lt;br /&gt;     Cohort cohort = new Cohort();&lt;br /&gt; &lt;br /&gt;     PatientSetService pss = Context.getPatientSetService();    &lt;br /&gt;     for (Form form : fcd.getForms()) {&lt;br /&gt;         List&lt;encountertype&gt; types = null;&lt;br /&gt;         Cohort tempCohort = pss.getPatientsHavingEncounters(types, null, form, fromDate, toDate, null, null);        &lt;br /&gt;         cohort = Cohort.union(cohort, tempCohort);&lt;br /&gt;     }&lt;br /&gt;     return cohort;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I want to use the API (instead of writing my own DAO, so we have to do something slightly stupid here.  The PatientSetService.getPatientsHavingEncounters(...) method only takes a single form as a parameter, therefore I need to iterate over the forms in the cohort definition and call the API each time.  If performance was an issue (and if I had more time) I would write a DAO that does the actually query I want.  But neither of those statements are true, so this is a perfectly good solution.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size:130%;&quot;&gt;3.)  Now, let&#39;s can go back and run our JUnit test ... and hopefully see green.&lt;br /&gt;&lt;/span&gt;&lt;pre&gt;&lt;br /&gt;INFO - LoggingAdvice.invoke(102) |2009-09-21 17:13:46,399| In method CohortDefinitionService.evaluate. Arguments: CohortDefinition=null, EvaluationContext=org.openmrs.module.evaluation.EvaluationContext@1d742a1,&lt;br /&gt;INFO - LoggingAdvice.invoke(127) |2009-09-21 17:13:46,528| Exiting method evaluate&lt;br /&gt;INFO - FormCohortDefinitionEvaluatorTest.evaluate_shouldEvaluate(51) |2009-09-21 17:13:46,536| # of patients: 1&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbj0P0q4IMqLXM4y_k_EnwFYMs5nl33buA6JfeVbT9qIJws8fCvi5atO1_bS_fdWkRSuh8mq8m3IdsxC9tUGQh2vfj8QNs7esO7_KevXCPeZv-q2mPRhXglzg07En0VYQQL6IA07GVz67N/s1600-h/Screenshot-Java+EE+-+module-reporting-core-test-api-org-openmrs-module-cohort-definition-evaluator-FormCohortDefinitionEvaluatorTest.java+-+Eclipse+Platform+.png&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 423px; height: 245px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbj0P0q4IMqLXM4y_k_EnwFYMs5nl33buA6JfeVbT9qIJws8fCvi5atO1_bS_fdWkRSuh8mq8m3IdsxC9tUGQh2vfj8QNs7esO7_KevXCPeZv-q2mPRhXglzg07En0VYQQL6IA07GVz67N/s200/Screenshot-Java+EE+-+module-reporting-core-test-api-org-openmrs-module-cohort-definition-evaluator-FormCohortDefinitionEvaluatorTest.java+-+Eclipse+Platform+.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5383945997812539042&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;/code&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.justinmiranda.com/feeds/8334186703244974140/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/6214277125099466960/8334186703244974140' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/8334186703244974140'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/8334186703244974140'/><link rel='alternate' type='text/html' href='http://blog.justinmiranda.com/2009/09/extending-openmrs-reporting-api-cohort.html' title='Extending the OpenMRS Reporting API:  Cohort Queries'/><author><name>Justin Miranda</name><uri>http://www.blogger.com/profile/12794947822953373298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5AqKjeUVRaa2MOuWom3QvHZQDyyE6OPva7awOh5s6XMNh20agcuIoSFrRCkOKJxlNTuX1K85Lqolaaj9Tey0FhGtIO0VGfwOVEiDtrX9e89b6-sjCy-6ARG2xZSp89Do/s220/5493_128868133104_8302049_n+%28copy%29.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbj0P0q4IMqLXM4y_k_EnwFYMs5nl33buA6JfeVbT9qIJws8fCvi5atO1_bS_fdWkRSuh8mq8m3IdsxC9tUGQh2vfj8QNs7esO7_KevXCPeZv-q2mPRhXglzg07En0VYQQL6IA07GVz67N/s72-c/Screenshot-Java+EE+-+module-reporting-core-test-api-org-openmrs-module-cohort-definition-evaluator-FormCohortDefinitionEvaluatorTest.java+-+Eclipse+Platform+.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6214277125099466960.post-4694654803629892696</id><published>2009-08-07T13:26:00.003-04:00</published><updated>2009-08-10T18:08:59.819-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><category scheme="http://www.blogger.com/atom/ns#" term="reporting"/><category scheme="http://www.blogger.com/atom/ns#" term="usability"/><title type='text'>On the Cohort Dashboard (implementation)</title><content type='html'>So here&#39;s the first pass at an implementation of the Cohort Dashboard.  The only thing that is currently working is the fact that we can pass this page a cohort.  The rest of the functionality still needs to be implemented.  Let me know what you think.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFtkFqy9VPP4XsD7RfJHe9Qgls4Nh41FEHKCUwnXNqEKtnJ0kB202zBs4L4YCu7dmPN5_a9CmX9dEa6Qn6aEePeph66AdMHfVeKuJJZmoQ-B-Byur1ovyNvgk3X8d_Rx6UUgoaFOXjSGV3/s1600-h/cohort-dashboard.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 178px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFtkFqy9VPP4XsD7RfJHe9Qgls4Nh41FEHKCUwnXNqEKtnJ0kB202zBs4L4YCu7dmPN5_a9CmX9dEa6Qn6aEePeph66AdMHfVeKuJJZmoQ-B-Byur1ovyNvgk3X8d_Rx6UUgoaFOXjSGV3/s400/cohort-dashboard.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5367275104729404434&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.justinmiranda.com/feeds/4694654803629892696/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/6214277125099466960/4694654803629892696' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/4694654803629892696'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/4694654803629892696'/><link rel='alternate' type='text/html' href='http://blog.justinmiranda.com/2009/08/on-cohort-dashboard-initial.html' title='On the Cohort Dashboard (implementation)'/><author><name>Justin Miranda</name><uri>http://www.blogger.com/profile/12794947822953373298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5AqKjeUVRaa2MOuWom3QvHZQDyyE6OPva7awOh5s6XMNh20agcuIoSFrRCkOKJxlNTuX1K85Lqolaaj9Tey0FhGtIO0VGfwOVEiDtrX9e89b6-sjCy-6ARG2xZSp89Do/s220/5493_128868133104_8302049_n+%28copy%29.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFtkFqy9VPP4XsD7RfJHe9Qgls4Nh41FEHKCUwnXNqEKtnJ0kB202zBs4L4YCu7dmPN5_a9CmX9dEa6Qn6aEePeph66AdMHfVeKuJJZmoQ-B-Byur1ovyNvgk3X8d_Rx6UUgoaFOXjSGV3/s72-c/cohort-dashboard.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6214277125099466960.post-7432169785269515562</id><published>2009-08-06T10:25:00.005-04:00</published><updated>2009-08-10T18:07:35.972-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><category scheme="http://www.blogger.com/atom/ns#" term="reporting"/><category scheme="http://www.blogger.com/atom/ns#" term="usability"/><title type='text'>On the Cohort Dashboard (design)</title><content type='html'>This is the page that will complement the Cohort Builder.  The page will be accessible by users who want to analyze a set of patients from the top-down.  More details to come ...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuNeQPs9emEWgbx15Svnqhdk0u1c6MUyo5V6NO3p9QvEV8gXD7f5fzEFme3AEiMq5LuPr8nc3bzZfP5OB7yjTdA1SY4xPgjzGFMD9f42LjULoJqMDM2RYt3fetitZ2ZDZ8VRuK9R54zAOG/s1600-h/Analysis+Dashboard_2.png&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 365px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuNeQPs9emEWgbx15Svnqhdk0u1c6MUyo5V6NO3p9QvEV8gXD7f5fzEFme3AEiMq5LuPr8nc3bzZfP5OB7yjTdA1SY4xPgjzGFMD9f42LjULoJqMDM2RYt3fetitZ2ZDZ8VRuK9R54zAOG/s400/Analysis+Dashboard_2.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5366869150240393378&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.justinmiranda.com/feeds/7432169785269515562/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/6214277125099466960/7432169785269515562' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/7432169785269515562'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/7432169785269515562'/><link rel='alternate' type='text/html' href='http://blog.justinmiranda.com/2009/08/on-analysis-dashboard.html' title='On the Cohort Dashboard (design)'/><author><name>Justin Miranda</name><uri>http://www.blogger.com/profile/12794947822953373298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5AqKjeUVRaa2MOuWom3QvHZQDyyE6OPva7awOh5s6XMNh20agcuIoSFrRCkOKJxlNTuX1K85Lqolaaj9Tey0FhGtIO0VGfwOVEiDtrX9e89b6-sjCy-6ARG2xZSp89Do/s220/5493_128868133104_8302049_n+%28copy%29.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuNeQPs9emEWgbx15Svnqhdk0u1c6MUyo5V6NO3p9QvEV8gXD7f5fzEFme3AEiMq5LuPr8nc3bzZfP5OB7yjTdA1SY4xPgjzGFMD9f42LjULoJqMDM2RYt3fetitZ2ZDZ8VRuK9R54zAOG/s72-c/Analysis+Dashboard_2.png" height="72" width="72"/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6214277125099466960.post-4194025877481976702</id><published>2009-08-04T16:54:00.007-04:00</published><updated>2009-08-10T18:11:36.758-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><category scheme="http://www.blogger.com/atom/ns#" term="reporting"/><category scheme="http://www.blogger.com/atom/ns#" term="usability"/><title type='text'>On the Reporting Dashboard (implementation)</title><content type='html'>&lt;span style=&quot;font-weight: bold;&quot;&gt;Update&lt;/span&gt;d (10 August 2009):  Added a new screenshot. &lt;br /&gt;&lt;br /&gt;Here&#39;s the latest verison of the Reporting Dashboard with some working charts and a more intuitive Cohort Breakdown widget.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7hbm4RQatz2isFd6iyt7mSO00N-HaoiM0Xeh0Bx2K-SxWAx4osQOAjz_2-1F23XGz7IHwLCD_9WHlc0tyjJv8HNXaWWNsYChyphenhyphengetFezBh6yaxjozLqPZgqBpQ7_JMkoIlfccgSoUw35Gp/s1600-h/reporting-dashboard.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 190px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7hbm4RQatz2isFd6iyt7mSO00N-HaoiM0Xeh0Bx2K-SxWAx4osQOAjz_2-1F23XGz7IHwLCD_9WHlc0tyjJv8HNXaWWNsYChyphenhyphengetFezBh6yaxjozLqPZgqBpQ7_JMkoIlfccgSoUw35Gp/s400/reporting-dashboard.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5368460986868196610&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;Here&#39;s my initial version of the reporting dashboard, using JQuery&#39;s portlet library.  Let me know what you think.  Some of the fields (program, workflow, cohort, dataset) are populated dynamically, but there&#39;s nothing on the backend (yet) to process most of these.  Writing that code will be relatively simple once I hear back that this is the right direction to take the dashboard.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqJe96we9gXkLCN1aDEF7IxKuKYRm5Q8OAT3c398TLi5lG3dw0xQ1M9CiZ7E49b46Smj6uB3NvrI-2CS0lq_W8IA0dMi_Xw-jFVyB15TOcCCWsLYPP3ScuXWkXOOiAYNg-0cbCKvFROj78/s1600-h/report-dashboard.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 190px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqJe96we9gXkLCN1aDEF7IxKuKYRm5Q8OAT3c398TLi5lG3dw0xQ1M9CiZ7E49b46Smj6uB3NvrI-2CS0lq_W8IA0dMi_Xw-jFVyB15TOcCCWsLYPP3ScuXWkXOOiAYNg-0cbCKvFROj78/s400/report-dashboard.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5366216105136824930&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.justinmiranda.com/feeds/4194025877481976702/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/6214277125099466960/4194025877481976702' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/4194025877481976702'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/4194025877481976702'/><link rel='alternate' type='text/html' href='http://blog.justinmiranda.com/2009/08/on-reporting-dashboard.html' title='On the Reporting Dashboard (implementation)'/><author><name>Justin Miranda</name><uri>http://www.blogger.com/profile/12794947822953373298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5AqKjeUVRaa2MOuWom3QvHZQDyyE6OPva7awOh5s6XMNh20agcuIoSFrRCkOKJxlNTuX1K85Lqolaaj9Tey0FhGtIO0VGfwOVEiDtrX9e89b6-sjCy-6ARG2xZSp89Do/s220/5493_128868133104_8302049_n+%28copy%29.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7hbm4RQatz2isFd6iyt7mSO00N-HaoiM0Xeh0Bx2K-SxWAx4osQOAjz_2-1F23XGz7IHwLCD_9WHlc0tyjJv8HNXaWWNsYChyphenhyphengetFezBh6yaxjozLqPZgqBpQ7_JMkoIlfccgSoUw35Gp/s72-c/reporting-dashboard.jpg" height="72" width="72"/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6214277125099466960.post-7650733888086516128</id><published>2009-07-31T17:01:00.005-04:00</published><updated>2009-08-10T18:08:34.403-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><category scheme="http://www.blogger.com/atom/ns#" term="reporting"/><category scheme="http://www.blogger.com/atom/ns#" term="usability"/><title type='text'>On the Reporting Dashboard (design)</title><content type='html'>Here&#39;s a quick mockup of what I&#39;m thinking the Report Dashboard should look like.  I need some help with some of the most common queries that users ask about.  You&#39;ll quickly notice that the dashboard is missing a graphical widget.  Once I think of something to implement, I will add it.  Let me know if you have any suggestions.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZeDoQ4dhX45EboruQuxJ7_fvRGQcx1ulKOOnfNrHux4dfCd2YbbFqlyjR7ThVzQKIQ7R-LcyuS4jTCMU6UG9XJgLn7nt3teTrK4Wrnc6-cgZ-FWhTimR6ie45Y9UQKi_57JVEb5dGqYbI/s1600-h/Report+Dashboard_2.png&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 306px; height: 400px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZeDoQ4dhX45EboruQuxJ7_fvRGQcx1ulKOOnfNrHux4dfCd2YbbFqlyjR7ThVzQKIQ7R-LcyuS4jTCMU6UG9XJgLn7nt3teTrK4Wrnc6-cgZ-FWhTimR6ie45Y9UQKi_57JVEb5dGqYbI/s400/Report+Dashboard_2.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5364732990992092882&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.justinmiranda.com/feeds/7650733888086516128/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/6214277125099466960/7650733888086516128' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/7650733888086516128'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/7650733888086516128'/><link rel='alternate' type='text/html' href='http://blog.justinmiranda.com/2009/07/on-report-dashboard.html' title='On the Reporting Dashboard (design)'/><author><name>Justin Miranda</name><uri>http://www.blogger.com/profile/12794947822953373298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5AqKjeUVRaa2MOuWom3QvHZQDyyE6OPva7awOh5s6XMNh20agcuIoSFrRCkOKJxlNTuX1K85Lqolaaj9Tey0FhGtIO0VGfwOVEiDtrX9e89b6-sjCy-6ARG2xZSp89Do/s220/5493_128868133104_8302049_n+%28copy%29.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZeDoQ4dhX45EboruQuxJ7_fvRGQcx1ulKOOnfNrHux4dfCd2YbbFqlyjR7ThVzQKIQ7R-LcyuS4jTCMU6UG9XJgLn7nt3teTrK4Wrnc6-cgZ-FWhTimR6ie45Y9UQKi_57JVEb5dGqYbI/s72-c/Report+Dashboard_2.png" height="72" width="72"/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6214277125099466960.post-6347614951101577758</id><published>2009-07-31T14:36:00.009-04:00</published><updated>2009-07-31T16:10:45.662-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><category scheme="http://www.blogger.com/atom/ns#" term="reporting"/><category scheme="http://www.blogger.com/atom/ns#" term="usability"/><title type='text'>On the woes of usability (cohorts and indicators)</title><content type='html'>Finding a solution to the indicator report was a big step for me.  However, the best thing that came out of the conversation with Mike this morning was something kind of random.  For some reason, during the conversation about hard-wiring the &quot;design indicator report&quot; UI, I realized that we also needed to hard-wire the design of a few other pages, just to get the reporting system out the door and into the hands of users ... who could tell us what they really wanted.  Which is the gold at the end of the rainbow.  Get your application into the hands of your users and they&#39;ll tell you what they want.  Hopefully.&lt;br /&gt;&lt;br /&gt;So the basic conclusion that Mike and I came to today was that the user interface for the new reporting system should be somewhat hard-wired, at least to start with.  We&#39;ve been fighting with this idea for months now.  Every time we&#39;ve wanted to go down the path of &quot;hard-wiring&quot; a report or one of the reporting components, we&#39;ve designed a cool new widget maker that would hypothetically handle the general case in a way that most users would be ok with.  And so after a few conversations, we start heading back down the path toward a &quot;more generalizable&quot; solution.&lt;br /&gt;&lt;br /&gt;I now hate generalizable solutions.  They suck.  They&#39;re ugly, they take too long to implement, and they always break.  I&#39;m not smart enough to think of every use case that might ever be needed.  I&#39;ve spent 2+ years working on reporting and I&#39;m tired of thinking about vague/general user stories like &quot;Design a Report&quot;.  You go Design a Report!  I just want someone to ask for a very specific feature, like &quot;Give me the ability to retrieve a count of all patients in the HIV Program at the Rwinkwavu hospital&quot;.   I can do that.   I can implement that and make it look nice.   And I can build it in a general-enough way so that only the UI needs to be hard-wired.   I just can&#39;t (and won&#39;t ever again) design another generic UI.  Go to hell general UIs.&lt;br /&gt;&lt;br /&gt;I&#39;m exaggerating.  I&#39;ll be back to designing general UIs next week.  But, I&#39;ve found a way to handle some of the reporting UIs in such a way that we can build some very nice features for our users without spending months working on a general UI that looks pretty enough and is 100% extensible.&lt;br /&gt;&lt;br /&gt;So to get back to the point.  This conversation with Mike got me thinking about a part of the reporting tool that I have been dreading since I first conceptualized it.  I&#39;m speaking specifically about the Report Dashboard, the main UI that a user encounters when they want to use the new reporting tools.   At first, I wanted to make this a portal page ... a place where users could add and configure &quot;widgets&quot; to allow them to view patient data in a very interactive, easy to use manner.  I started thinking about all of the widgets we could have &quot;Graph concept X along datetime, break down by Dimension Y&quot; or &quot;Show 10 most recent indicators&quot; or &quot;Show a truncated table of patients that Provider X is supposed to see this week&quot;.  Any and all of these widgets would be cool and possibly useful.  But no one has every asked for them, so I don&#39;t think it would be a good use of time building a generalizable portal framework for widgets that might not ever be used.  Instead, we should put some effort into hard-wiring some of these widgets according to a user&#39;s specification and then try to find some patterns of reuse in those.  &lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTN56Y2LRQh-FJXMmIBWssDadZj9iDUtFFSLcuyMHwCGD4szu4tH88Q-mUjcABUV4KlG5DPYBl554jyWkYjtIqEsD2N_8yaKhC6XS7VHaVSFWW6zAjRPrL0ObS8HXok12kEX3ARIS0rp_4/s1600-h/dashboard.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 273px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTN56Y2LRQh-FJXMmIBWssDadZj9iDUtFFSLcuyMHwCGD4szu4tH88Q-mUjcABUV4KlG5DPYBl554jyWkYjtIqEsD2N_8yaKhC6XS7VHaVSFWW6zAjRPrL0ObS8HXok12kEX3ARIS0rp_4/s400/dashboard.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5364700532818080418&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style=&quot;text-align: center;&quot;&gt; (image stolen from the DHIS web site -- thanks guys!)&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;I still plan to build this dashboard (I want it to look a little like the image above) but we don&#39;t have the foundation within OpenMRS for a portal type user interface yet.  We have portlets, but we don&#39;t have the portal page that would hold the portlets nor do we have a way to configure the portlet to handle any case.  For example, there&#39;s no way to turn a cohort or dataset based on any concept into a nice graph.  But that time will come.  I promise you.&lt;br /&gt;&lt;br /&gt;However, what we need to be able to do from within the Report Dashboard is to allow a user, like Cheryl down in Rwanda, to quickly find out how many patients are currently enrolled in our HIV Program during a certain period.  The cohort builder is great and gives us a good start to solving this issue.  But the cohort builder is still too generic.   It requires a user to ask a bunch of questions to answer their overall query. A user is left combining multiple queries to figure out how many Male Adult patients are in the system.  Why not hard-wire a UI that allows the user to pick a Cohort and select a few dimensions (gender, age) and click &quot;Run&quot; in order to get a crosstab of patients broken down by these two dimensions.&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhB5rfDooL3REEgesFBhf7zgrJcKyu2WCXFfkPvc5IudwMkuP57ssLMIb0AM24XHDYlPvXPcPIUux5o-ulMcI3eR9GgFb0hvOkwDxna5gb0ItcnDm-d82Qz8-uZIQMt_koOuUdGuokgEK0a/s1600-h/Report+Dashboard.png&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 334px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhB5rfDooL3REEgesFBhf7zgrJcKyu2WCXFfkPvc5IudwMkuP57ssLMIb0AM24XHDYlPvXPcPIUux5o-ulMcI3eR9GgFb0hvOkwDxna5gb0ItcnDm-d82Qz8-uZIQMt_koOuUdGuokgEK0a/s400/Report+Dashboard.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5364712764970371282&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;We can easily handle this kind of query with our the reporting framework (our API is very flexible), but it&#39;s not at all easy for a user to put together all of the cohort definitions or logic queries through the cohort builder in order to answer this question.  They need to calculate each of these numbers separately and then put together the pieces.&lt;br /&gt;&lt;br /&gt;Or take this example.&lt;br /&gt;&lt;br /&gt;Find out how many patients were enrolled in the HIV Program in Rwinkwavu between 07/01/2009 and 07/31/2009.&lt;br /&gt;&lt;br /&gt;Why not hard-wire the UI to handle this kind of query?  Clearly, we don&#39;t want to hard-wire the values in this particular example.  But we want the general pattern to be hard-wired.   We&#39;d still generialize it enough and give the user the ability to specify the four variables:  Program, Location, Start Date, and End Date.  However, the query is a pattern that we know users will ask a lot. &lt;br /&gt;&lt;br /&gt;And when a user comes to us and says: &quot;This is great, but I want to be able to get all patients enrolled in the HIV Program AND On ARVs&quot;, we don&#39;t have to say &quot;Oh F&quot; and spend weeks trying to make the UI take an arbitrary number of Programs and States.  We can simply add a new query to the report dashboard to handle this. &lt;br /&gt;&lt;br /&gt;Find out how many patients were enrolled in the HIV Program and On ARVs in Rwinkwavu between 07/01/2009 and 07/31/2009.&lt;br /&gt;&lt;br /&gt;While it would be great to handle this generically so that a user can ask any question, any time they want, this isn&#39;t at all realistic.  However, if we could hard-wire a bunch of questions that users ask all the time across all of our implementations, then we&#39;d be 90% of the way there.  In addition, we&#39;d remove the need for all of our users to define the same cohort builder queries over all of these implementations.  And we&#39;d get some pretty good feedback about what&#39;s missing. &lt;br /&gt;&lt;br /&gt;That&#39;s not to say we don&#39;t want to extend the Cohort Builder to allow users to ask more general questions.  We just need to give our users a better foundation to start with. &lt;br /&gt;&lt;br /&gt;So what query would you like to run within your OpenMRS implementation?</content><link rel='replies' type='application/atom+xml' href='http://blog.justinmiranda.com/feeds/6347614951101577758/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/6214277125099466960/6347614951101577758' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/6347614951101577758'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/6347614951101577758'/><link rel='alternate' type='text/html' href='http://blog.justinmiranda.com/2009/07/on-woes-of-usability-cohorts-and.html' title='On the woes of usability (cohorts and indicators)'/><author><name>Justin Miranda</name><uri>http://www.blogger.com/profile/12794947822953373298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5AqKjeUVRaa2MOuWom3QvHZQDyyE6OPva7awOh5s6XMNh20agcuIoSFrRCkOKJxlNTuX1K85Lqolaaj9Tey0FhGtIO0VGfwOVEiDtrX9e89b6-sjCy-6ARG2xZSp89Do/s220/5493_128868133104_8302049_n+%28copy%29.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTN56Y2LRQh-FJXMmIBWssDadZj9iDUtFFSLcuyMHwCGD4szu4tH88Q-mUjcABUV4KlG5DPYBl554jyWkYjtIqEsD2N_8yaKhC6XS7VHaVSFWW6zAjRPrL0ObS8HXok12kEX3ARIS0rp_4/s72-c/dashboard.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6214277125099466960.post-4303095004459759198</id><published>2009-07-31T11:43:00.008-04:00</published><updated>2009-07-31T14:36:22.979-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><category scheme="http://www.blogger.com/atom/ns#" term="reporting"/><category scheme="http://www.blogger.com/atom/ns#" term="usability"/><title type='text'>On the woes of usability (from a developer&#39;s point-of-view)</title><content type='html'>I&#39;ve been struggling with the UI design and usability for our reporting system for weeks now.  We&#39;ve built most of the UIs for the general administration tools for defining cohorts, indicators, datasets, and reports.  However, these UI are the kind of pages that are completely unintuitive to a user:  a listing page to display all reports and a details page to allow the user to view/edit the details of a report.  We give away too much information, too many options and it&#39;s just an overwhelming experience for the user.  And it&#39;s tiring for a developer.  I want to build intuitive interfaces.  I do.  I want to make things easy on our users.  I just don&#39;t know how.  No matter how much I read about ux (user experience), I just can&#39;t seem to get it right.&lt;br /&gt;&lt;br /&gt;So this morning, instead of banging my head against the wall for another day, I decided to have a discussion with one of OpenMRS&#39;s most gifted developers.  No, not Ben Wolfe ... although, there&#39;s no doubt that he is a programming genius.  No the conversation with with Mike Seaton.  I asked him to give me a ring to discuss these issues.  He&#39;s been working on reporting for our legacy Haiti system for years and knows a thing or two about indicators and indicator reports.  I was expecting to have a quick conversation about the following mockup:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxA8nRBIA6hrd0qy7w5n9M05U330rLO8rQWnJT0eNI-ii8O34wlozoEOc-9q-mVZvBYZM_P2Ru_iEgbiuIu_c1NrBVd0zJ6D3SdY64vG_adGhL4_d3gLjWdokBwpeRkhb76eJHK0bpACZh/s1600-h/edit-indicator.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 381px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxA8nRBIA6hrd0qy7w5n9M05U330rLO8rQWnJT0eNI-ii8O34wlozoEOc-9q-mVZvBYZM_P2Ru_iEgbiuIu_c1NrBVd0zJ6D3SdY64vG_adGhL4_d3gLjWdokBwpeRkhb76eJHK0bpACZh/s400/edit-indicator.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5364691251133073026&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;insert screenshot=&quot;&quot; here=&quot;&quot;&gt;But we spend about an hour on the phone discussing the details of indicators and how we need to wire parameters (like start date) from the low level reporting components (an indicator) up through the indicator dataset definition and into the report.   The screenshot above isn&#39;t terribly complicated, but it requires a little too much knowledge of what the lies underneath an indicator.&lt;br /&gt;&lt;br /&gt;But as part of a larger process (creating an indicator report), this UI is just one little piece of confusion pie.  At first glance (in my mind), the entire UI for creating the indicator report looks like a messy hierarchical chaining type thingamajig because  I have been thinking about how one might design one of these reports from a bottom-up perspective.  Here&#39;s the process, in a nutshell:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;User creates the cohort definition (Gender Cohort Definition with &quot;gender&quot; parameter).  &lt;/li&gt;&lt;li&gt;User creates the indicator (# Male Patients with &quot;gender&quot; set to &quot;M&quot;).&lt;/li&gt;&lt;li&gt;User creates the dataset definition and adds the indicator to it (My Indicator Dataset)&lt;/li&gt;&lt;li&gt;User creates the report and adds the dataset definition (My Indicator Report).&lt;/li&gt;&lt;/ol&gt;Four different pages ... four different steps ... just to create a report with a single indicator.  Why would you do this to the user?  Why would you do this to yourself?&lt;br /&gt;&lt;br /&gt;I have no idea.&lt;br /&gt;&lt;br /&gt;Don&#39;t paint me in the moron category just yet.  I knew there was a better UI.  I had the image in my head, but I just got flustered with all of the &quot;stuff&quot; that needed to happen in order for that design to work.  There&#39;s a lot of &quot;stuff&quot; that needs to be configured, configuration options that &quot;should&quot; be available to the user.  To be more explicit, for each layer (cohort-&gt;indicator-&gt;dataset-&gt;report) there&#39;s some &quot;wiring&quot; that needs to happen in order for a report parameter (say &quot;location&quot;) to be passed down through the hierarchy of objects to allow a value like &quot;Rwinkwavu&quot; to be used by the indicator or cohort definition when it&#39;s time to evaluate the report.&lt;br /&gt;&lt;br /&gt;The thing that Mike and I figured out was that we really don&#39;t need to let the user configure everything when designing the report from scratch.   At least not at the beginning.  Let&#39;s give them just enough configurability (add an indicator) to get off the ground.  &lt;/insert&gt;We can make some assumptions for them (you want the &quot;location&quot; parameter to be .&lt;insert screenshot=&quot;&quot; here=&quot;&quot;&gt;  Then, once things are flowing, we can let them dig down and get dirty with the report configuration.  So here&#39;s the mockup I came up with from those conversations:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/insert&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTou_tJLfddRPvzkS-jNwnfqvdpWwqhQxuAFi3vA5Q2srI3EAZhysiHnM1wIgor0StRMzbyUOwOYqDFqR3kxu4Q4ey42Soy9CtaktY99fkn8THgspmNqb3gPIdDjsA4eBUNWkSfbawzcE0/s1600-h/Allow+user+to+design+a+simple+indicator+report.png&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 326px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTou_tJLfddRPvzkS-jNwnfqvdpWwqhQxuAFi3vA5Q2srI3EAZhysiHnM1wIgor0StRMzbyUOwOYqDFqR3kxu4Q4ey42Soy9CtaktY99fkn8THgspmNqb3gPIdDjsA4eBUNWkSfbawzcE0/s400/Allow+user+to+design+a+simple+indicator+report.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5364694193934189218&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;insert screenshot=&quot;&quot; here=&quot;&quot;&gt;&lt;br /&gt;Now, I know this isn&#39;t revolutionary ... but it&#39;s hard to make the kind of assumptions we need to make to hide the complexity from the user.  And there&#39;s still the issue of designing a somewhat intuitive interface for a user that wants to dig down into the details of each indicator in order to configure, say the &quot;location&quot; parameter to be hard-coded.  But we&#39;ll get to that feature once there&#39;s a need for it.  For now, the &quot;edit indicator&quot; feature will have to be left unimplemented.  Sorry Mike - I know that wasn&#39;t the conclusion we came to, but it feels like the right thing to do, rather than adding one more confusing element to this page.  This design feels right. &lt;br /&gt;&lt;br /&gt;Let me know what you guys think. &lt;br /&gt;&lt;/insert&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.justinmiranda.com/feeds/4303095004459759198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/6214277125099466960/4303095004459759198' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/4303095004459759198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/4303095004459759198'/><link rel='alternate' type='text/html' href='http://blog.justinmiranda.com/2009/07/on-woes-of-usability-from-developers.html' title='On the woes of usability (from a developer&#39;s point-of-view)'/><author><name>Justin Miranda</name><uri>http://www.blogger.com/profile/12794947822953373298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5AqKjeUVRaa2MOuWom3QvHZQDyyE6OPva7awOh5s6XMNh20agcuIoSFrRCkOKJxlNTuX1K85Lqolaaj9Tey0FhGtIO0VGfwOVEiDtrX9e89b6-sjCy-6ARG2xZSp89Do/s220/5493_128868133104_8302049_n+%28copy%29.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxA8nRBIA6hrd0qy7w5n9M05U330rLO8rQWnJT0eNI-ii8O34wlozoEOc-9q-mVZvBYZM_P2Ru_iEgbiuIu_c1NrBVd0zJ6D3SdY64vG_adGhL4_d3gLjWdokBwpeRkhb76eJHK0bpACZh/s72-c/edit-indicator.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6214277125099466960.post-2182990520680942138</id><published>2009-05-22T00:13:00.008-04:00</published><updated>2009-05-22T01:21:38.062-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="backup"/><category scheme="http://www.blogger.com/atom/ns#" term="clonezilla"/><category scheme="http://www.blogger.com/atom/ns#" term="gsoc"/><category scheme="http://www.blogger.com/atom/ns#" term="image"/><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><title type='text'>You know it&#39;s time to backup your hard-drive ...</title><content type='html'>&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNY5q3QpGMHIdzIXoLdF6iz0i6u-IGVZ2pSHX0vKro3EF3ysfzLrIhE4hvXkDnJ_0m0fPBdRLWh0ZPL27RQguwxnnRFEBQ1fx6aqGt9xZM4cgsO0ll7403rDLdBKBM5H2Emjb2KB7Npna7/s1600-h/clonezilla_logo3.gif&quot;&gt;&lt;img style=&quot;margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 141px; height: 200px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNY5q3QpGMHIdzIXoLdF6iz0i6u-IGVZ2pSHX0vKro3EF3ysfzLrIhE4hvXkDnJ_0m0fPBdRLWh0ZPL27RQguwxnnRFEBQ1fx6aqGt9xZM4cgsO0ll7403rDLdBKBM5H2Emjb2KB7Npna7/s200/clonezilla_logo3.gif&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5338513711958010354&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;... when it starts to make audible &quot;clicking&quot; sounds every 10 seconds.&lt;br /&gt;&lt;br /&gt;So, I figure, this is a good time for a backup and for me to finally document the procedures I&#39;m using to clone and backup my hard-drive ... (1) to archive them for posterity (2) to make this easier the next time I need to do a backup and (3) to save some others from having to spend time figuring it out on their own.&lt;br /&gt;&lt;br /&gt;So I have three backup options to choose from:&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;(1) Clonezilla:  device-device disk/partition to disk/partition&lt;/span&gt;&lt;br /&gt;Disk to disk image using Clonezilla.  Since this is a manual process I only do this every month or so.  However, this is the thing that will save you when your hard-drive crashes and you need to get back up and running as quickly as possibly.  Cloning to a drive with the same specs as your working drive will allow you to swap out the broken drive and swap in the cloned drive without losing a beat.  I just realized that I need a third internal drive to write the disk-to-disk image in order to keep one disk that will always work (i.e. what happens if both drives end up in the drink during the backup process).&lt;br /&gt;&lt;br /&gt;Here&#39;s the process for running a Clonezilla disk-to-disk image (screenshots would be nice, but this is all done via CD so I&#39;m not sure if it&#39;s possible without a camera)&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style=&quot;font-size:130%;&quot;&gt;Insert Clonezilla CD&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-size:130%;&quot;&gt;Reboot System&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-size:130%;&quot;&gt;Answer the following questions&lt;/span&gt;&lt;/li&gt;&lt;li&gt;clonezilla&gt; Which language do you prefer?  English&lt;/li&gt;&lt;li&gt;clonezilla&gt; Policy for handling keymaps:  Don&#39;t touch the keymap&lt;/li&gt;&lt;li&gt;clonezilla&gt; Choose the mode:  &lt;span style=&quot;font-weight: bold;&quot;&gt;Start Clonezilla&lt;/span&gt;&lt;/li&gt;&lt;li&gt;clonezilla&gt; Choose the mode:  &lt;span style=&quot;font-weight: bold;&quot;&gt;device-device disk/partition to disk/partition&lt;/span&gt;&lt;/li&gt;&lt;li&gt;clonezilla&gt; Choose the mode:  &lt;span style=&quot;font-weight: bold;&quot;&gt;disk_to_local_disk&lt;/span&gt;&lt;/li&gt;&lt;li&gt;clonezilla&gt; Choose the local disk as source:  &lt;span style=&quot;font-weight: bold;&quot;&gt;sda 200GB Hitachi ...&lt;/span&gt;&lt;/li&gt;&lt;li&gt;clonezilla&gt; Choose the local disk as target: &lt;span style=&quot;font-weight: bold;&quot;&gt;sdb 100GB Storage&lt;/span&gt;&lt;/li&gt;&lt;li&gt;clonezilla&gt; Set advanced parameters:  &lt;span style=&quot;font-weight: bold;&quot;&gt;-g-auto Reinstall grub to target harddisk boot sector&lt;/span&gt;&lt;/li&gt;&lt;li&gt;clonezilla&gt; Set advanced parameters: &lt;span style=&quot;font-weight: bold;&quot;&gt;Use the partition table from source disk &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-size:130%;&quot;&gt;And finally ... answer the following paranoid, &quot;just watching your back&quot; questions ... I love this part.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;clonezilla&gt; Are you sure you want to continue?  &lt;span style=&quot;font-weight: bold;&quot;&gt;y&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;clonezilla&gt; Are you sure you want to continue?  If you go on, the original data exist in the target device will be destroyed!!! Be careful!! Are you sure?&lt;span style=&quot;font-weight: bold;&quot;&gt; y&lt;/span&gt;&lt;/li&gt;&lt;li&gt;clonezilla&gt; Do you want to clone the boot loader to sdb?  &lt;span style=&quot;font-weight: bold;&quot;&gt;y&lt;/span&gt;&lt;/li&gt;&lt;li&gt;clonezilla&gt; Now we will start to clone data to target machine ... Are you sure you want to continue?  &lt;span style=&quot;font-weight: bold;&quot;&gt;y&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-size:130%;&quot;&gt;Now go get some coffee or a beer (i.e. Bell&#39;s Two Hearted Ale or Dogfish Head 60 Minute IPA)&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-size:130%;&quot;&gt;Relax as your life gets cloned over to another hard-drive.&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;(2) device-image disk/partition to/from image&lt;/span&gt;&lt;br /&gt;This is another option and one that I will likely incorporate soon, just so that I always have an extra image lying around in case something goes terribly wrong with the entire universe and this one external drive is the only thing that is spared.  For this option, you basically just create the same image as the disk-to-disk image, but copy it to an external hard-drive (any old backup drive), rather than having to buy an exact replica of your current hard drive.  This option just gives you a bit more piece of mind and might save you a few bucks in the short-term (you don&#39;t have to buy that second internal drive).  But once your current drive goes bad (and it will), you&#39;ll need to go out and buy that second drive anyway.  This just means that your recovery process will take a little longer (i.e. the amount of time it takes amazon to ship you that new drive).&lt;br /&gt;&lt;br /&gt;I want to use all three options (just to have an image lying around in case ... yes ... something goes terribly wrong with the universe).  However I still haven&#39;t adopted this approach (probably because my 500GB external hard-drive is full of Acronis&#39; crappy backups.  I hate Acronis, in case I&#39;ve never mentioned it before.  I&#39;ll explain in a different post, but essentially it comes down to &quot;four months&quot;, which is the time that elapsed between when I sent in an email request to their tech support and when I received a response.  If that had happened once, I would have given them a pass.  But it&#39;s happened twice and I still haven&#39;t heard back from them after my last response (sometime in February 2009).   For the record, Acronis is a company I want to love (they are from Burlington, MA) ... but I just can&#39;t.  And until they get back to me with an apology for their terrible tech support, I will continue to give them mean looks when I pass them in the hallway.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;(3) Daily backups with Ubuntu sbackup&lt;/span&gt;&lt;br /&gt;Daily backup using sbackup (which I just found out was a Google Summer of Code project from 2005).  This is going to be the next weapon I add to the backup arsenal, right after I finish my most recent disk-to-disk image.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Conclusion&lt;/span&gt;&lt;br /&gt;So I need to get a new external hard-drive.  Does anyone have any recommendations regarding backups?  I&#39;m thinking about going with a deal from Amazon that includes:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Western Digital My Book 1TB USB&lt;/li&gt;&lt;li&gt;Western Digital My Passport 320 GB USB&lt;/li&gt;&lt;/ul&gt;However, I&#39;d love a recommendation.  CNET and PCWorld have some recommendations, but nothing looked all that impressive.&lt;br /&gt;&lt;br /&gt;And does anyone out there make backups of their backups?  I&#39;m thinking about getting an external drive with a few TB of space in order to provide some redundancy in case one of the backup drives fail.  So would love some suggestions on that front too.</content><link rel='replies' type='application/atom+xml' href='http://blog.justinmiranda.com/feeds/2182990520680942138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/6214277125099466960/2182990520680942138' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/2182990520680942138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/2182990520680942138'/><link rel='alternate' type='text/html' href='http://blog.justinmiranda.com/2009/05/you-know-its-time-to-backup-your-hard.html' title='You know it&#39;s time to backup your hard-drive ...'/><author><name>Justin Miranda</name><uri>http://www.blogger.com/profile/12794947822953373298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5AqKjeUVRaa2MOuWom3QvHZQDyyE6OPva7awOh5s6XMNh20agcuIoSFrRCkOKJxlNTuX1K85Lqolaaj9Tey0FhGtIO0VGfwOVEiDtrX9e89b6-sjCy-6ARG2xZSp89Do/s220/5493_128868133104_8302049_n+%28copy%29.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNY5q3QpGMHIdzIXoLdF6iz0i6u-IGVZ2pSHX0vKro3EF3ysfzLrIhE4hvXkDnJ_0m0fPBdRLWh0ZPL27RQguwxnnRFEBQ1fx6aqGt9xZM4cgsO0ll7403rDLdBKBM5H2Emjb2KB7Npna7/s72-c/clonezilla_logo3.gif" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6214277125099466960.post-7073065678449085307</id><published>2009-05-08T12:13:00.015-04:00</published><updated>2009-05-14T13:45:34.727-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="bob ross"/><category scheme="http://www.blogger.com/atom/ns#" term="code-a-thon"/><category scheme="http://www.blogger.com/atom/ns#" term="fun"/><category scheme="http://www.blogger.com/atom/ns#" term="gsoc"/><category scheme="http://www.blogger.com/atom/ns#" term="junit"/><category scheme="http://www.blogger.com/atom/ns#" term="openmrs"/><category scheme="http://www.blogger.com/atom/ns#" term="test-a-thon"/><title type='text'>Update:  OpenMRS Test-a-Thon (May 16 - 17)</title><content type='html'>&lt;span style=&quot;font-weight: bold;&quot;&gt;What the heck is the OpenMRS Test-a-Thon?&lt;/span&gt;&lt;br /&gt;The OpenMRS Test-a-Thon is a code-a-thon event that allows people to collaboratively increase and improve our testing process in order to  make the OpenMRS platform a more stable and robust piece of software (&lt;a style=&quot;font-weight: bold;&quot; href=&quot;http://openmrs.org/wiki/Technical_Workshop_05/16-05/17/2009_Agenda&quot;&gt;click here for more details&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;When is it going down?&lt;/span&gt;&lt;br /&gt;We&#39;ll be starting at &lt;span style=&quot;font-weight: bold;&quot;&gt;noon&lt;/span&gt; (EDT) on Saturday, May 16 and ending at &lt;span style=&quot;font-weight: bold;&quot;&gt;noon&lt;/span&gt; (EDT) on Sunday, May 17.  You can come and go as you wish.  I&#39;ll be hanging out in our IRC Channel all day Saturday and will be taking in a feature film on Saturday night (9 - 11pm CDT).  So no pressure.  Come inside, submit yourself a junit test, and then go back out and finish your Saturday chores.   &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Where is the event going to take place?  &lt;/span&gt;&lt;br /&gt;The test-a-thon will take place online.  You can join us on the &lt;a style=&quot;font-weight: bold;&quot; href=&quot;http://openmrs.org/wiki/IRC&quot;&gt;OpenMRS IRC Channel&lt;/a&gt;.  Contact me via Skype (jmiranda) or on the IRC channel to discuss how you might be able to help out.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Who can participate?&lt;/span&gt;&lt;br /&gt;Anyone.  Developers, implementers, supporters, documenters ... people who are bored. &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Who should participate?&lt;/span&gt;&lt;br /&gt;Everyone.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Why should you participate?&lt;/span&gt;&lt;br /&gt;Because ...&lt;br /&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;You love OpenMRS.&lt;/li&gt;&lt;li&gt;You want to learn about test driven develement (TDD).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;You want to learn about behavior driven development (BDD).&lt;/li&gt;&lt;li&gt;You want to learn about cool unit testing frameworks (i.e. JUnit).&lt;/li&gt;&lt;li&gt;You want to learn about cool web testing frameworks (Selenium).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;You want to learn about continuous integration.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;You want to write documentation for OpenMRS.&lt;/li&gt;&lt;li&gt;You want to meet the team.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;You want to make Ben Wolfe happy.&lt;/li&gt;&lt;li&gt;You want to win a prize.&lt;/li&gt;&lt;li&gt;You have nothing better to do on a Saturday.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;How can I participate in this once in a lifetime (more like bi-annual) event?&lt;/span&gt;&lt;br /&gt;You can head over to the &lt;a style=&quot;font-weight: bold;&quot; href=&quot;http://openmrs.org/wiki/Technical_Workshop_05/16-05/17/2009_Agenda&quot;&gt;OpenMRS wiki&lt;/a&gt;   for more details.&lt;br /&gt;&lt;br /&gt;Thank you,&lt;br /&gt;&lt;br /&gt;The OpenMRS Team</content><link rel='replies' type='application/atom+xml' href='http://blog.justinmiranda.com/feeds/7073065678449085307/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/6214277125099466960/7073065678449085307' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/7073065678449085307'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/7073065678449085307'/><link rel='alternate' type='text/html' href='http://blog.justinmiranda.com/2009/05/may-16-17-openmrs-pre-gsoc-test-thon.html' title='Update:  OpenMRS Test-a-Thon (May 16 - 17)'/><author><name>Justin Miranda</name><uri>http://www.blogger.com/profile/12794947822953373298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5AqKjeUVRaa2MOuWom3QvHZQDyyE6OPva7awOh5s6XMNh20agcuIoSFrRCkOKJxlNTuX1K85Lqolaaj9Tey0FhGtIO0VGfwOVEiDtrX9e89b6-sjCy-6ARG2xZSp89Do/s220/5493_128868133104_8302049_n+%28copy%29.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6214277125099466960.post-302335838219522575</id><published>2009-05-08T10:29:00.009-04:00</published><updated>2009-05-08T16:44:46.593-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="openmrs eclipse svn subversion subclipse"/><title type='text'>Warning:  DO NOT INSTALL Subclipse 1.6 for Eclipse 3.4.x</title><content type='html'>&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;The Problem&lt;/span&gt;&lt;br /&gt;Save yourself a few days of headache ... don&#39;t do it!  More details to come.&lt;br /&gt;&lt;br /&gt;So Mike (mseaton) and I recently upgraded to Eclipse 3.4.2 because of some messed up issues with JSP/XML Validation within Eclipse 3.4.  We also both installed Subclipse 1.6 thinking it would bring us joy.  Three days later, with lots of back-and-forth collaboration on a project that we have sitting in Subversion, we&#39;ve experienced nothing but headaches.  When he&#39;s committed code to the repository, I&#39;ll update my working copy only to find that the only changes that come through are ones that are non-conflicting.  So when I then try to commit my changes, I get warnings that my working copy is not up-to-date.  I think the problem might be the fact that the new &quot;SVN Update to HEAD&quot; feature does not do a --force (but that&#39;s just a hunch).  I just finished reverting my Eclipse upgrade to Subclipse 1.6 and have successfully reinstalled Subclipse 1.4.7.&lt;br /&gt;&lt;br /&gt;Now the issue is that Subclipse 1.6 (which uses Subversion 1.6 wc format) has upgraded all of my working copy metadata to Subversion 1.6.  Installing Subclipse 1.4.7 (which uses Subversion 1.4 wc format) means that I cannot use Subclipse on my currently checked out code.  Since I have about 30+ projects checked out, this is kind of a problem.  I can&#39;t waste hours&lt;br /&gt;&lt;br /&gt;Here&#39;s the error you&#39;ll get when&lt;br /&gt;&lt;code&gt;&lt;br /&gt;root@jmiranda-laptop:~/Workspace/module-birtreport# svn diff&lt;br /&gt;svn: This client is too old to work with working copy &#39;.&#39;.  You need&lt;br /&gt;to get a newer Subversion client, or to downgrade this working copy.&lt;br /&gt;See http://subversion.tigris.org/faq.html#working-copy-format-change&lt;br /&gt;for details.&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;So thankfully, the subversion folks have a downgrade script:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;http://subversion.tigris.org/faq.html#working-copy-format-change&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Download the script and run the following command:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;root@jmiranda-laptop:~/Workspace# python change-svn-wc-format.py module-birtreport --force --verbose 1.5&lt;br /&gt;Converted WC at &#39;module-birtreport&#39; into format 9 for Subversion 1.5&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now, at least, I can run svn commands on that directory.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;root@jmiranda-laptop:~/Workspace/module-birtreport# svn diff&lt;br /&gt;Index: .project&lt;br /&gt;===================================================================&lt;br /&gt;--- .project (revision 7566)&lt;br /&gt;+++ .project (working copy)&lt;br /&gt;@@ -1,18 +1,18 @@&lt;br /&gt;...&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;However, when I open Eclipse I can no longer see the very helpful icon overlays on top of files that are &quot;unchanged&quot; or &quot;dirty&quot;.  I just get unadorned, naked file icons.&lt;br /&gt;&lt;br /&gt;Anyone have any ideas on how to fix it?&lt;br /&gt;&lt;br /&gt;&quot;Taste my sad, Michael&quot; -G.O.B Bluth&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Update:&lt;/span&gt;&lt;br /&gt;So the &quot;icon overlay&quot; was looking more and more like an Eclipse issue, so I decided to start Eclipse with the &quot;-clean&quot; option.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;/usr/lib/eclipse3.4.2/eclipse -clean&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;That fixed it.  And still a few hours short of what it would have taken to reinstall Eclipse, plugins, and re-download all source code.&lt;br /&gt;&lt;br /&gt;&quot;Taste the happy, Michael&quot; -G.O.B Bluth&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Update: &lt;/span&gt;&lt;br /&gt;It&#39;s still broken.  Only the top-level folders were successfully restored after the -clean restart.  After a few restarts and rebuilds, none of the files or folders have the icon overlay.  So we&#39;re back to square one.&lt;br /&gt;&lt;br /&gt;Following Ben&#39;s advice, I tried to install Subversive, but this did not help either.  This seems to be a problem with Eclipse.  It&#39;s as if Eclipse is blocking the icon overlay feature of any plugin (except the core plugins that mark files with &quot;build errors&quot;.  Checking the properties of any of the files definitely shows that they are &quot;managed&quot; and should have at least the &quot;managed&quot; icon.&lt;br /&gt;&lt;br /&gt;One last thing (check the error logs again) and then I&#39;m going to re-install Eclipse.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Last Update: &lt;/span&gt;&lt;br /&gt;Ok, so some combination of the above instructions, as well as closing all projects and dealing with them one at a time, while drinking coffee, and threatening to reinstall Eclipse while shaking your fist at your computer, on top of the Celtics winning Game 2 of the Eastern Conference Semifinals has seemed to fix the problem. &lt;br /&gt;&lt;br /&gt;I can&#39;t explain it folks.  Just keep playing around until it works.  The one project at a time helped me focus on what I was doing. &lt;br /&gt;&lt;br /&gt;(1) Run the script to convert from svn 1.6 to svn 1.5&lt;br /&gt;(2) Clean project&lt;br /&gt;(3) Build project&lt;br /&gt;(4) If that fails to work, close Eclipse and restart with the (-clean) option. &lt;br /&gt;&lt;br /&gt;The last thing I was going to try was to create a brand new workspace and move one project over at a time (running the svn convert script).  It didn&#39;t come to that thankfully. &lt;br /&gt;&lt;br /&gt;As I mentioned earlier, the last resort option would have been to reinstall Eclipse and download all of my project source code.  Given that half of my day was spent troubleshooting this, I would recommend going that route when you&#39;re confronted with this issue and can&#39;t get it resolved within an hour.&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.justinmiranda.com/feeds/302335838219522575/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/6214277125099466960/302335838219522575' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/302335838219522575'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6214277125099466960/posts/default/302335838219522575'/><link rel='alternate' type='text/html' href='http://blog.justinmiranda.com/2009/05/warning-do-not-install-subclipse-16-for.html' title='Warning:  DO NOT INSTALL Subclipse 1.6 for Eclipse 3.4.x'/><author><name>Justin Miranda</name><uri>http://www.blogger.com/profile/12794947822953373298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5AqKjeUVRaa2MOuWom3QvHZQDyyE6OPva7awOh5s6XMNh20agcuIoSFrRCkOKJxlNTuX1K85Lqolaaj9Tey0FhGtIO0VGfwOVEiDtrX9e89b6-sjCy-6ARG2xZSp89Do/s220/5493_128868133104_8302049_n+%28copy%29.jpg'/></author><thr:total>7</thr:total></entry></feed>