<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Miles To Code Before I Sleep</title>
	<atom:link href="http://bryanhunt.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://bryanhunt.wordpress.com</link>
	<description>It&#039;s all about the code.</description>
	<lastBuildDate>Mon, 23 Nov 2009 18:21:58 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='bryanhunt.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/a7c516029012cd19a7bc8c7bc87bc02a?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>Miles To Code Before I Sleep</title>
		<link>http://bryanhunt.wordpress.com</link>
	</image>
			<item>
		<title>Updating Ensemble for Restlet 2.0 (license beware)</title>
		<link>http://bryanhunt.wordpress.com/2009/11/23/updating-ensemble-for-restlet-2-0-license-beware/</link>
		<comments>http://bryanhunt.wordpress.com/2009/11/23/updating-ensemble-for-restlet-2-0-license-beware/#comments</comments>
		<pubDate>Mon, 23 Nov 2009 18:21:58 +0000</pubDate>
		<dc:creator>bryanhunt</dc:creator>
				<category><![CDATA[Eclipse]]></category>

		<guid isPermaLink="false">http://bryanhunt.wordpress.com/?p=315</guid>
		<description><![CDATA[I attended a tutorial at EclipseCon 2009 on ReSTful OSGi Web Applications which was based on the Ensemble project at NASA and Restlet 1.x.  I recently started looking at Restlet 2.0 and updated the Ensemble code to work with the new API, cleaned up a possible threading issue, and added an OSGi service for extensibility. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&blog=7500940&post=315&subd=bryanhunt&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I attended a tutorial at <a href="http://www.eclipsecon.org" target="_blank">EclipseCon</a> 2009 on <a href="http://www.eclipsecon.org/2009/sessions?id=385" target="_blank">ReSTful OSGi Web Applications</a> which was based on the Ensemble project at NASA and <a href="http://www.restlet.org" target="_blank">Restlet</a> 1.x.  I recently started looking at Restlet 2.0 and updated the Ensemble code to work with the new API, cleaned up a possible threading issue, and added an OSGi service for extensibility.  I was hoping to share these changes in this post, but the open source <a href="https://www.openchannelsoftware.com/project/print_license.php?group_id=368&amp;license_id=61" target="_blank">license</a> under which the Ensemble code was released is too prohibitive (private, non-comercial, use only) for my use.  I had assumed that it was released under <a href="http://www.eclipse.org/org/documents/epl-v10.php" target="_blank">EPL</a>, and I was wrong.</p>
<p>The functionality provided by the Ensemble code is rather simple.  It provides an Eclipse extension point for registering a Restlet representation.  It also has the ability to handle the dynamic nature of OSGi bundles allowing extensions to come and go during runtime.  It&#8217;s too bad my work was for not.  Fortunately, a colleague has agreed to attempt to reproduce this functionality, and since he has not seen the Ensemble source code, nor discussed it with me, he will be able to release his code under EPL.</p>
<p>Lesson learned: Always check the license before looking at the source code.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bryanhunt.wordpress.com/315/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bryanhunt.wordpress.com/315/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bryanhunt.wordpress.com/315/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bryanhunt.wordpress.com/315/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bryanhunt.wordpress.com/315/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bryanhunt.wordpress.com/315/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bryanhunt.wordpress.com/315/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bryanhunt.wordpress.com/315/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bryanhunt.wordpress.com/315/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bryanhunt.wordpress.com/315/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&blog=7500940&post=315&subd=bryanhunt&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://bryanhunt.wordpress.com/2009/11/23/updating-ensemble-for-restlet-2-0-license-beware/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/96518750aa70c5f4794c5f074ac0dd93?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">bryanhunt</media:title>
		</media:content>
	</item>
		<item>
		<title>Using EMF to Model Your Build Process as a Workflow</title>
		<link>http://bryanhunt.wordpress.com/2009/10/19/using-emf-to-model-your-build-process-as-a-workflow/</link>
		<comments>http://bryanhunt.wordpress.com/2009/10/19/using-emf-to-model-your-build-process-as-a-workflow/#comments</comments>
		<pubDate>Mon, 19 Oct 2009 14:00:47 +0000</pubDate>
		<dc:creator>bryanhunt</dc:creator>
				<category><![CDATA[Eclipse]]></category>

		<guid isPermaLink="false">http://bryanhunt.wordpress.com/?p=288</guid>
		<description><![CDATA[There are a lot of tools available for building software, each with it&#8217;s own strengths and weaknesses.  They all fundamentally do the same job &#8211; they convert source code into an application that can be delivered to a customer.  Building an application generally involves multiple steps, and it seems natural that those steps [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&blog=7500940&post=288&subd=bryanhunt&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>There are a lot of tools available for building software, each with it&#8217;s own strengths and weaknesses.  They all fundamentally do the same job &#8211; they convert source code into an application that can be delivered to a customer.  Building an application generally involves multiple steps, and it seems natural that those steps could be described as a workflow.  I will demonstrate how to model a build process using my <a href="http://bryanhunt.wordpress.com/2009/08/24/emf-workflow-model/">EMF workflow model</a>.</p>
<p>Let&#8217;s define a build process with more than one task.  We will compile a Java source file into a class file, jar the class file, and finally zip the jar file.  I started by creating domain specific extensions (Figure 1) to the EMF workflow model.  Remember that the workflow model is a framework and domain specific tasks are developed as extensions to the model.</p>
<div id="attachment_294" class="wp-caption aligncenter" style="width: 364px"><img class="size-full wp-image-294" title="BuildDomain" src="http://bryanhunt.files.wordpress.com/2009/10/builddomain1.png?w=354&#038;h=230" alt="Figure 1" width="354" height="230" /><p class="wp-caption-text">Figure 1</p></div>
<p>I start by creating an <strong>Empty EMF Project</strong> and then a new <strong>Ecore Model</strong>.  Next, load the EMF workflow model as a resource of the ecore extension model.  Create three new classes: <strong>JavaCompiler</strong>, <strong>JavaJar</strong>, and <strong>ZipFile</strong> each extending <strong>WorkflowUnitOfWork</strong>. Finally, create non-containment references to WorkflowParameter as follows:</p>
<p>JavaCompiler</p>
<ul>
<li>classNameParameter</li>
<li>classpathParameter</li>
<li>workingDirectoryParameter</li>
</ul>
<p>JavaJar</p>
<ul>
<li>classNameParameter</li>
<li>workingDirectoryParameter</li>
<li>outputFileParameter</li>
</ul>
<p>ZipFile</p>
<ul>
<li>workingDirectoryParameter</li>
<li>inputFileParameter</li>
<li>outputFileParameter</li>
</ul>
<p>These con-containment references are created for convenience which will be apparent when the workflow is constructed.  Now that the model extensions have been defined, the model and edit code can be generated.  Remember to set <strong>Child Creation Extenders</strong> and <strong>Extensible Provider Factory</strong> to <strong>true</strong>.</p>
<p><img class="aligncenter size-full wp-image-295" title="EditProperties" src="http://bryanhunt.files.wordpress.com/2009/10/editproperties.png?w=460&#038;h=258" alt="EditProperties" width="460" height="258" /></p>
<p>The last piece of the development is to provide the executable functionality of each of the tasks.  Here are the implementations of each of the <strong>run()</strong> functions:</p>
<p>JavaCompiler</p>
<pre class="brush: java;">
@Override
public WorkflowState run(WorkflowContext context) throws WorkflowRuntimeException
{
	File workingDirectory = new File((String) workingDirectoryParameter.getValue(context));
	String[] command = {&quot;javac&quot;, &quot;-cp&quot;, (String) classpathParameter.getValue(context), (String) classNameParameter.getValue(context) + &quot;.java&quot;};
	int rc = 0;

	try
	{
		logDebug(context, &quot;Executing command: javac -cp &quot; + command[2] + &quot; &quot; + command[3]);
		Process process = Runtime.getRuntime().exec(command, null, workingDirectory);
		rc = process.waitFor();
	}
	catch (Exception e)
	{
		logException(context, e);
		return StateFactory.eINSTANCE.createWorkflowErrorState();
	}

	return rc == 0 ? StateFactory.eINSTANCE.createWorkflowSuccessState() : StateFactory.eINSTANCE.createWorkflowFailedState();
}
</pre>
<p>JavaJar</p>
<pre class="brush: java;">
@Override
public WorkflowState run(WorkflowContext context) throws WorkflowRuntimeException
{
	File workingDirectory = new File((String) workingDirectoryParameter.getValue(context));
	String[] command = {&quot;jar&quot;, &quot;-cf&quot;, (String) outputFileParameter.getValue(context), (String) classNameParameter.getValue(context) + &quot;.class&quot;};
	int rc = 0;

	try
	{
		logDebug(context, &quot;Executing command: jar -cf &quot; + command[2] + &quot; &quot; + command[3]);
		Process process = Runtime.getRuntime().exec(command, null, workingDirectory);
		rc = process.waitFor();
	}
	catch (Exception e)
	{
		logException(context, e);
		return StateFactory.eINSTANCE.createWorkflowErrorState();
	}

	return rc == 0 ? StateFactory.eINSTANCE.createWorkflowSuccessState() : StateFactory.eINSTANCE.createWorkflowFailedState();
}
</pre>
<p>ZipFile</p>
<pre class="brush: java;">
@Override
public WorkflowState run(WorkflowContext context) throws WorkflowRuntimeException
{
	File workingDirectory = new File((String) workingDirectoryParameter.getValue(context));
	String[] command = {&quot;zip&quot;, (String) outputFileParameter.getValue(context), (String) inputFileParameter.getValue(context)};
	int rc = 0;

	try
	{
		logDebug(context, &quot;Executing command: zip &quot; + command[1] + &quot; &quot; + command[2]);
		Process process = Runtime.getRuntime().exec(command, null, workingDirectory);
		rc = process.waitFor();
	}
	catch (Exception e)
	{
		logException(context, e);
		return StateFactory.eINSTANCE.createWorkflowErrorState();
	}

	return rc == 0 ? StateFactory.eINSTANCE.createWorkflowSuccessState() : StateFactory.eINSTANCE.createWorkflowFailedState();
}
</pre>
<p>Now that we have domain specific tasks that can do actual work, we can assemble them into a build process / workflow.  Launch the runtime workbench, create a new project, and create a new ecore model. Here are the results:</p>
<p><img src="http://bryanhunt.files.wordpress.com/2009/10/build-workflow.png?w=556&#038;h=528" alt="Build Workflow" title="Build Workflow" width="556" height="528" class="aligncenter size-full wp-image-300" /></p>
<p>After the build workflow has been created, we can create a runtime model that contains the parameter values for the build.</p>
<p><img src="http://bryanhunt.files.wordpress.com/2009/10/build-runtime.png?w=831&#038;h=311" alt="Build Runtime" title="Build Runtime" width="831" height="311" class="aligncenter size-full wp-image-303" /></p>
<p>I&#8217;ve set up this example runtime to build Hello.java in the working directory /tmp/build.  When you run the workflow, it will generate Hello.class, hello.jar, and finally hello.zip.  You may have noticed that not all modeled parameters have values in the runtime model.  I created parameter connections in the workflow model for those parameters that share values.  For this example, I also created a second runtime to build Bye.java using the same build process.  This complete example is available in CVS at dev.eclipse.org /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.mwe/examples.</p>
<p>There is a <a href="http://idisk.mac.com/bhunt-Public/BuildScreencast.mov">screencast</a> available until I need the disk space.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bryanhunt.wordpress.com/288/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bryanhunt.wordpress.com/288/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bryanhunt.wordpress.com/288/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bryanhunt.wordpress.com/288/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bryanhunt.wordpress.com/288/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bryanhunt.wordpress.com/288/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bryanhunt.wordpress.com/288/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bryanhunt.wordpress.com/288/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bryanhunt.wordpress.com/288/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bryanhunt.wordpress.com/288/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&blog=7500940&post=288&subd=bryanhunt&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://bryanhunt.wordpress.com/2009/10/19/using-emf-to-model-your-build-process-as-a-workflow/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/96518750aa70c5f4794c5f074ac0dd93?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">bryanhunt</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/10/builddomain1.png" medium="image">
			<media:title type="html">BuildDomain</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/10/editproperties.png" medium="image">
			<media:title type="html">EditProperties</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/10/build-workflow.png" medium="image">
			<media:title type="html">Build Workflow</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/10/build-runtime.png" medium="image">
			<media:title type="html">Build Runtime</media:title>
		</media:content>
	</item>
		<item>
		<title>EMF Workflow Model</title>
		<link>http://bryanhunt.wordpress.com/2009/08/24/emf-workflow-model/</link>
		<comments>http://bryanhunt.wordpress.com/2009/08/24/emf-workflow-model/#comments</comments>
		<pubDate>Mon, 24 Aug 2009 14:00:18 +0000</pubDate>
		<dc:creator>bryanhunt</dc:creator>
				<category><![CDATA[Eclipse]]></category>

		<guid isPermaLink="false">http://bryanhunt.wordpress.com/?p=208</guid>
		<description><![CDATA[I have been working on an EMF Workflow Model for some time now, and the documentation on how to use the model has been lacking.  In this post, I will show you how to extend and use the model with a complete example.  The EMF Workflow Model is a framework for modeling workflows.  Developers must [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&blog=7500940&post=208&subd=bryanhunt&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I have been working on an EMF Workflow Model for some time now, and the documentation on how to use the model has been lacking.  In this post, I will show you how to extend and use the model with a complete example.  The EMF Workflow Model is a framework for modeling workflows.  Developers must extend the model by creating objects that do useful work.  Once the model has been extended, users may then assemble workflows from the components provided.  The core of the model is a composite pattern that allows a workflow to be constructed as an arbitrary tree forming a directed graph.  The framework supports executing nodes of the model in serial, parallel, loops, and conditionally.  Each node can be parameterized, and provides execution state that can be persisted.</p>
<p>There are two major parts to the workflow model:  a design model, and a runtime model.  The design model specifies which tasks to execute and the order they are executed.  The runtime model specifies the parameter values and state of the running workflow.  Separating the design model from the runtime model allows you to have a single workflow that can be executed with different permutations by choosing a different runtime model.</p>
<h2>Workflow Design Model</h2>
<p>The design model is based on a <a href="http://en.wikipedia.org/wiki/Composite_pattern" target="_blank">composite pattern</a> (Figure 1).  The composite pattern allows for the construction of arbitrarily complex workflows.  Workflows can be a simple sequence of steps or a complicated tree of sub-workflows.  The flow of execution, or orchestration, is modeled as a <a href="http://en.wikipedia.org/wiki/Strategy_pattern" target="_self">strategy pattern</a> (Figure 2). This allows custom flow control strategies to be plugged into the workflow providing a rich framework for executing workflows.  The framework includes strategies for executing workflow tasks in serial, parallel, conditionally, and in a loop.</p>
<div id="attachment_218" class="wp-caption aligncenter" style="width: 413px"><img class="size-full wp-image-218" title="Workflow" src="http://bryanhunt.files.wordpress.com/2009/08/workflow.png?w=403&#038;h=302" alt="Workflow" width="403" height="302" /><p class="wp-caption-text">Figure 1</p></div>
<ul>
<li>WorkflowComponent &#8211; the abstract root of the composite</li>
<li>CompositeWorkflowComponent &#8211; the branches of the tree</li>
<li>WorkflowUnitOfWork &#8211; the abstract leaves of the tree (you must extend this class)</li>
<li>WorkflowParameter &#8211; the keys of the runtime parameter map</li>
<li>WorkflowParameterConnection &#8211; connect an output parameter to one or more input parameters</li>
</ul>
<div id="attachment_221" class="wp-caption aligncenter" style="width: 567px"><img class="size-full wp-image-221" title="Orchestration" src="http://bryanhunt.files.wordpress.com/2009/08/orchestration2.png?w=557&#038;h=517" alt="Figure 2" width="557" height="517" /><p class="wp-caption-text">Figure 2</p></div>
<p style="text-align:center;">
<ul>
<li>WorkflowCompositeOrchestrationStrategy &#8211; abstract base class that controls the execution of children of a composite</li>
<li>WorkflowParallelOrchestrationStrategy &#8211; executes the children of a composite in parallel</li>
<li>WorkflowSerialOrchestrationStrategy &#8211; executes the children of a composite in serial</li>
<li>WorkflowComponentOrchestrationStrategy &#8211; base class that controls the execution of a component</li>
<li>WorkflowLoopComponentOrchestrationStrategy &#8211; executes a component in a loop</li>
<li>WorkflowExecutionPredicate &#8211; abstract base class for conditional predicates</li>
<li>WorkflowPredicateAND &#8211; logical AND of the child predicates</li>
<li>WorkflowPredicateOR &#8211; logical OR of the child predicates</li>
<li>WorkflowRerunPredicate &#8211; predicate based on the state of the last run</li>
<li>WorkflowParameterPredicate &#8211; predicate based on a parameter</li>
<li>WorkflowLoopCountPredicate &#8211; predicate based on a parameter value count</li>
</ul>
<h2>Workflow Runtime Model</h2>
<p>The runtime model holds the dynamic information used by the workflow during execution.  This includes parameter values, execution state, and logging (Figure 3).  Parameter values are stored as instances of <strong>EObject</strong> allowing you to pass any modeled object to a workflow task.  Simple values such as <strong>String</strong>, <strong>Integer</strong>, etc can be wrapped in an instance of <strong>SimpleAnyType</strong>.  Since tasks can be executed in parallel, the runtime model makes use of <a href="http://www.eclipse.org/modeling/emf/?project=transaction" target="_self">EMF Transaction</a> for thread safe access to the workflow data.  Workflow states are modeled using the <a href="http://en.wikipedia.org/wiki/State_pattern" target="_blank">state pattern</a> (Figure 4).  You may extend a state if your task needs state granularity not currently provided.  You should not access the data in the WorkflowContext directly while the workflow is running, but instead use the convenience functions in the various design model classes.</p>
<div id="attachment_232" class="wp-caption aligncenter" style="width: 488px"><img class="size-full wp-image-232" title="Runtime" src="http://bryanhunt.files.wordpress.com/2009/08/runtime1.png?w=478&#038;h=287" alt="Figure 3" width="478" height="287" /><p class="wp-caption-text">Figure 3</p></div>
<ul>
<li>WorkflowContext &#8211; the root container for all runtime data</li>
<li>WorkflowStateMap &#8211; maps a WorkflowComponent to a WorlflowState</li>
<li>WorkflowComponentExecutionInfoMap &#8211; maps a WorkflowComponent to a WorkflowComponentExecutionInfo</li>
<li>WorkflowParameterMap &#8211; maps a WorkflowParameter to its value</li>
<li>WorkflowLogMap &#8211; maps a WorkflowComponent to a WorkflowLog</li>
</ul>
<div id="attachment_234" class="wp-caption aligncenter" style="width: 544px"><img class="size-full wp-image-234" title="State" src="http://bryanhunt.files.wordpress.com/2009/08/state.png?w=534&#038;h=254" alt="Figure 4" width="534" height="254" /><p class="wp-caption-text">Figure 4</p></div>
<ul>
<li>WorkflowState &#8211; abstract base class for all workflow states</li>
<li>WorkflowIdleState &#8211; the task has not been executed</li>
<li>WorkflowDoneState &#8211; the task has finished executing</li>
<li>WorkflowRunningState &#8211; the task is currently running</li>
<li>WorkflowSuccessState &#8211; the task has finished successfully</li>
<li>WorkflowFailedState &#8211; the task has finished with a failure</li>
<li>WorkflowErrorState &#8211; the task has finished with an exception</li>
</ul>
<h2>Getting The Workflow Model</h2>
<p>The model is contributed to the <a href="http://www.eclipse.org/modeling/emft/?project=mwe#mwe" target="_blank">MWE</a> sub-project under <a href="http://www.eclipse.org/modeling/emft/" target="_blank">EMFT</a> at <a href="http://www.eclipse.org" target="_blank">Eclipse.org</a>.  My contribution is not currently part of the MWE build, so you will have to start by extracting the model from CVS.  Start Eclipse and open the <strong>CVS Perspective</strong>.  Use the following connection:</p>
<ul>
<li>Host: <strong>dev.eclipse.org</strong></li>
<li>Path: <strong>/cvsroot/modeling</strong></li>
<li>User: <strong>anonymous</strong></li>
<li>Connection type: <strong>pserver</strong></li>
</ul>
<p>Expand the path: <strong>HEAD -&gt; org.eclipse.emf -&gt; org.eclipse.emf.mwe -&gt; plugins</strong> and checkout the bundles <strong>org.eclipse.emf.mwe.ewm.*</strong>.  The <strong>org.eclipse.emf.mwe.core</strong> bundle contains the EMF model that you will extend.  The other bundles are primarily for convenience of experimenting with the workflow model.</p>
<h2>Target Platform</h2>
<p>The EMF workflow model requires the following projects in your target platform:</p>
<ul>
<li><a href="http://download.eclipse.org/eclipse/downloads/drops/R-3.5-200906111540/index.php" target="_blank">Eclipse SDK</a> for your platform</li>
<li><a href="http://www.eclipse.org/modeling/download.php?file=/modeling/emf/emf/downloads/drops/2.5.0/R200906151043/emf-xsd-SDK-2.5.0.zip" target="_blank">EMF</a></li>
<li><a href="http://www.eclipse.org/modeling/download.php?file=/modeling/emf/transaction/downloads/drops/1.3.0/R200906221200/emf-transaction-SDK-1.3.0.zip" target="_self">EMF Transaction</a></li>
</ul>
<h2>Extending The Workflow Model</h2>
<p>Workflow tasks are domain specific and the EMF workflow model provides a framework for assembling and executing your domain specific tasks.  To use the EMF workflow model, you must extend <strong>WorkflowUnitOfWork</strong> to provide domain specific functionality in the <strong>run()</strong> function.  Use the following steps to create an extension to the workflow model:</p>
<ol>
<li>Create a new <strong>Empty EMF Project</strong> named org.example.workflow</li>
<li>Create a new <strong>Ecore Model</strong></li>
<li>Load Resource&#8230; <strong>platform:/resource/org.eclipse.emf.mwe.ewm.core/model/workflow.ecore</strong></li>
<li>Create a new <strong>EClass</strong></li>
<li>Name: <strong>ExampleTask</strong></li>
<li>ESuperTypes: <strong>WorkflowUnitOfWork</strong></li>
</ol>
<p><strong><img class="aligncenter size-full wp-image-245" title="Eclipse" src="http://bryanhunt.files.wordpress.com/2009/08/eclipse.png?w=457&#038;h=125" alt="Eclipse" width="457" height="125" /><span style="font-weight:normal;">Next, we need to create a genmodel and generate our code:</span></strong></p>
<ol>
<li>Create a new <strong>EMF Generator Model</strong></li>
<li>Import from <strong>Ecore model</strong></li>
<li>Add <strong>org.eclipse.emf.mwe.ewm.core/model/workflow.genmodel</strong> as a referenced generator model</li>
<li>Select both <strong>org.eclipse.emf.ecore </strong>and <strong>org.eclipse.emf.mwe.ewm.workflow</strong> as referenced generator models</li>
<li>Suppress Interfaces: <strong>true</strong></li>
<li>Base Package: <strong>org.example.workflow</strong></li>
<li>Child Creation Extenders: <strong>true</strong></li>
<li>Extensible Provider Factory: <strong>true</strong></li>
<li><strong>Generate Model Code</strong></li>
<li><strong>Generate Edit Code</strong></li>
</ol>
<p><img class="aligncenter size-full wp-image-279" title="Eclipse 9" src="http://bryanhunt.files.wordpress.com/2009/08/eclipse-9.png?w=674&#038;h=401" alt="Eclipse 9" width="674" height="401" /></p>
<p><img class="aligncenter size-full wp-image-246" title="Eclipse 2" src="http://bryanhunt.files.wordpress.com/2009/08/eclipse-2.png?w=495&#038;h=327" alt="Eclipse 2" width="495" height="327" /></p>
<p>You will notice that <strong>ExampleTask</strong> does not compile.  The <strong>run()</strong> function in <strong>WorkflowUnitOfWork</strong> is abstract and where you need to add your domain specific business logic.  Open <strong>ExampleTask</strong> in the editor and choose the quickfix: <strong>Add unimplemented methods</strong>.  Go to the <strong>run()</strong> function and provide the following implementation:</p>
<pre class="brush: java;">
@Override
public WorkflowState run(WorkflowContext context) throws WorkflowRuntimeException
{
	System.out.println(&quot;Hello world&quot;);
	return StateFactory.eINSTANCE.createWorkflowSuccessState();
}
</pre>
<h2>Composing A Workflow</h2>
<p>Now that you have a domain specific task that does useful work (&#8220;hello world&#8221; is arguably not useful &#8211; just envision a useful task), your task can be assembled into a workflow.  To do this, we will use the EMF generated editor to create an instance of the workflow model:</p>
<ol>
<li>Create a new <strong>Eclipse Application</strong> launch configuration</li>
<li>Launch the runtime workbench</li>
<li>Create a new <strong>General -&gt; Project</strong></li>
<li>Create a new <strong>Workflow Model</strong></li>
<li>Select the root model object: <strong>Composite Component</strong></li>
<li>Set the name of the composite to <strong>Root</strong></li>
<li>Create a New Child of Composite Component: <strong>Workflow Serial Orchestration Strategy</strong></li>
<li>Create a New Child of Composite Component: <strong>Workflow Component Orchestration Strategy</strong></li>
<li>Create a New Child of Composite Component: <strong>Workflow State Resolution Strategy</strong></li>
<li>Create a New Child of Composite Component: <strong>Task</strong></li>
<li>Set the name of the task to <strong>Task</strong></li>
<li>Create a New Child of Task: <strong>Workflow Component Orchestration Strategy</strong></li>
</ol>
<p><strong><img class="aligncenter size-full wp-image-256" title="Eclipse 4" src="http://bryanhunt.files.wordpress.com/2009/08/eclipse-4.png?w=412&#038;h=196" alt="Eclipse 4" width="412" height="196" /><span style="font-weight:normal;">Every component must have an orchestration strategy.  In this model, there are two components: the root composite, and your example task.  Each of these components has a </span>WorkflowComponentOrchestrationStrategy<span style="font-weight:normal;">.  This strategy, by default, simply runs the component.  Every composite must have a composite orchestration strategy, and a state resolution strategy.  In this model, the composite orchestration strategy is </span>WorkflowSerialOrchestrationStrategy</strong> which executes the children of the composite serially.  The <strong>WorkflowStateResolutionStrategy</strong> determines the state of the composite based on the state of the children after all of the children have executed.</p>
<h2>Running A Workflow</h2>
<p>To run the workflow you just assembled, you will need a runtime model and a launch configuration:</p>
<ol>
<li>Create a new <strong>Runtime Model</strong></li>
<li>Select the root model object: <strong>WorkflowContext</strong></li>
<li>Create a new <strong>EMF Workflow</strong> launch configuration</li>
<li>Set Workflfow: <strong>platform:/resource/test/My.workflow</strong></li>
<li>Set Context: <strong>platform:/resource/test/My.runtime</strong></li>
<li>Launch the workflow</li>
</ol>
<p><img class="aligncenter size-full wp-image-260" title="Run Configurations" src="http://bryanhunt.files.wordpress.com/2009/08/run-configurations.png?w=828&#038;h=526" alt="Run Configurations" width="828" height="526" />As your workflow executes, it will print &#8220;Hello world&#8221; to the console.  Don&#8217;t forget that the output will go to the Console view in the host workbench and not the runtime workbench.  There is an alternate way to run your workflow by right-clicking the workflow model and selecting <strong>Run Workflow</strong>.  You will be prompted to select the runtime model, the workflow will execute, and the runtime will be saved back to the workspace.  Note that the launcher will not save the runtime after execution.  After your workflow has terminated, you can view the contents of the runtime by right-clicking on the runtime model and selecting <strong>View Workflow Status</strong>.  You can reset the workflow runtime information by right-clicking on the runtime model and selecting <strong>Reset Workflow State</strong>.</p>
<p><img class="aligncenter size-full wp-image-262" title="Eclipse 5" src="http://bryanhunt.files.wordpress.com/2009/08/eclipse-51.png?w=750&#038;h=205" alt="Eclipse 5" width="750" height="205" /></p>
<h2>Parameterizing A Workflow</h2>
<p>Let&#8217;s make the workflow example task a bit more interesting by giving it a parameter for the message to print to the console instead of the hard-coded &#8220;Hello world&#8221;.  Change <strong>ExampleTask.run()</strong> to:</p>
<pre class="brush: java;">
@Override
public WorkflowState run(WorkflowContext context) throws WorkflowRuntimeException
{
	System.out.println(getParameters().get(0).getValue(context));
	return StateFactory.eINSTANCE.createWorkflowSuccessState();
}
</pre>
<p>This will print the value of the first parameter assigned to the task.  Before you can run the workflow, you must model the parameter, and give it a value in the runtime model.</p>
<ol>
<li>Launch the runtime workbench</li>
<li>Open the workflow model in the ecore editor</li>
<li>Create a new <strong>Workflow Parameter</strong> as a child of Task</li>
<li>Set the parameter name to <strong>Message</strong></li>
<li>Set the parameter type to <strong>EString</strong></li>
<li>Create a new <strong>Parameter Simple Value Strategy </strong>as a child of the Workflow Parameter</li>
<li>Open the runtime model in the ecore editor</li>
<li>Load Resource &#8230; <strong>platform:/resource/test/My.workflow</strong></li>
<li>Create a new <strong>Workflow Parameter Map</strong> as a child of WorkflowContext</li>
<li>Select <strong>Parameter Message</strong> as the key</li>
<li>Create a new <strong>Simple Any Type</strong> as a child of the workflow parameter map</li>
<li>Set the Instance Type to <strong>EString</strong></li>
<li>Set the Value to &#8220;That was easy&#8221;</li>
<li>Run the workflow and &#8220;That was easy&#8221; will print to the host Console</li>
</ol>
<p><img class="aligncenter size-full wp-image-269" title="Eclipse 6" src="http://bryanhunt.files.wordpress.com/2009/08/eclipse-6.png?w=563&#038;h=422" alt="Eclipse 6" width="563" height="422" /></p>
<p><img class="aligncenter size-full wp-image-270" title="Eclipse 7" src="http://bryanhunt.files.wordpress.com/2009/08/eclipse-7.png?w=646&#038;h=503" alt="Eclipse 7" width="646" height="503" /></p>
<h2>Future Direction</h2>
<p>This tutorial will eventually be moved into on-line documentation as part of the project.  The workflow model uses an explicit <a href="http://en.wikipedia.org/wiki/Visitor_pattern" target="_blank">visitor pattern</a> for some utility functions.  The switch object generated by EMF can be used as a visitor and I will probably look at using the switch object instead of the explicit visitor.  There is a need for the ability to run the tasks of a workflow on a distributed system.  I will be looking at adding the ability to suspend a workflow execution and transfer it to another machine for continued execution.  Finally, as you have seen from this tutorial, composing a workflow with the generated EMF editor is painful and a custom, structured, editor would make this easier.  Ultimately, I would like to have a graphical editor for visualizing and composing a workflow.  If there is any interest in contributing to this project, please contact me.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bryanhunt.wordpress.com/208/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bryanhunt.wordpress.com/208/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bryanhunt.wordpress.com/208/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bryanhunt.wordpress.com/208/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bryanhunt.wordpress.com/208/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bryanhunt.wordpress.com/208/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bryanhunt.wordpress.com/208/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bryanhunt.wordpress.com/208/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bryanhunt.wordpress.com/208/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bryanhunt.wordpress.com/208/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&blog=7500940&post=208&subd=bryanhunt&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://bryanhunt.wordpress.com/2009/08/24/emf-workflow-model/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/96518750aa70c5f4794c5f074ac0dd93?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">bryanhunt</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/08/workflow.png" medium="image">
			<media:title type="html">Workflow</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/08/orchestration2.png" medium="image">
			<media:title type="html">Orchestration</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/08/runtime1.png" medium="image">
			<media:title type="html">Runtime</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/08/state.png" medium="image">
			<media:title type="html">State</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/08/eclipse.png" medium="image">
			<media:title type="html">Eclipse</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/08/eclipse-9.png" medium="image">
			<media:title type="html">Eclipse 9</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/08/eclipse-2.png" medium="image">
			<media:title type="html">Eclipse 2</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/08/eclipse-4.png" medium="image">
			<media:title type="html">Eclipse 4</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/08/run-configurations.png" medium="image">
			<media:title type="html">Run Configurations</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/08/eclipse-51.png" medium="image">
			<media:title type="html">Eclipse 5</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/08/eclipse-6.png" medium="image">
			<media:title type="html">Eclipse 6</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/08/eclipse-7.png" medium="image">
			<media:title type="html">Eclipse 7</media:title>
		</media:content>
	</item>
		<item>
		<title>Native 2D Rendering In An Eclipse View Using OpenGL</title>
		<link>http://bryanhunt.wordpress.com/2009/07/27/native-2d-rendering-in-an-eclipse-view-using-opengl/</link>
		<comments>http://bryanhunt.wordpress.com/2009/07/27/native-2d-rendering-in-an-eclipse-view-using-opengl/#comments</comments>
		<pubDate>Mon, 27 Jul 2009 14:00:55 +0000</pubDate>
		<dc:creator>bryanhunt</dc:creator>
				<category><![CDATA[Eclipse]]></category>

		<guid isPermaLink="false">http://bryanhunt.wordpress.com/?p=148</guid>
		<description><![CDATA[I&#8217;ve been learning how to render graphics in an Eclipse view using OpenGL by putting together (hacking) bits and pieces from various articles I&#8217;ve found on the web.  I have enough working to share what I&#8217;ve learned and show you how to natively draw basic 2D graphics.  The end result will look like this &#8230;

SWT provides [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&blog=7500940&post=148&subd=bryanhunt&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I&#8217;ve been learning how to render graphics in an Eclipse view using OpenGL by putting together (hacking) bits and pieces from various articles I&#8217;ve found on the web.  I have enough working to share what I&#8217;ve learned and show you how to natively draw basic 2D graphics.  The end result will look like this &#8230;</p>
<p><img class="aligncenter size-full wp-image-154" title="End Result" src="http://bryanhunt.files.wordpress.com/2009/07/end-result2.png?w=963&#038;h=691" alt="End Result" width="963" height="691" /></p>
<p>SWT provides a <strong>GLCanvas</strong> widget for displaying graphics rendered using OpenGL but does not provide the JNI code that interfaces to the OpenGL library to actually draw the graphics.  <a href="http://www.lwjgl.org/" target="_blank">LWJGL</a> is a JNI library that interfaces to OpenGL and can be installed as an Eclipse bundle from the <a href="http://lwjgl.org/update" target="_blank">LWJGL update site</a>.  Another option is to write your own JNI to interface to OpenGL and do the rendering natively.  I have chosen the later path since LWJGL is not available for all platforms and I had a use-case where I needed to interface to an existing C library to retrieve the data to be rendered.  Writing the JNI is not all that hard as there are only a couple of functions that are needed to do basic rendering.</p>
<p>Let&#8217;s start by creating a new C++ project called <strong>com.example.opengl.native</strong>.  Set the <strong>Project type</strong> to <strong>Shared Library -&gt; Empty Project</strong> and <strong>Toolchains</strong> to <strong>MacOSX GCC</strong>.</p>
<p><img class="aligncenter size-full wp-image-160" title="C++ Project" src="http://bryanhunt.files.wordpress.com/2009/07/c-project.png?w=605&#038;h=712" alt="C++ Project" width="605" height="712" />After the project is created, bring up the project properties.  We need to tell the linker where to fine the OpenGL library, and the compiler where to find the JNI and OpenGL headers.  Navigate to the <strong>C/C++ Build -&gt; Settings</strong> section and under <strong>MacOS X C++ Linker -&gt; Miscellaneou</strong>s settings, add <strong>-framework OpenGL</strong> to the <strong>Linker flags</strong>.  The -framework option is a OS X specific GCC option that tells the linker which OS X frameworks (shared libraries) to link against.  If you are not using OS X, then add the appropriate -L and -l settings for your platform under the <strong>Libraries</strong> section.</p>
<p><img class="aligncenter size-full wp-image-161" title="Linker Flags" src="http://bryanhunt.files.wordpress.com/2009/07/linker-flags.png?w=850&#038;h=303" alt="Linker Flags" width="850" height="303" /></p>
<p>Next, in the <strong>GCC C++ Compiler -&gt; Directories </strong>settings add <strong>/System/Library/Frameworks/JavaVM.framework/Headers </strong>and <strong>/System/Library/Frameworks/OpenGL.framework</strong> as part of the include paths.  For other platforms add the appropriate directories containing the JRE and OpenGL header files.</p>
<p><strong><img class="aligncenter size-full wp-image-162" title="Header Dirs" src="http://bryanhunt.files.wordpress.com/2009/07/header-dirs.png?w=852&#038;h=372" alt="Header Dirs" width="852" height="372" /></strong></p>
<p>Finally, switch to the <strong>Build Artifact</strong> tab and change the <strong>Artifact name</strong> to <strong>opengl</strong> and the <strong>Artifact extensio</strong>n to <strong>jnilib</strong>.  Shared libraries in OS X typically have the extension .dylib; however, JNI libraries have a special .jnilib extension.  For other platforms, the default shared library extension is probably fine for JNI (.so for Linux as an example).</p>
<p><img class="aligncenter size-full wp-image-163" title="Build Artifacts" src="http://bryanhunt.files.wordpress.com/2009/07/build-artifacts.png?w=851&#038;h=291" alt="Build Artifacts" width="851" height="291" /></p>
<p>Now, let&#8217;s create a plug-in project called <strong>com.example.opengl</strong>.  You do not need to create an activator for this bundle.  First, we are going to create a class to hold the native functions that interface to OpenGL.</p>
<pre class="brush: java;">
package com.example.opengl;

public class OpenGL
{
	static
	{
		System.loadLibrary(&quot;opengl&quot;);
	}

	public static native void glClearColor(float red, float green, float blue, float alpha);
	public static native void glOrtho(double left, double right, double bottom, double top, double near, double far);
	public static native void glTranslatef(float x, float y, float z);
	public static native void glViewport(int x, int y, int width, int height);

	public static native void init2D();
}
</pre>
<p>Once we have the native functions declared, we need to create the corresponding header (.h) file in the C++ project using the javah program that comes with the JDK.  You can do this right from Eclipse by creating an external program launch configuration.  Set up the launch configuration on the <strong>Main</strong> tab as follows:</p>
<ul>
<li>Name: OpenGL JNI</li>
<li>Location: ${system_path:javah}</li>
<li>Working directory: ${workspace_loc:com.example.opengl.native}</li>
<li>Arguments: -classpath ${workspace_loc:com.example.opengl/bin} com.example.opengl.OpenGL</li>
</ul>
<p><img class="aligncenter size-full wp-image-171" title="OpenGL JNI Main" src="http://bryanhunt.files.wordpress.com/2009/07/opengl-jni-main.png?w=906&#038;h=659" alt="OpenGL JNI Main" width="906" height="659" />On the <strong>Refresh</strong> tab, select <strong>Specific resources</strong>, click <strong>Specify Resources&#8230;</strong> and check <strong>com.example.opengl.native</strong>.  This will cause the C++ project to be refreshed after the header file is created.</p>
<p><img class="aligncenter size-full wp-image-172" title="OpenGL JNI Refresh" src="http://bryanhunt.files.wordpress.com/2009/07/opengl-jni-refresh.png?w=984&#038;h=575" alt="OpenGL JNI Refresh" width="984" height="575" /></p>
<p>Finally, click <strong>Run</strong> to execute javah and place the header file in the C++ project.  If you expand the C++ project in the Project Explorer, you will see that the header file <strong>com_example_opengl_OpenGL.h</strong> was created.  In the C++ project create a source file named <strong>com_example_opengl_OpenGL.cpp</strong>.</p>
<pre class="brush: cpp;">
#include &quot;com_example_opengl_OpenGL.h&quot;
#include &quot;gl.h&quot;

void JNICALL Java_com_example_opengl_OpenGL_glClearColor(JNIEnv* env, jclass clazz, jfloat red, jfloat green, jfloat blue, jfloat alpha)
{
  glClearColor(red, green, blue, alpha);
}

void JNICALL Java_com_example_opengl_OpenGL_glOrtho(JNIEnv* env, jclass clazz, jdouble left, jdouble right, jdouble bottom, jdouble top, jdouble near, jdouble far)
{
  glMatrixMode (GL_PROJECTION);
  glLoadIdentity();
  glOrtho(left, right, bottom, top, near, far);
  glMatrixMode (GL_MODELVIEW);
  glLoadIdentity();
}

void JNICALL Java_com_example_opengl_OpenGL_glTranslatef(JNIEnv* env, jclass clazz, jfloat x, jfloat y, jfloat z)
{
  glTranslatef(x, y, z);
}

void JNICALL Java_com_example_opengl_OpenGL_glViewport(JNIEnv* env, jclass clazz, jint x, jint y, jint width, jint height)
{
  glViewport(x, y, width, height);
}

void JNICALL Java_com_example_opengl_OpenGL_init2D(JNIEnv* env, jclass clazz)
{
  glDisable(GL_DEPTH_TEST);
}
</pre>
<p>As you can see, the implementation of the JNI is almost a 1:1 mapping to the OpenGL API.  I did a little extra work in <strong>glOrtho()</strong> which you could break out into separate functions if you prefer.  Now, let&#8217;s create the native rendering engine to draw a rectangle in OpenGL.</p>
<pre class="brush: java;">
package com.example.opengl;

public class RenderEngine
{
	public native void draw();
}
</pre>
<p>Just like you did for the OpenGL class, create an external program launch configuration to run javah and create the header file in the C++ project.  Set up the launch configuration on the <strong>Main</strong> tab as follows:</p>
<ul>
<li>Name: RenderEngine JNI</li>
<li>Location: ${system_path:javah}</li>
<li>Working directory: ${workspace_loc:com.example.opengl.native}</li>
<li>Arguments: -classpath ${workspace_loc:com.example.opengl/bin} com.example.opengl.RenderEngine</li>
</ul>
<p><img class="aligncenter size-full wp-image-179" title="RenderEngine JNI Main" src="http://bryanhunt.files.wordpress.com/2009/07/renderengine-jni-main.png?w=860&#038;h=673" alt="RenderEngine JNI Main" width="860" height="673" />Click <strong>Run</strong> and the <strong>com_example_opengl_RenderEngine.h</strong> header file will be generated in the C++ project.  Switch to the C++ project and implement the <strong>draw()</strong> function by creating the source file <strong>com_example_opengl_RenderEngine.cpp</strong>.  The implementation draws a series of lines to form a rectangle.  I&#8217;ll explain the negative y axis in a minute.  This is all of the native code so you can build the C++ project which will result in a <strong>libopengl.jnilib</strong> in the <strong>Debug</strong> folder.</p>
<pre class="brush: cpp;">
#include &quot;com_example_opengl_RenderEngine.h&quot;
#include &quot;gl.h&quot;

void JNICALL Java_com_example_opengl_RenderEngine_draw(JNIEnv* env, jobject object)
{
  glClear(GL_COLOR_BUFFER_BIT);
  glColor3ub(255, 255, 255);
  glBegin(GL_LINE_LOOP);
  {
    glVertex2d(10, -10);
    glVertex2d(150, -10);
    glVertex2d(150, -40);
    glVertex2d(10, -40);
  }
  glEnd();
}
</pre>
<p>Now that we have code that interfaces to OpenGL and draws a rectangle, let&#8217;s put it all together in an Eclipse view.  In the Java plug-in project, create a new extension selecting <strong>org.eclipse.ui.views</strong> as the extension point.  Set the following fields in the extension:</p>
<ul>
<li>id: com.example.opengl.view</li>
<li>class: com.example.opengl.OpenGLView</li>
<li>name: OpenGL</li>
</ul>
<p>Implement the OpenGLView as:</p>
<pre class="brush: java;">
package com.example.opengl;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.opengl.GLCanvas;
import org.eclipse.swt.opengl.GLData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.part.ViewPart;

public class OpenGLView extends ViewPart
{
	@Override
	public void createPartControl(Composite parent)
	{
		parent.setLayout(new FillLayout());
		GLData glData = new GLData();
		glData.doubleBuffer = true;
		canvas = new GLCanvas(parent, SWT.H_SCROLL | SWT.V_SCROLL, glData);
		canvas.getHorizontalBar().setMaximum(2000);
		canvas.getVerticalBar().setMaximum(2000);

		renderEngine = new RenderEngine();

		Display.getDefault().asyncExec(new Runnable()
		{
			public void run()
			{
				canvas.setCurrent();
				OpenGL.init2D();
				OpenGL.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
			}
		});

		canvas.addControlListener(new ControlAdapter()
		{

			@Override
			public void controlResized(ControlEvent e)
			{
				redraw();
			}
		});

		canvas.getHorizontalBar().addSelectionListener(new SelectionAdapter()
		{
			@Override
			public void widgetSelected(SelectionEvent e)
			{
				redraw();
			}
		});

		canvas.getVerticalBar().addSelectionListener(new SelectionAdapter()
		{
			@Override
			public void widgetSelected(SelectionEvent e)
			{
				redraw();
			}
		});
	}

	@Override
	public void setFocus()
	{
		canvas.setFocus();
	}

	private void redraw()
	{
		Display.getDefault().asyncExec(new Runnable()
		{
			public void run()
			{
				Rectangle bounds = canvas.getClientArea();
				canvas.setCurrent();
				int xOffset = canvas.getHorizontalBar().getSelection();
				int yOffset = canvas.getVerticalBar().getSelection();
				OpenGL.glViewport(bounds.x, bounds.y, bounds.width, bounds.height);
				OpenGL.glOrtho(bounds.x + xOffset, bounds.width + xOffset, -bounds.height - yOffset, bounds.y - yOffset, 0.0, 1.0);
				OpenGL.glTranslatef(0.375f, 0.375f, 0.0f);
				renderEngine.draw();
				canvas.swapBuffers();
			}
		});
	}

	private GLCanvas canvas;
	private RenderEngine renderEngine;
}
</pre>
<p>Notice that all of the calls to OpenGL are made inside a <strong>Display.getDefault().asyncExec()</strong> call.  Why is this necessary when the code is already running in the UI thread?  This is the one thing that I don&#8217;t understand in this example.  If anyone has an explanation, please comment and I&#8217;ll update the entry.  The call to <strong>OpenGL.glViewport()</strong> is only necessary when the view is resized &#8211; it was just easier to have one <strong>redraw()</strong> function.  The call to <strong>OpenGL.glOrtho()</strong> does most of the interesting work.  It sets the orthographic projection of the 3D space into 2D space which translates to pan, zoom, and the axes origin and orientation in 2D.  The arguments to the function are: left, right, bottom, top, near, and far.  I will discuss each of the arguments in detail, but first, a word on the axes origin and orientation.</p>
<p>OpenGL by default orients the axes with positive x to the right, negative x to the left, positive y up, negative y down, positive z out of the display, and negative z into the display.  By specifying positive or negative values for the arguments to <strong>glOrtho()</strong>, you can change the orientation of the axes.  The absolute values of the arguments specify the location of the origin.  I&#8217;ve set the axes origin to be the upper left corder of the canvas (view), and it is oriented such that positive x is to the right and negative y is down.  It is possible to orient the axes such that positive y is down making 2D drawing match what you are used to but when I tried this, text rendered using GLUT was upside down.  Rather than trying to figure out if there was a way to flip the text, I found it much easier to draw in negative y.  I set the scale to be 1:1 in pixels, meaning that if the canvas is 1000 pixels wide, drawing at x = 1000 will draw on the right edge of the canvas.  Now, let&#8217;s look at the <strong>glOrtho()</strong> arguments:</p>
<p><strong>Left: bounds.x + xOffset</strong></p>
<p>This argument sets the left clipping plane which effectively sets the origin of the x axis relative to the left edge of the viewport.  The xOffset takes into account the position of the horizontal scrollbar.  If the scrollbar is all the way to the left, then you will see what was drawn starting at x = 0 and extending into positive x.</p>
<p><strong>Right: bounds.width + xOffset</strong></p>
<p>This argument sets the right clipping plane which effectively sets the x scale relative to the viewport.  The xOffset takes into account the position of the horizontal scrollbar so that the scale doesn&#8217;t change when you pan.  If the scrollbar is all the way to the left, then you will see what was drawn from x = 0 to x = bounds.width.</p>
<p><strong>Bottom: -bounds.height &#8211; yOffset</strong></p>
<p>This argument sets the bottom clipping plane which effectively sets the y scale relative to the viewport.  The yOffset takes into account the position of the vertical scrollbar so that the scale doesn&#8217;t change when you pan.  If the scrollbar is all the way to the top, then you will see what was drawn from y = 0 to y = -bounds.height.</p>
<p><strong>Top: bounds.y &#8211; yOffset</strong></p>
<p>This argument sets the top clipping plane which effectively sets the origin of the y axis relative to the top edge of the viewport.  The yOffset takes into account the position of the vertical scrollbar.  If the scrollbar is all the way to the top, then you will see what was drawn starting at y = 0 and extending into negative y.</p>
<p><strong>Near: 0.0</strong></p>
<p><strong>Far: 1.0</strong></p>
<p>These arguments set the values of the near and far clipping planes.  Since the z axis is not used in 2D, the examples I found all set the near clipping plane to 0.0, and the fat clipping plane to 1.0.</p>
<p>As you move the scrollbar to the right, both the left and right clipping planes move which pans the drawn area in the x axis.  As you move the scrollbar to the bottom, both the top and bottom clipping planes move which pans the drawn area in the y axis.  One thing I have not done in this example is to take into account the size of the scrollbar thumb.  You may have to adjust the right and bottom arguments to <strong>glOrtho()</strong> taking into account <strong>scrollbar.getThumb()</strong>.</p>
<p>The call to <strong>OpenGL.glTranslatef(0.375f, 0.375f, 0.0f)</strong> is a &#8220;trick&#8221; necessary to make your drawing pixel accurate.  Try drawing a line from (0, -10) to (10, -10) and a line from (0, -20) to (0, -30) without the call to <strong>glTranslate()</strong>.  The result will not be what you expect.</p>
<p>Before we can launch the Eclipse runtime workbench, we need to hook the JNI library into the plug-in.  We are going to bundle the native library with the plug-in so that it can be delivered as a single unit.  In the plug-in project, create a <strong>lib</strong> folder at the root of the project.  Copy the <strong>libopengl.jnilib</strong> file from the <strong>Debug</strong> folder in the C++ project to the <strong>lib</strong> folder in the plug-in project.  Edit the <strong>build.properties</strong> to include the newly created <strong>lib</strong> folder along with its contents.  Finally, edit the <strong>MANIFEST.MF</strong> of the plug-in project and using the source tab of the editor, add the line:</p>
<p><strong> Bundle-NativeCode: lib/libopengl.jnilib; osname=macosx; processor=x86</strong></p>
<p>This tells the class loader where to find the native library when System.loadLibrary() is called.  Now, we can create an Eclipse Application launch configuration to run the runtime workbench.  You can use the defaults for the launch configuration.  After you launch the runtime workbench, select <strong>Window -&gt; Show View -&gt; Other&#8230;</strong> and under the <strong>Other</strong> category, select the <strong>OpenGL</strong> view and click <strong>OK</strong>.  You should see the view with a white rectangle drawn on a black background just like the first screenshot above.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bryanhunt.wordpress.com/148/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bryanhunt.wordpress.com/148/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bryanhunt.wordpress.com/148/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bryanhunt.wordpress.com/148/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bryanhunt.wordpress.com/148/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bryanhunt.wordpress.com/148/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bryanhunt.wordpress.com/148/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bryanhunt.wordpress.com/148/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bryanhunt.wordpress.com/148/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bryanhunt.wordpress.com/148/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&blog=7500940&post=148&subd=bryanhunt&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://bryanhunt.wordpress.com/2009/07/27/native-2d-rendering-in-an-eclipse-view-using-opengl/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/96518750aa70c5f4794c5f074ac0dd93?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">bryanhunt</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/07/end-result2.png" medium="image">
			<media:title type="html">End Result</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/07/c-project.png" medium="image">
			<media:title type="html">C++ Project</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/07/linker-flags.png" medium="image">
			<media:title type="html">Linker Flags</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/07/header-dirs.png" medium="image">
			<media:title type="html">Header Dirs</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/07/build-artifacts.png" medium="image">
			<media:title type="html">Build Artifacts</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/07/opengl-jni-main.png" medium="image">
			<media:title type="html">OpenGL JNI Main</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/07/opengl-jni-refresh.png" medium="image">
			<media:title type="html">OpenGL JNI Refresh</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/07/renderengine-jni-main.png" medium="image">
			<media:title type="html">RenderEngine JNI Main</media:title>
		</media:content>
	</item>
		<item>
		<title>Running Rational Team Concert (Jazz) on Eclipse 3.5 / Mac OS X</title>
		<link>http://bryanhunt.wordpress.com/2009/07/02/running-rational-team-concert-jazz-on-eclipse-3-5-mac-os-x/</link>
		<comments>http://bryanhunt.wordpress.com/2009/07/02/running-rational-team-concert-jazz-on-eclipse-3-5-mac-os-x/#comments</comments>
		<pubDate>Thu, 02 Jul 2009 18:22:16 +0000</pubDate>
		<dc:creator>bryanhunt</dc:creator>
				<category><![CDATA[Eclipse]]></category>

		<guid isPermaLink="false">http://bryanhunt.wordpress.com/?p=125</guid>
		<description><![CDATA[Rational Team Concert 2.0 has been released. With a little work, you can get the client running on Eclipse 3.5 and the server running on Mac OS X.
Server
The Jazz team does not officially support running the server on OS X, and a download that runs on OS X out-of-the-box is not available.  With a couple [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&blog=7500940&post=125&subd=bryanhunt&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a href="http://jazz.net" target="_blank">Rational Team Concert</a> 2.0 has been released. With a little work, you can get the client running on Eclipse 3.5 and the server running on Mac OS X.</p>
<h2>Server</h2>
<p><span style="font-weight:normal;font-size:13px;">The Jazz team does not officially support running the server on OS X, and a download that runs on OS X out-of-the-box is not available.  With a couple of minor modifications, the Linux server download will run on OS X just fine.</span></p>
<ol>
<li>Download the <a href="https://jazz.net/downloads/rational-team-concert/releases/2.0/RTC-ExpressC-Server-2.0-Linux32.zip" target="_blank">Express C Server for Linux</a>.</li>
<li>Unzip the download</li>
<li>Launch the Terminal</li>
<li><strong>cd jazz/server</strong></li>
<li><strong>rm -rf jre</strong> (the Linux JRE is obviously not needed on OS X)</li>
<li>Edit <strong>tomcat/conf/server.xml</strong>.  You need to modify the Connector specification for port 9443.  Search for <strong>SSL_TLS</strong> and change it to <strong>TLS</strong>.  Also change the next line from <strong>IbmX509</strong> to <strong>SunX509</strong>.  The resulting Connector specification should look like:</li>
<pre class="brush: xml;">
&lt;Connector port=&quot;9443&quot;
               connectionTimeout=&quot;20000&quot;
               maxHttpHeaderSize=&quot;8192&quot;
               maxThreads=&quot;150&quot;
               minSpareThreads=&quot;25&quot;
               maxSpareThreads=&quot;75&quot;
               enableLookups=&quot;false&quot;
               disableUploadTimeout=&quot;true&quot;
               acceptCount=&quot;100&quot;
               scheme=&quot;https&quot;
               secure=&quot;true&quot;
               clientAuth=&quot;false&quot;
               keystoreFile=&quot;ibm-team-ssl.keystore&quot;
               keystorePass=&quot;ibm-team&quot;
               sslProtocol=&quot;TLS&quot;
			   algorithm=&quot;SunX509&quot;
			   URIEncoding=&quot;UTF-8&quot; /&gt;
</pre>
<li>Edit <strong>server.startup</strong> and <strong>server.shutdown</strong> changing JRE_HOME from <strong>`pwd`/jre</strong> to <strong>/System/Library/Frameworks/JavaVM.framework/Home</strong></li>
<li>While editing <strong>server.startup</strong> add <strong>-XX:MaxPermSize=256m</strong> to <strong>JAVA_OPTS</strong></li>
<li>Launch the server <strong>./server.startup</strong></li>
</ol>
<p>If you want to make sure the server started correctly, you can <strong>tail -f tomcat/logs/catalina.out</strong> and watch the server startup.  If you see any exceptions thrown, something went wrong.  If all goes well, the last message you see in the log should be:</p>
<p>INFO: Server startup in xxxxx ms</p>
<p>To get started right away, launch Safari and point it to <a href="https://localhost:9443/jazz" target="_blank">https://localhost:9443/jazz</a> login with User: <strong>ADMIN</strong> and Password: <strong>ADMIN</strong>.  You can use this admin account to create a personalized account.  Don&#8217;t forget to give yourself a Developer license.</p>
<h2>Client</h2>
<p><strong>These instructions are not specific to Mac OS X &#8211; they should work for any OS.</strong></p>
<p><strong></strong>The Jazz team does support a <a href="https://jazz.net/downloads/rational-team-concert/releases/2.0/RTC-Client-2.0-Mac.zip" target="_blank">Mac OS X Client</a> as an incubator project, but the client is based on Eclipse 3.4.  You can download the client and get the jazz bundles to work in an Eclipse 3.5 environment.   The Jazz client has dependencies on the following features:</p>
<ul>
<li><a href="http://www.eclipse.org/emf" target="_blank">EMF, XSD, SDO</a></li>
<li><a href="http://www.eclipse.org/gef" target="_blank">GEF</a></li>
<li><a href="http://www.eclipse.org/datatools" target="_blank">DTP</a></li>
</ul>
<p>With the exception of SDO, all of the features can be installed from the Galileo update site.  To get SDO, add the <a href="http://download.eclipse.org/modeling/emf/updates/releases/" target="_blank">EMF releases update site</a> and install the SDO runtime from the EMF 2.4.2 release.</p>
<p>From the downloaded client, move all of the sub-folders in <strong>jazz/client/eclipse/jazz</strong> to your Eclipse 3.5 <strong>dropins</strong> folder.  You could use P2 to install the contents of those sub-folders; however, you must manually check every bundle to be installed.  I&#8217;d rather spend 10 seconds doing a drag-and-drop rather than 15 minutes checking checkboxes.</p>
<p>After you launch the client, you should be able to open the Team Artifacts view and create a connection to the repository at <a href="https://localhost:9443/jazz" target="_blank">https://localhost:9443/jazz</a></p>
<h2>Next Steps</h2>
<p>See the <a href="http://jazz.net" target="_blank">Jazz</a> web site for tutorials on getting started.</p>
<p><strong>Update:</strong> Added -XX:MaxPermSize=256m to the server instructions</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bryanhunt.wordpress.com/125/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bryanhunt.wordpress.com/125/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bryanhunt.wordpress.com/125/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bryanhunt.wordpress.com/125/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bryanhunt.wordpress.com/125/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bryanhunt.wordpress.com/125/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bryanhunt.wordpress.com/125/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bryanhunt.wordpress.com/125/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bryanhunt.wordpress.com/125/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bryanhunt.wordpress.com/125/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&blog=7500940&post=125&subd=bryanhunt&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://bryanhunt.wordpress.com/2009/07/02/running-rational-team-concert-jazz-on-eclipse-3-5-mac-os-x/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/96518750aa70c5f4794c5f074ac0dd93?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">bryanhunt</media:title>
		</media:content>
	</item>
		<item>
		<title>Remote declarative OSGi services</title>
		<link>http://bryanhunt.wordpress.com/2009/06/20/remote-declarative-osgi-services/</link>
		<comments>http://bryanhunt.wordpress.com/2009/06/20/remote-declarative-osgi-services/#comments</comments>
		<pubDate>Sat, 20 Jun 2009 22:47:37 +0000</pubDate>
		<dc:creator>bryanhunt</dc:creator>
				<category><![CDATA[Eclipse]]></category>

		<guid isPermaLink="false">http://bryanhunt.wordpress.com/?p=65</guid>
		<description><![CDATA[My last post on OSGi services showed how you can dynamically configure OSGi services using the ConfigurationAdmin service.  I used an example where I configured a service to create a JDBC connection.  JDBC connections are often made on a server, and it would be nice to be able to do your configuration remotely.  This post will show [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&blog=7500940&post=65&subd=bryanhunt&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>My last <a title="Dynamically configured declarative OSGi services" href="http://bryanhunt.wordpress.com/2009/04/30/dynamically-configured-declarative-osgi-services/" target="_blank">post</a> on OSGi services showed how you can dynamically configure OSGi services using the <em>ConfigurationAdmin</em> service.  I used an example where I configured a service to create a JDBC connection.  JDBC connections are often made on a server, and it would be nice to be able to do your configuration remotely.  This post will show you how you can use <a title="OSGi 4.2 early draft" href="http://www.osgi.org/download/osgi-4.2-early-draft.pdf" target="_blank">RFC 119</a> to make remote OSGi service calls to configure the JDBC connection on a server.</p>
<p>There are two implementations of RFC 119: <a href="http://cxf.apache.org/" target="_blank">Apache CXF</a>, and <a href="http://www.eclipse.org/ecf/" target="_blank">ECF</a>.  I&#8217;m using ECF for this example.  This example also uses <a href="http://www.apple.com/support/bonjour/" target="_blank">Bonjour</a> (<a href="http://www.zeroconf.org/" target="_blank">Zeroconf</a>) for service discovery.  This means that the client and server must be running on the same local subnet for the client to discover the services advertised by the server.  ECF also supports <a href="http://www.ietf.org/rfc/rfc2608.txt" target="_blank">SLP</a> for service discovery, but like Bonjour is limited to the local subnet.  ECF allows you to plug in your own discovery provider, and I have done just that to support discovery across a WAN.  Look for a future blog post describing how to create your own ECF discovery provider.</p>
<h2>Service Interface</h2>
<p>Lets start by creating our remote service interface:</p>
<ol>
<li>Create a new plug-in project <strong>com.example.database.admin</strong></li>
<li>Create a new interface <strong>IDatabaseAdminService</strong></li>
</ol>
<pre class="brush: java;">
package com.example.database.admin;

import java.util.Dictionary;

public interface IDatabaseAdminService
{
	public void createConnection(Dictionary&lt;String, String&gt; connectionConfig);
}
</pre>
<h2>Service Implementation</h2>
<p>Create an implementation of IDatabaseAdminService.  The implementation creates a <em>Configuration</em> using the <em>ConfigurationAdmin</em> service.</p>
<pre class="brush: java;">
package com.example.database;

import java.io.IOException;
import java.util.Dictionary;

import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;

import com.example.database.admin.IDatabaseAdminService;

public class DatabaseAdminService implements IDatabaseAdminService
{
	public synchronized void createConnection(Dictionary&lt;String, String&gt; connectionConfig)
	{
		try
		{
			Configuration config = null;

			if (configAdmin != null)
				config = configAdmin.createFactoryConfiguration(&quot;com.example.database.connection&quot;, null);

			if (config != null)
				config.update(connectionConfig);
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}

	protected synchronized void bind(ConfigurationAdmin configAdmin)
	{
		this.configAdmin = configAdmin;
	}

	protected synchronized void unbind(ConfigurationAdmin configAdmin)
	{
		if (this.configAdmin == configAdmin)
			this.configAdmin = null;
	}

	private ConfigurationAdmin configAdmin;
}
</pre>
<h2>Declare the Admin Service</h2>
<p>Now that we have a service, let&#8217;s declare it:</p>
<ol>
<li>Create a new <strong>Component Definition</strong></li>
<li>Set File name: <strong>admin.xml</strong></li>
<li>Set name: <strong>com.example.database.admin</strong></li>
<li>Set Class: <strong>com.example.database.DatabaseAdminService</strong></li>
</ol>
<p>Using the Component Definition editor, we need to set a service property <strong>osgi.remote.interfaces=*</strong>.  This property tells the RFC 119 implementation to make all declared interfaces available remotely.</p>
<p><strong><img class="aligncenter size-full wp-image-99" title="Component Overview" src="http://bryanhunt.files.wordpress.com/2009/06/component-overview.png?w=748&#038;h=538" alt="Component Overview" width="748" height="538" /></strong></p>
<p>Next, on the services tab, add a dependency on the <em>ConfigurationAdmin</em> service, and declare the <em>IDatabaseAdminService</em>.  Don&#8217;t for get to set the bind and unbind functions on the referenced <em>ConfigurationAdmin</em> service.</p>
<p><img class="aligncenter size-full wp-image-100" title="Component Services" src="http://bryanhunt.files.wordpress.com/2009/06/component-services.png?w=748&#038;h=536" alt="Component Services" width="748" height="536" /></p>
<h2>Initialize the ECF Container</h2>
<p>ECF does much more than implement RFC 119, so in order to use distributed services, you must create an instance of the <strong>ecf.r_osgi.peer</strong> container.  This should be done in its own bundle since it is necessary on both the client and server.</p>
<ol>
<li>Create a new <strong>Plug-in Project</strong></li>
<li>Create an <strong>Activator</strong> for the bundle</li>
</ol>
<pre class="brush: java;">
package com.example.services.init;

import org.eclipse.ecf.core.ContainerCreateException;
import org.eclipse.ecf.core.IContainer;
import org.eclipse.ecf.core.IContainerManager;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;

/**
 * The activator class controls the plug-in life cycle
 */
public class Activator implements BundleActivator
{
	public void start(final BundleContext context) throws Exception
	{
		containerManagerTracker = new ServiceTracker(context, IContainerManager.class.getName(), new ServiceTrackerCustomizer()
		{
			public void removedService(ServiceReference reference, Object service)
			{
				if (container != null)
					container.disconnect();

				container = null;
			}

			public void modifiedService(ServiceReference reference, Object service)
			{}

			public Object addingService(ServiceReference reference)
			{
				try
				{
					IContainerManager containerManager = (IContainerManager) context.getService(reference);
					container = containerManager.getContainerFactory().createContainer(&quot;ecf.r_osgi.peer&quot;);
					return containerManager;
				}
				catch (ContainerCreateException e)
				{
					e.printStackTrace();
					return null;
				}
			}
		});

		containerManagerTracker.open();
	}

	public void stop(BundleContext context) throws Exception
	{
		containerManagerTracker.close();

		if (container != null)
			container.dispose();
	}

	private ServiceTracker containerManagerTracker;
	private IContainer container;
}
</pre>
<h2>Launch Server</h2>
<p>You can launch the server now, or wait until you have written the client code.  To launch the server:</p>
<ol>
<li>Create a new <strong>OSGi Framework</strong> launch configuration</li>
<li>Click <strong>Deselect All</strong></li>
<li>Uncheck <strong>Include optional dependencies when computing required bundles</strong></li>
<li>Uncheck <strong>Add new workspace bundles to this launch configuratin automatically</strong></li>
<li>Check <strong>com.example.database</strong></li>
<li>Check <strong>com.example.database.admin</strong></li>
<li>Check <strong>com.example.services.init</strong></li>
<li>Check <strong>ch.ethz.iks.r_osgi.remote</strong></li>
<li>Check <strong>org.eclipse.ecf.discovery</strong></li>
<li>Check <strong>org.eclipse.ecf.osgi.services</strong></li>
<li>Check <strong>org.eclipse.ecf.osgi.services.discovery</strong></li>
<li>Check <strong>org.eclipse.ecf.osgi.services.distribution</strong></li>
<li>Check <strong>org.eclipse.ecf.provider</strong></li>
<li>Check <strong>org.eclipse.ecf.provider.jmdns</strong></li>
<li>Check <strong>org.eclipse.ecf.provider.r_osgi</strong></li>
<li>Check <strong>org.eclipse.ecf.remoteservice</strong></li>
<li>Check <strong>org.eclipse.equinox.cm</strong></li>
<li>Check <strong>org.eclipse.equinox.ds</strong></li>
<li>Click <strong>Add Required Bundles</strong></li>
<li>Set the <strong>Start Level</strong> of <strong>org.eclipse.equinox.ds</strong> to 5</li>
<li>Set <strong>Auto-Start</strong> to true on <strong>org.eclipse.ecf.osgi.*</strong></li>
<li>Set <strong>Auto-Start</strong> to true on <strong>org.eclipse.ecf.provider.jmdns</strong></li>
<li>Set <strong>Auto-Start </strong>to true on <strong>org.eclipse.equinox.cm</strong></li>
<li>Set<strong> Auto-Start</strong> to true on <strong>org.eclipse.equinox.ds</strong></li>
</ol>
<p>You normally should not set the start level of <strong>org.eclipse.equinox.ds</strong>.  However, there is a start order dependency <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=277008" target="_blank">bug in ECF</a> that requires your services to be registered after the <strong>ecf.r_osgi.peer</strong> container, and a <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=276003" target="_blank">bug in declarative services</a> that requires <strong>DS</strong> to start after <strong>CM</strong>, so the easiest workaround is to set the start level of <strong>DS</strong> to 5 with a default start level of 4.  Your launch configuration should look something like:</p>
<p><img class="aligncenter size-full wp-image-104" title="Launch Config" src="http://bryanhunt.files.wordpress.com/2009/06/launch-config.png?w=811&#038;h=682" alt="Launch Config" width="811" height="682" /></p>
<p>After you launch the server, issue the command <strong>services (objectClass=com.example.database.admin.IDatabaseService)</strong>.  You should see the service listed twice.  Note that there are not really two instances of the service running.  One is a proxy created by ECF to handle the remote calls.</p>
<h2><img class="aligncenter size-full wp-image-105" title="Registered Services" src="http://bryanhunt.files.wordpress.com/2009/06/registered-services.png?w=809&#038;h=242" alt="Registered Services" width="809" height="242" /></h2>
<h2>Client</h2>
<p>Now we need to create the client code that will call the remote service.  To illustrate the power of RFC 119, let&#8217;s create the client code as a declared service itself that dynamically binds to the remote service.</p>
<ol>
<li>Create a new plug-in project <strong>com.example.database.client</strong></li>
<li>Check <strong>Activate this plug-in when one of its classes is loaded</strong></li>
<li>Create a new folder <strong>OSGI-INF</strong></li>
<li>Create a new <strong>Component Definition</strong></li>
<li>Create a new <em>ClientAdmin</em> class</li>
<li>Declare a dependency on <em>IDatabaseAdminService</em></li>
</ol>
<p><em><img class="aligncenter size-full wp-image-110" title="Client Component" src="http://bryanhunt.files.wordpress.com/2009/06/client-component.png?w=808&#038;h=258" alt="Client Component" width="808" height="258" /></em></p>
<p>Don&#8217;t forget to specify the bind and unbind functions for the referenced service.</p>
<p><em><img class="aligncenter size-full wp-image-111" title="Client Referenced Services" src="http://bryanhunt.files.wordpress.com/2009/06/client-referenced-services.png?w=807&#038;h=199" alt="Client Referenced Services" width="807" height="199" /></em></p>
<p>Here is the AdminClient:</p>
<pre class="brush: java;">
package com.example.database.client;

import java.util.Hashtable;

import org.osgi.service.component.ComponentContext;

import com.example.database.admin.IDatabaseAdminService;

public class AdminClient
{
	protected synchronized void activate(ComponentContext context)
	{
		if(adminService == null)
			return;

		Hashtable&lt;String, String&gt; properties = new Hashtable&lt;String, String&gt;();
		properties.put(&quot;database.id&quot;, &quot;example&quot;);
		properties.put(&quot;database&quot;, &quot;junit&quot;);
		properties.put(&quot;user&quot;, &quot;&quot;);
		properties.put(&quot;password&quot;, &quot;&quot;);
		properties.put(&quot;create&quot;, &quot;create&quot;);

		adminService.createConnection(properties);
		System.out.println(&quot;Database connection created&quot;);
	}

	protected synchronized void bind(IDatabaseAdminService adminService)
	{
		this.adminService = adminService;
	}

	protected synchronized void unbind(IDatabaseAdminService adminService)
	{
		if(this.adminService == adminService)
			this.adminService = null;
	}

	private IDatabaseAdminService adminService;
}
</pre>
<h2>Launch Client</h2>
<p>We can now launch the client:</p>
<ol>
<li><strong><span style="font-weight:normal;">Clone the Server launch configuration</span></strong></li>
<li>Uncheck <strong>com.example.database</strong></li>
<li>Check <strong>com.example.database.client</strong></li>
</ol>
<p><img class="aligncenter size-full wp-image-116" title="Client Launch" src="http://bryanhunt.files.wordpress.com/2009/06/client-launch.png?w=813&#038;h=686" alt="Client Launch" width="813" height="686" /></p>
<p>After launching the client and seeing &#8220;Database connection created&#8221; print to the console, switch over to the server console and type: <strong>services (objectClass=com.example.database.IDatabaseConnectionService)</strong> and you will see that the service was configured by the client and started.</p>
<p><img class="aligncenter size-full wp-image-117" title="Service Configured" src="http://bryanhunt.files.wordpress.com/2009/06/service-configured.png?w=807&#038;h=240" alt="Service Configured" width="807" height="240" /></p>
<p>What has happened here?  When the client started, ECF discovered the service advertised by the server and registered a proxy as if it were a local OSGi service.  The declarative services bundle saw the service and recognized that it was required by the client component.  The service proxy was dynamically bound to the client component by calling <em>bind(IDatabaseAdminService)</em>.  The client service was then activated by the declarative services bundle by calling <em>activate(ComponentContext)</em>.  The client then created a configuration and called <em>IDatabaseService.createConnection(Dictionary&lt;String, String&gt;)</em> which made a remote call to the service running on the server.  The server side service created a <em>Configuration</em> using the <em>ConfigurationAdmin</em> service.  The configuration of the service then caused the declarative services bundle on the server to create an instance of the <em>IDatabaseConnectionService</em>.  Pretty cool!</p>
<p><strong>Update:</strong> fixed a cut/paste problem with the source code.</p>
<p><strong>Update 8/23/09:</strong> There is a <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=248545" target="_blank">bug in ECF 3.0</a> that prevents more than one remote service from being discovered.  You may still use ECF 3.0, but will need to check out <strong>org.eclipse.ecf.provider.r_osgi</strong> from CVS to pick up the fix.  This fix will be released in ECF 3.1</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bryanhunt.wordpress.com/65/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bryanhunt.wordpress.com/65/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bryanhunt.wordpress.com/65/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bryanhunt.wordpress.com/65/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bryanhunt.wordpress.com/65/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bryanhunt.wordpress.com/65/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bryanhunt.wordpress.com/65/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bryanhunt.wordpress.com/65/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bryanhunt.wordpress.com/65/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bryanhunt.wordpress.com/65/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&blog=7500940&post=65&subd=bryanhunt&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://bryanhunt.wordpress.com/2009/06/20/remote-declarative-osgi-services/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/96518750aa70c5f4794c5f074ac0dd93?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">bryanhunt</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/06/component-overview.png" medium="image">
			<media:title type="html">Component Overview</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/06/component-services.png" medium="image">
			<media:title type="html">Component Services</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/06/launch-config.png" medium="image">
			<media:title type="html">Launch Config</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/06/registered-services.png" medium="image">
			<media:title type="html">Registered Services</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/06/client-component.png" medium="image">
			<media:title type="html">Client Component</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/06/client-referenced-services.png" medium="image">
			<media:title type="html">Client Referenced Services</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/06/client-launch.png" medium="image">
			<media:title type="html">Client Launch</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/06/service-configured.png" medium="image">
			<media:title type="html">Service Configured</media:title>
		</media:content>
	</item>
		<item>
		<title>Modeling SWT with EMF</title>
		<link>http://bryanhunt.wordpress.com/2009/06/10/modeling-swt-with-emf/</link>
		<comments>http://bryanhunt.wordpress.com/2009/06/10/modeling-swt-with-emf/#comments</comments>
		<pubDate>Wed, 10 Jun 2009 05:19:12 +0000</pubDate>
		<dc:creator>bryanhunt</dc:creator>
				<category><![CDATA[Eclipse]]></category>

		<guid isPermaLink="false">http://bryanhunt.wordpress.com/?p=80</guid>
		<description><![CDATA[My EMF Workflow Model is starting to take shape.  One of the next features I&#8217;d like to add is to make it easier to create and configure a workflow.  I was thinking it would be nice if the configuration editor was configurable without having to write a lot (if any) code.
I started playing around with [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&blog=7500940&post=80&subd=bryanhunt&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>My <a href="http://www.eclipsecon.org/2009/sessions?id=721" target="_blank">EMF Workflow Model</a> is starting to take shape.  One of the next features I&#8217;d like to add is to make it easier to create and configure a workflow.  I was thinking it would be nice if the configuration editor was configurable without having to write a lot (if any) code.</p>
<p>I started playing around with the idea of modeling SWT with EMF, and it actually seems to work nicely.  I&#8217;ve modeled about half of the SWT widgets and all of the layouts in EMF.  This <a href="http://idisk.mac.com/bhunt-Public/swt_emf.mov" target="_blank">screencast</a> shows an Eclipse view in which the contents are created from an EMF model, then I change the model and refresh the view to reflect the updated model.  The next step will be to figure out how to model databindings and connect them to a EMF Workflow Model.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bryanhunt.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bryanhunt.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bryanhunt.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bryanhunt.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bryanhunt.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bryanhunt.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bryanhunt.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bryanhunt.wordpress.com/80/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bryanhunt.wordpress.com/80/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bryanhunt.wordpress.com/80/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&blog=7500940&post=80&subd=bryanhunt&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://bryanhunt.wordpress.com/2009/06/10/modeling-swt-with-emf/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/96518750aa70c5f4794c5f074ac0dd93?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">bryanhunt</media:title>
		</media:content>
	</item>
		<item>
		<title>Catch the Wave</title>
		<link>http://bryanhunt.wordpress.com/2009/05/30/catch-the-wave/</link>
		<comments>http://bryanhunt.wordpress.com/2009/05/30/catch-the-wave/#comments</comments>
		<pubDate>Sun, 31 May 2009 03:44:59 +0000</pubDate>
		<dc:creator>bryanhunt</dc:creator>
				<category><![CDATA[Eclipse]]></category>

		<guid isPermaLink="false">http://bryanhunt.wordpress.com/?p=72</guid>
		<description><![CDATA[If you haven&#8217;t seen the Google Wave announcement, you need to crawl out of your cave and watch the demo.  This is by far the most impressive communication and collaboration tool I have ever seen.  Say good-bye to email, instant messaging, newsgroups, forums, wikis, and blogs as we know them.  All of these technologies are [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&blog=7500940&post=72&subd=bryanhunt&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>If you haven&#8217;t seen the <a href="http://wave.google.com" target="_blank">Google Wave</a> announcement, you need to crawl out of your cave and watch the demo.  This is by far the most impressive communication and collaboration tool I have ever seen.  Say good-bye to email, instant messaging, newsgroups, forums, wikis, and blogs as we know them.  All of these technologies are fundamentally a way to communicate and collaborate with others, and all have their strengths and weaknesses.  Wave seems to take all of the strengths of these tools and combines them into a seamless system.</p>
<blockquote><p>One Wave to rule them all, One Wave to find them, One Wave to bring them all and in the darkness bind them.</p></blockquote>
<p>Two questions came to mind as I watched the demo in awe:</p>
<ol>
<li>How can the <a href="http://www.eclipse.org" target="_blank">Eclipse</a> community use wave to better collaborate?</li>
<li>How can we integrate Wave into Eclipse?</li>
</ol>
<p>Imagine if the <a href="http://help.eclipse.org" target="_blank">Eclipse documentation</a> were a collaborative wave document.  Developers could contribute additional documentation, code examples, etc, and that information would be updated live for other developers.  Questions on newsgroups could be easily incorporated into the documentation, or into a FAQ.  Bugs could be opened from a newsgroup question by simply highlighting text and clicking a button.  I think the Wave protocols should be integrated into ECF, and Eclipse views and editors could be used to display and edit the Wave content.  The possibilities seem endless.</p>
<p>Most of all, I&#8217;d like to see some lively discussion by the Eclipse community on your ideas.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bryanhunt.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bryanhunt.wordpress.com/72/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bryanhunt.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bryanhunt.wordpress.com/72/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bryanhunt.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bryanhunt.wordpress.com/72/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bryanhunt.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bryanhunt.wordpress.com/72/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bryanhunt.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bryanhunt.wordpress.com/72/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&blog=7500940&post=72&subd=bryanhunt&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://bryanhunt.wordpress.com/2009/05/30/catch-the-wave/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/96518750aa70c5f4794c5f074ac0dd93?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">bryanhunt</media:title>
		</media:content>
	</item>
		<item>
		<title>Dynamically configured declarative OSGi services</title>
		<link>http://bryanhunt.wordpress.com/2009/04/30/dynamically-configured-declarative-osgi-services/</link>
		<comments>http://bryanhunt.wordpress.com/2009/04/30/dynamically-configured-declarative-osgi-services/#comments</comments>
		<pubDate>Thu, 30 Apr 2009 05:07:17 +0000</pubDate>
		<dc:creator>bryanhunt</dc:creator>
				<category><![CDATA[Eclipse]]></category>

		<guid isPermaLink="false">http://bryanhunt.wordpress.com/?p=3</guid>
		<description><![CDATA[I&#8217;m creating OSGi services and found the need to create one or more instances of a service that was registered with user configured parameters.  It&#8217;s fairly straightforward to do this with the ConfigurationAdmin service, a ManagedServiceFactory and context.registerService(), but I&#8217;ve recently become a declarative services convert and wanted to do all of this with declarative [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&blog=7500940&post=3&subd=bryanhunt&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I&#8217;m creating OSGi services and found the need to create one or more instances of a service that was registered with user configured parameters.  It&#8217;s fairly straightforward to do this with the <em>ConfigurationAdmin</em> service, a <em>ManagedServiceFactory</em> and <em>context.registerService()</em>, but I&#8217;ve recently become a declarative services convert and wanted to do all of this with declarative services.  It turns out that you still use the <em>ConfigurationAdmin</em> service, just not the <em>ManagedServiceFactory.</em> In this post, I will demonstrate how to create a dynamically configured declarative service.</p>
<h2><strong>Example Use-case</strong></h2>
<p><strong><span style="font-weight:normal;">Let&#8217;s say you are deploying an OSGi based server at multiple sites and your bundles need to access one or more databases using JDBC.  You create an OSGi service called <em>DatabaseConnectionService</em> that returns a JDBC <em><a title="Connection" href="http://java.sun.com/j2se/1.5.0/docs/api/java/sql/Connection.html" target="_blank">Connection</a><span style="font-style:normal;">.  To create the connection to the database, you need configuration information typically consisting of: hostname, port number, database, user id, and password.  Since this information can change, and will vary from site to site where your server is deployed, the configuration information needs to be dynamically updatable and persistable.</span></em></span></strong></p>
<p><strong><span style="font-weight:normal;"><em> </em></span></strong></p>
<p><strong> </strong></p>
<h2><strong>Development Environment</strong></h2>
<p><strong> </strong></p>
<p>You will need <a title="Eclipse Downloads" href="http://download.eclipse.org/eclipse/downloads/" target="_blank">Eclipse 3.5</a>, <a title="Equinox Download" href="http://download.eclipse.org/equinox/" target="_blank">Equinox</a>, and <a title="Download Apache Derby" href="http://apache.promopeddler.com/db/derby/db-derby-10.5.1.1/derby_core_plugin_10.5.1.764942.zip" target="_blank">Apache Derby</a> if you want to try this example on your own.  Create a <em>target</em> folder somewhere in your filesystem.  Extract the contents of the Equinox zip file into the <em>target</em> directory.  Create a <em>derby</em> folder as a child of <em>target</em> and extract the contents of the Derby zip into the <em>derby</em> folder.  The directory structure should look like:</p>
<div id="attachment_30" class="wp-caption aligncenter" style="width: 437px"><img class="size-full wp-image-30" title="Targets" src="http://bryanhunt.files.wordpress.com/2009/04/targets.png?w=427&#038;h=302" alt="Target platform directory structure" width="427" height="302" /><p class="wp-caption-text">Target platform directory structure</p></div>
<p>Launch Eclipse 3.5 and select <strong>Preferences -&gt; Plug-in Development -&gt; Target Platform</strong>.  We need to add Equinox and Derby to our target platform.  Select <strong>Running Platform</strong> and click <strong>Edit&#8230;</strong> Add the Equinox and Derby folders to your target platform.  Your target platform should look like:</p>
<div id="attachment_31" class="wp-caption aligncenter" style="width: 848px"><img class="size-full wp-image-31" title="Target Definition" src="http://bryanhunt.files.wordpress.com/2009/04/target-definition.png?w=838&#038;h=551" alt="Target Definition" width="838" height="551" /><p class="wp-caption-text">Target Definition</p></div>
<h2><strong>Unit Test</strong></h2>
<p>Create a new plug-in project and make sure the option is checked to generate an Activator.  In the Manifest editor, check <strong>Activate this plug-in when one of its classes is loaded</strong>.  Add org.junit4 to your required bundles and org.osgi.service.cm to your imported packages.  [Let's not debate require bundle vs import package ... just set up your dependencies however you like to get the junit tests to build.]</p>
<p>The unit test first gets the ConfigurationAdmin service from the bundle context.  I&#8217;ve taken a short-cut with my unit test for this example, and I&#8217;m relying on the fact that the ConfigurationAdmin service will be started before the unit test.  You should not rely on bundle start order in your production code.  Once you have the ConfigurationAdmin service, create a configuration and set the properties for your declarative service.  After you update the properties on the configuration, you will then have to wait for the service to be created.  Make sure you include a timeout so your unit test doesn&#8217;t hang forever in the event that the service is not started.  Your unit test will contain a compile error until you create the service interface.</p>
<pre class="brush: java;">
package com.example.database.junit;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Hashtable;

import org.junit.Test;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.util.tracker.ServiceTracker;

import com.example.database.IDatabaseConnectionService;

public class TestDatabaseConnectionService
{
	@Test
	public void testCreateConnection() throws SQLException, IOException, InvalidSyntaxException, InterruptedException
	{
		BundleContext context = Activator.getDefault().getBundle().getBundleContext();

		ServiceReference configAdminReference = context.getServiceReference(ConfigurationAdmin.class.getName());
		assertThat(configAdminReference, is(notNullValue()));
		ConfigurationAdmin configAdmin = (ConfigurationAdmin) context.getService(configAdminReference);
		assertThat(configAdmin, is(notNullValue()));

		Configuration config = configAdmin.createFactoryConfiguration(&quot;com.example.database.connection&quot;, null);
		assertThat(config, is(notNullValue()));

		Hashtable&lt;String, Object&gt; properties = new Hashtable&lt;String, Object&gt;();
		properties.put(&quot;database.id&quot;, &quot;example&quot;);
		properties.put(&quot;database&quot;, &quot;junit&quot;);
		properties.put(&quot;user&quot;, &quot;&quot;);
		properties.put(&quot;password&quot;, &quot;&quot;);
		properties.put(&quot;create&quot;, &quot;create&quot;);
		config.update(properties);

		ServiceTracker connectionServiceTracker = new ServiceTracker(context, IDatabaseConnectionService.class.getName(), null);
		connectionServiceTracker.open();
		IDatabaseConnectionService connectionService = (IDatabaseConnectionService) connectionServiceTracker.waitForService(1000);
		assertThat(connectionService, is(notNullValue()));
		Connection connection = connectionService.createConnection();
		assertThat(connection, is(notNullValue()));
		connection.close();
	}
}
</pre>
<h2>Service Interface</h2>
<p>Create a new plug-in project <strong>com.example.database</strong> and add the following interface:</p>
<pre class="brush: java;">
package com.example.database;

import java.sql.Connection;
import java.sql.SQLException;

public interface IDatabaseConnectionService
{
	Connection createConnection() throws SQLException;
}
</pre>
<p>Edit your junit plug-in manifest to include a dependency on <strong>com.example.database</strong>.</p>
<h2>Launch Configuration</h2>
<p>Create a <strong>JUnit Plug-in Test</strong> launch configuration.  Make sure your test is selected, and that the <strong>Test runner</strong> is set to <strong>JUnit 4</strong>.</p>
<div id="attachment_42" class="wp-caption aligncenter" style="width: 966px"><img class="size-full wp-image-42" title="Launch Config Test" src="http://bryanhunt.files.wordpress.com/2009/04/launch-config-test.png?w=956&#038;h=680" alt="Launch Configuration (Test tab)" width="956" height="680" /><p class="wp-caption-text">Launch Configuration (Test tab)</p></div>
<p>You will also need to set up the included plug-ins.</p>
<ol>
<li>Select the <strong>Plug-ins</strong> tab</li>
<li>Select <strong>Launch with: plug-ins selected below only</strong></li>
<li>Click <strong>Deselect All</strong></li>
<li>Uncheck <strong>Include optional dependencies when computing required plug-ins</strong></li>
<li>Uncheck <strong>Add new workspace plug-ins to this launch configuration automatically</strong></li>
<li>Check <strong>com.example.database</strong></li>
<li>Check <strong>com.example.database.junit</strong></li>
<li>Check <strong>org.eclipse.equinox.cm</strong></li>
<li>Check <strong>org.eclipse.equinox.ds</strong></li>
<li>Click <strong>Add Required Plug-ins</strong></li>
<li>Set the <strong>Start Level </strong>on <strong>org.eclipse.equinox.cm</strong> to <strong>3</strong> and <strong>Auto Start</strong> to <strong>true</strong></li>
</ol>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<div id="attachment_47" class="wp-caption aligncenter" style="width: 1034px"><img class="size-large wp-image-47" title="Launch Config Plug-ins" src="http://bryanhunt.files.wordpress.com/2009/04/launch-config-plug-ins1.png?w=1024&#038;h=634" alt="Launch Configuration (Plug-ins tab)" width="1024" height="634" /><p class="wp-caption-text">Launch Configuration (Plug-ins tab)</p></div>
<p>The start level of the ConfigurationAdmin bundle must be set to something lower than the declarative services bundle because of bug <a title="CM / DS start order problem" href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=276003" target="_blank">276003</a>.  Run your junit test, and it should fail on line 62.</p>
<h2>Service Implementation</h2>
<p>Now, lets create a real service that constructs a JDBC connection to derby.</p>
<pre class="brush: java;">
package com.example.database;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Dictionary;

import org.apache.derby.jdbc.EmbeddedDataSource;
import org.osgi.service.component.ComponentContext;

public class DatabaseConnectionService implements IDatabaseConnectionService
{
	public Connection createConnection() throws SQLException
	{
		EmbeddedDataSource dataSource = new EmbeddedDataSource();
		dataSource.setDataSourceName(id);
		dataSource.setDatabaseName(database);
		dataSource.setUser(user);
		dataSource.setPassword(password);
		dataSource.setCreateDatabase(create);
		return dataSource.getConnection();
	}

	@SuppressWarnings(&quot;unchecked&quot;)
	protected void activate(ComponentContext context)
	{
		Dictionary&lt;String, Object&gt; properties = context.getProperties();
		id = (String) properties.get(&quot;database.id&quot;);
		database = (String) properties.get(&quot;database&quot;);
		user = (String) properties.get(&quot;user&quot;);
		password = (String) properties.get(&quot;password&quot;);
		create = (String) properties.get(&quot;create&quot;);
	}

	private String id;
	private String database;
	private String user;
	private String password;
	private String create;
}
</pre>
<h2>Declare The Service</h2>
<p>You are now ready to declare your service.  Eclipse 3.5 contains new tooling for declarative services that makes this a snap.</p>
<ol>
<li>Right-click on your project and select <strong>New -&gt; Folder</strong></li>
<li>Create a folder called <strong>OSGI-INF</strong></li>
<li>Right-click on the OSGI-INF folder and select <strong>New -&gt; Other</strong></li>
<li>Select <strong>Plug-in Development -&gt; Component Declaration</strong></li>
<li>Click <strong>Next</strong></li>
<li>Choose a file name such as <strong>component.xml</strong></li>
<li>Give your component a globally unique name such as <strong>com.example.database.connection</strong></li>
<li>For the Class, click <strong>Browse</strong></li>
<li>Choose <strong>DatabaseConnectionService</strong></li>
<li>Click <strong>Finish</strong></li>
</ol>
<p>The component definition editor will appear allowing you to set additional parameters and options.  Set the <strong>Configuration Policy</strong> to <strong>require</strong>.  This policy tells the service manager to not start the service component until it has a configuration from the ConfigurationAdmin service.  Check the options: <strong>This component is enabled when started</strong> and <strong>This component is immediately activated</strong>.</p>
<div id="attachment_33" class="wp-caption aligncenter" style="width: 654px"><img class="size-full wp-image-33" title="Component Overview" src="http://bryanhunt.files.wordpress.com/2009/04/component-overview.png?w=644&#038;h=538" alt="Component Options" width="644" height="538" /><p class="wp-caption-text">Component Options</p></div>
<p>On the <strong>Services</strong> tab of the component editor, add the service interface as a provided service:</p>
<div id="attachment_34" class="wp-caption aligncenter" style="width: 653px"><img class="size-full wp-image-34" title="Component Services" src="http://bryanhunt.files.wordpress.com/2009/04/component-services.png?w=643&#038;h=539" alt="Component Services" width="643" height="539" /><p class="wp-caption-text">Component Services</p></div>
<p>If you re-run your junit test, it should now pass.  If you want to dig a little deeper, set a breakpoint on line 55 of <strong>TestDatabaseConnectionService.java</strong> and run under the debugger.  When your breakpoint is triggered, switch to the console view and type in <strong>services (objectClass=com.example.database.IDatabaseConnectionService)</strong> and you will get information on your registered service including it&#8217;s configuration parameters.</p>
<div id="attachment_51" class="wp-caption aligncenter" style="width: 755px"><img class="size-full wp-image-51" title="Console" src="http://bryanhunt.files.wordpress.com/2009/04/console.png?w=745&#038;h=284" alt="OSGi Console" width="745" height="284" /><p class="wp-caption-text">OSGi Console</p></div>
<p>That&#8217;s how you dynamically configure a declarative service!</p>
<p><strong>Update:</strong> Simplified the unit test by using <em>ServiceTracker.waitForService()</em>.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bryanhunt.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bryanhunt.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bryanhunt.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bryanhunt.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bryanhunt.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bryanhunt.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bryanhunt.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bryanhunt.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bryanhunt.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bryanhunt.wordpress.com/3/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bryanhunt.wordpress.com&blog=7500940&post=3&subd=bryanhunt&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://bryanhunt.wordpress.com/2009/04/30/dynamically-configured-declarative-osgi-services/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/96518750aa70c5f4794c5f074ac0dd93?s=96&#38;d=&#38;r=PG" medium="image">
			<media:title type="html">bryanhunt</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/04/targets.png" medium="image">
			<media:title type="html">Targets</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/04/target-definition.png" medium="image">
			<media:title type="html">Target Definition</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/04/launch-config-test.png" medium="image">
			<media:title type="html">Launch Config Test</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/04/launch-config-plug-ins1.png?w=1024" medium="image">
			<media:title type="html">Launch Config Plug-ins</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/04/component-overview.png" medium="image">
			<media:title type="html">Component Overview</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/04/component-services.png" medium="image">
			<media:title type="html">Component Services</media:title>
		</media:content>

		<media:content url="http://bryanhunt.files.wordpress.com/2009/04/console.png" medium="image">
			<media:title type="html">Console</media:title>
		</media:content>
	</item>
	</channel>
</rss>