<?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: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-8577867822575605000</id><updated>2012-02-15T23:25:16.257-08:00</updated><category term='apache'/><category term='facebook'/><category term='web scripts'/><category term='xml'/><category term='exist db'/><category term='jsf'/><category term='core api'/><category term='documentation'/><category term='java'/><category term='alfresco'/><category term='converter'/><category term='development'/><category term='mac os'/><category term='multithreading'/><category term='maven'/><category term='yourkit'/><category term='concurrency'/><category term='file system'/><category term='jmeter'/><category term='troubleshooting'/><category term='firefox'/><category term='grails'/><category term='osgi'/><category term='foundation API'/><category term='transactions'/><category term='unix'/><category term='nullpointerexception'/><category term='remoting'/><category term='performance testing'/><category term='alfresco workflow jbpm'/><category term='windows'/><category term='actions'/><category term='eclipse'/><title type='text'>mv</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://michielverkaik.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://michielverkaik.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>michiel verkaik</name><uri>http://www.blogger.com/profile/07977714296269801643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_sPQCPmuPeLI/S0X_DUhDvHI/AAAAAAAAAY0/JTJwj-P7XSg/S220/mv.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>22</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8577867822575605000.post-25090571876768948</id><published>2011-04-28T07:07:00.000-07:00</published><updated>2011-04-28T07:07:13.457-07:00</updated><title type='text'>Maven Copy Dependencies</title><content type='html'>The last project I started, which is really a web app prototype, I decided not to use Maven and go with a standard Eclipse project layout instead. &amp;nbsp;It's easy to run that way from the IDE. &amp;nbsp;However, lots of libraries are Mavenized these days, so it's a tedious process to gather all your dependent jars. &amp;nbsp;I used to do this by trying to run it, and fixing the situation whenever encountering a ClassNotFoundException. &amp;nbsp;It's a tedious job, especially if you use a handful of libraries. &amp;nbsp;That's when I stumbled across the &lt;a href="http://maven.apache.org/plugins/maven-dependency-plugin/copy-dependencies-mojo.html"&gt;dependency:copy-dependencies&lt;/a&gt; goal. &amp;nbsp;This is handy, because Maven will get all the jars you need for a particular library. &amp;nbsp;Anyway, a big time saver.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8577867822575605000-25090571876768948?l=michielverkaik.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://michielverkaik.blogspot.com/feeds/25090571876768948/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8577867822575605000&amp;postID=25090571876768948' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/25090571876768948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/25090571876768948'/><link rel='alternate' type='text/html' href='http://michielverkaik.blogspot.com/2011/04/maven-copy-dependencies.html' title='Maven Copy Dependencies'/><author><name>michiel verkaik</name><uri>http://www.blogger.com/profile/07977714296269801643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_sPQCPmuPeLI/S0X_DUhDvHI/AAAAAAAAAY0/JTJwj-P7XSg/S220/mv.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8577867822575605000.post-1205407771800512915</id><published>2011-03-04T03:55:00.000-08:00</published><updated>2011-03-04T03:55:34.456-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='converter'/><category scheme='http://www.blogger.com/atom/ns#' term='facebook'/><category scheme='http://www.blogger.com/atom/ns#' term='jsf'/><title type='text'>Facebook Style Time Ago as a JSF Converter</title><content type='html'>Here is a way to render date-time values the way &lt;a href="http://www.facebook.com/"&gt;Facebook&lt;/a&gt; does (4 hours ago, 2 days ago, etc.) &amp;nbsp;The algorithm was taken from a &lt;a href="http://snipplr.com/view/37578/facebook-style-time-ago/"&gt;Snipplr post&lt;/a&gt;, which was written in PHP, so I had to convert it into Java. &amp;nbsp;So this is what the &lt;a href="http://en.wikipedia.org/wiki/JavaServer_Faces"&gt;JSF&lt;/a&gt; converter looks like:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;public class RelativeDateTimeConverter implements Converter {&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;private static final String[] periods = {"second", "minute", "hour", "day", "week", "month", "year", "decade"};&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;private static final double[] lengths = {60, 60, 24, 7, 4.35, 12, 10};&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;@Override&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;public Object getAsObject(FacesContext context, UIComponent component, String param) {&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;// Not implemented because not needed&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;@Override&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;public String getAsString(FacesContext context, UIComponent component, Object value) {&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;Date now = new Date();&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;Date date = (Date) value;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;long diff = (now.getTime() - date.getTime()) / 1000; // diff in seconds&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;int j = 0;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;for (int i=0; diff &amp;gt;= lengths[i] &amp;nbsp;&amp;amp;&amp;amp; i &amp;lt; lengths.length -1; i++) {&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;j = i;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;diff = (long) (diff / lengths[i]);&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;String period = periods[j + 1];&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;if (diff != 1) {&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;period = period + "s";&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;return diff + " " + period + " ago";&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You have to register the converter in the faces-config.xml file, like such:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;converter&gt;&lt;/converter&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;converter-id&gt;RelativeDateTimeConverter&lt;/converter-id&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;converter-class&gt;com.ferdinand.datebook.util.RelativeDateTimeConverter&lt;/converter-class&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And once that's done it's easy to use, like such (took the prefixes out because for some reason they won't render in the blog :-):&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;outputtext value="#{_msg.created}"&gt;&lt;/outputtext&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;converter converterid="RelativeDateTimeConverter"&gt;&lt;/converter&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8577867822575605000-1205407771800512915?l=michielverkaik.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://michielverkaik.blogspot.com/feeds/1205407771800512915/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8577867822575605000&amp;postID=1205407771800512915' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/1205407771800512915'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/1205407771800512915'/><link rel='alternate' type='text/html' href='http://michielverkaik.blogspot.com/2011/03/facebook-style-time-ago-as-jsf.html' title='Facebook Style Time Ago as a JSF Converter'/><author><name>michiel verkaik</name><uri>http://www.blogger.com/profile/07977714296269801643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_sPQCPmuPeLI/S0X_DUhDvHI/AAAAAAAAAY0/JTJwj-P7XSg/S220/mv.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8577867822575605000.post-4997575350435597089</id><published>2011-03-03T12:32:00.000-08:00</published><updated>2011-03-03T12:32:17.298-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='transactions'/><category scheme='http://www.blogger.com/atom/ns#' term='nullpointerexception'/><category scheme='http://www.blogger.com/atom/ns#' term='xml'/><category scheme='http://www.blogger.com/atom/ns#' term='core api'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrency'/><category scheme='http://www.blogger.com/atom/ns#' term='alfresco'/><title type='text'>More Alfresco Content Rule Weirdness</title><content type='html'>I've been having some issues with &lt;a href="http://wiki.alfresco.com/wiki/Client_Manage_Content_Rules"&gt;Alfresco Content Rules&lt;/a&gt; and &lt;a href="http://wiki.alfresco.com/wiki/Custom_Actions"&gt;Custom Actions&lt;/a&gt; lately. The Alfresco Core API, and transactionality, it's a not quite a reliable (or controllable) thing. &amp;nbsp;But now I got another strange thing happening.&lt;br /&gt;&lt;br /&gt;We now have another setup for content ingestion, this time with a &lt;a href="http://www.mulesoft.org/"&gt;Mule&lt;/a&gt; based solution for XSL and other transformations.  These are happening before content is pushed into the repo, and in fact, Mule itself does the push through a remote API based on &lt;a href="http://wiki.alfresco.com/wiki/Web_Scripts"&gt;Web Scripts&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The reason for this setup was the earlier concurrency problems we experienced between action executor threads.  We wanted to have an alternative to &lt;a href="http://www.samba.org/cifs/"&gt;CIFS&lt;/a&gt;, &lt;a href="http://www.webdav.org/"&gt;WebDAV&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/File_Transfer_Protocol"&gt;FTP&lt;/a&gt;, and Web Scripts seemed a more reliable approach.&lt;br /&gt;&lt;br /&gt;Indeed, we have more control on how fast or slow content is pushed into the CMS, and the concurrency issues were gone.  But still, we have some problems with an action that's trying to read the content of a node, to update some &lt;a href="http://en.wikipedia.org/wiki/XML"&gt;XML&lt;/a&gt;. &amp;nbsp; We are using a Core API call like such:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;ContentReader contentReader = contentService.getReader(&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;actionedUponNodeRef, ContentModel.PROP_CONTENT);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;But for any subsequent calls on contentReader we get the infamous &lt;a href="http://download.oracle.com/javase/1.5.0/docs/api/java/lang/NullPointerException.html"&gt;NullPointerException&lt;/a&gt;. &amp;nbsp;So, somehow, the node is there, but the content is not. &amp;nbsp;The web script that creates the node is wrapped in a transaction, so the action code should only execute after the script is completely done. &amp;nbsp;Anyway, it seems like it isn't.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8577867822575605000-4997575350435597089?l=michielverkaik.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://michielverkaik.blogspot.com/feeds/4997575350435597089/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8577867822575605000&amp;postID=4997575350435597089' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/4997575350435597089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/4997575350435597089'/><link rel='alternate' type='text/html' href='http://michielverkaik.blogspot.com/2011/03/more-alfresco-content-rule-weirdness.html' title='More Alfresco Content Rule Weirdness'/><author><name>michiel verkaik</name><uri>http://www.blogger.com/profile/07977714296269801643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_sPQCPmuPeLI/S0X_DUhDvHI/AAAAAAAAAY0/JTJwj-P7XSg/S220/mv.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8577867822575605000.post-8482734538230261329</id><published>2011-02-27T17:29:00.000-08:00</published><updated>2011-02-27T17:29:04.084-08:00</updated><title type='text'>Dumb Guy with a Smart Phone</title><content type='html'>That's how I feel whenever I leave that damn thing at home.  :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8577867822575605000-8482734538230261329?l=michielverkaik.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://michielverkaik.blogspot.com/feeds/8482734538230261329/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8577867822575605000&amp;postID=8482734538230261329' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/8482734538230261329'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/8482734538230261329'/><link rel='alternate' type='text/html' href='http://michielverkaik.blogspot.com/2011/02/dumb-guy-with-smart-phone.html' title='Dumb Guy with a Smart Phone'/><author><name>michiel verkaik</name><uri>http://www.blogger.com/profile/07977714296269801643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_sPQCPmuPeLI/S0X_DUhDvHI/AAAAAAAAAY0/JTJwj-P7XSg/S220/mv.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8577867822575605000.post-1928739461769259113</id><published>2011-02-25T10:52:00.000-08:00</published><updated>2011-02-25T10:58:14.839-08:00</updated><title type='text'>Multi-lingual</title><content type='html'>I was trying to come up with a list of languages I touched in the past, and in chronological order, it would look something like this:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;0. Dutch&lt;/b&gt;: I was born and raised in Holland, so Dutch (Nederlands) is my main programming language of choice.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1. German&lt;/b&gt;: It's actually very similar to Dutch, it's a germanic language as well.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;2. English&lt;/b&gt;: Yes, very simple language to learn.  Seems less verbose than Dutch in some ways.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;3. French&lt;/b&gt;: Got to learn this in school for 3 years I think.  I was pretty good at pronunciation, but too many exceptions than rules.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;4. "Multinational English"&lt;/b&gt;: Living in NYC, you get to work with a lot of different people from all over, each bringing our own English pronunciation.  I've worked with people from Vietnam, India, Ukraine, Russia, Germany, France, Costa Rica and it all sounds a little different.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;5. Basic&lt;/b&gt;: Back in the 80s, when there was such a thing like a home computer, that's what you had to program with.  Stored on a tape recorder for retrieval :-)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;6. Pascal&lt;/b&gt;:  We got to do some programming with this in university.  This was all in a DOS kind of environment, although later I think they came up with Turbo Pascal on Windows.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;7. Visual Basic&lt;/b&gt;: This was another assignment I had to do in university, to program a GUI for a WYSIWYG text editor.  Drag-and-drop building displays with programmable event handlers.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;8. Lisp&lt;/b&gt;: Don't remember too much about this one, other than that we used it inside AutoCAD to create macros.  Running on Apollo workstations and later on Sun Solaris.  Must have been mid nineties.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;9. LotusScript&lt;/b&gt;: I have spend a lot of time coding in LS while doing Notes development.  This was late nineties, when "groupware" was hot.  Later on, Lotus also started to support Java and JavaScript within its platform.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;10. JavaScript&lt;/b&gt;: Once I started doing web applications in Lotus Notes &amp; Domino, JavaScript was the next logical thing.  Simple things like form validation etc, nothing too fancy.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;11. HTML&lt;/b&gt;: One can argue that HTML is not really a language, but when you go DHTML is becomes a lot more programming.  Mostly did some nifty drop-down menus etc and rotating banners.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;12. Java&lt;/b&gt;: Java was another language that got introduced into Lotus Notes.  But at a certain point in time, we went all out Java, with a portal, a CMS, search and IDM all on the same platform.  There was no escaping Java with IBM as your vendor.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;13. MS ASP&lt;/b&gt;: My company used to do a lot of stuff for Intel, and the main agency was a big Microsoft shop.  So everything was on in Active Service Pages on IIS, with SQL 2000 for relational storage.  It was great, because simple to use.  Not much object orientation or code reuse though...&lt;br /&gt;&lt;br /&gt;&lt;b&gt;14. Python&lt;/b&gt;:  This is a weird one.  I got to program in it when working on a Vignette CMS for collaboration.  It's an elegant language, easy to read.  I've also used it recently to export a SQLite database into XML documents.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;15. DotNet &amp; C#&lt;/b&gt;:  This one I liked, but I only worked with .NET for 10 months or so.  I was able to clobber together a time tracking application, hand-coded AJAX calls included :-)  Visual Studio is great, and C# is easy to learn when you know java.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;16. Groovy&lt;/b&gt;: This is a nice one, which I got to play with a little when I was checking out Groovy.  It's an elegant language, more compact than java.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8577867822575605000-1928739461769259113?l=michielverkaik.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://michielverkaik.blogspot.com/feeds/1928739461769259113/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8577867822575605000&amp;postID=1928739461769259113' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/1928739461769259113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/1928739461769259113'/><link rel='alternate' type='text/html' href='http://michielverkaik.blogspot.com/2011/02/multi-lingual.html' title='Multi-lingual'/><author><name>michiel verkaik</name><uri>http://www.blogger.com/profile/07977714296269801643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_sPQCPmuPeLI/S0X_DUhDvHI/AAAAAAAAAY0/JTJwj-P7XSg/S220/mv.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8577867822575605000.post-5897746416062203227</id><published>2011-02-20T11:55:00.000-08:00</published><updated>2011-02-20T11:55:13.290-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='transactions'/><category scheme='http://www.blogger.com/atom/ns#' term='multithreading'/><category scheme='http://www.blogger.com/atom/ns#' term='xml'/><category scheme='http://www.blogger.com/atom/ns#' term='web scripts'/><category scheme='http://www.blogger.com/atom/ns#' term='remoting'/><category scheme='http://www.blogger.com/atom/ns#' term='actions'/><category scheme='http://www.blogger.com/atom/ns#' term='foundation API'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrency'/><category scheme='http://www.blogger.com/atom/ns#' term='alfresco'/><title type='text'>Alfresco Actions &amp; Multi-Threading</title><content type='html'>For a particular project we ingest large amounts of XML and binary data into &lt;a href="http://www.alfresco.com/"&gt;Alfresco&lt;/a&gt; on a continuous basis.  We use a "drop box" approach, where spaces in Alfresco are assigned a content rule to call a certain action.  The action attempts to file a node into a certain repository path, and tries to create the path structure if it doesn't exist.  It works great with a single request, but when you start dropping multiple files at the same time, we run into &lt;a href="http://en.wikipedia.org/wiki/Concurrency_(computer_science)"&gt;concurrency&lt;/a&gt; issues.  For dropping we use a custom web-script that takes the file as multi-part form-data stream in a form POST.&lt;br /&gt;&lt;br /&gt;It seems that each action invocation is wrapped in its own implicit &lt;a href="http://en.wikipedia.org/wiki/Transaction"&gt;transaction&lt;/a&gt;, with its own private memory space.  The problem arises with concurrent drops, when thread #1 attempts to create a node that was already created by thread #2, more or less while both transactions are running.  Both transactions are not aware of each other's state.&lt;br /&gt;&lt;br /&gt;This last statement is not completely true.  It seems that you can find a NodeRef through the &lt;a href="http://wiki.alfresco.com/wiki/Search_Service_API"&gt;SearchService&lt;/a&gt; with a Lucene query, even if it was created in another transaction.  Unfortunately this is not the case for the NodeService, which you need to rely on for a lot of the work.  It chokes on NodeRef instances found by the SearchService.  &lt;br /&gt;&lt;br /&gt;It's possible to synchronize all action code, but this still doesn't solve the duplicate node issue, which is what happens when 2 threads try to create the same node in isolation from each other.  You simply don't seem to have control over which thread will be committed first, even if you use your own non-propagating transactions within the synchronized block.&lt;br /&gt;&lt;br /&gt;Even a &lt;a href="http://dev.alfresco.com/resource/docs/java/repository/org/alfresco/repo/transaction/RetryingTransactionHelper.html"&gt;RetryingTransactionHelper&lt;/a&gt; CallBack was implemented, but to no avail.  One thread simply cannot see the state of the other thread's transaction, at least the NodeService can't.  It would be cool if you could refresh a current transaction with the latest changes to the repo.&lt;br /&gt;&lt;br /&gt;Anyway, this whole ordeal took more than 3 days with multiple engineers looking at the issue at the same time.  We considered using a &lt;a href="http://wiki.alfresco.com/wiki/Scheduled_Actions"&gt;scheduled Alfresco Action&lt;/a&gt; as an alternative to the content rules, but decided against it.  Now we're implementing the action as a remote call using &lt;a href="http://wiki.rivetlogic.com/display/RAAR/About+RAAr"&gt;RAAr, a java API for remote communication with Alfresco ECM&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The cool thing about RAAr is that it follows the &lt;a href="http://wiki.alfresco.com/wiki/Developer_Guide#Java_Foundation_APIs"&gt;Alfresco Foundation API&lt;/a&gt; to the letter, so in theory you can take Alfresco compliant code and drop use it in conjunction with RAAr without a problem.  &lt;br /&gt;&lt;br /&gt;All method call with RAAr are are remote, and handled by a web script.  Every call is also wrapped in its own transaction, which is... nice :-)  The only downside is that it will be slower, but if it's more reliable I don't care too much about that.&lt;br /&gt;&lt;br /&gt;Ok, after this shameless plug, a few last words.  Although Alfresco is highly transactional, it may not always work as expected using the Alfresco Foundation API.  There's probably a bug, or a possibility for improvement, but it would be time consuming.  A remote ingestion approach, while slower, is a more reliable way of managing new and updated content inside the repo.&lt;br /&gt;&lt;br /&gt;That's it for now.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8577867822575605000-5897746416062203227?l=michielverkaik.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://michielverkaik.blogspot.com/feeds/5897746416062203227/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8577867822575605000&amp;postID=5897746416062203227' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/5897746416062203227'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/5897746416062203227'/><link rel='alternate' type='text/html' href='http://michielverkaik.blogspot.com/2011/02/alfresco-actions-multi-threading.html' title='Alfresco Actions &amp; Multi-Threading'/><author><name>michiel verkaik</name><uri>http://www.blogger.com/profile/07977714296269801643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_sPQCPmuPeLI/S0X_DUhDvHI/AAAAAAAAAY0/JTJwj-P7XSg/S220/mv.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8577867822575605000.post-2905280749380759767</id><published>2011-02-18T06:49:00.000-08:00</published><updated>2011-02-18T06:58:59.847-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mac os'/><category scheme='http://www.blogger.com/atom/ns#' term='file system'/><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><category scheme='http://www.blogger.com/atom/ns#' term='unix'/><title type='text'>Windows vs Unix File System</title><content type='html'>I'm running a project at the moment, where we need to publish files to a &lt;a href="http://en.wikipedia.org/wiki/NTFS"&gt;Windows NTFS&lt;/a&gt; file system.  &lt;br /&gt;&lt;br /&gt;Ran into some issues, because some of the file paths were getting longer than 256 characters.  At least it seems an issue extracting such long file names from a ZIP or TAR file.  Not sure if there are difference between Windows XP and Windows 2008 Server.  It seems possible to go over the limitation of 256 chars on the server, when you copy files directly over the file system (SMB in this case).&lt;br /&gt;&lt;br /&gt;Also saw some issues with the use of &lt;a href="http://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words"&gt;reserved words&lt;/a&gt; on the Windows FS.  The following words are reserved for devices on NTFS: CON, PRN, AUX, CLOCK$, NUL, COM0, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT0, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9.  So as a solution we had to wrap them.&lt;br /&gt;&lt;br /&gt;Very odd, and in that respect we're a lot better off on &lt;a href="http://www.linux.com/"&gt;Linux&lt;/a&gt; and &lt;a href="http://www.apple.com/macosx/"&gt;Mac OS&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8577867822575605000-2905280749380759767?l=michielverkaik.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://michielverkaik.blogspot.com/feeds/2905280749380759767/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8577867822575605000&amp;postID=2905280749380759767' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/2905280749380759767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/2905280749380759767'/><link rel='alternate' type='text/html' href='http://michielverkaik.blogspot.com/2011/02/windows-vs-unix-file-system.html' title='Windows vs Unix File System'/><author><name>michiel verkaik</name><uri>http://www.blogger.com/profile/07977714296269801643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_sPQCPmuPeLI/S0X_DUhDvHI/AAAAAAAAAY0/JTJwj-P7XSg/S220/mv.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8577867822575605000.post-7884006822621115728</id><published>2011-02-02T07:07:00.000-08:00</published><updated>2011-02-02T07:52:46.199-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='osgi'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><category scheme='http://www.blogger.com/atom/ns#' term='alfresco'/><title type='text'>Writing custom actions for Alfresco</title><content type='html'>As we all know, writing code is an iterative process.  You never get it right until you tried several iterations, maybe up to 20 depending on complexity.  Too bad java code needs to be compiled, which is particularly annoying for deploying and running &lt;a href="http://www.alfresco.com/"&gt;Alfresco&lt;/a&gt; extensions.  &lt;br /&gt;&lt;br /&gt;So here is my iterative development cycle:&lt;br /&gt;&lt;br /&gt;1.) Write some code (in Eclipse, mostly)&lt;br /&gt;2.) ./alfresco.sh stop&lt;br /&gt;3.) mvn package&lt;br /&gt;4.) java -jar bin/alfresco-mmt.jar install ~/path/to/my/extension.amp tomcat/webapps/alfresco.war -force -nobackup;rm -r tomcat/webapps/alfresco;./alfresco.sh start&lt;br /&gt;5.) Test and see what happens&lt;br /&gt;&lt;br /&gt;Step 4 as you can see is the killer, as starting Alfresco takes 90 seconds (I want an &lt;a href="http://en.wikipedia.org/wiki/Ssd"&gt;SSD&lt;/a&gt;, please).  Enough to keep checking my e-mail for no reason. Maybe they should do something cool like &lt;a href="http://en.wikipedia.org/wiki/OSGi"&gt;OSGI&lt;/a&gt; next time, so we can deploy that stuff on-the-fly into the box.  Anything to make my cycle go faster :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8577867822575605000-7884006822621115728?l=michielverkaik.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://michielverkaik.blogspot.com/feeds/7884006822621115728/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8577867822575605000&amp;postID=7884006822621115728' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/7884006822621115728'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/7884006822621115728'/><link rel='alternate' type='text/html' href='http://michielverkaik.blogspot.com/2011/02/writing-custom-actions-for-alfresco.html' title='Writing custom actions for Alfresco'/><author><name>michiel verkaik</name><uri>http://www.blogger.com/profile/07977714296269801643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_sPQCPmuPeLI/S0X_DUhDvHI/AAAAAAAAAY0/JTJwj-P7XSg/S220/mv.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8577867822575605000.post-4551775590853526712</id><published>2011-02-01T08:04:00.000-08:00</published><updated>2011-02-01T08:23:33.335-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='documentation'/><category scheme='http://www.blogger.com/atom/ns#' term='alfresco'/><title type='text'>Alfresco Documentation</title><content type='html'>When you do Alfresco development or integration, &lt;a href="http://wiki.alfresco.com/wiki/Main_Page"&gt;the wiki&lt;/a&gt; is your friend.  Don't try to use the wiki's search though, I usually use Google with better results (site:wiki.alfresco.com keyword1 keyword2 etc.)  Your other friend will be the &lt;a href="http://wiki.alfresco.com/wiki/Source_Code"&gt;Alfresco source code&lt;/a&gt;, since the wiki won't tell you everything.  I guess this is true for any open source product.  Once I have the source code, all I need is Mac OS's &lt;a href="http://www.apple.com/macosx/what-is-macosx/spotlight.html"&gt;Spotlight&lt;/a&gt; and a text editor and that's it :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8577867822575605000-4551775590853526712?l=michielverkaik.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://michielverkaik.blogspot.com/feeds/4551775590853526712/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8577867822575605000&amp;postID=4551775590853526712' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/4551775590853526712'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/4551775590853526712'/><link rel='alternate' type='text/html' href='http://michielverkaik.blogspot.com/2011/02/alfresco-documentation.html' title='Alfresco Documentation'/><author><name>michiel verkaik</name><uri>http://www.blogger.com/profile/07977714296269801643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_sPQCPmuPeLI/S0X_DUhDvHI/AAAAAAAAAY0/JTJwj-P7XSg/S220/mv.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8577867822575605000.post-2968753949593687575</id><published>2011-01-22T07:27:00.000-08:00</published><updated>2011-01-22T07:37:12.166-08:00</updated><title type='text'>iPod Quality</title><content type='html'>So the other day I accidentally dropped my iPod in a big puddle of water on the corner of the street.  It got completely submerged for maybe 5 seconds.  It was actually on when it happened, and after I picked it back up, I saw the screen slowly die :-(  Ok, it's about six years old, but still...  Anyway, I found &lt;a href="http://www.ipodwizard.net/showthread.php?t=5747"&gt;this post&lt;/a&gt; which basically said to dry it out good, and it could still come back to life, and it did!!!  Pretty amazing, although it doesn't beat the story of the guy who had his iPod in a commercial washer for 40 minutes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8577867822575605000-2968753949593687575?l=michielverkaik.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://michielverkaik.blogspot.com/feeds/2968753949593687575/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8577867822575605000&amp;postID=2968753949593687575' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/2968753949593687575'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/2968753949593687575'/><link rel='alternate' type='text/html' href='http://michielverkaik.blogspot.com/2011/01/ipod-quality.html' title='iPod Quality'/><author><name>michiel verkaik</name><uri>http://www.blogger.com/profile/07977714296269801643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_sPQCPmuPeLI/S0X_DUhDvHI/AAAAAAAAAY0/JTJwj-P7XSg/S220/mv.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8577867822575605000.post-6007514099425606241</id><published>2010-05-19T07:27:00.001-07:00</published><updated>2010-05-19T07:39:24.921-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='troubleshooting'/><category scheme='http://www.blogger.com/atom/ns#' term='alfresco'/><title type='text'>Recreating an Alfresco instance</title><content type='html'>&lt;blockquote&gt;&lt;/blockquote&gt;Sometimes Alfresco becomes a little messed up, and you may not have a choice other than to recreate it.  This can be done by deleting everything in the &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;alf_data&lt;/span&gt; directory and recreating the (empty) database with the mysql command line client:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;drop database alfresco;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;create database alfresco default character set utf8 collate utf8_bin;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Once Alfresco starts up, it will recognize that the database is empty, and it will kick off a process to recreate the schema.  However, be sure to restart Mysql before starting Alfresco.  It seems that foreign key names get stuck in cache, even after the database holding the keys gets dropped.  If you don't restart Mysql, you may see messages like this in the &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;catalina.out&lt;/span&gt;:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:georgia;"&gt;1&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;0:00:55,707  INFO  [domain.schema.SchemaBootstrap] Schema managed by database dialect org.hibernate.dialect.MySQLInnoDBDialect.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;10:00:55,857  INFO  [domain.schema.SchemaBootstrap] Executing database script /Users/mverkaik/servers/alfresco-3.2.1/tomcat/temp/Alfresco/AlfrescoSchema-MySQLInnoDBDialect-Update-2896636379215681530.sql (Generated).&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;10:01:03,872  ERROR [domain.schema.SchemaBootstrap] Statement execution failed:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   SQL:     alter table JBPM_BYTEBLOCK&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;        add index FK_BYTEBLOCK_FILE (PROCESSFILE_),&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;        add constraint FK_BYTEBLOCK_FILE&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;        foreign key (PROCESSFILE_)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;        references JBPM_BYTEARRAY (ID_)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   Error: Duplicate key name 'FK_BYTEBLOCK_FILE'&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   File: /Users/mverkaik/servers/alfresco-3.2.1/tomcat/temp/Alfresco/AlfrescoSchema-MySQLInnoDBDialect-Update-2896636379215681530.sql&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;   Line: 813&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;10:01:03,873  ERROR [domain.schema.SchemaBootstrap] Schema auto-update failed&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8577867822575605000-6007514099425606241?l=michielverkaik.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://michielverkaik.blogspot.com/feeds/6007514099425606241/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8577867822575605000&amp;postID=6007514099425606241' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/6007514099425606241'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/6007514099425606241'/><link rel='alternate' type='text/html' href='http://michielverkaik.blogspot.com/2010/05/recreating-alfresco-instance.html' title='Recreating an Alfresco instance'/><author><name>michiel verkaik</name><uri>http://www.blogger.com/profile/07977714296269801643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_sPQCPmuPeLI/S0X_DUhDvHI/AAAAAAAAAY0/JTJwj-P7XSg/S220/mv.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8577867822575605000.post-3774688702686078729</id><published>2010-05-14T07:07:00.000-07:00</published><updated>2010-05-14T10:50:19.847-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='alfresco workflow jbpm'/><title type='text'>Alfresco Workflow</title><content type='html'>&lt;a href="http://wiki.alfresco.com/wiki/Workflow"&gt;Workflow in Alfresco WCM&lt;/a&gt; is a powerful tool to implement review &amp;amp; approval processes.  At the same time, workflow development is not a trivial exercise.  Alfresco uses &lt;a href="http://www.jboss.org/jbpm"&gt;JBoss jBPM&lt;/a&gt; as a foundation, with Alfresco javascript to define actions.  The workflow itself is defined as and XML file, with mixed in the javascript.  You can deploy one or more workflows as an &lt;a href="http://wiki.alfresco.com/wiki/Category:AMP_Files"&gt;AMP file&lt;/a&gt; into the Alfresco web archive.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There is a tool for workflow development called &lt;a href="http://docs.jboss.org/jbpm/v3/gpd/"&gt;jBPM Designer&lt;/a&gt;.  It's an Eclipse based plugin, which has some nice graphical features to define workflows.  It's not required to use this tool.  Alternatively you can take an &lt;a href="http://issues.alfresco.com/jira/browse/ALF-1965"&gt;sample workflow&lt;/a&gt; and alter it using a regular text editor.  Ensure to change module name, module directory name, namespace and possibly variable names.  Otherwise the workflow might clash if the same sample workflow has already been deployed.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I haven't quite figured out what's the most efficient way to develop workflows.  Code changes happen in the workflow's task definition, and every time you update it, you need to have it somehow redeployed in Alfresco.  If you make code changes directly in the deployed workflow, you can restart the server to have the changes take effect.  Alfresco will automatically create a new version of the workflow definition.  There may be a way to redeploy the updated workflow through Alfresco's &lt;a href="http://wiki.alfresco.com/wiki/Workflow_Console"&gt;workflow console&lt;/a&gt;, but I haven't seen any concrete examples of that yet.  I believe this works easier when you use the jBPM Designer, because you're supposed to be able to redeploy straight from the IDE.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It would be fantastic if the development process could be streamlined, to a point that you don't have to write too much code.  I'm thinking about some sort of ant build process, which asks a series of questions, and based on the questions, it will generate the necessary artifacts for you.  This could really save a lot of time.  I think such a wizard-like approach already exists in the jBPM process designer, so that's another option as well.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ultimately it would be great if workflows could be designed by the power user, using the Alfresco web client.  This could be a form based interface to define task nodes, transitions, conditions, etc.  There are some common components that may be re-usable, such as code to send e-mail alerts to assignees.  This could be easily abstracted as a function that can be turned on or off and configured with GUI controls.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The challenge with the last approach is the deployment of the workflow.  Is Alfresco capable of (re-)deploying a workflow definitions after a workflow has been configured.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8577867822575605000-3774688702686078729?l=michielverkaik.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://michielverkaik.blogspot.com/feeds/3774688702686078729/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8577867822575605000&amp;postID=3774688702686078729' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/3774688702686078729'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/3774688702686078729'/><link rel='alternate' type='text/html' href='http://michielverkaik.blogspot.com/2010/05/alfresco-workflow.html' title='Alfresco Workflow'/><author><name>michiel verkaik</name><uri>http://www.blogger.com/profile/07977714296269801643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_sPQCPmuPeLI/S0X_DUhDvHI/AAAAAAAAAY0/JTJwj-P7XSg/S220/mv.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8577867822575605000.post-7954936059109618037</id><published>2010-05-09T12:23:00.000-07:00</published><updated>2010-05-09T14:08:55.237-07:00</updated><title type='text'>I Pad</title><content type='html'>Since a couple of weeks, I've been playing with an iPad, which my daughter Lilly won on an raffle at her school :-)  To be honest, I wouldn't have bought one.  It's definitely not a device one could not live without.  But it's cool, and I like the whole tablet concept thing.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The touch screen is nice, and I like how you can easily navigate.  It's a very shallow UI, but rich nonetheless.  The YouTube, Mail and Safari apps are used frequently.  Also installed the Weather Channel app, MLB, BBC, Skype, Doodle Buddy and some simple games.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The weak point of the iPad I find to be the data input.  The virtual keyboard is big enough, but it's hard to type fast with one hand as you're holding the device with the other hand.  It would be really nice if it had built in voice recognition.  Maybe in the second generation iPad.  There may even be apps out there that already do this.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8577867822575605000-7954936059109618037?l=michielverkaik.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://michielverkaik.blogspot.com/feeds/7954936059109618037/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8577867822575605000&amp;postID=7954936059109618037' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/7954936059109618037'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/7954936059109618037'/><link rel='alternate' type='text/html' href='http://michielverkaik.blogspot.com/2010/05/i-pad.html' title='I Pad'/><author><name>michiel verkaik</name><uri>http://www.blogger.com/profile/07977714296269801643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_sPQCPmuPeLI/S0X_DUhDvHI/AAAAAAAAAY0/JTJwj-P7XSg/S220/mv.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8577867822575605000.post-289575878296998853</id><published>2010-05-04T07:37:00.000-07:00</published><updated>2010-05-08T13:59:49.552-07:00</updated><title type='text'>Project Handoff</title><content type='html'>I've done now a couple of project as a software consultant, and one of the crucial part always seems to be the handoff / the delivery.  It's something you don't always think about when you start a new project. But ultimately the goal is to make the client proficient with most every aspect of the new system.  The IT team needs to know how to compile, configure, deploy and to troubleshoot.  End users have to be become familiar with the user interface.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One obvious way of knowledge transfer is through documentation.  It's helpful to create some notes during the development phase.  Using a &lt;a href="http://en.wikipedia.org/wiki/Wiki"&gt;wiki&lt;/a&gt; this is typically not too time consuming, and it's easy to publish pages as PDF or Word.  Always understand what level of detail is needed.  Depending of the client team experience, the documentation may need to be more or less verbose.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Sometimes it's useful to walk the customer through the deployment process.  I think of this as the best way of knowledge transfer.  One time I had to do two eight hour web conference sessions with a client to, since I had no direct access to the system.  It was painful, but it forced me to walk the customer through the process step-by-step.  Even fixed a few small bugs along the way :-)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&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;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8577867822575605000-289575878296998853?l=michielverkaik.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://michielverkaik.blogspot.com/feeds/289575878296998853/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8577867822575605000&amp;postID=289575878296998853' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/289575878296998853'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/289575878296998853'/><link rel='alternate' type='text/html' href='http://michielverkaik.blogspot.com/2010/05/project-handoff.html' title='Project Handoff'/><author><name>michiel verkaik</name><uri>http://www.blogger.com/profile/07977714296269801643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_sPQCPmuPeLI/S0X_DUhDvHI/AAAAAAAAAY0/JTJwj-P7XSg/S220/mv.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8577867822575605000.post-2811807550866370935</id><published>2010-05-03T07:47:00.000-07:00</published><updated>2010-05-03T10:01:14.895-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='exist db'/><category scheme='http://www.blogger.com/atom/ns#' term='yourkit'/><category scheme='http://www.blogger.com/atom/ns#' term='jmeter'/><category scheme='http://www.blogger.com/atom/ns#' term='performance testing'/><title type='text'>Performance Testing Learnings</title><content type='html'>The last few weeks I've been performance testing a proof-of-concept application with good old &lt;a href="http://jakarta.apache.org/jmeter/"&gt;JMeter&lt;/a&gt;.  Here are some of my findings.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To me, this testing is still more of an art form than a exact science.  There are simply too many parameters that can be changed, so tweaking and system tuning seems to be going hand in hand.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The main things you can change in between tests is the # of concurrent requests, and the target throughput (transactions per minute).  It's important to monitor the the JMeter logs to ensure there are no time-outs occurring.  If you make the sampler time-out settings to conservative, this will sooner or later happen as load increases.  What exactly is conservative depends on the type of site and audience.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What's important to find out is what kind of maximum throughput can be accomplished with a minimum amount of time-outs.  You have to do several test runs to find this out, each time increasing the load on the system.  For each load level you will also want to measure the average and median response times. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As you're running JMeter tests, it's very useful to profile the server to see how CPU and memory resources are being utilized.  In my case I used &lt;a href="http://www.yourkit.com/"&gt;YourKit&lt;/a&gt; for profiling &lt;a href="http://tomcat.apache.org/tomcat-6.0-doc/index.html"&gt;Tomcat 6&lt;/a&gt;.  It's easy to setup, and it can show you when resources are getting over utilized, or even locking issues.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Especially locking issues, caused by concurrent access to synchronized code blocks, can slow things down.  When you are fully loading the application, and CPU does not spike all the way to 100%, that could be an indication of locking issues.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Monitoring Java heap memory is important when doing a lot of caching, and in general to see if the application has memory leaks.  Provided you have no such leaks, you still want to find out the memory footprint of your application, to determine what kind of memory should be allocated to the JVM.  When using caching, it can be useful to understand the footprint on an object (type) level, so you know how the application scales under different concurrent loads.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As performance tests are executed, you undoubtedly will end up trying to tune the full application stack.  The prototype I tested used &lt;a href="http://exist.sourceforge.net/"&gt;eXist DB&lt;/a&gt; and &lt;a href="http://ehcache.org/"&gt;EHCache&lt;/a&gt;, and was deployed on Tomcat and fronted by Apache.  In each components there are configuration properties that can be tweaked.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There is always a bottleneck in the stack, and the challenge is to find it.  There can be a combination of weak links.  The next steps would be tune each weak component, and to see if certain links can be replaced, or even skipped.  You may end up tweaking the overall system architecture, based on the findings of the system tuning effort.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8577867822575605000-2811807550866370935?l=michielverkaik.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://michielverkaik.blogspot.com/feeds/2811807550866370935/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8577867822575605000&amp;postID=2811807550866370935' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/2811807550866370935'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/2811807550866370935'/><link rel='alternate' type='text/html' href='http://michielverkaik.blogspot.com/2010/05/performance-testing-learnings.html' title='Performance Testing Learnings'/><author><name>michiel verkaik</name><uri>http://www.blogger.com/profile/07977714296269801643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_sPQCPmuPeLI/S0X_DUhDvHI/AAAAAAAAAY0/JTJwj-P7XSg/S220/mv.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8577867822575605000.post-502031778048960335</id><published>2010-04-19T11:32:00.000-07:00</published><updated>2010-04-19T13:49:55.594-07:00</updated><title type='text'>Stress Testing Basics</title><content type='html'>Every once in a while you have to &lt;a href="http://en.wikipedia.org/wiki/Stress_testing_%28software%29"&gt;stress test&lt;/a&gt; a newly cobbled together system, to determine how it performs under a lot of load.  From my experience, I'm finding that you want to find out is something like this:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;How many transactions per second can it support?&lt;/li&gt;&lt;li&gt;What is the average response times under different load levels (concurrent threads)?&lt;/li&gt;&lt;li&gt;At what load level start requests to time out frequently?&lt;/li&gt;&lt;/ul&gt;Before you can even start testing, you have to come up with some sort of test design.  This requires you quantify some of your anticipated usage.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;How many daily users expected?&lt;/li&gt;&lt;li&gt;How many clicks per user session?&lt;/li&gt;&lt;li&gt;What kind of queries expected in a user session?&lt;/li&gt;&lt;li&gt;Different user profiles?&lt;/li&gt;&lt;li&gt;What is my goal for average/median response time?&lt;/li&gt;&lt;/ul&gt;Answering these questions will give you some constraints to work with, and will drive the test design &amp;amp; execution.  The goal is to make the design as realistic as possible. &lt;br /&gt;&lt;br /&gt;Sometimes you'll find that you need to re-think your goals a bit.  A single server can only handle so many transactions per time unit.  For certain usage load you have to start thinking about &lt;a href="http://en.wikipedia.org/wiki/Cluster_%28computing%29"&gt;clustering&lt;/a&gt; or &lt;a href="http://en.wikipedia.org/wiki/Sharding"&gt;sharding&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8577867822575605000-502031778048960335?l=michielverkaik.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://michielverkaik.blogspot.com/feeds/502031778048960335/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8577867822575605000&amp;postID=502031778048960335' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/502031778048960335'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/502031778048960335'/><link rel='alternate' type='text/html' href='http://michielverkaik.blogspot.com/2010/04/stress-testing-basics.html' title='Stress Testing Basics'/><author><name>michiel verkaik</name><uri>http://www.blogger.com/profile/07977714296269801643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_sPQCPmuPeLI/S0X_DUhDvHI/AAAAAAAAAY0/JTJwj-P7XSg/S220/mv.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8577867822575605000.post-2828740904465993957</id><published>2010-04-14T09:18:00.000-07:00</published><updated>2010-04-14T09:28:07.619-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firefox'/><category scheme='http://www.blogger.com/atom/ns#' term='jmeter'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><title type='text'>To test a web site with JMeter requiring Basic Authentication</title><content type='html'>I'm currently stress testing a web application with &lt;a href="http://jakarta.apache.org/jmeter/"&gt;JMeter&lt;/a&gt;.  My test plan has a handful of HTTP samplers, but the application is protected by &lt;a href="http://httpd.apache.org/"&gt;Apache&lt;/a&gt; with basic authentication. &lt;br /&gt;&lt;br /&gt;To allow the test plan to authenticate with each request, you need to add an HTTP Header Manager configuration element to the Thread Group.  In it you add one field named "Authorization". &lt;br /&gt;&lt;br /&gt;The only thing left is to set the header value, which can be obtained by looking at the requests of a browser.   In &lt;a href="http://www.mozilla.com/en-US/firefox/personal.html"&gt;Firefox&lt;/a&gt; this can be done with the &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/3829"&gt;Live HTTP Headers Add-on&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8577867822575605000-2828740904465993957?l=michielverkaik.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://michielverkaik.blogspot.com/feeds/2828740904465993957/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8577867822575605000&amp;postID=2828740904465993957' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/2828740904465993957'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/2828740904465993957'/><link rel='alternate' type='text/html' href='http://michielverkaik.blogspot.com/2010/04/to-test-web-site-with-jmeter-requiring.html' title='To test a web site with JMeter requiring Basic Authentication'/><author><name>michiel verkaik</name><uri>http://www.blogger.com/profile/07977714296269801643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_sPQCPmuPeLI/S0X_DUhDvHI/AAAAAAAAAY0/JTJwj-P7XSg/S220/mv.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8577867822575605000.post-4865147036002693765</id><published>2010-02-25T08:17:00.001-08:00</published><updated>2010-02-25T08:34:07.359-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><title type='text'>Grails, Ivy and Maven</title><content type='html'>As I'm diving deeper into Grails 1.2.1, I get to learn more about the dependency resolution mechanism.  I came across the following scenario:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Grails project with dependency in local Maven repo&lt;/li&gt;&lt;li&gt;Project compiles and runs fine, but Maven project dependency has a bug&lt;/li&gt;&lt;li&gt;Let's fix the bug, and do a '&lt;span style="font-family: courier new;"&gt;mvn clean install&lt;/span&gt;'.&lt;/li&gt;&lt;li&gt;Now, let's run Grails project again, after doing a '&lt;span style="font-family:courier new;"&gt;grails clean&lt;/span&gt;'.&lt;/li&gt;&lt;li&gt;Hmmm, the bug is still there, even as I fixed it and re-installed in my local Maven repo???&lt;/li&gt;&lt;/ol&gt;Interesting enough, it appears that Grails actually retrieves my Maven project dependency from the Ivy cache.  There is a crude way around that, by deleting the Ivy cache altogether (&lt;span style="font-family:courier new;"&gt;rm -r ~/.ivy2/cache&lt;/span&gt;), but the next time you build the Grails project, it again will cache the Maven defined project.  This can be seen when the log level in &lt;span style="font-family:courier new;"&gt;BuildConfig.groovy&lt;/span&gt; is set to "&lt;span style="font-family:courier new;"&gt;debug&lt;/span&gt;" level:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    grailsHome: no ivy file nor artifact found for org.rivetlogic#crafter;1.7.0-SNAPSHOT&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;don't use cache for org.rivetlogic#crafter;1.7.0-SNAPSHOT: changing=true&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Very strange.  Hopefully I will find out how to change this soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8577867822575605000-4865147036002693765?l=michielverkaik.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://michielverkaik.blogspot.com/feeds/4865147036002693765/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8577867822575605000&amp;postID=4865147036002693765' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/4865147036002693765'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/4865147036002693765'/><link rel='alternate' type='text/html' href='http://michielverkaik.blogspot.com/2010/02/grails-ivy-and-maven.html' title='Grails, Ivy and Maven'/><author><name>michiel verkaik</name><uri>http://www.blogger.com/profile/07977714296269801643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_sPQCPmuPeLI/S0X_DUhDvHI/AAAAAAAAAY0/JTJwj-P7XSg/S220/mv.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8577867822575605000.post-7773208987431659122</id><published>2010-02-25T04:30:00.000-08:00</published><updated>2010-02-25T06:06:15.206-08:00</updated><title type='text'>Grails 1.2.1 Loader Constraint Violation</title><content type='html'>I came across this error after adding a dependency to my Grails project:&lt;br /&gt;&lt;blockquote style="font-family: courier new;"&gt;java.lang.LinkageError: loader constraint violation: loader (instance of &lt;bootloader&gt;) previously initiated loading for a different type with name "org/xml/sax/SAXParseException"&lt;/bootloader&gt;&lt;/blockquote&gt;This error was thrown every time I tried to do a 'grails run-app'.  This seems to be a &lt;a href="http://jira.codehaus.org/browse/GRAILS-5500"&gt;known issue&lt;/a&gt;, but I found very little information online about what it was caused by.  One thing is clear: The Grails class loader gets unhappy when it finds the same class in different libraries.&lt;br /&gt;&lt;br /&gt;It turns out this &lt;a href="http://www.saxproject.org/"&gt;SAX&lt;/a&gt; class org.xml.sax.SAXParseException is embedded in a couple of jars (xml-apis and xmlParserAPIs) used in my Maven project.   The way to solve it was to add an excludes directive to the grails-app/conf/BuildConfig.groovy file:&lt;br /&gt;&lt;br /&gt;   &lt;span style="font-family: courier new;"&gt;dependencies {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;           runtime('org.rivetlogic:crafter:1.7.0-SNAPSHOT') {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;                    excludes 'xml-apis', 'xmlParserAPIs'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;           }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;    }&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8577867822575605000-7773208987431659122?l=michielverkaik.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://michielverkaik.blogspot.com/feeds/7773208987431659122/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8577867822575605000&amp;postID=7773208987431659122' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/7773208987431659122'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/7773208987431659122'/><link rel='alternate' type='text/html' href='http://michielverkaik.blogspot.com/2010/02/grails-121-loader-constraint-violation.html' title='Grails 1.2.1 Loader Constraint Violation'/><author><name>michiel verkaik</name><uri>http://www.blogger.com/profile/07977714296269801643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_sPQCPmuPeLI/S0X_DUhDvHI/AAAAAAAAAY0/JTJwj-P7XSg/S220/mv.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8577867822575605000.post-4159697626887632496</id><published>2010-02-23T08:56:00.000-08:00</published><updated>2010-02-23T09:34:00.267-08:00</updated><title type='text'>Alfresco 3.3 and further...</title><content type='html'>Alfresco recently released a &lt;a href="http://www.slideshare.net/alfresco/wcm-roadmap-versions-3-3-and-4-0"&gt;slideshow&lt;/a&gt; about Alfresco 3.3 and 4.0, and it gives a good overview of where the product is heading. &lt;br /&gt;&lt;br /&gt;Overall it seems that the Alfresco is becoming a more integrated platform, which is both good and bad.  It depends on how it all will be packaged.  If we can turn on and off certain modules quickly, then things will be fine.&lt;br /&gt;&lt;br /&gt;One of the big trends in Alfresco 3.3 and further is a tighter integration with Spring Surf, a web application framework for WCM based sites.  A major feature will be the notion of In Context Editing, implemented using a browser-based JavaScript toolbar.  I hope this toolbar will at least work well in Firefox and IE, although the latter is always a challenge.&lt;br /&gt;&lt;br /&gt;Of course, you don't have to be married to Spring Surf to deliver your web site.  You are supposed to be able to write Alfresco Web Editor extensions to make the toolbar work in other application frameworks.&lt;br /&gt;&lt;br /&gt;Completely new in 3.3 will be the CMIS based Web Delivery Runtime, and it appears to be a File System Receiver on steriods.  It is supposedly technology agnostic, but is highly extensible and pluggable.  It seems to be working in conjunction with "Deployment Services", something that allows the "core Alfresco repository to be utilized in the delivery tear".  That sounds to me as if you'll have more flexibility and control over deployment within the web client.&lt;br /&gt;&lt;br /&gt;This all seems very nice, and I look forward to the new release.  However, it all appears to be highly technical, and I'm sure that lots more configuration will have to be done in tedious XML files. &lt;br /&gt;&lt;br /&gt;I only hope that Alfresco would pay some more attention to the web user interface.  There is always lots that can be improved upon, and the GUI is never an exception.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8577867822575605000-4159697626887632496?l=michielverkaik.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://michielverkaik.blogspot.com/feeds/4159697626887632496/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8577867822575605000&amp;postID=4159697626887632496' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/4159697626887632496'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/4159697626887632496'/><link rel='alternate' type='text/html' href='http://michielverkaik.blogspot.com/2010/02/alfresco-33-and-further.html' title='Alfresco 3.3 and further...'/><author><name>michiel verkaik</name><uri>http://www.blogger.com/profile/07977714296269801643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_sPQCPmuPeLI/S0X_DUhDvHI/AAAAAAAAAY0/JTJwj-P7XSg/S220/mv.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8577867822575605000.post-8082209169798597703</id><published>2010-02-19T11:38:00.000-08:00</published><updated>2010-02-22T11:26:49.333-08:00</updated><title type='text'>A first look at Grails</title><content type='html'>Since a week or two I've been playing around with &lt;a href="http://grails.org/"&gt;Grails&lt;/a&gt;, which really is a nice web framework.  It's the java equivalent of &lt;a href="http://rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt;, with Groovy as its language.  The Groovy syntax is more streamlined than java, and in a lot of ways more powerful and compact.&lt;br /&gt;&lt;br /&gt;Grails, as of version 1.2, also comes with &lt;a href="http://www.ilyasterin.com/blog/2009/09/grails-12-dependency-management.html"&gt;dependency management&lt;/a&gt;, similar to Maven, but so far I've found it to be a bit buggy.  The Grails class loader has some issues with multiple copies and/or versions of the same libraries, or so it seems.&lt;br /&gt;&lt;br /&gt;When you run an application in Grails, it uses a build in &lt;a href="http://grails.org/plugin/tomcat"&gt;Tomcat plugin&lt;/a&gt;, which is nice.  You can create a war from your project, but while developing the embedded Tomcat works just fine.  It speeds up development.&lt;br /&gt;&lt;br /&gt;Grails also comes with its own testing framework, for both unit and integration tests.  Test skeleton classes are automatically created when you define a new domain, controller or service.&lt;br /&gt;&lt;br /&gt;The test classes are written in &lt;a href="http://groovy.codehaus.org/"&gt;Groovy language&lt;/a&gt;, as is any other class in a Grails project.  You may actually mix plain old Java and Groovy, as long as the file extension is '.groovy'.&lt;br /&gt;&lt;br /&gt;These are just a few first observations on Grails, but there is much more.  The framework is all about &lt;a href="http://en.wikipedia.org/wiki/Convention_over_configuration"&gt;convention over configuration&lt;/a&gt;, and spots many best practices featured in other web frameworks.  It also does dependency injection, as we now from &lt;a href="http://seamframework.org/"&gt;JBoss Seam&lt;/a&gt;, it has a templating &amp;amp; tagging system, an object-relational-mapper, and a validation mechanism among other things.&lt;br /&gt;&lt;br /&gt;More to follow...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8577867822575605000-8082209169798597703?l=michielverkaik.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://michielverkaik.blogspot.com/feeds/8082209169798597703/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8577867822575605000&amp;postID=8082209169798597703' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/8082209169798597703'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/8082209169798597703'/><link rel='alternate' type='text/html' href='http://michielverkaik.blogspot.com/2010/02/grails.html' title='A first look at Grails'/><author><name>michiel verkaik</name><uri>http://www.blogger.com/profile/07977714296269801643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_sPQCPmuPeLI/S0X_DUhDvHI/AAAAAAAAAY0/JTJwj-P7XSg/S220/mv.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8577867822575605000.post-6551679486066242323</id><published>2010-01-07T07:15:00.000-08:00</published><updated>2010-01-07T07:38:52.481-08:00</updated><title type='text'>Alfresco indexes out of date</title><content type='html'>I recently restored my Alfresco 3.1.1 Enterprise deployment entirely because of some configuration issue, and found out at startup that consequently the Lucene index had become out of date.  I saw messages in the catalina.out such as:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;WARN  [node.index.FullIndexRecoveryComponent] The indexes are not synchronized with the database.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;WARN  [node.index.AVMFullIndexRecoveryComponent]     Index for avm store xxx is out of date&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;ERROR: Indexes not found for X stores.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Turns out Alfresco won't start when it encounters this.  In order to resolve I had to change a setting in &lt;span style="font-family:courier new;"&gt;WEB-INF/classes/alfresco/repository.properties&lt;/span&gt;, located in the exploded WAR.  I set &lt;span style="font-family:courier new;"&gt;index.recovery.mode&lt;/span&gt; to &lt;span style="font-family:courier new;"&gt;AUTO&lt;/span&gt;.  I tried &lt;span style="font-family:courier new;"&gt;FULL&lt;/span&gt; first, but that did not seem to help.  Not sure as it was trying to recover in the background, but Alfresco did not start properly with &lt;span style="font-family:courier new;"&gt;FULL&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;By default this setting is set to &lt;span style="font-family:courier new;"&gt;VALIDATE&lt;/span&gt;.  I wonder why it would not be &lt;span style="font-family:courier new;"&gt;AUTO&lt;/span&gt;.  As a description in the properties file it says: Validates and auto-recovers if validation fails.  That seems to make a lot of sense for default behavior.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8577867822575605000-6551679486066242323?l=michielverkaik.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://michielverkaik.blogspot.com/feeds/6551679486066242323/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8577867822575605000&amp;postID=6551679486066242323' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/6551679486066242323'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8577867822575605000/posts/default/6551679486066242323'/><link rel='alternate' type='text/html' href='http://michielverkaik.blogspot.com/2010/01/alfresco-indexes-out-of-date.html' title='Alfresco indexes out of date'/><author><name>michiel verkaik</name><uri>http://www.blogger.com/profile/07977714296269801643</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_sPQCPmuPeLI/S0X_DUhDvHI/AAAAAAAAAY0/JTJwj-P7XSg/S220/mv.jpg'/></author><thr:total>0</thr:total></entry></feed>
