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

<channel>
	<title>Christian Posta -- Software Blog</title>
	<atom:link href="http://www.christianposta.com/blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.christianposta.com/blog</link>
	<description>My thoughts to lend context and direction to developers striving to become better at their craft</description>
	<lastBuildDate>Tue, 08 May 2012 00:17:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>Understanding how OSGI bundles get resolved part II</title>
		<link>http://www.christianposta.com/blog/?p=247</link>
		<comments>http://www.christianposta.com/blog/?p=247#comments</comments>
		<pubDate>Tue, 08 May 2012 00:17:14 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.christianposta.com/blog/?p=247</guid>
		<description><![CDATA[In my previous post, I introduced the rules for how bundles get resolved in an OSGI container. In this post, I&#8217;d like to demonstrate each rule step using the Apache Karaf OSGI container. Karaf is based on the Apache Felix core, although the Equinox core can be substituted if desired. Karaf is a full-featured OSGI [...]]]></description>
			<content:encoded><![CDATA[<p>In my <a href="http://www.christianposta.com/blog/?p=241">previous post</a>, I introduced the rules for how bundles get resolved in an OSGI container. In this post, I&#8217;d like to demonstrate each rule step using the <a href="http://karaf.apache.org/">Apache Karaf</a> OSGI container. Karaf is based on the <a href="http://felix.apache.org/site/index.html">Apache Felix</a> core, although the <a href="http://www.eclipse.org/equinox/">Equinox</a> core can be substituted if desired. Karaf is a full-featured OSGI container and is the cornerstone of the <a href="http://servicemix.apache.org/">Apache ServiceMix</a> integration container. ServiceMix is basically Karaf but specifically tuned for Apache Camel, Apache ActiveMQ and Apache CXF.</p>
<p>This tutorial will require Maven and Karaf. <a href="http://maven.apache.org/download.html">Download maven</a> from the maven website. Download and install karaf as described in the <a href="http://karaf.apache.org/manual/latest-2.2.x/quick-start.html">getting started guide</a> on the Karaf website. You will also need the code that goes along with this example. You <a href="https://github.com/christian-posta/explore-bundle-resolution">can get it at my github</a> repo. After getting it, make sure to run &#8216;mvn install&#8217; from the top-level project. This will build and install all of the bundles into your <em>local</em> maven repository. Although you can install bundles a couple different ways, using maven is easiest. Note that this sample code is mostly made up of package names without any real Java classes (except where the tutorial specifies).</p>
<p>First thing to do is start up karaf. In a plain distribution there should be no bundles installed. Verify this by doing &#8220;osgi:list&#8221; at the karaf commandline. Going in order, we will test out the rules <a href="http://www.christianposta.com/blog/?p=241">from part one of this two-part series</a>:</p>
<h3>For every Import-Package package declaration, there must be a corresponding Export-Package with the same package</h3>
<p>To test this rule, let&#8217;s install Bundle A from our sample bundles. Bundle A specifies an Import-Package of &#8220;org.apache.foo&#8221; package. According to the first rule, this bundle cannot move to the &#8220;Resolved&#8221; state since there is no corresponding bundle with an &#8220;Export-Package&#8221; of org.apache.foo.</p>
<p>From the karaf commandline, type &#8220;osgi:install mvn:explore-bundle-resolution/bundleA/1.0&#8243;. This will install the bundleA bundle. Now do a &#8220;osgi:list&#8221; again. You should see the bundle installed, and under the &#8220;State&#8221; column, it should say &#8220;Installed&#8221;. Now try &#8220;osgi:resolve <em>bundle id</em>&#8221; where bundle id is the ID listed from the &#8220;osgi:list&#8221; command. This will try to resolve all bundle dependencies and put it into the &#8220;Resolved&#8221; state. It won&#8217;t resolve, however. Type &#8220;osgi:list&#8221; again to see the state of the bundle. It&#8217;s still in &#8220;Installed&#8221; state even though we asked OSGI to resolve it. Let&#8217;s find out why. Execute the &#8220;osgi:headers <em>bundle id</em>&#8220;. Under the Import-Package, you should see the package name org.apache.foo listed in a red color. This dependency is missing, so let&#8217;s add it. Type &#8220;osgi:install -s mvn:explore-bundle-resolution/bundleB/1.0&#8243;. Note the &#8216;-s&#8217; switch in the command. This tells OSGI to start the bundle once it&#8217;s installed. Now type the osgi:resolve command again (with the appropriate bundle ID). This will now resolve the bundle.</p>
<h3>Import-Package dictates exactly what version (or attribute) it needs, and a corresponding Export-Package with the same attribute must exist</h3>
<p>Let&#8217;s install bundle C: &#8220;osgi:install -s mvn:explore-bundle-resolution/bundleC/1.0&#8243; List the bundles again, and you&#8217;ll see that although bundle C depends on org.apache.foo, it specifies an Import-Package with a specific version=1.5. There is no version 1.5 that is resolved, so bundle C will also not resolve. Bundle D happens to export a package org.apache.foo with a version equal to 1.5. Install bundle D the same way we&#8217;ve installed the others, using the -s to start it. Now try to resolve bundle C and it should work (&#8220;osgi:resolve <em>bundle id</em>&#8220;).</p>
<h3>Bundles installed first are used to satisfy a dependency when multiple packages with the same version are found</h3>
<p>This rule says that if there are multiple packages exported with the same version, OSGI will choose the first-installed bundle to use when trying to resolve bundles that import the package. Continuing on with the previous example where we installed bundle C and D&#8230; consider that bundle D exports org.apache.foo;version=1.5. So if we install bundle F that exports the exact same package and version, we should see that bundle C is resolved with the package from bundle D and not bundle F. Let&#8217;s see.. install bundle F: &#8220;osgi:install -s mvn:explore-bundle-resolution/bundleF/1.0&#8243;. Do an osgi:list and see that both bundle D and F are correctly installed and &#8220;Active&#8221;. This is a cool feature of OSGI: we can have multiple versions of the same package deployed at the same time, (including in this example the exact same version). Now we should uninstall bundle C and re-install it to see which bundle it uses to resolve for its import of org.apache.foo. Try running &#8220;osgi:uninstall <em>bundle id</em>&#8221; to uninstall bundle C. Now re-install it using the command from above. It should resolve to use bundle D. Use &#8220;package:import <em>bundle id</em>&#8221; to verify. You can try switching things around to get F to resolve. You may need to use &#8220;osgi:refresh&#8221; to refresh the OSGI bundles.</p>
<h3>Bundles that have already been resolved have a higher precedence that those not resolved</h3>
<p>In a way, we have already seen this with the previous rule, but this rule comes into play when hot deploying. This is left as an exercise to the reader as this post is already getting pretty long and I would like to cover the &#8220;uses&#8221; directive next.</p>
<h2>Bundle &#8220;uses&#8221; directive</h2>
<p>The &#8220;uses&#8221; directive adds one of the last rules and constraints to avoid runtime class-cast exceptions. Please review <a href="http://www.christianposta.com/blog/?p=241">my previous blog post</a> for details about the &#8220;uses&#8221; directive. To simulate how the &#8220;uses&#8221; directive works, we will install bundles G, H, I, and J and notice how the container enforces the &#8220;uses&#8221; directive.</p>
<p>Bundle G represents a sort of &#8220;service&#8221; module that client modules can call to &#8220;execute&#8221; some form of processing and return a result. The result it returns is an object of type BarClass that comes from Bundle H. But if a client makes a call to bundle G, it too must use the BarClass from bundle H or it will result in a class cast exception. In our samples, Bundle I is the client code and Bundle J represents a different version of the BarClass. Install the bundles in any order you like, but my demonstration followed this order: J, H, G, I. Note that the version of org.apache.bar is indeed the 2.0.0 version which comes from bundle H even though bundle H was installed second (contrary to the rule above). This is because bundle G specified the &#8220;uses&#8221; directive to depend on a specific version of org.apache.bar.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.christianposta.com/blog/?feed=rss2&#038;p=247</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>From inside the code: ActiveMQ Network Connectors</title>
		<link>http://www.christianposta.com/blog/?p=242</link>
		<comments>http://www.christianposta.com/blog/?p=242#comments</comments>
		<pubDate>Wed, 02 May 2012 00:44:33 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[ActiveMQ]]></category>
		<category><![CDATA[FuseSource]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.christianposta.com/blog/?p=242</guid>
		<description><![CDATA[This post is more for me and any ActiveMQ contributors that may be interested in how the Network Connectors work for ActiveMQ. I recently spent some time looking at the code and thought that it would be good to draw up some quick diagrams to help me remember what I learned and help to identify [...]]]></description>
			<content:encoded><![CDATA[<p>This post is more for me and any ActiveMQ contributors that may be interested in how the Network Connectors work for ActiveMQ. I recently spent some time looking at the code and thought that it would be good to draw up some quick diagrams to help me remember what I learned and help to identify where to debug in the future if there are issues I am researching. If I make a mistake and you&#8217;d like to add clarification, please do so in the comments.</p>
<p>First, you set up your network connectors by configuring them in the ActiveMQ configuration file. This configuration gets mapped to the corresponding ActiveMQ beans using the xbean library for which I have <a href="http://www.christianposta.com/blog/?p=111">a separate blog post</a> which explains exactly how this is done. To specify network connectors, you add the <code>&lt;networkConnectors/&gt;</code> element to your configuration file and add a <code>&lt;networkConnector/&gt;</code>, <code>&lt;multicastNetworkConnector/&gt;</code>, or <code>&lt;ldapNetworkConnector/&gt;</code>. These three different types of network connectors can be used to establish a network of brokers with <code>&lt;networkConnector/&gt;</code> being most common. Here&#8217;s how the three map to Java classes:</p>
<p><code>&lt;networkConnector/&gt;</code> maps to org.apache.activemq.network.DiscoveryNetworkConnector<br />
<code>&lt;multicastNetworkConnector/&gt;</code> maps to org.apache.activemq.network.MulticastNetworkConnector<br />
<code>&lt;ldapNetworkConnector/&gt;</code> maps to org.apache.activemq.network.LdapNetworkConnector</p>
<p>Each of those inherit from the <code>org.apache.activemq.network.NetworkConnector</code> super type as depicted in this diagram:</p>
<p><img src="http://www.christianposta.com/images/amqnotes/networkconnector.png" alt="Network Connectors Diagram" /></p>
<p>So when you have a configuration like this:</p>
<p>
<pre class="brush: xml; title: ; notranslate">
&lt;networkConnector uri=&quot;static://(tcp://localhost:61626,tcp://localhost:61627)&quot; /&gt;
</pre>
</p>
<p>a new DiscoverNetworkConnector will be configured, instantiated, and added as a connector to the BrokerService (which is the main class for where a lot of the ActiveMQ broker details is handled). While the DiscoverNetworkConnector is being assembled from the configuration, the URI that you specify is used to create a DiscoveryAgent. The discover agent is in charge of assembling the connection and handling failover events that are packaged as DiscoverEvents. Determining which DiscoverAgent is picked depends on the DiscoverAgentFactory and the URI specified. In the case of &#8220;static&#8221;, the SimpleDiscoverAgent is used. Each URI in the list of possible URIs are treated differently and are assigned their own Transport (more on this in a sec). Which means, for each URI you list, a new socket will be established and the broker will attempt to establish a network connector over each of the sockets. You may be wondering how to best implement failover then? In the case described above, you will have multiple connections, and if one of those connections is to a slave that isn&#8217;t listening, you will see that the connection fails and the discover agent tries to establish the connection again. This could go on infinitely which consumes resources. Another approach is to use just one URI for the static discover agent that utilizes the failover() logic:</p>
<p>
<pre class="brush: xml; title: ; notranslate">
&lt;networkConnector uri=&quot;static:failover:(tcp://localhost:61626,tcp://localhost:61627)&quot; /&gt;
</pre>
</p>
<p>In this case, only one transport will be created, and the failover logic will wrap it and know about both URIs. If one is not available, it won&#8217;t keep retrying needlessly. Instead it will connect to whichever one it can and only reconnect to the failover URL if the current connection goes down. Note this approach had a bug in it before ActiveMQ version 5.5.1.-fuse-00-06.</p>
<p>The discover agent is in charge of creating the bridge, but it delegates that responsibility to a DiscoverListener. In the example from above, the DiscoverListener interface is implemented by the DiscoverNetworkConnector.onServiceAdd() method.</p>
<p>To establish the bridge, a transport is opened up for both the local broker (using VM) and the remote broker (using the specified protocol, in this case TCP). Once the local and remote transports are created, the bridge can be assembled in the DiscoverNetworkConnector.createBridge(&#8230;) method. This method uses the Factory pattern again to find which bridge to use.</p>
<p>The possible bridge implementations are shown below:</p>
<p><img src="http://www.christianposta.com/images/amqnotes/networkbridge.png" alt="Network Bridge Implementations Diagram" /></p>
<p>By default, with conduitSubscriptions=true, the DurableConduitBridge is used. Conduit subscriptions establish a single flow of messages to a remote broker to reduce duplicates that can happen when remote topics have multiple consumers. This works great by default, but if you want to load balance your messages across <em>all</em> consumers, then you will want to set conduit subscriptions to false (see <a href="http://fusesource.com/docs/esb/4.3/amq_clustering/Networks-Connectors.html">the documentation for conduit subscriptions</a> at <a href="http://www.fusesource.com/">FuseSource</a>&#8216;s documentation on <a href="http://fusesource.com/products/enterprise-activemq/">Fuse Message Broker</a>). When set to false, the DemandForwardingBridge is used. Once the bridge is assembled, it is configured in the NetworkConnector.configureBridge(&#8230;) method.</p>
<p>Once everything is assembled and configured on the bridge, it&#8217;s then started. Once it&#8217;s started, it begins sending broker Command objects to the remote broker to identify itself, set up a session, and demand consumer info from it. This is in the DemandForwardingBridgeSupport.startRemoteBridge() super class method as seen from the diagram.</p>
<p>If you&#8217;re debugging errors with the network connectors, hopefully this helps identify possible locations for where errors can take place.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.christianposta.com/blog/?feed=rss2&#038;p=242</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Understanding how OSGI bundles get resolved part I</title>
		<link>http://www.christianposta.com/blog/?p=241</link>
		<comments>http://www.christianposta.com/blog/?p=241#comments</comments>
		<pubDate>Mon, 30 Apr 2012 18:45:22 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[OSGI]]></category>
		<category><![CDATA[osgi]]></category>

		<guid isPermaLink="false">http://www.christianposta.com/blog/?p=241</guid>
		<description><![CDATA[I&#8217;d like to review how OSGI bundles get resolved and use Apache Karaf to demonstrate. Karaf is a full-featured OSGI container based on the Apache Felix kernel and is the corner stone for the Apache ServiceMix integration container. For part one, I will discuss how bundles are resolved by an OSGI framework. In part two, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;d like to review how OSGI bundles get resolved and use <a href="http://karaf.apache.org/">Apache Karaf</a> to demonstrate. <a href="http://karaf.apache.org/">Karaf</a> is a full-featured OSGI container based on the <a href="http://felix.apache.org/">Apache Felix</a> kernel and is the corner stone for the <a href="http://servicemix.apache.org/">Apache ServiceMix</a> integration container. For part one, I will discuss how bundles are resolved by an OSGI framework. In part two, I&#8217;ll demonstrate each rule using Apache Karaf. Let&#8217;s get started.</p>
<h2>Bundle Resolution Rules</h2>
<p>An OSGI <a href="http://en.wikipedia.org/wiki/OSGi#Life-cycle">bundle&#8217;s lifecycle</a> defines the possible states and transitions for a bundle. We will be discussing the &#8220;Resolved&#8221; state of a bundle which means the state it can reach after being &#8220;Installed&#8221; and when all of its required dependencies are satisfied. Traditional Java classloading is susceptible to runtime ClassCastExceptions where two classes with the same fully-qualified name from two different class loaders become mixed up and one is used in the wrong classpath space. One of the main goals of OSGI is to avoiding this kind of runtime exception by resolving all dependencies at deploy time with the idea being failing &#8220;fast&#8221; at deploy time will be easier to debug than trying to track down classloading issues at runtime. Think about how annoying some of the class not found or class cast exceptions are to debug in a Weblogic deployment, for example. OSGI solves this. For a bundle to reach the &#8220;Resolved&#8221; state, it must have it&#8217;s dependencies fulfilled. Think of the &#8220;fail fast&#8221; approach to bundle resolution like this: if you use a spring application, and one of your beans cannot be wired properly because a bean definition is missing, you will know this at deploy time instead of when a customer is calling your code. The same principle is applied with OSGI; instead of object-level wiring dependencies, we are wiring module and class-loading dependencies.</p>
<p>A trivial explanation of a bundle having its dependencies resolved could go like this: if a bundle imports (Import-Package) a specific package, that package must be made available by another bundle&#8217;s exports (Export-Package). If bundle A has <em>Import-Package: org.apache.foo</em> then there must be a bundle deployed that has an <em>Export-Package: org.apache.foo</em></p>
<h3>For every Import-Package package declaration, there must be a corresponding Export-Package with the same package</h3>
<p>Bundles can also attach other attributes to the packages it imports or exports. What if we added a version attribute to our example:</p>
<p><code>Bundle-Name: Bundle A<br />
Import-Package: org.apache.foo;version="1.2.0"</code></p>
<p>This means, Bundle A has a dependency on package <em>org.apache.foo</em> with a <em>minimum</em> version of 1.2.0. Yes, you read correctly. Although with OSGI you can specify a range of versions, if you don&#8217;t specify a range but rather use a fixed version, it will result in a meaning of &#8220;a minimum&#8221; of the fixed value. <strong>If there is a higher version for that same package, the higher version will be used</strong>. So bundle A will not resolve correctly unless there is a corresponding bundle B that exports the required package:</p>
<p><code>Bundle-Name: Bundle B<br />
Export-Package: org.apache.foo;version="1.2.0"</code></p>
<p>Note that the reverse is not true&#8230; If Bundle B exported version 1.2.0, Bundle A is <em>not</em> required to specify a version 1.2.0. It can use this import and resolve just fine:</p>
<p><code>Bundle-Name: Bundle A<br />
Import-Package: org.apache.foo</code></p>
<p>This is because <em>imports</em> declare the versions they need. An exported version does not specify anything an importing bundle must use (which holds for any attributes, not just version).</p>
<h3>Import-Package dictates exactly what version (or attribute) it needs, and a corresponding Export-Package with the same attribute must exist</h3>
<p>What happens if you have a scenario where Bundle A imports a package and it specifies a version that is provided by two bundles:</p>
<p><code>Bundle-Name: Bundle A<br />
Import-Package: org.apache.foo;version="1.2.0"</code></p>
<p><code>Bundle-Name: Bundle B<br />
Export-Package: org.apache.foo;version="1.2.0"</code></p>
<p><code>Bundle-Name: Bundle C<br />
Export-Package: org.apache.foo;version="1.2.0"</code></p>
<p>Which one bundle does Bundle A use?<br />
The answer is it depends on which bundle (B or C) was installed first.</p>
<h3>Bundles installed first are used to satisfy a dependency when multiple packages with the same version are found</h3>
<p>Things can get a little more complicated when hot deploying bundles after some have already been resolved. What if you install Bundle B first, then try to install Bundle A and the following Bundle D together:</p>
<p><code>Bundle-Name: Bundle D<br />
Export-Package: org.apache.foo;version="1.3.0"</code></p>
<p>As we saw from above, the version declaration in Bundle A (1.2.0) means a minimum version of 1.2.0; so if a higher version was available then it would select that (version 1.3.0 from Bundle D in this case). However, that brings us to another temporal rule for the bundle resolution:</p>
<h3>Bundles that have already been resolved have a higher precedence that those not resolved</h3>
<p>The reason for this is the OSGI framework tends to favor reusability for a given bundle. If it&#8217;s resolved, and new bundles need it, then it won&#8217;t try to have many other versions of the same package if it doesn&#8217;t need to.</p>
<h2>Bundle &#8220;uses&#8221; directive</h2>
<p>The above rules for bundle resolution are still not enough and the wrong class could still be used at runtime resulting in a class-cast exception or similar. Can you see what could be missing?</p>
<p>What if we had this scenario. Bundle A exports a package, <em>org.apache.foo</em>, that contains a class, FooClass. FooClass has a method that returns an object of type BarClass, but BarClass is not defined in the bundle&#8217;s class space, it&#8217;s imported like this:</p>
<p>
<pre class="brush: java; title: ; notranslate">
public class FooClass {
    public BarClass execute(){ ... }
}
</pre>
</p>
<p><code>Bundle-Name: Bundle A<br />
Import-Package: org.apache.bar;version="3.6.0"<br />
Export-Package: org.apache.foo;version="1.2.0"</code></p>
<p>So far everything is fine as long as there is another bundle that properly exports <em>org.apache.bar</em> with the correct version.</p>
<p><code>Bundle-Name: Bundle B<br />
Export-Package: org.apache.bar;version="3.6.0"</code></p>
<p>These two bundles will resolve fine. Now, if we install two more bundles, Bundle C and Bundle D that look like this:</p>
<p><code>Bundle-Name: Bundle C<br />
Import-Package: org.apache.foo;version="1.2.0", org.apache.bar;version="4.0.0"</code></p>
<p><code>Bundle-Name: Bundle D<br />
Export-Package: org.apache.bar;version="4.0.0"</code></p>
<p>We can see that Bundle C imports a package, <em>org.apache.foo</em> from Bundle A. Bundle C can try to use FooClass from org.apache.foo, but when it gets the return value, a type of BarClass, what will happen? Bundle A expects to use version 3.6.0 of BarClass, but bundle C is using version 4.0.0. So the classes used are not consistent within bundles at runtime (i.e., you could experience some type of mismatch or class cast exception), but everything will still resolve just fine at deploy time following the rules from above. What we need is to tell anyone that imports <em>org.apache.foo</em> that we use classes from a specific version of <em>org.apache.bar</em>, and if you want to use <em>org.apache.foo</em> you must use the same version that we import. That&#8217;s exactly what the <strong>uses</strong> directive does. Let&#8217;s change bundle A to specify exactly that:</p>
<p><code>Bundle-Name: Bundle A<br />
Import-Package: org.apache.bar;version="3.6.0"<br />
Export-Package: org.apache.foo;version="1.2.0"";uses:=org.apache.bar</code></p>
<p>Given the new configuration for Bundle A, the bundles would not resolve correctly from above. Bundle C could not resolve, because it imports <em>org.apache.foo</em> but the &#8220;uses&#8221; constraint on Bundle A specifies that C must use the same version that A does (3.6.0) for <em>org.apache.bar</em>, otherwise the bundle will not resolve when trying to deploy. The solution to this is change the version in Bundle C for <em>org.apache.bar</em> to be 3.6.0.</p>
<p>If my examples were not clear or there is some misunderstanding, please leave a comment.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.christianposta.com/blog/?feed=rss2&#038;p=241</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>REST endpoint for integration using Apache Camel</title>
		<link>http://www.christianposta.com/blog/?p=229</link>
		<comments>http://www.christianposta.com/blog/?p=229#comments</comments>
		<pubDate>Wed, 25 Apr 2012 14:38:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Camel]]></category>
		<category><![CDATA[FuseSource]]></category>
		<category><![CDATA[java fusesource camel cxf]]></category>

		<guid isPermaLink="false">http://www.christianposta.com/blog/?p=229</guid>
		<description><![CDATA[REST is an architectural style used for organizing resources and when applied to HTTP-based services allows building stateless, decoupled, scalable services. HTTP methods, HTTP headers, and mime-types all allow a developer to achieve the REST style. Frameworks like Jersey and Fuse Services Framework (Apache CXF) can be used to speed up the development and deployment [...]]]></description>
			<content:encoded><![CDATA[<p>REST is an architectural style used for organizing resources and when applied to HTTP-based services allows building stateless, decoupled, scalable services. HTTP methods, HTTP headers, and mime-types all allow a developer to achieve the REST style. Frameworks like <a href="http://jersey.java.net/">Jersey</a> and <a href="http://fusesource.com/products/enterprise-cxf/">Fuse Services Framework (Apache CXF)</a> can be used to speed up the development and deployment of services trying to achieve a RESTful style, and in this blog post I&#8217;d like to discuss how to build the backend of a resource that relies on integration provided by <a href="http://fusesource.com/products/enterprise-camel/">Fuse Mediation Router</a> also known as <a href="http://camel.apache.org/">Apache Camel</a>.</p>
<p>Just as an aside, a link that I&#8217;ve had tucked away in the recesses of my bookmarks may be of interest for those of you wondering whether your architecture is indeed RESTful or just the same highly coupled RPC style that REST tries to alleviate. Roy Fielding, who wrote his dissertation on REST, actively asserts the notion that <a href="http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven">hyerlinks within resource representations are a must</a> for REST styles, and even further clarifies the uncertainties around implementing REST.</p>
<p>The source code for this sample can be found <a href="https://github.com/christian-posta/file-rest-blog">on my github repository</a></p>
<p><a href="http://fusesource.com/products/enterprise-camel/">Fuse Mediation Router</a> is <a href="http://architects.dzone.com/articles/apache-camel-integration">FuseSource&#8217;s</a> enterprise-grade, hardened version of Apache Camel that provides a comfortable DSL for describing integrations, mediations, and routing. It&#8217;s free, open-source, and has an Apache License. For those unfamiliar with Mediation Router/Camel, take a look at an introduction from Jon Anstey (co-author of <a href="http://www.amazon.com/gp/product/1935182366/ref=as_li_ss_tl?ie=UTF8&amp;tag=christianc0aa-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1935182366">Camel in Action</a>)at DZone&#8217;s Enterprise Integration Zone: <a href="http://architects.dzone.com/articles/apache-camel-integration">Apache Camel: Integration Nirvana</a>.</p>
<p>We will be using Mediation Router to help write a simple integration between a REST endpoint and a resource files on a file system. I&#8217;ll be using <a href="http://fusesource.com/docs/router/2.8/component_ref/_IDU_CXFRS.html">camel-cxfrs</a> component to expose the REST endpoint and will be using the <a href="http://fusesource.com/docs/router/2.8/component_ref/_IDU_File2.html">camel-file</a> component to read a directory on the file system. The intention of the sample is to describe the configuration necessary to expose the REST interface with Mediation Router, integrate with a backend somehow, transform the data into an appropriate REST response, and send back the response.</p>
<p>To get started, let&#8217;s focus on how to set up the REST endpoint. To do so, you would create a JAX-RS resource that describes the java methods that will act as REST endpoints. This sample code requires familiarity with <a href="http://jcp.org/en/jsr/detail?id=311">Java API for RESTful Web Services</a> aka JAX-RS. For those unfamiliar, here are some <a href="http://www.mkyong.com/tutorials/jax-rs-tutorials/">great tutorials to follow along</a> that help to understand JAX-RS.</p>
<p>
<pre class="brush: java; title: ; notranslate">
@Path(&quot;/customerservice/&quot;)
public class CustomerServiceResource {

// NOTE: The instance member variables will not be available to the
// Camel Exchange. They must be used as method parameters for them to
// be made available
@Context
private UriInfo uriInfo;

public CustomerServiceResource() {
}

@GET
@Path(&amp;quot;/customers/{id}/&amp;quot;)
@Produces(&amp;quot;text/xml&amp;quot;)
public Customer getCustomer(@PathParam(&amp;quot;id&amp;quot;) String id) {
    return null;
}

@PUT
@Path(&amp;quot;/customers/&amp;quot;)
public Response updateCustomer(Customer customer) {
    return null;
}

}
</pre>
</p>
<p>As you can see, the annotations are the JAX-RS annotations that describe the operations, HTTP methods, and mime-types involved with the REST endpoint. Notice, the return values are all null as this class will not actually be used to handle the requests that come in to the endpoint; the Mediation Router routes will be responsible for processing and responding. Note, however, that instance members are not available to the Mediation Router exchanges, i.e., any instance members injected via the JAX-RS @Context annotations will not be available. To make them available, add them as parameters to your methods.</p>
<p>Declaring the CXF-RS endpoint with Mediation Router can be done one of two ways: Directly in the endpoint configuration like this:</p>
<p>
<pre class="brush: java; title: ; notranslate">
from(&quot;cxfrs://http://localhost:9090/route?resourceClasses=com.fusesource.samples.CustomerServiceResource&quot;)
</pre>
</p>
<p>Creating it directly in the configuration requires less xml configuration but offers limited flexibility. Another option is creating a separate bean that&#8217;s responsible for the endpoint and then referencing it within the endpoint configuration:</p>
<p>
<pre class="brush: java; title: ; notranslate">
from(&quot;cxfrs:bean:rsServer&quot;)
</pre>
</p>
<p>The bean <em>rsServer</em> should be defined in the camel context. An example:</p>
<p>
<pre class="brush: xml; title: ; notranslate">
&lt;cxf:rsServer id=&quot;rsServer&quot; address=&quot;http://localhost:9090/route&quot;
              serviceClass=&quot;com.fusesource.samples.CustomerServiceResource&quot;/&gt;
</pre>
</p>
<p>This approach allows you to decouple the endpoint configuration and allows to be quicker and less verbose in the endpoint configuration. Both options are shown in the sample code, although the first option is used.</p>
<p>That&#8217;s all the configuration required to expose the REST endpoint with Mediation Router. Fairly simple. The next step is to consume a file from the file system based on what comes in from the REST endpoint. The contents of the file will be returned to the client of the REST call. To do this, we use the <a href="http://fusesource.com/docs/router/2.8/component_ref/_IDU_File2.html">camel-file</a> component and enrich the Exchange with a <a href="http://fusesource.com/docs/router/2.8/apidoc/org/apache/camel/model/ProcessorDefinition.html#pollEnrich(java.lang.String)">pollEnrich</a> call in the DSL:</p>
<p>
<pre class="brush: java; title: ; notranslate">
.setHeader(Exchange.FILE_NAME, simple(&quot;test-${body}.xml&quot;))
.pollEnrich(&quot;file:src/data?noop=true&quot;, 1000, new CustomerEnricher())
</pre>
</p>
<p>We cannot use any dynamic expressions in the pollEnrich call, so we set a header that the file component understands before we do the enrichment. In this case, the body of the REST message is an identifier that can be used to template the file-system resource.</p>
<p>Lastly, we can attach some additional processing to the route:</p>
<pre class="brush: java; title: ; notranslate">
.process(new CustomerServiceProcessor())
</pre>
</p>
<p>The intent of the example, as described above, is to show how to configure the endpoint and attach it to further Mediation Router processing. Note, the Message Exchange Pattern (MEP) for the REST endpoint is InOut and expects a response. The example is not meant to be a complete end-to-end solution as that will vary depending on intended functionality. Please note above the links <a href="http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven">to Roy&#8217;s discussions</a> on what REST is and is not.</p>
<p>If I have left something out, or you need more clarification around the example, drop me a comment and we can discuss.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.christianposta.com/blog/?feed=rss2&#038;p=229</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Including additional artifacts with Maven</title>
		<link>http://www.christianposta.com/blog/?p=214</link>
		<comments>http://www.christianposta.com/blog/?p=214#comments</comments>
		<pubDate>Mon, 23 Apr 2012 19:09:46 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.christianposta.com/blog/?p=214</guid>
		<description><![CDATA[Sometimes your build will contain other artifacts for a build other than the pom, a jar, etc. For example, you may wish to attach data-source configurations to that are meant to deploy along with your artifacts, or include other descriptor configurations like a features.xml file to be deployed into Fuse ESB aka ServiceMix. This makes [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes your build will contain other artifacts for a build other than the pom, a jar, etc. For example, you may wish to attach data-source configurations to that are meant to deploy along with your artifacts, or include other descriptor configurations like a features.xml file to be deployed into <a href="http://fusesource.com/products/enterprise-servicemix/">Fuse ESB</a>  aka <a href="servicemix.apache.org/">ServiceMix</a>. This makes it easier to use maven, or any other provisioning tool, to also grab the attached artifacts. To do this, use the <a href="http://mojo.codehaus.org/build-helper-maven-plugin/attach-artifact-mojo.html">build-helper-maven-plugin</a> and the following configuration:</p>

<p><pre class="brush: xml; title: ; notranslate">
 &lt;plugin&gt;
    &lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;
    &lt;artifactId&gt;build-helper-maven-plugin&lt;/artifactId&gt;
    &lt;executions&gt;
        &lt;execution&gt;
            &lt;id&gt;attach-artifacts&lt;/id&gt;
            &lt;phase&gt;package&lt;/phase&gt;
            &lt;goals&gt;
                &lt;goal&gt;attach-artifact&lt;/goal&gt;
            &lt;/goals&gt;
            &lt;configuration&gt;
                &lt;artifacts&gt;
                    &lt;artifact&gt;
                        &lt;file&gt;target/classes/features.xml&lt;/file&gt;
                        &lt;type&gt;xml&lt;/type&gt;
                        &lt;classifier&gt;features&lt;/classifier&gt;
                    &lt;/artifact&gt;
                &lt;/artifacts&gt;
            &lt;/configuration&gt;
        &lt;/execution&gt;
    &lt;/executions&gt;
&lt;/plugin&gt;
</pre></p>

<p>If you would like to also filter/tokenize the artifacts before attaching them, add the following resource plugin:</p>

<p><pre class="brush: xml; title: ; notranslate">
&lt;plugin&gt;
    &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
    &lt;artifactId&gt;maven-resources-plugin&lt;/artifactId&gt;
    &lt;executions&gt;
        &lt;execution&gt;
            &lt;id&gt;filter&lt;/id&gt;
            &lt;phase&gt;generate-resources&lt;/phase&gt;
            &lt;goals&gt;
                &lt;goal&gt;resources&lt;/goal&gt;
            &lt;/goals&gt;
        &lt;/execution&gt;
    &lt;/executions&gt;
&lt;/plugin&gt;
</pre></p>
]]></content:encoded>
			<wfw:commentRss>http://www.christianposta.com/blog/?feed=rss2&#038;p=214</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why I&#8217;m excited to attend Camel One</title>
		<link>http://www.christianposta.com/blog/?p=213</link>
		<comments>http://www.christianposta.com/blog/?p=213#comments</comments>
		<pubDate>Thu, 19 Apr 2012 13:57:14 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.christianposta.com/blog/?p=213</guid>
		<description><![CDATA[I&#8217;ll be attending CamelOne this year, and I&#8217;m pretty excited. I didn&#8217;t make it to the event last year, but judging by the speaker line up and the presentations given last year, this conference is definitely a must for developers involved in enterprise integration. Check out the presentations from last year. As you can see, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ll be attending CamelOne this year, and I&#8217;m pretty excited. I didn&#8217;t make it to the event last year, but judging by the speaker line up and the presentations given last year, this conference is definitely a must for developers involved in enterprise integration. Check out the <a href="http://fusesource.com/fuse/camelone-2011-videos/">presentations from last year</a>. As you can see, the content covered is applicable even if you&#8217;re not using the <a href="http://fusesource.com/products/">Apache projects</a>. But of course if you are, all the better.</p>
<p>Of course attending a conference like this and hanging out with and listening to some of the leaders in open-source integration software like James, Strachan Claus Ibsen, Jon Anstey, Rob Davies, and many others, is awesome, there&#8217;s another reason to attend. Being around people who are highly dedicated to the software craft and developing best-of-breed software really gets you excited and motivated. Seeing others excited and passionate about their projects is contagious. Looking at this year&#8217;s conference, the <a href="http://fusesource.com/apache-camel-conference-2012/camelone_speakers_2012/">speaker list and sessions</a> here are the ones that appeal to me and I hope to get the most from:</p>
<h3>A Hundred Departments, Same Integration Solution</h3>
<p>Overview: How integration and SOA fit in a broad enterprise architecture; techniques for adding APIs to and integrating with legacy systems; design patterns for building new enterprise systems with integration in mind; techniques and code for business process management (BPM) using Camel &amp; ActiveMQ; and how the new paradigms are enabling us to work with external partners, lower the cost of software development, and offer new innovative services.</p>
<h3>Next Generation Open Source Messaging with Apollo</h3>
<p>Overview: Apache Apollo is built from the foundations of the Apache ActiveMQ project but with a radically different threading architecture which lets it scale to large number of concurrent connections and destinations while using a constant number of threads.</p>
<h3>Replacing MQSeries with ActiveMQ in Large Scale Retailer</h3>
<p>Overview: This session will discuss the development, deployment and lessons learned in a large scale retail implementation (1,000s of stores) where we are converting from IBM MQ Series to ActiveMQ and ServiceMix in a gradual manner</p>
<h3>Using Apache Camel in ServiceMix</h3>
<p>Overview: Jon Anstey (co-author Camel in Action) will show you the best practices for deploying Camel applications to ServiceMix. Since ServiceMix is built on top of Apache Karaf, most tips are applicable to that container as well.</p>
<h3>Apache Camel in Action: Common Problems, Solutions and Best Practices</h3>
<p>Overview: Advanced topics like transaction management in Camel (XA and non XA) and when you can live without it. This talk will give examples for how to start, stop, create, or modify Camel routes at runtime. It will also cover basic questions like “Java DSL vs. XML DSL”, “Exchange In-Message vs. Exchange Out-Message” or whether you should use one or multiple Camel contexts.</p>
<h3>Apache Camel at a Top 3 Online Retailer</h3>
<p>Overview: A Top 3 online retailer recently completed a live integration of their warehouse management and fulfillment systems with those of their parent company. The integration and cutover event was described as “open heart surgery on a moving train” by their CEO. This presentation will highlight how Apache Camel helped to make the integration possible, and how Camel is being leveraged at the online retailer today for a variety of integration solutions. Best practices, lessons learned, and insights based upon use cases from one of the world’s largest online retailers.</p>
<p>There are many others, so <a href="http://fusesource.com/apache-camel-conference-2012/camelone_speakers_2012/">check out the complete list</a>. You can use the following discount codes:</p>
<p>SpeakerFriend &#8211; $150 off registration<br />
AMQAction -$100 off, and free ebook of ActiveMQ in Action<br />
CamelAction &#8211; $100 off, and free ebook of Camel in Action</p>
<p>Hope to see you there!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.christianposta.com/blog/?feed=rss2&#038;p=213</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Focused, informative documentation for ActiveMQ, Camel, ServiceMix and CXF</title>
		<link>http://www.christianposta.com/blog/?p=208</link>
		<comments>http://www.christianposta.com/blog/?p=208#comments</comments>
		<pubDate>Mon, 16 Apr 2012 15:03:43 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[FuseSource]]></category>
		<category><![CDATA[activemq]]></category>
		<category><![CDATA[camel]]></category>
		<category><![CDATA[cxf]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[fusesource]]></category>
		<category><![CDATA[servicemix]]></category>

		<guid isPermaLink="false">http://www.christianposta.com/blog/?p=208</guid>
		<description><![CDATA[What criteria do you use when evaluating whether to use a commercial product or open-source project to support your system-integration development? Is documentation near the top? To me it seems the commercial vendors pump out volumes upon volumes of documentation which makes finding what you need a needle in a haystack. On the other hand, [...]]]></description>
			<content:encoded><![CDATA[<p>What criteria do you use when evaluating whether to use a commercial product or open-source project to support your system-integration development? Is documentation near the top? To me it seems the commercial vendors pump out volumes upon volumes of documentation which makes finding what you need a needle in a haystack. On the other hand, open-source projects seem to have very little documentation and what they do have presupposes non-trivial knowledge of the project. Which makes total sense to me. The commercial vendors are trying to sell you on the multitude of capabilities their product supposedly has, so they better have reams of documents to show somebody. The open-source developers want to write code and expect anyone interested in their work to read their code. They don&#8217;t want to be bothered writing documentation that will probably be outdated as soon as they make their next commit.</p>
<p>I wanted to quickly point out something that I&#8217;ve noticed to be quite different for the open-source projects supported by <a href="http://www.fusesource.com" target="_blank">FuseSource</a>. Apache ActiveMQ, Camel, ServiceMix and CXF have documentation at their Apache sites that varies in terms of quality. But FuseSource has put together top-quality docs for each of the aforementioned projects focused on helping the reader quickly come up to speed and understand how to use the important features of a product. And it&#8217;s not just mickey-mouse examples either. They&#8217;ve put together examples gathered from years of experience consulting at various types of clients that focus on the intended way of using the product . When it comes to wanting to know how to use, for example ServiceMix, and the pitfalls to avoid and best practices to employ, having the FuseSource docs for ServiceMix (aka Fuse ESB) close at hand is a must.</p>
<p>Another thing that can frustrate developers is outdated documentation. You may find a page, even hosted at the project&#8217;s website, that explains a certain way to develop a solution, but when you try it yourself, it doesn&#8217;t work. You can spend hours trying to figure out what you did wrong only to find you&#8217;re actually not supposed to do it that way anymore. The <a href="http://www.fusesource.com" target="_blank">FuseSource</a> documentation solves that by organizing all of the documentation for a specific version.  When you click on a doc set for a particular version, you can be sure that the features and examples covered are specific for that version and not just clobbered together with whatever else used to work and is outdated.</p>
<p>The docs at FuseSource are tailored to help you quickly coming up to speed and are focused on solving problems with the technology without the unnecessary fluff to get in your way. If you are using ActiveMQ, Camel, ServiceMix, or CXF, I highly recommend checking out the FuseSource docs. If you don&#8217;t use those products yet, consider that the documentation is an asset as you explore whether or not to use them.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.christianposta.com/blog/?feed=rss2&#038;p=208</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using Excel Templates with Excel Mac 2011</title>
		<link>http://www.christianposta.com/blog/?p=197</link>
		<comments>http://www.christianposta.com/blog/?p=197#comments</comments>
		<pubDate>Mon, 09 Apr 2012 20:55:18 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.christianposta.com/blog/?p=197</guid>
		<description><![CDATA[I use a Mac for all of my development (where I can), but one thing I had to do recently was use Excel on a Mac and create a new spreadsheet from a template. To my surprise and frustration, I could find no reliable documentation online. I figured it out.Here&#8217;s what I did (and if [...]]]></description>
			<content:encoded><![CDATA[<p>I use a Mac for all of my development (where I can), but one thing I had to do recently was use Excel on a Mac and create a new spreadsheet from a template. To my surprise and frustration, I could find no reliable documentation online. I figured it out.<span id="more-197"></span>Here&#8217;s what I did (and if anyone has a link to where it was on Google or the MS website, please share with me. I wasted time and my own frustration trying to find the correct solution, but was instead pointed to many directions that ended up being absolutely wrong): I created a new template in Excel and saved it. Then I checked the properties for that file and where it was located on the disk. I ended up with this location for templates:<br />
&gt; /Users//Library/Application Support/Microsoft/Office/User Templates/My Templates</p>
]]></content:encoded>
			<wfw:commentRss>http://www.christianposta.com/blog/?feed=rss2&#038;p=197</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Test Entry From TextMate</title>
		<link>http://www.christianposta.com/blog/?p=196</link>
		<comments>http://www.christianposta.com/blog/?p=196#comments</comments>
		<pubDate>Mon, 09 Apr 2012 20:45:23 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.christianposta.com/blog/?p=196</guid>
		<description><![CDATA[Using the amazing TextMate editor to blog offline and publish when ready&#8230;I was looking recently for a good solution to blog offline and later publish to wordpress. I&#8217;v also wanted to get more familiar with Markdown, so I found the [Blogging bundle][http://blog.macromates.com/2006/blogging-from-textmate/] for TextMate that allows me to write my blogs in text with Markdown [...]]]></description>
			<content:encoded><![CDATA[<p>Using the amazing TextMate editor to blog offline and publish when ready&#8230;<span id="more-196"></span>I was looking recently for a good solution to blog offline and later publish to wordpress. I&#8217;v also wanted to get more familiar with Markdown, so I found the [Blogging bundle]<a href="http://blog.macromates.com/2006/blogging-from-textmate/">[http://blog.macromates.com/2006/blogging-from-textmate/]</a> for TextMate that allows me to write my blogs in text with Markdown and publish when I&#8217;m ready. Here&#8217;s my first post, with many more to come.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.christianposta.com/blog/?feed=rss2&#038;p=196</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Serious about your software career? Leave your job</title>
		<link>http://www.christianposta.com/blog/?p=193</link>
		<comments>http://www.christianposta.com/blog/?p=193#comments</comments>
		<pubDate>Mon, 02 Apr 2012 15:45:21 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[fusesource]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://www.christianposta.com/blog/?p=193</guid>
		<description><![CDATA[I recently resigned my position as senior software engineer and technical lead for a middleware services group at Wells Fargo. The job was great: work from home, great immediate manager, respected among the team members, trusted to explore new technologies when justified, boss stood up for us and got us the tools, training, and working [...]]]></description>
			<content:encoded><![CDATA[<p>I recently resigned my position as senior software engineer and technical lead for a middleware services group at Wells Fargo. The job was great: work from home, great immediate manager, respected among the team members, trusted to explore new technologies when justified, boss stood up for us and got us the tools, training, and working environments we needed, etc, etc. Something still prompted me to move, and it’s not the first time I’ve done so. I’ve opted to resign jobs that had great setups in the past, either as a full-time or consultant, and in this blog I try to articulate why.</p>
<p>I believe to be successful and well-rounded in the technology/software space, you have to change jobs every few years or so. Ultimately, as a software engineer, your job is to solve problems using technology. In most cases, a problem can be solved in many different ways, but not all solutions are created equal. The more problems and solutions you’ve seen and experienced, the more apt you are to solve the problem with a “better” or “elegant” solution. In my opinion, you have to experience how problems are solved in different groups, and different companies using different methods, different approaches, etc etc to really become proficient at problem solving and weigh the benefits and tradeoffs that come with a solution. Otherwise, the traditions and customs of a single company crush your mind from thinking “outside the box” or evaluate how similar problems have been solved in the past by similar companies.</p>
<p>Another part of the equation is ability to learn and your exposure to new technologies. Big companies offer the “this is the way we’ve always done it and we’re not going to change” mentality which is really a career killer for a software engineer. If you’re career goals involve trying to climb the corporate ladder, then by all means embrace the corporate mindset but if you want to stay in the technology space and excel, you will have to seek out opportunities to expose yourself to new technologies and problems..</p>
<p>I feel at this point in my career, I can’t settle for all the comforts of a cushy corporate job. I am still young enough and interested enough in technology to the point that I want to push myself. I want to get out and be exposed to new problems. I crave learning and the challenges of doing so. I honestly feel that if you’re not learning and not solving new problems and not thinking outside of the box you’re going to end up like those technology folks complaining about not having a job because the technology they cling to is slowly going away or drying up. I don’t want to end up complaining about something that I have control over right now. In the end, the technology industry is about problem solving, ability to learn, and pushing yourself to not get comfortable. Maybe I’m cynical in this respect, but the longer you stay at a big company, the more locked-in you get and the more dependent you become on that company (pension, retirement, tenure, job-security, whatever). The longer you stay, the less motivated you get to learn the new technologies that aren’t being used at your company. The longer you stay, you *think* you become critical to their operations, but before you know it the operations themselves are being phased out and your chances of being kept around are becoming slimmer and slimmer. I believe times have changed, and trying to stay at a corporate job in a company for 30 years is a career killer for a software engineer. I want my resume to be my job security, not the number of years I’ve had the corporate mentality beaten into me.</p>
<p>Who knows, though. My wife and I are expecting our first child in the next few weeks, and I know my priorities will shift big time. My focus will be on her and my family. Maybe I’ll do a 180 change of opinion about staying at a big company. But while I’m still motivated, I have to explore other options and opportunities that I know will solve all three of those items mentioned above: exposure to problem solving, learning, and staying hungry. So I continue my journey in the software craft by taking on the role of Principal Consultant at an open-source subscription company, FuseSource, who is the support company behind Apache Camel, ActiveMQ, ServiceMix, CXF, and a few others. I will be helping different companies use these open-source projects, facilitate proper design of their architecture, deliver training, and i’m sure much more. It seems to be a good balance of exposure to new problems, learning opportunities, and working with some of the smartest people in the open-source space which will drive me to stay hungry. Wish me luck!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.christianposta.com/blog/?feed=rss2&#038;p=193</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
	</channel>
</rss>

