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

<channel>
	<title>let x=x &#187; applicationcontext</title>
	<atom:link href="http://www.crazymcphee.net/x/tag/applicationcontext/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.crazymcphee.net/x</link>
	<description>programming idiom and methodology</description>
	<lastBuildDate>Fri, 27 Jan 2012 09:36:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Dynamically loading Spring contexts from the classpath at runtime</title>
		<link>http://www.crazymcphee.net/x/2010/04/29/dynamically-loading-spring-contexts-from-the-classpath-at-runtime/</link>
		<comments>http://www.crazymcphee.net/x/2010/04/29/dynamically-loading-spring-contexts-from-the-classpath-at-runtime/#comments</comments>
		<pubDate>Thu, 29 Apr 2010 06:45:11 +0000</pubDate>
		<dc:creator>Scot Mcphee</dc:creator>
				<category><![CDATA[infrastructure and frameworks]]></category>
		<category><![CDATA[tools and techniques]]></category>
		<category><![CDATA[applicationcontext]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[PathMatchingResourcePatternResolver]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://www.crazymcphee.net/x/?p=540</guid>
		<description><![CDATA[Using these three Spring features will enable us to be able to place a JAR file containing an interface implementation, and a Spring context XML file matching a particular pattern, into the classpath of our WAR, and on restart, we can dynamically pick up the newly inserted features into our application installation.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m just going to document a way I&#8217;ve found to use Spring ApplicationContext to dynamically load other context XML configurations that it find in the classpath. We have a requirement to do this coming up on a product we&#8217;re building. Let me describe the sort of problem we are trying to solve (with many specifics omitted or glossed over):</p>
<blockquote><p>There is a web service inside a component, let&#8217;s call that component a &#8216;Node&#8217;, that receives something like (but not identical to!) an Event on its interface. Inside the Event is some data that the Node does not particularly care about (and actually has no access to &#8211; it&#8217;s just a <em>byte[]</em> as far as the Node can tell). However, the Node contains a Registry which enables components, lets call them Event Handlers, to register themselves with the Node, as available to process certain Events (i.e. decode that <em>byte[]</em> and do something with it) according to criteria which the EventHandler injects into the Node&#8217;s Registry.  EventHandler is an interface with a handful of simple methods related to handling the Event, and also registration with the Registry.</p>
<p>So, the process flow looks something like this: The Node first records the reception of the Event at the interface in a log. Then it tells the Registry about the Event, and the Registry produces the EventHandler(s) it needs to use.  The Registry gives the Node back the instances of the EventHandler interface. The Node then hands off the Event to the EventHandler, which does whatever it does unbeknownst to the Node, and returns a fairly simple EventResponse object. The Node records the EventResponse object in its log (i.e. a database) and returns it as the response to the web service call.</p>
<p>Consider the Node service method as looking something like this (you&#8217;ll have to excuse the Java 1.4-ness of this code, the WordPress code highlighting plugin apparently hates Java 5) :</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">List</span> receive<span style="color: #009900;">&#40;</span><span style="color: #003399;">Event</span> event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003399;">List</span> responses <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">ArrayList</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>EventHandler handler <span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">registry</span>.<span style="color: #006633;">lookup</span><span style="color: #009900;">&#40;</span>event.<span style="color: #006633;">getMetadata</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      Response response <span style="color: #339933;">=</span> handler.<span style="color: #006633;">handle</span><span style="color: #009900;">&#40;</span>event<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      saveResponse<span style="color: #009900;">&#40;</span>response, event, handler<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      responses.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>response<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">return</span> responses<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p>To enable the wiring, the Registry has a method:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">  <span style="color: #000066; font-weight: bold;">void</span> register<span style="color: #009900;">&#40;</span>EventMetadata metadata, EventHandler handler<span style="color: #009900;">&#41;</span></pre></div></div>

<p>and among other methods the EventHandler interface defines:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">  <span style="color: #000066; font-weight: bold;">void</span> setRegistry<span style="color: #009900;">&#40;</span><span style="color: #003399;">Registry</span> registry<span style="color: #009900;">&#41;</span></pre></div></div>

<p>Currently the WAR file imports the Node.JAR and a group of EventHandler.JAR files which are specific implementations for handling different kinds of Events. We configure it in Spring currently so that the specific EventHandler is injected with the Registry object (from the Node.JAR). The EventHandler implementation then registers itself with the Registry in a call-back operation, telling it what sort of Events it will handle<em>.</em></p></blockquote>
<p><span style="text-decoration: underline;">This all works just fine at the moment</span>. The <span style="text-decoration: underline;">problem</span> with what we have is that it is all currently statically compiled into the WAR file.The WAR file specifies a Spring application context XML file which in turn loads the Spring configuration for the Node and Registry component, and every Spring application context for each Handler JAR included inside the WAR file&#8217;s <em>WEB-INF/lib</em> directory.</p>
<p>Now, we now don&#8217;t want every deployed instance of every Node to handle every possible Event. Currently we&#8217;ve got a small <em>.properties</em> file that actually tells another Spring component which EventHandlers are be to be instantiated or not. This is working fine when we only desire some Nodes to handle maybe one or two of a larger group of related Events. That is, where we currently don&#8217;t mind that the WAR file is identical in every respect on every Node &#8212; it&#8217;s just that each node contains a <em>.properties</em> file in its classpath that tells it which EventHandlers it is allowed to load and use (and therefore what Events it is capable of receiving, bearing in mind that when I say &#8216;Events&#8217; there is really only one concrete type of Event, I mean the encrypted data which is held <span style="text-decoration: underline;">within</span> the Event which is actually consumed by the Handler).</p>
<p>However, we are now in a situation where we want to use this same architecture for a completely different group of Events. We definitely don&#8217;t want to have to compile and assemble a new WAR file for different Nodes based on the Event cluster. We want to deploy a standardized <em>Node.WAR</em> which has available on its classpath a dynamic set of <em>XxxEventHandler.JAR</em> which can dynamically register themselves with the Node&#8217;s registry. There may be also a requirement for some related custom extension points in the future.</p>
<p>Initially we considered OSGi as the technology to enable this. After some discussion yesterday with people who know better about OSGi, this approach was rejected as impractical for the moment. Therefore last night I set out tooling about with the Spring 2.5.6 ApplicationContext and its related objects to see what could be done to enable dynamically-loaded JAR files within a parent Spring application context. Here is what I&#8217;ve discovered we can do, with only some small restrictions on developers writing the individual EventHandler implementations.</p>
<p>The first issue is, we need to locate a set of Spring application context XML file which should be on the classpath but not yet instantiated into any live Spring context.</p>
<p>Assuming we&#8217;re in a bean that&#8217;s <em>ContextAware</em> or otherwise has access to the Spring application context which is loading it, after the parent context has loaded and initialized (there are method hooks for this sort of thing) we can use the <em>org.springframework.core.io.support.PathMatchingResourcePatternResolver</em> class to search the classpath for a resource:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">  PathMatchingResourcePatternResolver pmrl <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> PathMatchingResourcePatternResolver<span style="color: #009900;">&#40;</span>context.<span style="color: #006633;">getClassLoader</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  Resource<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> resources <span style="color: #339933;">=</span> pmrl.<span style="color: #006633;">getResources</span><span style="color: #009900;">&#40;</span>
    <span style="color: #0000ff;">&quot;classpath*:/net/crazymcphee/dynamiccontext/*/Crazy*DynamicContext.xml&quot;</span>
  <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Looking at the Spring 2.5.6 source code we found that the String passed to the <em>getResources()</em> method isn&#8217;t a proper regular expression, which is a pity. So you can&#8217;t do something like look for <em>**/Crazy*DynamicContext.xml</em> and expect to match a file <em>Crazy*DynamicContext.xml</em> in any package. Also we found that it had to prefixed with that <em>classpath*:</em> &#8230; yes, the asterix, literally &#8230; else it wouldn&#8217;t search the classpath, as opposed to the file path. So we&#8217;re restricted in the above example to a file called <em>Crazy&lt;something&gt;DynamicContext.xml </em>in a package exactly one deep from <em>net.crazymcphee.dynamiccontext</em> &#8230; e.g. <em>net.crazymcphee.dynamiccontext.package.CrazyMcpheeDynamicPackage.xml</em> matches but <em>net.crazymcphee.dynamiccontext.package.sub.CrazySubDynamicPackage.xml </em>and <em>net.crazymcphee.dynamiccontext.CrazySuperDynamicPackage.xml </em>do not. Therefore we will have a restriction on what package the dynamic context can be in and what it&#8217;s name will be. I don&#8217;t think that&#8217;s too onerous on our developers &#8211; we just have to pick a sensible standard.</p>
<p>The next part of the problem is that we have to load the &#8216;Resource&#8217; thus found into a Spring context. This is pretty easy:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"> <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>Resource r <span style="color: #339933;">:</span> resources<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   GenericApplicationContext createdContext <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> GenericApplicationContext<span style="color: #009900;">&#40;</span>context<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   XmlBeanDefinitionReader reader <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> XmlBeanDefinitionReader<span style="color: #009900;">&#40;</span>createdContext<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> reader.<span style="color: #006633;">loadBeanDefinitions</span><span style="color: #009900;">&#40;</span>r<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span></pre></div></div>

<p>The<em> int i</em> will be set to the number of beans found in the <em>createdContext</em>. The <em>createdContext</em> will have the original <em>context</em> as its parent context, so it can gain access to any beans defined there (and also, although we are yet to test this (!), it should also be intercepted by the AOP-based transaction interceptors in the parent, and so forth).</p>
<p>The only other part of the puzzle may be to query the <em>createdContext</em> to see if it has any target beans within it, luckily for us an ApplicationContext has a method <em>getBeansOfType(Class clazz)</em> which will load all the beans of a particular type:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">  <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>Resource r <span style="color: #339933;">:</span> resources<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    GenericApplicationContext createdContext <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> GenericApplicationContext<span style="color: #009900;">&#40;</span>context<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    XmlBeanDefinitionReader reader <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> XmlBeanDefinitionReader<span style="color: #009900;">&#40;</span>createdContext<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> reader.<span style="color: #006633;">loadBeanDefinitions</span><span style="color: #009900;">&#40;</span>r<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #003399;">Map</span> map <span style="color: #339933;">=</span> createdContext.<span style="color: #006633;">getBeansOfType</span><span style="color: #009900;">&#40;</span>EventHandler.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> o <span style="color: #339933;">:</span> map.<span style="color: #006633;">keySet</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      EventHandler handler <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>EventHandler<span style="color: #009900;">&#41;</span> createdContext.<span style="color: #006633;">getBean</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#41;</span> o<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #666666; font-style: italic;">// do some programmatic manipulation with the EventHandler that we found here</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Using these three Spring features will enable us to be able to place a JAR file containing an interface implementation, and a Spring context XML file matching a particular pattern, into the classpath of our WAR, and on restart, we can dynamically pick up the newly inserted features into our application installation. I&#8217;ll report back when we get an actual production prototype together that can do this. Hopefully it will be OK to put the code in the blog too (if we make it generic enough).</p>
<p>If you have any further ideas or refinements to this idea, please leave them in the comments!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.crazymcphee.net/x/2010/04/29/dynamically-loading-spring-contexts-from-the-classpath-at-runtime/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

