<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0">

<channel>
	<title>Handful of sand</title>
	
	<link>http://php.sabscape.com/blog</link>
	<description>What we know is but a handful of sand when compared to the world of unknown</description>
	<lastBuildDate>Mon, 20 Feb 2012 12:40:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/HandfulOfSand" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="handfulofsand" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>A Spring SessionScope that works without a HTTP Session</title>
		<link>http://php.sabscape.com/blog/?p=454&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=a-spring-sessionscope-that-works-without-a-http-session</link>
		<comments>http://php.sabscape.com/blog/?p=454#comments</comments>
		<pubDate>Mon, 20 Feb 2012 12:33:26 +0000</pubDate>
		<dc:creator>Sab</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[custom scope]]></category>
		<category><![CDATA[http session]]></category>
		<category><![CDATA[session scope]]></category>

		<guid isPermaLink="false">http://php.sabscape.com/blog/?p=454</guid>
		<description><![CDATA[Now that i got your attention, yes, contrary to what the title states it&#8217;s simply not possible for a session scope to work without a HttpSession. But that doesn&#8217;t mean nothing can be done about it. Allow me to explain what I am babbling about. What do we gain by using the session scope? So [...]]]></description>
			<content:encoded><![CDATA[<p>Now that i got your attention, yes, contrary to what the title states it&#8217;s simply not possible for a session scope to work without a <code>HttpSession</code>. But that doesn&#8217;t mean nothing can be done about it. Allow me to explain what I am babbling about.</p>
<h3>What do we gain by using the session scope?</h3>
<p>So you decided one of the instances of your bean has to live in the <code>HttpSession</code>. And it needs to be wired as a dependency to other services. One example is a simple cache that sits in the session and is injected into services.</p>
<pre>
&lt;bean id="cache" class="FooCache" scope="session"&gt;
    &lt;aop:scoped-proxy/&gt;
&lt;/bean&gt;

&lt;bean id="myService" class="FooService"&gt;
    &lt;property name="cache" ref="cache"/&gt;
&lt;/bean&gt;
</pre>
<p>So here we have a <code>FooCache </code>injected into the <code>FooService</code>. Note the <code>aop:scoped-proxy</code>. We gained a lot by that. Spring takes care of storing the <code>FooCache</code> instance as an attribute in the <code>HttpSession</code> without me having to write a single line of code. And everything works fine across sessions even if the <code>FooService</code> is a singleton.</p>
<h3>Now what did we lose?</h3>
<p>We lost the flexibility to use the <code>FooCache</code> in non-web environments. So your unit tests and your batch environment cannot use the <code>FooCache</code> the way your services use them. Now you can very well say that we should go for a FooCacheNonWeb implementation for these cases. But having one such extension for each session-enabled class can become laborious and doesn&#8217;t sound &#8216;easy&#8217; enough for a lazy developer.</p>
<h3>Now, what can we do about it?</h3>
<p>That&#8217;s exactly the point of this post. Why not have a session scope that would fallback to a singleton-like scope if it is not running in a web environment? Folks, welcome the star of the show, the <code>NeverFailWebScope</code>. The <code>NeverFailWebScope</code> will act as a proxy to the actual scope you want to use in production web environment. But it will fallback to it&#8217;s own map store if the environment is alien to the wrapped/proxied scope. Here&#8217;s a simple implementation</p>
<pre>public class NeverFailWebScope implements Scope, ApplicationContextAware {

	private AbstractRequestAttributesScope proxiedScope;
	private ConcurrentHashMap objectMap = new ConcurrentHashMap();
	private boolean fallbackDisabled = false;
	private boolean executingInWebContext = false;
	private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory
			.getLogger(NeverFailWebScope.class);

	public NeverFailWebScope(AbstractRequestAttributesScope proxied) {
		this.proxiedScope = proxied;
	}

	public Object get(String name, ObjectFactory factory) {
		if (fallbackDisabled || executingInWebContext) {
			logger.debug("Via proxied scope");
			return proxiedScope.get(name, factory);
		}
		else {
			logger.debug("Via fallback");
			return objectMap.putIfAbsent(name, factory.getObject());
		}
	}

	public String getConversationId() {
		if (fallbackDisabled || executingInWebContext) {
			return proxiedScope.getConversationId();
		}
		else {
			return null;
		}
	}

	public void registerDestructionCallback(String name, Runnable callback) {
		if (fallbackDisabled || executingInWebContext) {
			proxiedScope.registerDestructionCallback(name, callback);
		}
	}

	public Object remove(String name) {
		if (fallbackDisabled || executingInWebContext) {
			return proxiedScope.remove(name);
		}
		else {
			return objectMap.remove(name);
		}
	}

	public boolean isFallbackDisabled() {
		return fallbackDisabled;
	}

	public void setFallbackDisabled(boolean fallbackEnabled) {
		this.fallbackDisabled = fallbackEnabled;
	}

	public void setApplicationContext(ApplicationContext context)
			throws BeansException {
		executingInWebContext = context instanceof WebApplicationContext;
	}
}</pre>
<p>A couple things to note</p>
<ul>
<li>NeverFailWebScope favors composition over inheritance. Any scope (session/request) can be wrapped. The inheritance approach would have been to extend Spring&#8217;s SessionScope.</li>
<li>It also allows the <code>NeverFailWebScope</code> to &#8220;not fallback&#8221; by setting <code>fallbackDisabled</code> to true. You might want to set that to false in the production/web environment using a <code>PropertyPlaceHolderConfigurer</code>.</li>
<li>It detects a web environment by checking if the context is a <code>WebApplicationContext</code>. This is not totally fail-proof. And there are other ways to do the same check.</li>
<li>Note that this was built for the Spring 2.0 API. You would have to implement an additional method if you want to use a later version of Spring.</li>
</ul>
<p>It ain&#8217;t curtains time yet. The scope has to be registered with Spring before it can be used. And that can be done as shown below (again in XML configuration)</p>
<pre>&lt;bean class="org.springframework.beans.factory.config.CustomScopeConfigurer"&gt;
	&lt;property name="scopes"&gt;
		&lt;map&gt;
		&lt;entry key="neverFailSession"&gt;
			&lt;bean class="com.sabscape.NeverFailWebScope"&gt;
				&lt;constructor-arg&gt;
					&lt;bean class="org.springframework.web.context.request.SessionScope"/&gt;
				&lt;/constructor-arg&gt;
				&lt;property name="fallbackDisabled" value="false"/&gt;
			&lt;/bean&gt;
		&lt;/entry&gt;
		&lt;/map&gt;
	&lt;/property&gt;
&lt;/bean&gt;</pre>
<p>And the FooCache configuration can now use the <code>neverFailSession</code> scope.</p>
<pre>&lt;bean id="cache" class="FooCache" scope="neverFailSession"&gt;
    &lt;aop:scoped-proxy/&gt;
&lt;/bean&gt;</pre>
]]></content:encoded>
			<wfw:commentRss>http://php.sabscape.com/blog/?feed=rss2&amp;p=454</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Evaluating mathematical expressions in Java</title>
		<link>http://php.sabscape.com/blog/?p=440&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=evaluating-mathematical-expressions-in-java</link>
		<comments>http://php.sabscape.com/blog/?p=440#comments</comments>
		<pubDate>Sat, 18 Feb 2012 03:40:56 +0000</pubDate>
		<dc:creator>Sab</dc:creator>
				<category><![CDATA[Expr]]></category>
		<category><![CDATA[Expression evaluation]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[expression]]></category>
		<category><![CDATA[expression evaluation]]></category>
		<category><![CDATA[formula evaluation]]></category>
		<category><![CDATA[JEval]]></category>
		<category><![CDATA[mathematical expression]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://php.sabscape.com/blog/?p=440</guid>
		<description><![CDATA[We were quite happily using JEval for evaluating mathematical expressions. that is until our requirements changed (as is typically the case). Wherein we were executing formulas around 500 times in the use-case execution, we now needed to execute formulas around 5000 times. On analyzing the performance, it became apparent that in-memory formula processing was consuming [...]]]></description>
			<content:encoded><![CDATA[<p>We were quite happily using <a href="http://jeval.sourceforge.net/">JEval</a> for evaluating mathematical expressions. that is until our requirements changed (as is typically the case). Wherein we were executing formulas around 500 times in the use-case execution, we now needed to execute formulas around 5000 times.</p>
<p>On analyzing the performance, it became apparent that in-memory formula processing was consuming a lot of time, around 3 seconds approximately per request. I confirmed that this was the bottleneck by replacing some heavily used formulas with hard-coded java code.</p>
<p>With the cause identified, I tried looking into JEval source to see if something obvious can be done towards improving performance. I couldn&#8217;t find much. The one option was to pre-parse the expression so that parsing is avoided at run-time. The other option was to disable nested functions, but then my formulas wouldn&#8217;t work.</p>
<p>That set the tone for the subsequent hunt for a better expression evaluator. Ended up at <a href="http://stackoverflow.com/questions/2226863/whats-a-good-library-for-parsing-mathematical-expressions-in-java">stackoverflow.com</a>, as is typically the case these days, and evaluated <a href="https://github.com/darius/expr/tree/master/expr">Expr</a>. </p>
<p>Unbelievably good performance. The source code is much simpler. And just like JEval, it doesn&#8217;t have additional dependencies. It might need some extra tweaks to support variables the way I want, but overall, the experience was much better.</p>
<p>Here&#8217;s some numbers that compares Jeval with Expr for some hypothetical but close to real-world expressions</p>
<table>
<tr>
<th>Sample expression</th>
<th>#times executed</th>
<th>JEval (ms)</th>
<th>Expr (ms)</th>
<th>JEval Average (ms)</th>
<th>Expr Average (ms)</th>
<th>Gain (%)</th>
</tr>
<tr>
<td>(a*b)^(c*d)</td>
<td>1474</td>
<td>498</td>
<td>160</td>
<td>0.338</td>
<td>0.109</td>
<td>67</td>
</tr>
<tr>
<td>((a*((b*c)^(d*e)))^(f*g))</td>
<td>2880</td>
<td>2045</td>
<td>451</td>
<td>0.710</td>
<td>0.157</td>
<td>78</td>
</tr>
</table>
<p>Please note that these timings include the overhead of an AOP layer (that weaves only application classes).</p>
<p>Of course, Expr doesn&#8217;t boast of all the features like JEval, string &#038; custom functions for example, but performance-wise it beats JEval for simple to moderately complex mathematical expressions. It makes us think again if doing things the most right way often leads to solutions that are both telling in complexity and performance. May be JEval could have had a simpler engine for parsing simpler expressions and a costlier engine for parsing full blown formulas with the user given the option of executing either of the two depending on his requirements.</p>
<p>The best solution IMO would be to use both JEval and Expr and let configuration decide which evaluator to use for each expression. This is what I did. I added a layer that abstracts out the differences in how we use these two frameworks. That way we get the best of both the worlds. Their expression languages are easy to learn and there is no burden in managing both at the same time.</p>
]]></content:encoded>
			<wfw:commentRss>http://php.sabscape.com/blog/?feed=rss2&amp;p=440</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A quick fix for the “java.lang.VerifyError/Stack shape inconsistent error/Register 2/3 blah blah” seen with Spring and AspectJ LTW</title>
		<link>http://php.sabscape.com/blog/?p=424&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=a-quick-fix-for-the-java-lang-verifyerrorstack-shape-inconsistent-errorregister-23-blah-blah-seen-with-spring-and-aspectj-ltw</link>
		<comments>http://php.sabscape.com/blog/?p=424#comments</comments>
		<pubDate>Tue, 14 Feb 2012 17:20:01 +0000</pubDate>
		<dc:creator>Sab</dc:creator>
				<category><![CDATA[AspectJ]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[Load time weaving]]></category>
		<category><![CDATA[LTW]]></category>
		<category><![CDATA[Stack shape inconsistent]]></category>
		<category><![CDATA[VerifyError]]></category>

		<guid isPermaLink="false">http://php.sabscape.com/blog/?p=424</guid>
		<description><![CDATA[So here i was in bad need of some help from my custom JaMon + Spring based performance monitoring &#8216;stuff&#8217;. But this time around, I was asking more of it, I wanted to monitor classes that the Spring factory wasn&#8217;t aware of. So had to resort to full blown AspectJ and decided to go with [...]]]></description>
			<content:encoded><![CDATA[<p>So here i was in bad need of some help from my custom JaMon + Spring based performance monitoring &#8216;stuff&#8217;. But this time around, I was asking more of it, I wanted to monitor classes that the Spring factory wasn&#8217;t aware of. So had to resort to full blown AspectJ and decided to go with LTW-Load Time Weaving. The app is still stuck at Spring 2.0. Went by the book to configure the aspect and then launched the application with the javaagent. And what did i get?</p>
<pre>Exception in thread "main" org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'XXXXXX' defined in class path resource [hibernate-dao-config.xml]:
Instantiation of bean failed; nested exception is java.lang.VerifyError:
(class: XXXXXXDAO,method: findBy_aroundBody9$advice signature: (LXXXXX;JJJLjava/lang/Boolean;
Lorg/aspectj/lang/JoinPoint; Lprofiling/JamonPerformanceInt`i7#-(

Caused by: java.lang.VerifyError: (class: XXXXDAO, method: findBy_aroundBody9$advice
signature: (LcomXXXXXXDAO;JJJLjava/lang/Boolean;Lorg/aspectj/lang/JoinPoint;
Lprofiling/JamonPerformanceInt`i7#-(</pre>
<p>The problem would only occur in certain scenarios (methods with 2 primitive arguments, methods that accepted other objects whose methods were advised).</p>
<p>Without further ado let me say what fixed it for me. <strong>-Xnoinline</strong>. It&#8217;s one of the options exposed by the aspectj weaver. -Xnoinline appeared promising because i was using &#8216;Around&#8217; advice and the error messages showed a weird signature for my advised methods. Tried with that and voila, the rough weather was all gone. Here&#8217;s the aop.xml where the -Xnoinline is passed to the LTW mechanism.</p>
<pre>&lt;aspectj&gt;
    &lt;weaver
        options="-showWeaveInfo
        -XmessageHandlerClass:org.springframework.aop.aspectj.AspectJWeaverMessageHandler -Xnoinline"&gt;
        &lt;!-- only weave classes in our application-specific packages --&gt;
        &lt;include within="my.package..*"/&gt;
    &lt;/weaver&gt;
    &lt;aspects&gt;
        &lt;aspect name="profiling.JamonPerformanceInterceptor"/&gt;
    &lt;/aspects&gt;
&lt;/aspectj&gt;</pre>
<p>There is not much literature around this on the net. I tried the following, but to no avail.</p>
<ol>
<li>Ensure the aspectjrt.jar and aspectjweaver.jar are of the same version. In my case, they already were.</li>
<li>Ensure that the VM is the latest for that release. In my case, it already was</li>
<li>Ensure that the jars are not duplicated on the classpath with conflicting versions</li>
</ol>
<p>The result was the same when i tried with the IBM JVM as well, though it was sugarcoated differently (stack shape inconsistent blah blah).</p>
<p>I am thinking the -Xnoinline will affect performance. But I wouldn&#8217;t mind that for the job at hand.</p>
]]></content:encoded>
			<wfw:commentRss>http://php.sabscape.com/blog/?feed=rss2&amp;p=424</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Merging unrelated Subversion branches using Subclipse</title>
		<link>http://php.sabscape.com/blog/?p=413&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=merging-unrelated-subversion-versions-using-subclipse</link>
		<comments>http://php.sabscape.com/blog/?p=413#comments</comments>
		<pubDate>Thu, 12 Jan 2012 07:14:09 +0000</pubDate>
		<dc:creator>Sab</dc:creator>
				<category><![CDATA[Subversion]]></category>
		<category><![CDATA[branch]]></category>
		<category><![CDATA[merge]]></category>
		<category><![CDATA[merge revisions]]></category>
		<category><![CDATA[merging]]></category>
		<category><![CDATA[subversion]]></category>
		<category><![CDATA[svn]]></category>

		<guid isPermaLink="false">http://php.sabscape.com/blog/?p=413</guid>
		<description><![CDATA[So you ended up with 2 feature branches that were forked off from the trunk at different points in time. And you want to merge some changes from one branch to the other. No problemo. Subclipse supports selective merging of revisions. Let&#8217;s say you want to merge some changes from feature_branch101 into feature_branch100. Here&#8217;s how [...]]]></description>
			<content:encoded><![CDATA[<p>So you ended up with 2 feature branches that were forked off from the trunk at different points in time. And you want to merge some changes from one branch to the other. No problemo. Subclipse supports selective merging of revisions. Let&#8217;s say you want to merge some changes from feature_branch101 into feature_branch100. Here&#8217;s how you should go about it</p>
<ol>
<li>Just as with any merge, make sure your working copy has been switched to the branch you want to update. So in our case, the local working copy should be feature_branch101. You can read more on this in my <a href="http://php.sabscape.com/blog/?p=380">previous Subversion merge post</a>.</li>
<li>Make sure there are no outgoing (i.e., not checked in) changes in your local working copy.</li>
<li>Right-click your project in eclipse and choose Team -&gt; Merge&#8230;</li>
<li>In the wonderfully misnamed &#8216;Merge input&#8217; section choose &#8216;Merge a range of revisions&#8217;. Uncheck &#8216;Perform pre-merge best practices checks&#8217;. Here&#8217;s a capture to illustrate better<br />
<a href="http://php.sabscape.com/blog/wp-content/uploads/2012/01/merge011.png"><img class="aligncenter size-full wp-image-414" title="merge01" src="http://php.sabscape.com/blog/wp-content/uploads/2012/01/merge011.png" alt="" width="559" height="658" /></a></li>
<li>Click Next. In this screen we have to choose the merge source &#8216;from&#8217; which we want to grab the changes to merge into our local working copy. This is feature_branch101 in our case. Here&#8217;s another capture<br />
<a href="http://php.sabscape.com/blog/wp-content/uploads/2012/01/merge023.png"><img class="aligncenter size-full wp-image-415" title="merge02" src="http://php.sabscape.com/blog/wp-content/uploads/2012/01/merge023.png" alt="" width="702" height="693" /></a></li>
<li>Make sure &#8216;Select revisions on next page&#8217; is selected to allow hand-picking of the revisions we want</li>
<li>Click Next. In the &#8216;Select the revisions&#8217; dialog, you can select the revisions you want.<br />
<a href="http://php.sabscape.com/blog/wp-content/uploads/2012/01/merge03.png"><img class="aligncenter size-full wp-image-416" title="merge03" src="http://php.sabscape.com/blog/wp-content/uploads/2012/01/merge03.png" alt="" width="702" height="693" /></a></li>
<li>Click Next. This takes you to the merge options. Just leave things the way they are. Click &#8216;Finish&#8217;.</li>
<li>You can check the SVN console for the progress of the merge. Here you should find the merge command and the list of changes happening. Something like below</li>
<pre>
merge -c 5064 -c 5073 -r 5086:5088 <url_of_feature_branch_101> W:/<LOCAL_PROJECT>
    --- Merging r5063 through r5064 into W:/<LOCAL_PROJECT>
	...
	...
	Merge complete.
    ===== File Statistics: =====
    Merged: 1
    Added: 6
    Updated: 17
</pre>
<li>Subclipse will popup the merge statistics once the merge is complete. You can now synchronize your changes with the feature_branch100 in the svn repository. Right click your project, Team -&gt; Synchronize</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://php.sabscape.com/blog/?feed=rss2&amp;p=413</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Post it – Combining property placeholder replacement and SpEL</title>
		<link>http://php.sabscape.com/blog/?p=402&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=post-it-combining-property-placeholder-replacement-and-spel</link>
		<comments>http://php.sabscape.com/blog/?p=402#comments</comments>
		<pubDate>Sat, 07 Jan 2012 12:33:33 +0000</pubDate>
		<dc:creator>Sab</dc:creator>
				<category><![CDATA[Post it]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[property placeholder]]></category>
		<category><![CDATA[spel]]></category>
		<category><![CDATA[Spring Expression Language]]></category>

		<guid isPermaLink="false">http://php.sabscape.com/blog/?p=402</guid>
		<description><![CDATA[Ever wanted to negate a boolean placeholder property value before its set for one of your bean&#8217;s properties? We can do this with SpEL support &#60;bean class="com.oh.my.DingDongRepeater"&#62; &#60;property name="enabled" value="#{!${dingDongDisabled}}"/&#62; &#60;/bean&#62; The #{!} negates the ${dingDongDisabled}. You might be curious why one needs to do this rather than renaming the property the other way around. [...]]]></description>
			<content:encoded><![CDATA[<p>Ever wanted to negate a boolean placeholder property value before its set for one of your bean&#8217;s properties? We can do this with SpEL support</p>
<pre>
&lt;bean class="com.oh.my.DingDongRepeater"&gt;
	&lt;property name="enabled" value="#{!${dingDongDisabled}}"/&gt;
&lt;/bean&gt;
</pre>
<p>The #{!} negates the ${dingDongDisabled}. You might be curious why one needs to do this rather than renaming the property the other way around. Well, let&#8217;s just say that i get stubborn/adamant/picky every once in a while.</p>
]]></content:encoded>
			<wfw:commentRss>http://php.sabscape.com/blog/?feed=rss2&amp;p=402</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Merging with Subclipse (and Subversion)</title>
		<link>http://php.sabscape.com/blog/?p=380&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=merging-with-subclipse-and-subversion</link>
		<comments>http://php.sabscape.com/blog/?p=380#comments</comments>
		<pubDate>Sat, 07 Jan 2012 12:15:20 +0000</pubDate>
		<dc:creator>Sab</dc:creator>
				<category><![CDATA[Subversion]]></category>
		<category><![CDATA[error]]></category>
		<category><![CDATA[merge]]></category>
		<category><![CDATA[mergeinfo unsupported]]></category>
		<category><![CDATA[merging]]></category>
		<category><![CDATA[subclipse]]></category>
		<category><![CDATA[svn]]></category>

		<guid isPermaLink="false">http://php.sabscape.com/blog/?p=380</guid>
		<description><![CDATA[If you have been stumped by the &#8220;Trying to use an unsupported feature svn: Retrieval of mergeinfo unsupported by&#8221; error messages, you are not alone. I think this happens when the subclipse version (and features) is different from the server repository version (and capabilities). But i am just not sure. [Edit: Mark's comment below explains [...]]]></description>
			<content:encoded><![CDATA[<p>If you have been stumped by the &#8220;<strong><em>Trying to use an unsupported feature svn: Retrieval of mergeinfo unsupported by</em></strong>&#8221; error messages, you are not alone. I think this happens when the subclipse version (and features) is different from the server repository version (and capabilities). But i am just not sure. <strong>[Edit: Mark's comment below explains why. Thanks Mark!]</strong> So here&#8217;s how to do a merge in this case.</p>
<ol>
<li>Make sure the working copy reflects the target of the merge. If you want to merge your feature branch to trunk (so that the trunk gets up-to-date with the feature), then the working copy (the current project in eclipse) should be trunk. If you are not in trunk, then switch your project&#8217;s working copy using context menu Team -&gt; Switch&#8230; Ideally changes should be checked in before switching.</li>
<li>Wait for switch to complete. The SVN console will display the list of files that get added, deleted or updated by subversion client to make the working copy reflect the new version it is switching to.</li>
<li>Now do Team -&gt; Merge</li>
<li>In there choose &#8216;Merge two different trees&#8217; as the merge input (what&#8217;s with these cryptic names). This allows a fully configurable merge.</li>
<li>Uncheck &#8216;Perform pre-merge best practice checks&#8217;. But make sure there are no unchecked changes in the working copy.<br />
<a href="http://php.sabscape.com/blog/wp-content/uploads/2012/01/merge01.png"><img class="aligncenter size-full wp-image-397" title="merge01" src="http://php.sabscape.com/blog/wp-content/uploads/2012/01/merge01.png" alt="" width="559" height="658" /></a></li>
<li>In the next window specify the &#8216;from&#8217; and &#8216;to&#8217; urls for the merge. This I have found to be quite confusing the first time. It helps to take an analogy. If one wants to go from Bangalore to Chicago then the  &#8216;from&#8217; location is Bangalore and the &#8216;to&#8217; location is Chicago. Now let&#8217;s translate that to repository versions. If we want the working copy to go &#8216;from&#8217; trunk &#8216;to&#8217; the feature branch state, then the &#8216;from&#8217; has to be the trunk and the  &#8216;to&#8217; has to be the feature branch URL. If instead we are merging a branch101 back to branch100, then the working copy should be branch100,  the  &#8216;from&#8217; should be branch100 and the &#8216;to&#8217; should be branch101. <del>Phew! That&#8217;s a lot of words.</del></li>
<li>In the same window, specify the revisions. Typically one would choose HEAD revision for both the &#8216;from&#8217; and the &#8216;to&#8217;.<a href="http://php.sabscape.com/blog/wp-content/uploads/2012/01/merge02.png"><br />
</a><a href="http://php.sabscape.com/blog/wp-content/uploads/2012/01/merge021.png"></a><a href="http://php.sabscape.com/blog/wp-content/uploads/2012/01/merge022.png"><img class="aligncenter size-full wp-image-396" title="merge02" src="http://php.sabscape.com/blog/wp-content/uploads/2012/01/merge022.png" alt="" width="559" height="658" /></a></li>
<li>Click Next. In the conflict handling options window, just leave it to the defaults. If it doesn&#8217;t work with defaults, then enable &#8216;Ignore ancestry&#8217; and &#8216;Allow unversioned obstructions&#8217;.</li>
<li>Click Finish. That&#8217;s it. Easy peasy lemon squeezy. SVN console will log all that the SVN client does to update the working copy to the &#8216;to&#8217; location and revision.</li>
<li>Once its all done, the working copy can now be synchronized with the repository to merge/check-in the changes to the trunk. Trunk of course, stays safe, till you do this.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://php.sabscape.com/blog/?feed=rss2&amp;p=380</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Displaying custom labels in Spark DataGrid when using ComboBoxGridItemEditor</title>
		<link>http://php.sabscape.com/blog/?p=353&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=displaying-custom-labels-in-spark-datagrid-when-using-comboboxgriditemeditor</link>
		<comments>http://php.sabscape.com/blog/?p=353#comments</comments>
		<pubDate>Sun, 18 Dec 2011 11:04:54 +0000</pubDate>
		<dc:creator>Sab</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[ComboBox]]></category>
		<category><![CDATA[Item Renderer]]></category>
		<category><![CDATA[Spark DataGrid]]></category>

		<guid isPermaLink="false">http://php.sabscape.com/blog/?p=353</guid>
		<description><![CDATA[The spark DataGrid component ships with a handy ComboBoxGridItemEditor. But all&#8217;s not well if you want to display data from something more serious than a string. For ex, you might have a list of PropertyStatus instances that you want to display in the grid&#8217;s cell public var statuses:ArrayList = new ArrayList([ {name: "sold", desc: "Sold [...]]]></description>
			<content:encoded><![CDATA[<p>The spark DataGrid component ships with a handy ComboBoxGridItemEditor. But all&#8217;s not well if you want to display data from something more serious than a string.</p>
<p>For ex, you might have a list of PropertyStatus instances that you want to display in the grid&#8217;s cell</p>
<pre>
public var statuses:ArrayList =
	new ArrayList([
	{name: "sold", desc: "Sold out"},
	{name: "avail", desc: "Still available"}
]);
</pre>
<p>Though the ComboBox supports this case, the ComboBoxGridItemEditor does not. So the following wouldn&#8217;t work.</p>
<pre>
&lt;s:DataGrid dataProvider="{props}" width="400" editable="true">
	&lt;s:columns&gt;
		&lt;s:ArrayList&gt;
			&lt;s:GridColumn dataField="name" editable="false"/&gt;
			&lt;s:GridColumn dataField="status"&gt;
				&lt;s:itemEditor&gt;
					&lt;fx:Component&gt;
						&lt;s:ComboBoxGridItemEditor dataProvider="{outerDocument.statuses}"/&gt;
					&lt;/fx:Component&gt;
				&lt;/s:itemEditor&gt;
			&lt;/s:GridColumn&gt;
		&lt;/s:ArrayList&gt;
	&lt;/s:columns&gt;
&lt;/s:DataGrid&gt;
</pre>
<p>So we would see something like below<br />
<a href="http://php.sabscape.com/blog/wp-content/uploads/2011/12/objectobject.jpg"><img src="http://php.sabscape.com/blog/wp-content/uploads/2011/12/objectobject-300x87.jpg" alt="" title="objectobject" width="300" height="87" class="aligncenter size-medium wp-image-375" /></a></p>
<p>But it&#8217;s pretty easy to enable this by extending the ComboBoxGridItemEditor as shown below. All we need to do is add a labelFunction attribute and pass it onto the ComboBox.</p>
<pre>
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;s:ComboBoxGridItemEditor xmlns:fx="http://ns.adobe.com/mxml/2009"
						  xmlns:s="library://ns.adobe.com/flex/spark"
						  xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300"&gt;
	&lt;fx:Declarations&gt;
		&lt;!-- Place non-visual elements (e.g., services, value objects) here --&gt;
	&lt;/fx:Declarations&gt;
	&lt;fx:Script&gt;
		&lt;![CDATA[
			import spark.components.gridClasses.GridItemRenderer;
			private var _labelFunction:Function;

			public function get labelFunction():Function {
				return _labelFunction;
			}

			public function set labelFunction(func:Function):void {
				_labelFunction = func;
				comboBox.labelFunction = _labelFunction;
			}
		]]&gt;
	&lt;/fx:Script&gt;
&lt;/s:ComboBoxGridItemEditor&gt;
</pre>
<p>So now the following would work</p>
<pre>
&lt;local:CustomizableComboBoxGridItemEditor
        dataProvider="{outerDocument.statuses}" labelFunction="{outerDocument.statusLabel}"/&gt;
</pre>
<p>So we would see something like<br />
<a href="http://php.sabscape.com/blog/wp-content/uploads/2011/12/combolabel.jpg"><img src="http://php.sabscape.com/blog/wp-content/uploads/2011/12/combolabel-300x89.jpg" alt="" title="combolabel" width="300" height="89" class="aligncenter size-medium wp-image-376" /></a><br />
But wait, is that enough? Good catch. Note that the DataGrid uses two UI component instances for each cell. One for the display mode and one for the edit mode. We fixed the edit mode. But the display mode would still display gibberish. </p>
<p>The simplest way to fix this is to use GridColumn.labelFunction.</p>
<pre>
	public function columnStatusLabel(data:Object, col:GridColumn):String {
				return data[col.dataField].desc;
			}
		]]&gt;
	&lt;/fx:Script&gt;
	&lt;s:DataGrid dataProvider="{props}" width="400" editable="true"&gt;
		....
			&lt;s:GridColumn dataField="status" labelFunction="{columnStatusLabel}"&gt;
</pre>
<p>So the grid would now look like<br />
<a href="http://php.sabscape.com/blog/wp-content/uploads/2011/12/proplabels.jpg"><img src="http://php.sabscape.com/blog/wp-content/uploads/2011/12/proplabels-300x75.jpg" alt="" title="proplabels" width="300" height="75" class="aligncenter size-medium wp-image-377" /></a></p>
<p>All these labelFunctions floating around would do us no good when we want to reuse them across dialogs. The best way in this case would be to have a PropertyStatus class and define the label functions there. This makes the functions available wherever we want them and leaves them in a place logical enough to find. Something like </p>
<pre>
public class PropertyStatus {
	public var name:String;
	public var desc: String;

        public static function statusLabel(status:Object):String {
		return status.desc;
	}
	public static function columnStatusLabel(data:Object, col:GridColumn):String {
		return data[col.dataField].desc;
	}
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://php.sabscape.com/blog/?feed=rss2&amp;p=353</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Throttling message processing with the Spring JMS MessageListenerContainer</title>
		<link>http://php.sabscape.com/blog/?p=339&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=throttling-message-processing-with-the-spring-jms-messagelistenercontainer</link>
		<comments>http://php.sabscape.com/blog/?p=339#comments</comments>
		<pubDate>Wed, 15 Jun 2011 16:35:03 +0000</pubDate>
		<dc:creator>Sab</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[Spring JMS]]></category>
		<category><![CDATA[jms]]></category>
		<category><![CDATA[message listener container]]></category>
		<category><![CDATA[spring jms]]></category>

		<guid isPermaLink="false">http://php.sabscape.com/blog/?p=339</guid>
		<description><![CDATA[In the previous post we saw how we could easily scale the parallel processing of messages by tweaking the concurrency attribute of the MessageListenerContainer abstraction. In this post, we will see how we can do the reverse, ie, throttle message processing. What do we want? Lets assume a requirement which dictates that we shouldn&#8217;t be [...]]]></description>
			<content:encoded><![CDATA[<p>In the <a href="http://php.sabscape.com/blog/?p=315">previous post</a> we saw how we could easily scale the parallel processing of messages by tweaking the concurrency attribute of the MessageListenerContainer abstraction. In this post, we will see how we can do the reverse, ie, throttle message processing.</p>
<h3>What do we want?</h3>
<p>Lets assume a requirement which dictates that we shouldn&#8217;t be processing more than 2 messages simultaneously on the server. That&#8217;s easy, we just need to set the concurrency attribute to 2. But to complicate things, lets assume we have another message listener container defined in the same context, wired to listen on a different queue. And we want to process a maximum of 2 messages simultaneously, across these 2 queues. </p>
<p>Also, if one of the queues is empty, we would naturally want 2 messages of the other queue be processed simultaneously so that the app doesn&#8217;t just sit twiddling its thumb.</p>
<h3>How do we do it</h3>
<p>The solution is quite simple. The MessageListenerContainer abstraction supports injection of a custom task executor. And if we inject the same task executor instance to the 2 MLC instances, we end up controlling both the MLCs from one  common threadpool. Now whatever throttling we apply on the task executor will in turn dictate how the MLCs process messages.</p>
<p>So the configuration now looks like</p>
<pre>
&lt;jms:listener-container connection-factory=&quot;connectionFactory&quot;
	destination-resolver=&quot;serverDestinationResolver&quot; message-converter=&quot;messageConverter&quot;
	concurrency=&quot;3-3&quot; task-executor=&quot;executor&quot;&gt;
	&lt;jms:listener id=&quot;someName&quot; destination=&quot;trRequestQueue&quot;
		ref=&quot;remoteExecutionEndPoint&quot; method=&quot;receive&quot; response-destination=&quot;trStatusQueue&quot;/&gt;
&lt;/jms:listener-container&gt;

&lt;task:executor id=&quot;executor&quot; pool-size=&quot;2&quot; queue-capacity=&quot;2&quot;
	rejection-policy=&quot;ABORT&quot;/&gt;
</pre>
<p>All we did was define a task executor and inject it to the MLC(s). And voila, only 2 messages will be processed simultaneously from now. This works with the concurrency attribute, for ex, if the pool size is increased to 6, then both MLCs will start processing 3 messages a a time, because their concurrency attribute limits each of them to 3. And all we did was type one extra line of configuration XML !</p>
]]></content:encoded>
			<wfw:commentRss>http://php.sabscape.com/blog/?feed=rss2&amp;p=339</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scaling with the Spring JMS MessageListenerContainer</title>
		<link>http://php.sabscape.com/blog/?p=315&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=scaling-with-the-spring-jms-messagelistenercontainer</link>
		<comments>http://php.sabscape.com/blog/?p=315#comments</comments>
		<pubDate>Tue, 24 May 2011 13:54:20 +0000</pubDate>
		<dc:creator>Sab</dc:creator>
				<category><![CDATA[Spring]]></category>
		<category><![CDATA[Spring JMS]]></category>
		<category><![CDATA[concurrency]]></category>
		<category><![CDATA[messagelistenercontainer]]></category>
		<category><![CDATA[scale]]></category>
		<category><![CDATA[spring jms]]></category>

		<guid isPermaLink="false">http://php.sabscape.com/blog/?p=315</guid>
		<description><![CDATA[This is in continuation to the previous post on Spring JMS MessageListenerContainer. Lets see how we can use the MessageListenerContainer to scale message consumption. Here&#8217;s the basic message listener container configuration to start with. &#60;jms:listener-container connection-factory="connectionFactory" destination-resolver="serverDestinationResolver" message-converter="messageConverter"&#62; &#60;jms:listener id="someName" destination="trRequestQueue" ref="remoteExecutionEndPoint" method="runAround" response-destination="trStatusQueue"/&#62; &#60;/jms:listener-container&#62; Check out the appendix at the end for the surrounding [...]]]></description>
			<content:encoded><![CDATA[<p>This is in continuation to the <a href="http://php.sabscape.com/blog/?p=293">previous post</a> on Spring JMS <code>MessageListenerContainer</code>. Lets see how we can use the <code>MessageListenerContainer</code> to scale message consumption.</p>
<p>Here&#8217;s the basic message listener container configuration to start with.</p>
<pre>        &lt;jms:listener-container connection-factory="connectionFactory"
		destination-resolver="serverDestinationResolver" message-converter="messageConverter"&gt;
		&lt;jms:listener id="someName" destination="trRequestQueue"
			ref="remoteExecutionEndPoint" method="runAround"
                        response-destination="trStatusQueue"/&gt;
	&lt;/jms:listener-container&gt;
</pre>
<p>Check out the appendix at the end for the surrounding configuration like <code>serverDestinationResolver, messageConverter</code> etc. I wouldn&#8217;t have needed the <code>messageConverter</code> if i had a symmetric interface that accepted a String and returned a String for ex.<br />
The server-side listener can be a simple POJO. The implementation sleeps for 3 seconds to simulate work being done.</p>
<pre>public interface Park {
	public String runAround(TextMessage message);
}
public class ParkImpl implements Park {
...
	public String runAround(TextMessage message) {
		try {
			logger.info("Received message: " + message.getText());
			Thread.sleep(3000);
			return "processed: " + message.getText();
		}
		catch (Exception e) {
			return "processed: junk";
		}
	}
}
</pre>
<p>Our client will use the Spring <code>JMSTemplate</code> to send 3 Hello messages as shown below</p>
<pre>public void interact() throws Exception {
		for (int i = 1; i &lt;= 3; i++) {
			final int iVal = i;
			clientTemplate.send(sendDestination,
				new MessageCreator() {
					public Message createMessage(
						Session session) throws JMSException {
					return session.
						createTextMessage("Hello " + iVal);
				}
			});
			logger.info("Sent");
		}
		for (int i = 1; i &lt;= 3; i++) {
			TextMessage message = (TextMessage)
				clientTemplate.receive(replyDestination);
		}
	}
</pre>
<p>In our simple application, we are embedding both the client and the server in the same vm.</p>
<p>Let&#8217;s see the default behavior in the console on running this</p>
<pre>23:07:10.062 [main] INFO  c.s.rexec.RemoteExecutionClient - Sent
23:07:10.093 [main] INFO  c.s.rexec.RemoteExecutionClient - Sent
23:07:10.171 [main] INFO  c.s.rexec.RemoteExecutionClient - Sent
23:07:10.031 [someName-1] INFO  c.s.r.RemoteExecutionEndPointImpl
	- Received message: Hello 1
23:07:13.078 [someName-1] INFO  c.s.r.RemoteExecutionEndPointImpl
	- Received message: Hello 2
23:07:16.109 [someName-1] INFO  c.s.r.RemoteExecutionEndPointImpl
	- Received message: Hello 3
</pre>
<p>We see that one message is processed every 3 seconds. This is the default settings at work. A JMS Session processes only one message a time so that the consumer need not be multi-threaded. </p>
<p>Now how do we scale? Simple. The message listener container has a concurrency attribute. Lets set it to 3 so that all 3 of our messages get processed simultaneously.</p>
<pre>        &lt;jms:listener-container connection-factory="connectionFactory"
		destination-resolver="serverDestinationResolver" message-converter="messageConverter"&gt;
		&lt;jms:listener id="someName" destination="trRequestQueue"
			ref="remoteExecutionEndPoint" method="runAround"
                        response-destination="trStatusQueue" concurrency="3"/&gt;
	&lt;/jms:listener-container&gt;
</pre>
<p>Now lets observe the behavior on running the program</p>
<pre>07:42:23.246 [main] INFO  c.n.rexec.RemoteExecutionClient - Sent
07:42:23.277 [main] INFO  c.n.rexec.RemoteExecutionClient - Sent
07:42:23.308 [main] INFO  c.n.rexec.RemoteExecutionClient - Sent
07:42:23.199 [someName-1] INFO  c.n.r.RemoteExecutionEndPointImpl
	- Received message: Hello 1
07:42:23.277 [someName-2] INFO  c.n.r.RemoteExecutionEndPointImpl
	- Received message: Hello 3
07:42:26.386 [someName-1] INFO  c.n.r.RemoteExecutionEndPointImpl
	- Received message: Hello 2
</pre>
<p>What we are seeing instead is that 2 messages are processed simultaneously, not 3 as we had configured. The third message is picked up at 07:42:26 while the first 2 at 07:42:23. So what&#8217;s going on?</p>
<p>The MessageListenerContainer documentation does not mention anything specially about the concurrency attribute. But the DefaultMessageListenerContainer API tells us that there are 2 attributes related to concurrency, concurrentConsumers and maxConcurrentConsumers. So it could be that the default max is 2. So lets try upping the max. Here&#8217;s our new configuration.</p>
<pre>        &lt;jms:listener-container connection-factory="connectionFactory"
		destination-resolver="serverDestinationResolver" message-converter="messageConverter"&gt;
		&lt;jms:listener id="someName" destination="trRequestQueue"
			ref="remoteExecutionEndPoint" method="runAround"
                        response-destination="trStatusQueue" concurrency="3-3"/&gt;
	&lt;/jms:listener-container&gt;
</pre>
<p>The only change (yet again) is the <code>concurrency</code> which is now set to 3-3. This is typically the way we set a range in Spring configuration. Lets observe the behavior again</p>
<pre>
07:51:19.933 [main] INFO  c.n.rexec.RemoteExecutionClient - Sent
07:51:19.980 [main] INFO  c.n.rexec.RemoteExecutionClient - Sent
07:51:19.996 [main] INFO  c.n.rexec.RemoteExecutionClient - Sent
07:51:19.886 [someName-1] INFO  c.n.r.RemoteExecutionEndPointImpl
	- Received message: Hello 1
07:51:19.949 [someName-3] INFO  c.n.r.RemoteExecutionEndPointImpl
	- Received message: Hello 2
07:51:19.980 [someName-2] INFO  c.n.r.RemoteExecutionEndPointImpl
	- Received message: Hello 3
</pre>
<p>Good, that works, all 3 messages have been handled simultaneously. And its working because the <code>MessageListenerContainer</code> is creating extra sessions as per the <code>concurrency</code> attribute. As mentioned in the documentation, these attributes are modifiable at runtime via JMX, thereby allowing us to scale even more dynamically, staying truly J2EE container independent all the while.</p>
<p>This is already quite a long post, so i will discuss the throttling part in the next post.</p>
<h4>Appendix A: ActiveMQ configuration</h4>
<p>Active MQ configuration to configure the broker, queues. One queue to submit requests to the server and another to get response from server.</p>
<pre>
        &lt;amq:broker useJmx="false" id="amqServer"&gt;
		&lt;amq:transportConnectors&gt;
			&lt;amq:transportConnector uri="${mqBrokerURL}"/&gt;
		&lt;/amq:transportConnectors&gt;
	&lt;/amq:broker&gt;

	&lt;!-- Predefined queues, we don't need dynamic queues --&gt;
	&lt;amq:queue id="trRequestQueue" name="sendDestination"
		physicalName="queue.trRequest"/&gt;
	&lt;amq:queue id="trStatusQueue" physicalName="queue.trResponse"/&gt;

	&lt;!-- J2EE ConnectionFactory --&gt;
	&lt;amq:connectionFactory id="targetConnectionFactory" brokerURL="vm://localhost"/&gt;

	&lt;!-- Cache the connection --&gt;
	&lt;bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory"&gt;
		&lt;property name="targetConnectionFactory" ref="targetConnectionFactory"/&gt;
		&lt;property name="reconnectOnException" value="true"/&gt;
	&lt;/bean&gt;
</pre>
<h4>Appendix B: Listener configuration</h4>
<pre>	&lt;jms:listener-container connection-factory="connectionFactory"
		destination-resolver="serverDestinationResolver" message-converter="messageConverter"&gt;
		&lt;jms:listener id="someName" destination="trRequestQueue"
			ref="remoteExecutionEndPoint" method="receive" response-destination="trStatusQueue"/&gt;
	&lt;/jms:listener-container&gt;
	&lt;bean id="remoteExecutionEndPoint"
		class="com.sabscape.rexec.ParkImpl"/&gt;
	&lt;bean id="serverDestinationResolver"
		class="org.springframework.jms.support.destination.BeanFactoryDestinationResolver"/&gt;
	&lt;bean id="messageConverter"
		class="com.sabscape.rexec.PassthroughMessageConverter"/&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://php.sabscape.com/blog/?feed=rss2&amp;p=315</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Why would you want to use a Spring JMS MessageListenerContainer</title>
		<link>http://php.sabscape.com/blog/?p=293&amp;utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=why-would-you-want-to-use-a-spring-jms-messagelistenercontainer</link>
		<comments>http://php.sabscape.com/blog/?p=293#comments</comments>
		<pubDate>Sat, 21 May 2011 17:15:31 +0000</pubDate>
		<dc:creator>Sab</dc:creator>
				<category><![CDATA[Spring]]></category>
		<category><![CDATA[Spring JMS]]></category>
		<category><![CDATA[jms]]></category>
		<category><![CDATA[message listener container]]></category>
		<category><![CDATA[spring jms]]></category>

		<guid isPermaLink="false">http://php.sabscape.com/blog/?p=293</guid>
		<description><![CDATA[Flexibility. Here&#8217;s a few stuff i noticed Scale message consumption easily. We can specify the concurrency level we want and it will create additional sessions (because JMS, by design, disallows concurrent use of a Session) as required. This is modifiable at run-time as well. Allows our POJO message handlers a.k.a listeners to be JMS agnostic [...]]]></description>
			<content:encoded><![CDATA[<p>Flexibility. Here&#8217;s a few stuff i noticed</p>
<ul>
<li>Scale message consumption easily. We can specify the concurrency level we want and it will create additional sessions (because JMS, by design, disallows concurrent use of a Session) as required. This is modifiable at run-time as well.</li>
<li>Allows our POJO message handlers a.k.a listeners to be JMS agnostic (actually integration channel agnostic). So i can have a business-driven method name like <code>runAroundThePark()</code> instead of something that means nothing like <code>onMessage</code>. Of course its not a big deal to dispatch to a business centric method from onMessage, still, why should another level of redirection be forced upon us just because our logic is being invoked through a JMS channel</li>
<li>Our POJO message handling class can send a response message, again while being JMS agnostic</li>
<li>Easily throttle across queues (and/or selector-based-listeners)</li>
<ul>
<li>The scenario is something like this. Assume that you are handling messages that are requesting some jobs to be run and these jobs involve some heavy processing. And you have been asked to ensure that not more than 4 jobs are run at a time</li>
<li>And there are multiple queues that accept a variety of jobs</li>
<li>Now you want to make sure that (across the whole broker) not more than 4 jobs are running at a time</li>
</ul>
</ul>
<p>How we can scale and how we can throttle across the application&#8217;s queues is going to be the content of the next post.</p>
]]></content:encoded>
			<wfw:commentRss>http://php.sabscape.com/blog/?feed=rss2&amp;p=293</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

