<?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"
	>

<channel>
	<title>unitstep.net &#187; java</title>
	<atom:link href="http://unitstep.net/blog/category/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://unitstep.net</link>
	<description>the home of peter chng</description>
	<pubDate>Tue, 18 Nov 2008 02:09:57 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.3</generator>
	<language>en</language>
			<item>
		<title>Extracting X509 Extensions from a CSR using the Bouncy Castle APIs</title>
		<link>http://unitstep.net/blog/2008/10/27/extracting-x509-extensions-from-a-csr-using-the-bouncy-castle-apis/</link>
		<comments>http://unitstep.net/blog/2008/10/27/extracting-x509-extensions-from-a-csr-using-the-bouncy-castle-apis/#comments</comments>
		<pubDate>Tue, 28 Oct 2008 02:01:07 +0000</pubDate>
		<dc:creator>Peter Chng</dc:creator>
		
		<category><![CDATA[X.509]]></category>

		<category><![CDATA[certificates]]></category>

		<category><![CDATA[cryptography]]></category>

		<category><![CDATA[guides]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[pki]]></category>

		<category><![CDATA[programming]]></category>

		<category><![CDATA[tutorials]]></category>

		<category><![CDATA[ca]]></category>

		<category><![CDATA[certificate]]></category>

		<category><![CDATA[certificate request]]></category>

		<category><![CDATA[csr]]></category>

		<category><![CDATA[guide]]></category>

		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://unitstep.net/?p=407</guid>
		<description><![CDATA[The Bouncy Castle Cryptography Java APIs are an excellent set of APIs that act as a provider for JCE and JCA.  Additionally, they take care of the mundane and tedious (some would say overly complicated) details involved in reading and creating the data structures associated with the X.500 and PKCS standards. (The APIs are [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://bouncycastle.org/">Bouncy Castle Cryptography Java APIs</a> are an excellent set of APIs that act as a provider for JCE and JCA.  Additionally, they take care of the mundane and tedious (some would say overly complicated) details involved in reading and creating the data structures associated with the X.500 and PKCS standards. (The APIs are also available in C#, for .NET developers out there)</p>
<p>One thing they handle well is the concept of certificate extensions.  X.509 v3 certificates introduced the concept of these extensions, which are basically additional (potentially optional) fields containing information not contained in the older original X.509 specifications.  Each extension is specified by an OID (Object Identifier); a good <a href="http://www.alvestrand.no/objectid/2.5.29.html">list of these extensions</a> is available.</p>
<p>While it&#8217;s easy to read these extensions from an existing X.509 v3 certificate using the Bouncy Castle APIs it is a bit more involved to read these extensions from a <a href="http://en.wikipedia.org/wiki/Certificate_signing_request">Certificate Signing Request</a>, or CSR; this is the data structure that is sent to a CA to request a certificate.  The CA then reads the data from this and creates a signed certificate issued to the requester.  In this guide I&#8217;ll present a brief way to extract X.509 <a href="http://www.alvestrand.no/objectid/submissions/1.2.840.113549.1.9.14.html">extensions request</a> from a CSR so that they may be included in the resulting issued certificate.</p>
<h3>Code: The good stuff</h3>
<p>Assuming you have added the Bouncy Castle JARs to your classpath, you should have access to the classes used here.  </p>
<p>You must first have the CSR in the format of a Bouncy Castle data object, namely the <a href="http://www.cs.berkeley.edu/~jonah/bc/org/bouncycastle/jce/PKCS10CertificationRequest.html"><code>PKCS10CertificationRequest</code></a>. If all you have is the PEM-format of the CSR (i.e. Base64-encoded contents delimited by headers like <code>----- BEGIN CERTIFICATE REQUEST -----</code> and <code>----- END CERTIFICATE REQUEST -----</code>) then you will need to convert  this to the proper data structure using something like<br />
<a href="http://juliusdavies.ca/commons-ssl/javadocs/org/apache/commons/ssl/PEMUtil.html">PEMUtil</a> from Commons-SSL like I have done below.  (BC has a <a href="http://www.eecs.berkeley.edu/~jonah/javadoc/org/bouncycastle/jce/provider/PEMUtil.html">PEMUtil</a> class as well, but it appears to be only for internal use)</p>
<pre><code>// NOTE: Commons-SSL doesn't support generics.
final List pemItems = PEMUtil.decode( csrContent.getBytes() );

// Verify list isn't empty - uses Apache Commons Lang.
Validate.isTrue( !pemItems.isEmpty() );

// No support for generics, so have to cast. (Could have cast the entire List)
final PEMItem csrPemFormat = (PEMItem) pemItems.get( 0 );

// Verify the type.
Validate.isTrue( csrPemFormat.pemType.equals( "CERTIFICATE REQUEST" ),
  "This is not a CSR" );

final PKCS10CertificationRequest csr = new PKCS10CertificationRequest(
  csrPemFormat.getDerBytes() );</code></pre>
<p>We first decode the PEM (Base64) CSR into <code>List</code> of <a href="http://juliusdavies.ca/commons-ssl/javadocs/org/apache/commons/ssl/PEMItem.html"><code>PEMItem</code></a>s. Note that Commons-SSL doesn&#8217;t support <a href="http://java.sun.com/j2se/1.5.0/docs/guide/language/generics.html">generics</a>, so you are going to get a cast warning somewhere in the code, no matter what.  When calling <code>getBytes()</code> on the CSR string, you may want to specify the <code>US-ASCII</code> character set, since the no-arg method uses the platform default character set, which might give inconsistent results across different systems when converting from characters to bytes. </p>
<p>We then grab the first entry in the list, checking if it is a CSR.  We can now convert this into the proper data structure by supplying the raw bytes (i.e. the DER-encoded format) to the constructor of <code>PKCS10CertificationRequest</code>.</p>
<p>The method to extract the <a href="http://www.cs.berkeley.edu/~jonah/bc/org/bouncycastle/asn1/x509/X509Extensions.html"><code>X509Extensions</code></a> structure from the <code>PKCS10CertificationRequest</code> is shown below.</p>
<pre><code>   /**
    * Gets the X509 Extensions contained in a CSR (Certificate Signing Request).
    *
    * @param certificateSigningRequest the CSR.
    * @return the X509 Extensions in the request.
    * @throws CertificateException if the extensions could not be found.
    */
   X509Extensions getX509ExtensionsFromCsr(
         final PKCS10CertificationRequest certificateSigningRequest ) throws CertificateException
   {
      final CertificationRequestInfo certificationRequestInfo = certificateSigningRequest
            .getCertificationRequestInfo();

      final ASN1Set attributesAsn1Set = certificationRequestInfo.getAttributes();

      // The `Extension Request` attribute is contained within an ASN.1 Set,
      // usually as the first element.
      X509Extensions certificateRequestExtensions = null;
      for (int i = 0; i &lt; attributesAsn1Set.size(); ++i)
      {
         // There should be only only one attribute in the set. (that is, only
         // the `Extension Request`, but loop through to find it properly)
         final DEREncodable derEncodable = attributesAsn1Set.getObjectAt( i );
         if (derEncodable instanceof DERSequence)
         {
            final Attribute attribute = new Attribute( (DERSequence) attributesAsn1Set
                  .getObjectAt( i ) );

            if (attribute.getAttrType().equals( PKCSObjectIdentifiers.pkcs_9_at_extensionRequest ))
            {
               // The `Extension Request` attribute is present.
               final ASN1Set attributeValues = attribute.getAttrValues();

               // The X509Extensions are contained as a value of the ASN.1 Set.
               // Assume that it is the first value of the set.
               if (attributeValues.size() &gt;= 1)
               {
                  certificateRequestExtensions = new X509Extensions( (ASN1Sequence) attributeValues
                        .getObjectAt( 0 ) );

                  // No need to search any more.
                  break;
               }
            }
         }
      }

      if (null == certificateRequestExtensions)
      {
         throw new CertificateException( "Could not obtain X509 Extensions from the CSR" );
      }

      return certificateRequestExtensions;
   }</code></pre>
<p>Basically, we get the certificate request info from the CSR structure and then extract attributes from it.  Then, we loop through to find the attribute with the <a href="http://www.alvestrand.no/objectid/submissions/1.2.840.113549.1.9.14.html">&#8220;Extension Request&#8221; OID</a>.</p>
<p>After that, I make an assumption that the actual extensions are contained in the first value of the place of the ASN.1 Set that makes up the &#8220;Extensions Request&#8221; structure - not a big assumption, and in my testing I haven&#8217;t encountered a situation where this wasn&#8217;t the case.  It&#8217;s worthwhile to keep in mind that ASN.1 often prescribes Set or multi-value structures in places where the underlying data can  only be single-valued. </p>
<p>After running through that code, we&#8217;ll have either found the extensions, and be returning them in a <a href="http://www.cs.berkeley.edu/~jonah/bc/org/bouncycastle/asn1/x509/X509Extensions.html"><code>X509Extensions</code></a> structure, or an exception will be thrown.  You could modify the code to return <code>null</code> if that suits your style or purpose better.</p>
<h3>A few more notes</h3>
<p>Once you have the <code>X509Extensions</code> structure you can use the extensions contained within to create/issue a certificate with them.  Check out the <a href="http://www.bouncycastle.org/wiki/display/JA1/X.509+Public+Key+Certificate+and+Certification+Request+Generation">Bouncy Castle Guide on Certificate Generation</a> for more details.</p>
<p>Note that a CA is <em>not required</em> to use any of the extension requests present in a CSR - hence the name &#8220;requests&#8221;.  It is entirely up to the CA to decide what extensions are appropriate, along with their values, for the certificates that it issues.  </p>
<h3>Code Review</h3>
<p>The code is a little complicated and could probably benefit from some refactoring.  However, a lot of the complexity derives from the fact that the X.509 and associated standards are quite complex themselves.  This is a reflection on the vision that the designers of X.509 had for the future of the standard.  However, the <a href="http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt">complexity of X.509</a> is another topic for another article.  </p>
<p>I hope you found this article useful, as while I found lots of information for <a href="http://www.bouncycastle.org/wiki/display/JA1/X.509+Public+Key+Certificate+and+Certification+Request+Generation">generating CSRs</a>, information on parsing and working with them was a little sparse.  Please feel free to leave your comments below!</p>
<hr/>Copyright &copy; 2008 <strong><a href="http://unitstep.net">unitstep.net</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact <strong><a href="mailto:webmaster@unitstep.net">webmaster@unitstep.net</a></strong> for more information.<br/><span style="float: right;font-size: 7pt"><a href="http://blog.taragana.com/index.php/archive/wordpress-plugins-provided-by-taraganacom/">Plugin</a> by <a href="http://www.taragana.com/">Taragana</a></span>]]></content:encoded>
			<wfw:commentRss>http://unitstep.net/blog/2008/10/27/extracting-x509-extensions-from-a-csr-using-the-bouncy-castle-apis/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The importance of Draconian validation for method parameters</title>
		<link>http://unitstep.net/blog/2008/05/15/the-importance-of-draconian-validation-for-method-parameters/</link>
		<comments>http://unitstep.net/blog/2008/05/15/the-importance-of-draconian-validation-for-method-parameters/#comments</comments>
		<pubDate>Fri, 16 May 2008 01:55:17 +0000</pubDate>
		<dc:creator>Peter Chng</dc:creator>
		
		<category><![CDATA[development]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[programming]]></category>

		<category><![CDATA[testing]]></category>

		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://unitstep.net/?p=326</guid>
		<description><![CDATA[I recently ran into a problem where the callers of one of my methods was using it improperly by suppling a parameter that did not conform to the required values.  However, the problems did not surface until I changed the implementation; previously, things worked by chance due to an implementation detail.
I had been using [...]]]></description>
			<content:encoded><![CDATA[<p>I recently ran into a problem where the callers of one of my methods was using it improperly by suppling a parameter that did not conform to the required values.  However, the problems did not surface until I changed the implementation; previously, things worked <em>by chance</em> due to an implementation detail.</p>
<p>I had been using input validation, but my validation procedure was not stringent enough to detect the improper parameter.  This was tied to the fact that before the implementation change, things worked perfectly fine even with the improper inputs.  However, the implementation change &#8220;broke&#8221; this work flow.  All of this has led me to believe in the great importance of:</p>
<ol>
<li>Draconian validation: For inputs, only accept what you say you will accept.  Nothing else should pass.</li>
<li>Proper unit testing: Test your method with a variety of inputs, both expected and unexpected or non-conforming.  You never know what callers will pass into your methods.</li>
</ol>
<p>Let me go into some more detail.</p>
<h3>Unintended consequences</h3>
<p>I had written a method that would accept a FQDN (Fully-Qualified Domain Name) as its argument.  The purpose of this method was to retrieve some information over HTTPs from the web server running on the server with the specified domain.  Since domain names are protocol-neutral (i.e. they aren&#8217;t preceded by something like &#8220;http://&#8221;), I ended up forming a <code><acronym class="uttInitialism" title="Uniform Resource Locator">URL</acronym></code> object based on the FQDN, since eventually I&#8217;d be retrieving information over HTTPs anyways:</p>
<pre><code>final <acronym class="uttInitialism" title="Uniform Resource Locator">URL</acronym> url = new <acronym class="uttInitialism" title="Uniform Resource Locator">URL</acronym>("https://" + fqdn + "/path_to_service");</code></pre>
<p>I figured that this was enough protection in terms of input validation, since the constructor for <code><acronym class="uttInitialism" title="Uniform Resource Locator">URL</acronym></code> throws a <a href="http://java.sun.com/javase/6/docs/api/java/net/URL.html#URL(java.lang.String)"><code>MalformedURLException </code></a> if something goes wrong.  (There was other code to check if the web server at the specified <acronym class="uttInitialism" title="Uniform Resource Locator">URL</acronym> could actually be contacted and this was contained in the actual retrieval)</p>
<p>However, it turned out that callers had started using this method by passing in not just an FQDN, but an FQDN followed by a port number in the following format: host.name:portNumber.  This was being used so that servers operating on non-default HTTPs ports could be contacted.</p>
<p>Initially, this worked, as then the statement above was executed with something like this:</p>
<pre><code>// With fqdn == "some.host.name:portNumber", nothing fails.
final <acronym class="uttInitialism" title="Uniform Resource Locator">URL</acronym> url = new <acronym class="uttInitialism" title="Uniform Resource Locator">URL</acronym>("https://" + fqdn + "/path_to_service");</code></pre>
<p>This was because the <acronym class="uttInitialism" title="Uniform Resource Locator">URL</acronym> formed was still valid.  However, this was an invalid use of my method because we had never specified that this sort of input was allowed.  It just <em>happened</em> to work.  The issue of non-default HTTPs ports and the usage here was never discussed and because it seemingly worked, nothing was done about it.</p>
<h3>Changing times</h3>
<p>Some time went on until I decided to make an implementation change.  Instead of retrieving the information from the web server itself, I would instead retrieve it directly from the TLS handshake process using a API provided to me.  (The information was related to the certificates)</p>
<p>This API accepted two parameters: The server host name or FQDN, and a separate port number.  Not realizing that callers were passing in non-default port numbers in the first place, I ignorantly just passed the FQDN supplied to me into this API along with the default HTTPs port. (443)</p>
<p>As expected, this broke the functionality that callers had come to expect of my API, namely, custom HTTPs ports specified alongside the FQDN in the argument.  It was only after these complaints were filed that I realized my API was expected to take not just the FQDN, but something like &#8220;server.host.name:8080&#8243;.</p>
<h3>The causes</h3>
<p>The problem was quickly fixed as the solution was fairly trivial, but the causes have taught me several lessons.</p>
<ol>
<li>
<h4>Be Draconian in your input validation</h4>
<p>Or, don&#8217;t trust your callers to read your documentation.  Initially, I thought my method was to accept only an FQDN.  Even though I was wrong in this respect, the problem could&#8217;ve been identified earlier if I had coded my method to fail (i.e. throw an exception) if anything that <strong>was not</strong> an FQDN was passed in.  (Simply forming a <code><acronym class="uttInitialism" title="Uniform Resource Locator">URL</acronym></code> object around it was not stringent enough) This way, things wouldn&#8217;t have initially worked by coincidence and I would&#8217;ve had an earlier opportunity to correct my mistake.
</li>
<li>
<h4>Unit test for exceptional cases</h4>
<p>My unit testing of my method was not extensive enough.  Though I coded both pass and fail tests using <a href="http://junit.sourceforge.net/">JUnit</a>, I did not test for cases where someone would (very likely) try to pass in a port number along with the FQDN.  This step goes hand-in-hand with the above: Code your methods to accept <strong>only</strong> what you&#8217;ve said they&#8217;d accept, and fail on everything else.  Then, unit test to make sure this contract is fulfilled.
</li>
</ol>
<p>While the problem was frustrating, I&#8217;m glad to have learned these lessons.</p>
<hr/>Copyright &copy; 2008 <strong><a href="http://unitstep.net">unitstep.net</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact <strong><a href="mailto:webmaster@unitstep.net">webmaster@unitstep.net</a></strong> for more information.<br/><span style="float: right;font-size: 7pt"><a href="http://blog.taragana.com/index.php/archive/wordpress-plugins-provided-by-taraganacom/">Plugin</a> by <a href="http://www.taragana.com/">Taragana</a></span>]]></content:encoded>
			<wfw:commentRss>http://unitstep.net/blog/2008/05/15/the-importance-of-draconian-validation-for-method-parameters/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Eclipse: The best and only IDE you&#8217;ll ever need*</title>
		<link>http://unitstep.net/blog/2008/02/10/eclipse-the-best-and-only-ide-youll-ever-need/</link>
		<comments>http://unitstep.net/blog/2008/02/10/eclipse-the-best-and-only-ide-youll-ever-need/#comments</comments>
		<pubDate>Mon, 11 Feb 2008 00:39:16 +0000</pubDate>
		<dc:creator>Peter Chng</dc:creator>
		
		<category><![CDATA[JavaScript]]></category>

		<category><![CDATA[PHP]]></category>

		<category><![CDATA[development]]></category>

		<category><![CDATA[eclipse]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[programming]]></category>

		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://unitstep.net/blog/2008/02/10/eclipse-the-best-and-only-ide-youll-ever-need/</guid>
		<description><![CDATA[
* Sensationalist headline inspired by previous posts
Eclipse is my IDE of choice, as you&#8217;l probably have noticed from some of my previous articles.  I had been wanting to write an article about why I use it (and why I switched to it), but kept putting it off.  Recently, Matt Mullenweg wrote about his [...]]]></description>
			<content:encoded><![CDATA[<p class="img align-right"><img src='http://unitstep.net/wordpress/wp-content/uploads/2008/02/eclipse-ide.thumbnail.jpg' alt='Copyright The Eclipse Foundation' /></p>
<p class="note less">* Sensationalist headline inspired by <a href="/blog/2007/10/16/sirreals-g15-plugin-the-best-and-only-logitech-g15-sdk-applet-youll-ever-need/">previous posts</a></p>
<p>Eclipse is my IDE of choice, as you&#8217;l probably have noticed from some of my <a href="/blog/2008/01/19/using-assemblas-trac-with-eclipse-mylyn-xml-rpc-access/">previous articles</a>.  I had been wanting to write an article about why I use it (and why I switched to it), but kept putting it off.  Recently, Matt Mullenweg <a href="http://ma.tt/2008/02/wither-dreamweaver/">wrote about his problems with Dreamweaver</a>, and this perhaps prompted me to organize my notes on why I&#8217;ve chosen to use Eclipse.  Don&#8217;t get me wrong - I&#8217;m not advocating that you immediately switch and throw out your current editing tool (the headline above, as noted, is purely for sensationalism) - but rather I&#8217;m just urging you to consider Eclipse for your next project.</p>
<h3>Changing Gears</h3>
<p>Like many, before switching to Eclipse I had been using a pure text editor, Ultraedit, for most of my web-development activities.  Ultraedit seemed fine for <a href="/blog/2007/06/10/ultraedit-php-5-and-the-function-list/">most things</a>, offering basic features like code highlight and autocompletion.  However, it lacked a certain finesse when it came to dealing with larger projects.  For example, if you&#8217;d defined a class, its members wouldn&#8217;t be available for autocompletion.  Something else was needed.  I finally decided to take the plunge, and switch over to Eclipse for all my development towards the end of the summer last year.</p>
<p>Some might wonder why I was even using a text-editor in the first place for development.  For those coming from a traditional programming/development background, the idea of not using an IDE (Integrated Development Environment) is silly.  This is because a lot of programming languages are compiled, and in this case, it just makes sense to use an IDE since it&#8217;s easier to write code, compile and debug using one tool instead of multiple ones. </p>
<p>However, for scripting languages, especially those meant to run on a web server, one can &#8220;get away&#8221; with not using an IDE quite easily.  This is because the scripts are not run standalone but are almost always executed in the context of a web server; thus you&#8217;re usually editing code that you then run on a development web server, without the need for a special tool like a compiler.  Additionally, it&#8217;s easy to view the output using any web browser.  These reasons are what allowed me to persist in using a text-editor for so long.</p>
<h3>No turning back</h3>
<p>However, once I started using Eclipse, I was hooked.  I downloaded Eclipse PDT (<acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> Development Tools), which is basically a version of Eclipse bundled with the tools/plugins necessary for setting up a <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> development environment.  Besides offering everything Ultraedit did, it also offered nice features like easy &#8216;Todo&#8217; lists, (just type &#8216;todo&#8217; anywhere in a comment and it&#8217;s automatically indexed by Eclipse into a list), code completion for built-in <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> functions and your own as well as a multitude of other advanced features that IDEs have.  Oh, and it&#8217;s also FOSS. (Free and Open Source Software)</p>
<p>However, perhaps the best part about Eclipse is its robust and well-supported plugin system.  This allows Eclipse to pretty much assume any feature that someone is willing to write a plugin for.  This is what really sold me on Eclipse, because this almost makes its abilities endless.  Some of the plugins I use are <a href="http://subclipse.tigris.org/">Subclipse</a> for SVN integration, <a href="http://www.eclipse.org/mylyn/">Mylyn for Trac integration</a> and <a href="http://labs.adobe.com/technologies/jseclipse/">JSEclipse</a> for JavaScript editing.  This is part of the reason why Eclipse is the <a href="http://en.wikipedia.org/wiki/List_of_Eclipse-based_software">basis for many other IDEs</a> out there.</p>
<p>Some other nice features are the ability to link the IDE in with the <a href="http://www.zend.com/en/community/pdt#debugger">Zend Debugger</a>, thus allowing for proper debugging sessions with <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym>.</p>
<h3>Spoiled</h3>
<p>However, I&#8217;ve been pampered somewhat and have found a few things to complain about, at least when it comes to Eclipse PDT.  I use Eclipse JDT (Java) a work and its advanced <a href="http://en.wikipedia.org/wiki/Refactoring">refactoring abilities</a> are a feature I find myself wanting in the PDT version.  Have you ever found yourself wanting to rename a variable to something more descriptive but putting it off because you&#8217;re afraid you&#8217;ll mess something up by forgetting to change the name somewhere?</p>
<p>With some IDEs, you&#8217;re left having to just do a search-and-replace in order to accomplish what should be a trivial name refactor.  Even if your editor supports regex searches, things can still be tricky - what if you&#8217;ve used the same name, but in a different context, and thus shouldn&#8217;t change the variable there?  The point is, the process still has to be human-supervised and is tedious.  With Eclipse JDT&#8217;s advanced refactoring, you can rename the variable once - and the IDE is smart enough to know where else to change it to keep the code consistent - <strong>very</strong> neat, and I was amazed when I first used it.  Other refactoring abilities include extracting methods out of blocks of code in order to clean up lengthy methods.  All of this makes your life 10 times easier and allows you focus on real programming rather than annoying tasks.</p>
<p>However, Eclipse PDT doesn&#8217;t support this for <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> code, yet.  I hear that it may be supported in a <a href="http://wiki.eclipse.org/PDT/1.5_Features_Proposal">later release</a>, so I have my fingers crossed.  Perhaps accomplishing these refactoring tasks is easier in Java because of its compiled nature or because the JDT project has received more attention.  It&#8217;s definitely possible in <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym>, as some IDEs, such as the <a href="http://www.zend.com/en/products/studio/">Zend Studio</a> (which is based on Eclipse) support this ability.  Zend Studio, however, is a commercial solution and I haven&#8217;t tried it out yet.</p>
<h3>Nothing&#8217;s perfect</h3>
<p>Eclipse does have its downsides as compared to a traditional text editor.  First of all, it&#8217;s a memory hog - though most IDEs are.  I have regularly seen Eclipse eat up 300-400 MB of RAM if I&#8217;ve been using it for a long time.  However, it should be noted that I have not had it crash once, so it&#8217;s been rock-solid as far as stability goes.  Nonetheless, I recommend you to have at least 2 GB of memory if you really want to use it properly, since you&#8217;re likely to have other programs open.  This is especially important if you&#8217;re running Windows Vista.  RAM is quiet cheap nowadays, and you can easily pick up 2 GB for $50 or less and upgrading is a painless process, so there&#8217;s no reason not to.</p>
<h3>Finishing up</h3>
<p>Eclipse has changed my life.  Okay, so perhaps I&#8217;m exaggerating a bit.  But, I can say that development, at least for me, would be much harder without Eclipse.  If you&#8217;re still using a text editor for development, I urge you to give Eclipse a try - just for 30 days, and see how you like it.  I don&#8217;t guarantee results as good as mine, but you may be pleasantly surprised.</p>
<hr/>Copyright &copy; 2008 <strong><a href="http://unitstep.net">unitstep.net</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact <strong><a href="mailto:webmaster@unitstep.net">webmaster@unitstep.net</a></strong> for more information.<br/><span style="float: right;font-size: 7pt"><a href="http://blog.taragana.com/index.php/archive/wordpress-plugins-provided-by-taraganacom/">Plugin</a> by <a href="http://www.taragana.com/">Taragana</a></span>]]></content:encoded>
			<wfw:commentRss>http://unitstep.net/blog/2008/02/10/eclipse-the-best-and-only-ide-youll-ever-need/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Sun acquires MySQL for $1 billion USD</title>
		<link>http://unitstep.net/blog/2008/01/16/sun-acquires-mysql-for-1-billion-usd/</link>
		<comments>http://unitstep.net/blog/2008/01/16/sun-acquires-mysql-for-1-billion-usd/#comments</comments>
		<pubDate>Thu, 17 Jan 2008 00:12:47 +0000</pubDate>
		<dc:creator>Peter Chng</dc:creator>
		
		<category><![CDATA[SQL]]></category>

		<category><![CDATA[database]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[mysql]]></category>

		<category><![CDATA[sun]]></category>

		<guid isPermaLink="false">http://unitstep.net/blog/2008/01/16/sun-acquires-mysql-for-1-billion-usd/</guid>
		<description><![CDATA[There was some unexpected news this morning when Sun announced plans to acquire MySQL. (Offhand remark: What is up with that handshake?!?)  Though rumours of a MySQL IPO had surfaced and re-surfaced throughout last year, this was quite a shock to me, and apparently many others.  The price - $1 billion USD - [...]]]></description>
			<content:encoded><![CDATA[<p>There was some unexpected news this morning when <a href="http://blogs.mysql.com/kaj/2008/01/16/sun-acquires-mysql/">Sun announced plans</a> to acquire MySQL. (Offhand remark: What is up with that handshake?!?)  Though rumours of a <a href="http://www.techcrunch.com/2007/10/26/mysql-ipo-chatter-picking-up-again/">MySQL IPO</a> had surfaced and re-surfaced throughout last year, this was quite a shock to me, and apparently many others.  The price - $1 billion USD - had no small part in this surprise.  Indeed, when you consider that their main software product is open source, some may question the valuation.</p>
<h3>Software is only a piece of the puzzle</h3>
<p>While MySQL is indeed open-source - licensed under the GPL - <a href="http://en.wikipedia.org/wiki/MySQL_AB">MySQL AB</a>, the company in control of the project, sells services and support relating to their flagship product.  Furthermore, the software is dual-licensed (as are many projects, such as the JavaScript library, <a href="http://jquery.com">jQuery</a>), allowing the company to sell the product to clients that may not want the provisions of the GPL to be imposed upon their usage of the software.</p>
<p>With the traditional model of software, customers and clients pay for the software or a license to use it.  In these newer models, almost all based around open-source, it is the value-added service and support that are at the heart of the business model.  Note that MySQL AB is not the only company to do this; <a href="http://en.wikipedia.org/wiki/Red_Hat">Red Hat</a> has been around for years and they are certainly profitable.  With the success of open-source software, I have to believe that this, at least in part, is the future of software development.</p>
<h3>A great learning tool</h3>
<p>Open-source software also highlights another point - the value it brings by easing learning.  I remember when I was back in high school and starting to get into <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> and other web technologies.  Naturally, with <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> came MySQL (back then at version 3.23), and it was the availability of this quality, open-source and easy-to-setup DBMS that prompted me to learn SQL.  In my first real software project, creating the Cool Case Gallery for <a href="http://www.virtual-hideout.net">Virtual-Hideout</a>, I used both of these languages, which have since become valuable assets for me.  Kudos to MySQL and the open-source community for providing such great tools.</p>
<hr/>Copyright &copy; 2008 <strong><a href="http://unitstep.net">unitstep.net</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact <strong><a href="mailto:webmaster@unitstep.net">webmaster@unitstep.net</a></strong> for more information.<br/><span style="float: right;font-size: 7pt"><a href="http://blog.taragana.com/index.php/archive/wordpress-plugins-provided-by-taraganacom/">Plugin</a> by <a href="http://www.taragana.com/">Taragana</a></span>]]></content:encoded>
			<wfw:commentRss>http://unitstep.net/blog/2008/01/16/sun-acquires-mysql-for-1-billion-usd/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
