<?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>unitstep.net &#187; development</title>
	<atom:link href="http://unitstep.net/blog/category/development/feed/" rel="self" type="application/rss+xml" />
	<link>http://unitstep.net</link>
	<description>the home of peter chng</description>
	<lastBuildDate>Mon, 01 Mar 2010 02:28:39 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Evaluation of boolean values in JavaScript</title>
		<link>http://unitstep.net/blog/2009/08/11/evaluation-of-boolean-values-in-javascript/</link>
		<comments>http://unitstep.net/blog/2009/08/11/evaluation-of-boolean-values-in-javascript/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 01:20:05 +0000</pubDate>
		<dc:creator>Peter Chng</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[guides]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[boolean]]></category>
		<category><![CDATA[logical]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://unitstep.net/?p=987</guid>
		<description><![CDATA[If you have a background in a strongly-typed language such as Java, you&#8217;ll be used to using logical operators only with boolean values/expressions.  However, in most dynamically-typed languages this doesn&#8217;t have to be the case, due to the nature of dynamic typing: The type of the variable is often determined based on the context [...]]]></description>
			<content:encoded><![CDATA[<p>If you have a background in a strongly-typed language such as Java, you&#8217;ll be used to using logical operators only with boolean values/expressions.  However, in most dynamically-typed languages this doesn&#8217;t have to be the case, due to the nature of dynamic typing: The type of the variable is often determined based on the <em>context</em> in which it is used.</p>
<p>With <strong>JavaScript</strong> there are actually two concepts at play when using logical operators: What is actually returned from the result of a logical operation, and how variables are converted to boolean values when the context requires it.</p>
<h2>Undergoing a conversion</h2>
<p>Firstly, we&#8217;ll look at how variables in JavaScript are converted to boolean values.  One way to explicitly convert a non-boolean value to a boolean one in JavaScript is to use the <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Boolean#Description">global Boolean object as a function</a>.  By using the following code, you can explicitly get the boolean conversion of a variable or expression:</p>
<pre><code>var asBoolean = Boolean(someVariable);</code></pre>
<p>The variable <code>asBoolean</code> is now guaranteed to have a boolean value.  <strong>Note that this is not the same as the expression <code>new Boolean(someVariable)</code>, as that returns a Boolean (wrapper) object representing the converted value of <code>someVariable</code>, not a boolean primitive.</strong></p>
<p>So what values of <code>someVariable</code> will result in <code>true</code> being returned, and which ones will result in <code>false?</code>  The following values will evaluate to <code>false</code>, while all others will evaluate to <code>true</code>:</p>
<ul>
<li>0 or -0 (Most floating-point implementations have <a href="http://en.wikipedia.org/wiki/Signed_zero">positive and negative zero</a>, due to the IEEE 754 standard)</li>
<li>null</li>
<li>undefined</li>
<li>NaN</li>
<li>The empty string (&#8220;&#8221;)</li>
<li><code>false</code> itself</li>
</ul>
<p>This means that all other expressions or values, including any non-null object (including the <code>Boolean</code> object for false!) and the string &#8220;false&#8221; will be converted to true.</p>
<p>Note that using the <code>Boolean</code> function isn&#8217;t the only way to explicitly convert a variable to its boolean equivalent.  You could also apply the logical NOT operator twice, like so:</p>
<pre><code>var asBoolean = !(!someVariable);</code></pre>
<p>This is because the contract of the logical NOT operator in JavaScript is to return false if the operand can be converted to true and true otherwise.  The second NOT simply reverses the negation done by the first NOT operator.  While all of this may seem dead simple, it will be important to note as we move on to how other logical operators work.</p>
<h2>Logical conversion</h2>
<p>This is perhaps the most important difference with JavaScript.  <strong>Although the logical NOT operator (!) is guaranteed to return a boolean value, the logical AND (&#038;&#038;) and logical OR (||) operators are not</strong>.  This is by design, and although it might be a bit of a change for some developers, the feature can actually be quite useful.</p>
<p>Consider the following code examples:</p>
<pre><code>var result = a &amp;&amp; b</code></pre>
<p><strong>In this example of using logical AND, <code>a</code> is returned if it can be converted to false; otherwise <code>b</code> is returned.</strong></p>
<pre><code>var result = a || b</code></pre>
<p><strong>In this example of using logical OR, <code>a</code> is returned if it can be converted to true; otherwise <code>b</code> is returned.</strong></p>
<p>This means that one of the original operands or expressions used with the logical operators will be returned as a result of the evaluation.  You will not always get an actual boolean value, unless both of the operands were booleans to begin with.  Usually, this doesn&#8217;t matter, since if you use the result in a boolean context, it will get converted to the expected value.  For example:</p>
<pre><code>var string1 = "";
var string2 = "a string that is not empty";
var result = string1 || string2;
if (result)
{
  window.alert("At least one string was not empty");
  window.alert(result);
}</code></pre>
<p>This example will output &#8220;At least one string was empty&#8221;, and then &#8220;a string that is not empty&#8221;.  This is because the logical OR operator first converts <code>string1</code> to a boolean, which results in <code>false</code>.  Thus, the result of the logical OR returns <code>string2</code> into the result.  Since the result is now a non-empty string, it converts to <code>true</code> for the if-conditional.  </p>
<p>This also highlights a convenient way of using logical OR &#8211; give me the first expression if it evaluates to true, otherwise give me the second.  This is usually used to test for the availability of built-in objects in a particular JavaScript environment.</p>
<p>However, consider the following example:</p>
<pre><code>var string1 = "";
var string2 = "a string that is not empty";
var result = string1 || string2;
if (true == result)
{
  // We will never get here.
  window.alert("At least one string was not empty");
  window.alert(result);
}</code></pre>
<p>In this slightly changed example, instead of directly supplying the result to the if-conditional, we test whether it is equal to <code>true</code>.  In this case, it fails, since when using the <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Operators/Comparison_Operators">equality operator</a>, operands are not converted to booleans.  (Using the strict equality operator also would not work)</p>
<p>This underscores an important point: <strong>If you actually want a boolean value to work with, you will have to explicitly convert it, using either the <code>Boolean</code> function or a double application of the logical NOT operator</strong>, like so:</p>
<pre><code>result = Boolean(result);
// Or, we could do this:
result = !(!result);</code></pre>
<h2>Conclusion</h2>
<p>JavaScript offers some neat features due to its dynamic typing and these can help speed development, but you just need to be aware of how they work so that you don&#8217;t get tripped up.  This is especially true when dealing with implicit type conversion and how logical operators work.  I hope you found this helpful and as always, any feedback is appreciated!</p>
<h3>References</h3>
<ol class="less note">
<li><a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Operators/Logical_Operators">Logical Operators</a></li>
<li><a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Predefined_Core_Objects/Boolean_Object">Boolean Object</a></li>
<li><a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Boolean#Description">Boolean Description</a></li>
<li><a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Operators/Comparison_Operators">Comparison Operators</a></li>
</ol>
<hr/>Copyright &copy; 2010 <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/2009/08/11/evaluation-of-boolean-values-in-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Separating UI from implementation</title>
		<link>http://unitstep.net/blog/2009/07/05/separating-ui-from-implementation/</link>
		<comments>http://unitstep.net/blog/2009/07/05/separating-ui-from-implementation/#comments</comments>
		<pubDate>Mon, 06 Jul 2009 02:21:10 +0000</pubDate>
		<dc:creator>Peter Chng</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[usability]]></category>
		<category><![CDATA[user interface]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[ui]]></category>

		<guid isPermaLink="false">http://unitstep.net/?p=960</guid>
		<description><![CDATA[I saw this comic about usability (linked from this question at Stack Overflow) and couldn&#8217;t help but let out a distressed laugh.  How often have you seen this happen at your workplace, or in an application you&#8217;ve had the &#8220;pleasure&#8221; of using? For every elegantly designed UI that exists, there seems to be a [...]]]></description>
			<content:encoded><![CDATA[<p>I saw <a href="http://stuffthathappens.com/blog/2008/03/05/simplicity/">this comic about usability</a> (linked from <a href="http://stackoverflow.com/questions/84556/whats-your-favorite-programmer-cartoon">this question at Stack Overflow</a>) and couldn&#8217;t help but let out a distressed laugh.  How often have you seen this happen at your workplace, or in an application you&#8217;ve had the &#8220;pleasure&#8221; of using? For every elegantly designed UI that exists, there seems to be a plethora of poorly designed ones that do their best to confuse users.</p>
<p>To me, a lot of this UI complexity stems directly from a lack of separation between the UI and business logic layers.</p>
<h2>Proper separation</h2>
<p>As developers, we&#8217;re accustomed to the best practices of modularity and separating the implementation from the interface.  This has lead to such patterns as MVC and Interface Oriented Design.  However, when it comes to <strong>designing</strong> the UI layer, these rules sometimes aren&#8217;t followed.  This is why we end up with overly complex &#8220;Search&#8221; pages, offering every option under the Sun, and configuration dialogs/screens with a <a href="http://developers.slashdot.org/comments.pl?sid=102620&#038;cid=8744744">one-to-one relationship</a> to settings files or some other underlying implementation detail under the guise of &#8220;letting the user decide what they want&#8221;.</p>
<p>Without clear UI planning, this one-to-one relationship tends to rear its ugly head more often.  Take our first example of a &#8220;Search&#8221; page.  In most applications, the search functionality is interacting with some sort of a database backend, most likely a SQL RDBMS.  The lazy approach is to design the search form based on the format of the SQL query itself.  This is how we get search forms with multiple fields, drop-down boxes and so forth &#8211; <strong>because this format translates almost directly into a SQL query; </strong> i.e. of the form <code>WHERE col1 LIKE... AND col2 LIKE...</code></p>
<p>Just because this is easier for the developer, doesn&#8217;t mean it&#8217;s the best solution for the end user.  In fact, it&#8217;s often the case that this is the exact opposite.  </p>
<h2>Thinking like a user</h2>
<p>In general, users don&#8217;t care about the implementation of your application or how it stores data.  They shouldn&#8217;t have to know about the columns of the table where the data is stored, so why make a search form that exposes this? Instead, you need to understand what your users want and how they&#8217;re most likely to use your application.  This isn&#8217;t an easy task, as <a href="http://mpt.net.nz/archive/2004/05/23/design">many have pointed out</a>.</p>
<p>This is where I think most UI problems come from &#8211; a misunderstanding of what users want.  This isn&#8217;t to say that these developers are dumb or careless; but just that when it comes to empathizing with their users, they often are unable to because they know their own software and have such an intimate view of it from a coder&#8217;s perspective. </p>
<p>Take the example of <a href="http://qttabbar.wikidot.com/">QTTabBar</a>, a Windows Explorer extension written in .NET that adds many useful features such as tabs, etc. to the interface.  It is an excellent extension and does things very well, but the options page is a complete nightmare.</p>
<p class="image">
<a href="http://unitstep.net/wordpress/wp-content/uploads/2009/07/ui-implementation-1.jpg"><img src="http://unitstep.net/wordpress/wp-content/uploads/2009/07/ui-implementation-1-250x300.jpg" alt="ui-implementation-1" title="ui-implementation-1" width="250" height="300" class="alignnone size-medium wp-image-972" /></a>
</p>
<p>There are just too many options on this one page; what do they all mean? Furthermore, there are nine more tabs, each with roughly the same number of additional options! This is far too complicated, and I&#8217;m guessing most people will never have a use for all of these options.</p>
<p>Of course, it&#8217;s completely unfair of me to pick on <a href="http://qttabbar.wikidot.com">QTTabBar</a> in this manner, considering it&#8217;s written by one guy who has chosen to give it away for free.  And, as I mentioned before, it&#8217;s a very useful utility that I can wholeheartedly recommend.</p>
<h2>A simple story</h2>
<p>Take a simply example, where we want to search a set of <em>items</em>, each of which have four separate properties &#8211; <em>name, description, <acronym class="uttInitialism" title="Uniform Resource Locator">URL</acronym></em> and <em>tags</em>.  The items are displayed on screen with all of the four properties shown.  The naive way would be to provide a search form that had fields for each property and allow users to search that way.</p>
<p>But with this simple (albeit contrived) example, there is an obviously simpler solution.  Since all of the four pieces of information about an item are shown onscreen, it would be much better just to provide a single search field whose input would be used to search all four properties, returning all items that had a match in any of the properties.  From a user&#8217;s point of view, this makes sense, since they are searching through what they know they can see and interact with. </p>
<p>If an advanced search was needed, it could be added later, but I would only do this if I knew it was absolutely needed by users, since the simple case is likely good for >90% of your users.</p>
<hr/>Copyright &copy; 2010 <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/2009/07/05/separating-ui-from-implementation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Determine your visitor&#8217;s location based on IP address</title>
		<link>http://unitstep.net/blog/2009/06/29/determine-your-visitors-location-based-on-ip-address/</link>
		<comments>http://unitstep.net/blog/2009/06/29/determine-your-visitors-location-based-on-ip-address/#comments</comments>
		<pubDate>Tue, 30 Jun 2009 02:37:17 +0000</pubDate>
		<dc:creator>Peter Chng</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[geolocation]]></category>
		<category><![CDATA[maps]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[ip address]]></category>
		<category><![CDATA[location]]></category>
		<category><![CDATA[lookup ip-geolocation]]></category>

		<guid isPermaLink="false">http://unitstep.net/?p=935</guid>
		<description><![CDATA[If you&#8217;re running a website that provides a service, it&#8217;s likely that it would be beneficial to know a user&#8217;s location (or have a rough idea) so that the content could be tailored to their specific geographic area.  But how do you get their location, without having to ask them? By using their IP [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re running a website that provides a service, it&#8217;s likely that it would be beneficial to know a user&#8217;s location (or have a rough idea) so that the content could be tailored to their specific geographic area.  But how do you get their location, without having to ask them? By using their IP address, it&#8217;s possibly to determine their general area with fairly good accuracy. In this tutorial, I&#8217;ll explain how to do that using the free <a href="http://ipinfodb.com/ip_database.php">IP address geolocation database</a> from <a href="http://ipinfodb.com/">IPInfoDB</a>.</p>
<h2>Motivation and Usage</h2>
<p>There are numerous reasons for using the user&#8217;s location to improve the quality of a service.  For example, the restaurant guide and review site, <a href="http://www.restaurantica.com/">Restaurantica</a>, automatically makes a guess as to your location and populates the &#8220;Search&#8221; field so that you are one click away from finding information tailored to your geographic area.  </p>
<p>This determination is based on the user&#8217;s IP address.  Usually, the lookup is done based on a static set of mappings from IP addresses to geographical locations, like cities.  In fact, this is exactly what the <a href="http://ipinfodb.com/ip_database.php">IP address geolocation database</a> (that we&#8217;ll use) does.  It has the advantage of being easy to understand but unfortunately the accuracy can degrade over time, as IP addresses are usually not hardwired to specific locations.  For example, most DSL users are subject to DHCP, so the same IP address may be re-used across different cities. (The IP address database from IPInfoDB is updated periodically to help reduce this inaccuracy)</p>
<p>Thus, you should not rely on the information provided to be 100% accurate; it should only be used as a suggestion.  This is why <a href="http://www.restaurantica.com/">Restaurantica</a> only <em>populates</em> the search field with your estimated location, rather than giving you the results for that location right away; if it was wrong, the results for a different location would certainly be confusing to a user.  This gives the user a chance to correct any inaccurate lookups.</p>
<h2>Using the IP Address geolocation database</h2>
<p>The first step is to <a href="http://ipinfodb.com/ip_database.php">download the database</a> and import it into your local database; for this example I&#8217;ll use MySQL.  Note that the site also offers an <a href="http://ipinfodb.com/ip_location_api.php">IP location Lookup API</a>, which has the advantage of not requiring a local database but may be subject to usage limits; if you&#8217;ll be getting a lot of traffic you&#8217;ll be better off using the local database.</p>
<h3>Import the contents into MySQL</h3>
<p>I downloaded the <a href="http://mirrors.portafixe.com/ipinfodb/ip_database/current/ipinfodb_one_table_full.sql.bz2">Complete (City) database as one table in SQL format</a>.  Extracting the file from the archive, you&#8217;ll see that it&#8217;s well over 300 MB in size. If you&#8217;re fond of using <a href="http://www.phpmyadmin.net/home_page/index.php">phpMyAdmin</a>, you unfortunately won&#8217;t be able to import such a large file using that tool, so we&#8217;ll have to rely on the command line to import the contents.  Go to your <code>mysql/bin</code> folder and enter the following command, assuming you extracted the SQL file to the same location:</p>
<pre><code>mysql -u root -p [name of database] &lt; ipinfodb_one_table_full.sql</code></pre>
<p><strong>Running this command will take some time, as it won&#8217;t be fast having to import such a huge table</strong>.  Take a break and come back in a few minutes. <img src='http://unitstep.net/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  (You may want to create a new database to hold just this table, do that before running this command)  After that&#8217;s done, you should be able to see the contents in phpMyAdmin, like below:</p>
<p class="image">
<a href="http://unitstep.net/wordpress/wp-content/uploads/2009/06/ip-geolocation-1.jpg"><img src="http://unitstep.net/wordpress/wp-content/uploads/2009/06/ip-geolocation-1-300x84.jpg" alt="ip-geolocation-1" title="ip-geolocation-1" width="300" height="84" class="alignnone size-medium wp-image-945" /></a>
</p>
<h3>Using the database</h3>
<p>Querying the database is straightforward, and the IP Info DB website has plenty of examples <a href="http://ipinfodb.com/ip_database.php">at the bottom of the download page</a>.  Basically, once you have the user&#8217;s IP, you can use a query like this to find the most likely city it originated from:</p>
<pre><code>SELECT *
FROM `ip_group_city`
WHERE `ip_start` &lt;= INET_ATON([ip address as a string])
ORDER BY ip_start DESC
LIMIT 1;</code></pre>
<p>The INET_ATON function converts a string that is the dotted-quad octet form of an IP address (the form you&#8217;re most used to seeing) into a 32-bit unsigned integer.  This integer is then used to locate the record that most likely corresponds to the geographical location.  The database is structured such that row with the highest <code>ip_start</code> value not greater than the given IP address is deemed to be the most likely location.</p>
<p>An example:</p>
<pre><code>SELECT * FROM `ip_group_city` WHERE `ip_start` &lt;= INET_ATON('69.156.150.155') ORDER BY ip_start DESC limit 1;</code></pre>
<p>(This returns the city of Toronto, Ontario, Canada) If you want to get a list of likely locations, just increase the LIMIT argument to something like 10, and this will return 10 locations that are likely close to where the IP address is located.  <strong>Note that there may be duplicates in this list</strong>.</p>
<h2>A simple example</h2>
<p>Here&#8217;s a simple <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> script that takes the user&#8217;s IP address and displays their most likely location on a map using the <a href="http://code.google.com/apis/maps/documentation/staticmaps/">Google Static Maps API</a>.</p>
<pre><code>&lt;?php
$ipGeolocationDatabaseName = 'ip_geolocation';

$link = mysql_connect('localhost', 'root', '');
$ipAddress = mysql_real_escape_string($_SERVER['REMOTE_ADDR']);

echo $ipAddress;

mysql_select_db($ipGeolocationDatabaseName, $link);

$query = "SELECT * FROM `ip_group_city` " .
         "WHERE `ip_start` &lt;= INET_ATON( '$ipAddress' ) " .
         "ORDER BY ip_start DESC " .
         "LIMIT 1";
$resultLocation = mysql_query($query);

$numRows = mysql_num_rows($resultLocation);

if (0 == $numRows)
{
  echo "No likely locations found.";
}

while ($row = mysql_fetch_array($resultLocation))
{
  echo "&lt;pre&gt;";
  print_r($row);
  echo "&lt;/pre&gt;";

  $lat = urlencode($row['latitude']);
  $lng = urlencode($row['longitude']);
  if (!empty($lat) &amp;&amp; !empty($lng))
  {
    // NOTE: Replace the `key` parameter with your own, obtained from:
    // http://code.google.com/apis/maps/signup.html
    // (The one in use is only good for URLs on `localhost`)
    $queryString = "center=$lat,$lng";
    $queryString .= "&amp;zoom=10";
    $queryString .= "&amp;size=300x300";
    $queryString .= "&amp;markers=$lat,$lng,blue";
    $queryString .= "&amp;key=ABQIAAAAicCf6MqoHlR-MsfivtVWPRT2yXp_ZAY8_ufC3CFXhHIE1NvwkxTNmqRdvnM9orG9QdyALHoUZfmFuQ";
    $queryString .= "&amp;sensor=false";

    echo '&lt;img src="http://maps.google.com/staticmap?' . htmlentities($queryString) . '" alt="location" /&gt;';
  }
}
?&gt;</code></pre>
<p>Here&#8217;s what it display for my IP address:</p>
<p class="image">
<a href="http://unitstep.net/wordpress/wp-content/uploads/2009/06/ip-geolocation-2.jpg"><img src="http://unitstep.net/wordpress/wp-content/uploads/2009/06/ip-geolocation-2.jpg" alt="ip-geolocation-2" title="ip-geolocation-2" width="300" height="300" class="alignnone size-full wp-image-956" /></a>
</p>
<p>As you can see, it&#8217;s not always accurate, but it&#8217;s a good start to enhancing your website to offer localized services and features.</p>
<hr/>Copyright &copy; 2010 <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/2009/06/29/determine-your-visitors-location-based-on-ip-address/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Resolving log4j 1.2.15 dependency problems in Maven using exclusions</title>
		<link>http://unitstep.net/blog/2009/05/18/resolving-log4j-1215-dependency-problems-in-maven-using-exclusions/</link>
		<comments>http://unitstep.net/blog/2009/05/18/resolving-log4j-1215-dependency-problems-in-maven-using-exclusions/#comments</comments>
		<pubDate>Mon, 18 May 2009 15:44:35 +0000</pubDate>
		<dc:creator>Peter Chng</dc:creator>
				<category><![CDATA[build]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[dependency]]></category>
		<category><![CDATA[exclusion]]></category>
		<category><![CDATA[log4j]]></category>

		<guid isPermaLink="false">http://unitstep.net/?p=906</guid>
		<description><![CDATA[
If you&#8217;re using Maven to manage your project&#8217;s build and dependencies, you may have encountered some problems when trying to include the latest version of log4j as a dependency.  Specifically, log4j 1.2.15 depends on some artifacts that are not available in the central Maven repository due to licensing issues, and thus when you try [...]]]></description>
			<content:encoded><![CDATA[<p class="image align-right"><img src="http://unitstep.net/wordpress/wp-content/uploads/2009/05/maven.jpg" alt="maven" title="maven" width="150" height="37" class="alignnone size-full wp-image-916" /></p>
<p>If you&#8217;re using Maven to manage your project&#8217;s build and dependencies, you may have encountered some problems when trying to include the latest version of log4j as a dependency.  Specifically, <a href="http://mvnrepository.com/artifact/log4j/log4j/1.2.15">log4j 1.2.15</a> depends on some artifacts that are not available in the <a href="http://repo1.maven.org/maven2/">central Maven repository</a> due to <a href="http://www.mail-archive.com/log4j-dev@logging.apache.org/msg07529.html">licensing issues</a>, and thus when you try to build a project that depends on this version of log4j, you may not be able to download the artifacts and your build will fail.</p>
<p>We could download and <a href="http://onemanwenttomow.wordpress.com/2007/12/31/maven2-log4j-and-jmx-dependencies/">install these artifacts to the local repository</a>, if we really needed them.  But in most cases, they&#8217;re not needed and thus you won&#8217;t want your project relying on these artifacts just because some parts of log4j do.  Thus, we need to exclude them.</p>
<h2>The problem: Not really needed</h2>
<p>The issue is going from log4j <a href="http://mvnrepository.com/artifact/log4j/log4j/1.2.14">1.2.14</a> to <a href="http://mvnrepository.com/artifact/log4j/log4j/1.2.15">1.2.15</a>, the developers added some features which required some dependencies on various <code>sun</code> and <code>javax</code> packages.  However in most cases, you won&#8217;t be using this extra functionality, but if you just include log4j 1.2.15, this will cause your project to require those extra artifacts as per the <em>transitive dependency</em> rule.</p>
<p>Because some of these artifacts are not available from the central Maven repository, due to licensing issues, they will not be automatically installed to your local repository.  So, if you attempt to run <code>mvn install</code>, you&#8217;re likely to encounter this sort of error:</p>
<pre><code>[INFO] Unable to find resource 'com.sun.jdmk:jmxtools:jar:1.2.1' in repository central (http://repo1.maven.org/maven2)
[INFO] Unable to find resource 'javax.jms:jms:jar:1.1' in repository central (http://repo1.maven.org/maven2)
[INFO] Unable to find resource 'com.sun.jmx:jmxri:jar:1.2.1' in repository central (http://repo1.maven.org/maven2)
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Failed to resolve artifact.

Missing:
----------
1) com.sun.jdmk:jmxtools:jar:1.2.1
...
2) javax.jms:jms:jar:1.1
...
3) com.sun.jmx:jmxri:jar:1.2.1
...
----------
3 required artifacts are missing.</code></pre>
<p>And if you&#8217;re using Eclipse, and have used the Maven Eclipse plugin command (<code>mvn eclipse:eclipse</code>) to generate the project settings, you&#8217;ll have the problem of Eclipse not being able to find the artifacts references on the build path, resulting in an error like so:</p>
<p class="image">
<a href="http://unitstep.net/wordpress/wp-content/uploads/2009/05/maven-log4j-1.jpg"><img src="http://unitstep.net/wordpress/wp-content/uploads/2009/05/maven-log4j-1-300x237.jpg" alt="maven-log4j-1" title="maven-log4j-1" width="300" height="237" class="alignnone size-medium wp-image-911" /></a>
</p>
<p>This causes a big problem as it essentially prevents you from building your project.  You could <a href="http://onemanwenttomow.wordpress.com/2007/12/31/maven2-log4j-and-jmx-dependencies/">download and install these artifacts</a> to your local repository, but since they&#8217;re not really needed, we should <em>exclude</em> them from the dependency list for log4j.</p>
<h2>Excluding dependencies</h2>
<p>Thankfully, Maven make it easy to <a href="http://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html">exclude dependencies</a> from a certain project.  Looking at the <a href="http://mirrors.ibiblio.org/pub/mirrors/maven2/log4j/log4j/1.2.15/log4j-1.2.15.pom">log4j 1.2.15 POM file</a> (you may have to select &#8220;View Source&#8221;), we can see several dependencies that weren&#8217;t there in the previous release.  These are likely to support new features, and aren&#8217;t needed for the most common uses of log4j.  Here are the actual dependencies for log4j 1.2.15:</p>
<pre><code>&lt;dependencies&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;javax.mail&lt;/groupId&gt;
    &lt;artifactId&gt;mail&lt;/artifactId&gt;
    &lt;version&gt;1.4&lt;/version&gt;
  &lt;/dependency&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;javax.jms&lt;/groupId&gt;
    &lt;artifactId&gt;jms&lt;/artifactId&gt;
    &lt;version&gt;1.1&lt;/version&gt;
  &lt;/dependency&gt;
 &lt;dependency&gt;
    &lt;groupId&gt;com.sun.jdmk&lt;/groupId&gt;
    &lt;artifactId&gt;jmxtools&lt;/artifactId&gt;
    &lt;version&gt;1.2.1&lt;/version&gt;
  &lt;/dependency&gt;
 &lt;dependency&gt;
    &lt;groupId&gt;com.sun.jmx&lt;/groupId&gt;
    &lt;artifactId&gt;jmxri&lt;/artifactId&gt;
    &lt;version&gt;1.2.1&lt;/version&gt;
  &lt;/dependency&gt;
 &lt;dependency&gt;
    &lt;groupId&gt;oro&lt;/groupId&gt;
    &lt;artifactId&gt;oro&lt;/artifactId&gt;
    &lt;version&gt;2.0.8&lt;/version&gt;
    &lt;scope&gt;test&lt;/scope&gt;
  &lt;/dependency&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;junit&lt;/groupId&gt;
    &lt;artifactId&gt;junit&lt;/artifactId&gt;
    &lt;version&gt;3.8.1&lt;/version&gt;
    &lt;scope&gt;test&lt;/scope&gt;
  &lt;/dependency&gt;
&lt;/dependencies&gt;</code></pre>
<p>We only need to exclude the first four, and not the last two, since they have a scope of test, and won&#8217;t be included anyways.  <strong>To exclude these dependencies, add the log4j 1.2.15 dependency as show below.</strong></p>
<pre><code>&lt;dependency&gt;
  &lt;groupId&gt;log4j&lt;/groupId&gt;
  &lt;artifactId&gt;log4j&lt;/artifactId&gt;
  &lt;version&gt;1.2.15&lt;/version&gt;
  &lt;scope&gt;provided&lt;/scope&gt;
  &lt;exclusions&gt;
    &lt;exclusion&gt;
      &lt;groupId&gt;javax.mail&lt;/groupId&gt;
      &lt;artifactId&gt;mail&lt;/artifactId&gt;
    &lt;/exclusion&gt;
    &lt;exclusion&gt;
      &lt;groupId&gt;javax.jms&lt;/groupId&gt;
      &lt;artifactId&gt;jms&lt;/artifactId&gt;
    &lt;/exclusion&gt;
    &lt;exclusion&gt;
      &lt;groupId&gt;com.sun.jdmk&lt;/groupId&gt;
      &lt;artifactId&gt;jmxtools&lt;/artifactId&gt;
    &lt;/exclusion&gt;
    &lt;exclusion&gt;
      &lt;groupId&gt;com.sun.jmx&lt;/groupId&gt;
      &lt;artifactId&gt;jmxri&lt;/artifactId&gt;
    &lt;/exclusion&gt;
  &lt;/exclusions&gt;
&lt;/dependency&gt;</code></pre>
<p>This tells Maven not to add those artifacts to the classpath and so they won&#8217;t be needed to build your project anymore.  Note that you have to explicitly exclude each one, there is no way to exclude <strong>all</strong> of the dependencies for a project, but there is a <a href="http://jira.codehaus.org/browse/MNG-2315">feature request</a> for such an ability. </p>
<p>If you&#8217;re using Eclipse, after running <code>mvn eclipse:clean/mvn eclipse:eclipse</code>, you should have the build path properly setup without any missing artifacts:</p>
<p class="image">
<a href="http://unitstep.net/wordpress/wp-content/uploads/2009/05/maven-log4j-2.jpg"><img src="http://unitstep.net/wordpress/wp-content/uploads/2009/05/maven-log4j-2-300x264.jpg" alt="maven-log4j-2" title="maven-log4j-2" width="300" height="264" class="alignnone size-medium wp-image-914" /></a>
</p>
<p>Everything should now work!</p>
<h2>Transitive Dependencies and Exclusions</h2>
<p>The issue here is that the log4j 1.2.15 POM file probably should have marked these dependencies as <strong>optional</strong>, which would have had the same effect as having to exclude them on every project that referenced that version of log4j.  What does an <strong>optional</strong> dependency mean?  The <a href="http://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html">Maven website has a pretty good explanation</a>.</p>
<p>Basically, if you have a large project that requires a lot of dependencies, but the &#8220;core&#8221; features only require a subset of those dependencies, you may want to mark the others as &#8220;optional&#8221; so as not to burden any projects that reference yours.  Your project will still need all of the dependencies to build, but other projects that reference yours will only need the optional dependencies if they are using the additional features.  In this case, they&#8217;ll have to explicitly add those dependencies, as the transitive dependency rule won&#8217;t kick in for &#8220;optional&#8221; ones.</p>
<p>Also worthy to note: <strong>exclusions are done on a per-dependency basis</strong>.  This means that the dependencies that we excluded from log4j are <strong>only excluded from the log4j scope</strong>.  This has the effect of <strong>not</strong> globally excluding those dependencies.  So, for example, if we added another dependency that did really require the <code>javax.jms/jms</code> artifact, it would not be prevented from being added.  Furthermore, if we wanted, we could manually add a dependency to our own list for that JMS artifact, and it would show up as normal.</p>
<h4>References</h4>
<ol class="note less">
<li><a href="http://mavenize.blogspot.com/2007/06/exclude-transitive-dependencies.html">Exclude Transitive Dependencies</a></li>
<li><a href="http://techpolesen.blogspot.com/2007/11/maven-and-excluding-transitive.html">Maven and Excluding Transitive Dependencies</a></li>
</ol>
<hr/>Copyright &copy; 2010 <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/2009/05/18/resolving-log4j-1215-dependency-problems-in-maven-using-exclusions/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Using cURL in PHP to access HTTPS (SSL/TLS) protected sites</title>
		<link>http://unitstep.net/blog/2009/05/05/using-curl-in-php-to-access-https-ssltls-protected-sites/</link>
		<comments>http://unitstep.net/blog/2009/05/05/using-curl-in-php-to-access-https-ssltls-protected-sites/#comments</comments>
		<pubDate>Wed, 06 May 2009 01:22:12 +0000</pubDate>
		<dc:creator>Peter Chng</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[curl]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[pki]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[https]]></category>
		<category><![CDATA[ssl]]></category>
		<category><![CDATA[tls]]></category>

		<guid isPermaLink="false">http://unitstep.net/?p=877</guid>
		<description><![CDATA[
From PHP, you can access the useful cURL Library (libcurl) to make requests to URLs using a variety of protocols such as HTTP, FTP, LDAP and even Gopher.  (If you&#8217;ve spent time on the *nix command line, most environments also have the curl command available that uses the libcurl library)
In practice, however, the most [...]]]></description>
			<content:encoded><![CDATA[<p class="image align-right"><img src="http://unitstep.net/wordpress/wp-content/uploads/2009/05/curl-https-padlock.jpg" alt="curl-https-padlock" title="curl-https-padlock" width="100" height="116" class="alignnone size-full wp-image-895" /></p>
<p>From <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym>, you can access the useful <a href="http://ca2.php.net/manual/en/book.curl.php">cURL Library (libcurl)</a> to make requests to URLs using a variety of protocols such as <acronym class="uttInitialism" title="HyperText Transfer Protocol">HTTP</acronym>, FTP, LDAP and even <a href="http://blog.delicious.com/blog/2009/04/delicious-now-supports-gopher.html">Gopher</a>.  (If you&#8217;ve spent time on the *nix command line, most environments also have the <code>curl</code> command available that uses the libcurl library)</p>
<p>In practice, however, the most commonly-used protocol tends to be <acronym class="uttInitialism" title="HyperText Transfer Protocol">HTTP</acronym>, especially when using <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> for server-to-server communication.  Typically this involves accessing another web server as part of a web service call, using some method such as <a href="http://www.w3.org/XML/" class="ubernym uttInitialism"><acronym class="uttInitialism" title="eXtensible Markup Language">XML</acronym></a>-RPC or REST to query a resource.  For example, <a href="http://delicious.com/">Delicious</a> offers <a href="http://delicious.com/help/api">a <acronym class="uttInitialism" title="HyperText Transfer Protocol">HTTP</acronym>-based API</a> to manipulate and read a user&#8217;s posts.  However, when trying to access a HTTPS resource (such as the delicious API), there&#8217;s a little more configuration you have to do before you can get cURL working right in <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym>.</p>
<h2>The problem</h2>
<p>If you simply try to access a HTTPS (SSL or TLS-protected resource) in <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> using cURL, you&#8217;re likely to run into some difficulty.  Say you have the following code: (Error handling omitted for brevity)</p>
<pre><code>// Initialize session and set <acronym class="uttInitialism" title="Uniform Resource Locator">URL</acronym>.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);

// Set so curl_exec returns the result instead of outputting it.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

// Get the response and close the channel.
$response = curl_exec($ch);
curl_close($ch);</code></pre>
<p>If <code>$url</code> points toward an HTTPS resource, you&#8217;re likely to encounter an error like the one below:</p>
<pre><code>Failed: Error Number: 60. Reason: SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed</code></pre>
<p>The problem is that cURL has not been configured to trust the server&#8217;s HTTPS certificate.  The concepts of certificates and PKI revolves around the trust of Certificate Authorities (CAs), and by default, cURL is setup to <strong>not trust any CAs</strong>, thus it won&#8217;t trust any web server&#8217;s certificate.  So why don&#8217;t you have problems visiting HTTPs sites through your web browser? As it happens, the browser developers were nice enough to <a href="/blog/2009/03/16/using-the-basic-constraints-extension-in-x509-v3-certificates-for-intermediate-cas/">include a list of default CAs to trust</a>, covering most situations, so as long as the website operator purchased a certificate from one of these CAs.</p>
<h2>The quick fix</h2>
<p>There are two ways to solve this problem.  Firstly, we can simply configure cURL to accept <strong>any server(peer) certificate</strong>.  This isn&#8217;t optimal from a security point of view, but if you&#8217;re not passing sensitive information back and forth, this is probably alright.  Simply add the following line before calling <code>curl_exec()</code>:</p>
<pre><code>curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);</code></pre>
<p>This basically causes cURL to blindly accept any server certificate, without doing any verification as to which CA signed it, and whether or not that CA is trusted.  If you&#8217;re at all concerned about the data you&#8217;re passing to or receiving from the server, you&#8217;ll want to enable this peer verification properly.  Doing so is a bit more complicated.</p>
<h2>The proper fix</h2>
<p>The proper fix involves setting the <code>CURLOPT_CAINFO</code> parameter.  This is used to point towards a CA certificate that cURL should trust.  Thus, any server/peer certificates issued by this CA will also be trusted.  In order to do this, we first need to get the CA certificate.  In this example, I&#8217;ll be using the <a href="https://api.del.icio.us/">https://api.del.icio.us/</a> server as a reference.</p>
<p>First, you&#8217;ll need to visit the <acronym class="uttInitialism" title="Uniform Resource Locator">URL</acronym> with your web browser in order to grab the CA certificate.  Then, (in Firefox) open up the security details for the site by double-clicking on the padlock icon in the lower right corner:</p>
<p class="image">
<img src="http://unitstep.net/wordpress/wp-content/uploads/2009/05/curl-https-1.jpg" alt="curl-https-1" title="curl-https-1" width="263" height="84" class="alignnone size-full wp-image-891" />
</p>
<p>Then click on &#8220;View Certificate&#8221;:</p>
<p class="image">
<a href="http://unitstep.net/wordpress/wp-content/uploads/2009/05/curl-https-2.jpg"><img src="http://unitstep.net/wordpress/wp-content/uploads/2009/05/curl-https-2-300x250.jpg" alt="curl-https-2" title="curl-https-2" width="300" height="250" class="alignnone size-medium wp-image-890" /></a>
</p>
<p>Bring up the &#8220;Details&#8221; tab of the cerficates page, and <strong>select the certificate at the top of the hierarchy</strong>.  This is the CA certificate.</p>
<p class="image">
<a href="http://unitstep.net/wordpress/wp-content/uploads/2009/05/curl-https-3.jpg"><img src="http://unitstep.net/wordpress/wp-content/uploads/2009/05/curl-https-3-255x300.jpg" alt="curl-https-3" title="curl-https-3" width="255" height="300" class="alignnone size-medium wp-image-892" /></a>
</p>
<p>Then click &#8220;Export&#8221;, and save the CA certificate to your selected location, making sure to select the <strong>X.509 Certificate (PEM)</strong> as the save type/format.</p>
<p class="image">
<a href="http://unitstep.net/wordpress/wp-content/uploads/2009/05/curl-https-4.jpg"><img src="http://unitstep.net/wordpress/wp-content/uploads/2009/05/curl-https-4-300x223.jpg" alt="curl-https-4" title="curl-https-4" width="300" height="223" class="alignnone size-medium wp-image-893" /></a>
</p>
<p>Now we need to modify the cURL setup to use this CA certificate, with <code>CURLOPT_CAINFO</code> set to point to where we saved the CA certificate file to.</p>
<pre><code>curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAINFO, getcwd() . "/CAcerts/BuiltinObjectToken-EquifaxSecureCA.crt");</code></pre>
<p>The other option I&#8217;ve included, <code>CURLOPT_SSL_VERIFYHOST</code> can be set to the following integer values:</p>
<ul>
<li>0: Don&#8217;t check the common name (CN) attribute</li>
<li>1: Check that the common name attribute at least exists</li>
<li>2: Check that the common name exists and that it matches the host name of the server</li>
</ul>
<p>If you have <code>CURLOPT_SSL_VERIFYPEER</code> set to false, then from a security perspective, it doesn&#8217;t really matter what you&#8217;ve set <code>CURLOPT_SSL_VERIFYHOST</code> to, since without peer certificate verification, the server could use any certificate, including a self-signed one that was guaranteed to have a CN that matched the server&#8217;s host name.  So this setting is really only relevant if you&#8217;ve enabled certificate verification.</p>
<p>This ensures that not just any server certificate will be trusted by your cURL session.  For example, if an attacker were to somehow redirect traffic from <strong>api.delicious.com</strong> to their own server, the cURL session here would not properly initialize, since the attacker would not have access to a server certificate (i.e. would not have the private key) trusted by the CA we added.  These steps effectively export the trusted CA from the web browser to the cURL configuration.</p>
<h2>More information</h2>
<p>If you have the CA certificate, but it is not in the PEM format (i.e. it is in a binary or DER format that isn&#8217;t Base64-encoded), you&#8217;ll need to use something like OpenSSL to convert it to the PEM format.  The exact command differs depending on whether you&#8217;re converting from PKCS12 or DER format.</p>
<p>There is a <code>CURLOPT_CAPATH</code> option that allows you to specify a directory that holds multiple CA certificates to trust.  But it&#8217;s not as simple as dumping every single CA certificate in this directory.  Instead, they CA certificates must be named properly, and the <a href="http://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html">OpenSSL <code>c_rehash</code> utility can be used</a> to properly setup this directory for use by cURL.</p>
<hr/>Copyright &copy; 2010 <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/2009/05/05/using-curl-in-php-to-access-https-ssltls-protected-sites/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>Google App Engine for Java: First thoughts</title>
		<link>http://unitstep.net/blog/2009/04/15/google-app-engine-for-java-first-thoughts/</link>
		<comments>http://unitstep.net/blog/2009/04/15/google-app-engine-for-java-first-thoughts/#comments</comments>
		<pubDate>Wed, 15 Apr 2009 23:29:22 +0000</pubDate>
		<dc:creator>Peter Chng</dc:creator>
				<category><![CDATA[app engine]]></category>
		<category><![CDATA[cloud computing]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[web2.0]]></category>
		<category><![CDATA[hosting]]></category>
		<category><![CDATA[web applications]]></category>

		<guid isPermaLink="false">http://unitstep.net/?p=866</guid>
		<description><![CDATA[
When Google launched App Engine about one year ago, many were excited about their expected move into the cloud computing space, but at the same time, dismayed that it only supported Python, a language seemingly favoured at the Mountain View-headquartered company.
However, Google was adamant that they would begin supporting new languages and began taking requests [...]]]></description>
			<content:encoded><![CDATA[<p class="image align-right"><img src="http://unitstep.net/wordpress/wp-content/uploads/2009/04/google-app-engine-java.jpg" alt="google-app-engine-java" title="google-app-engine-java" width="175" height="154" class="alignnone size-full wp-image-873" /></p>
<p>When Google <a href="http://www.readwriteweb.com/archives/google_cloud_control.php">launched App Engine about one year ago</a>, many were excited about their expected move into the cloud computing space, but at the same time, dismayed that it only supported Python, a language seemingly favoured at the Mountain View-headquartered company.</p>
<p>However, Google was adamant that they would begin supporting new languages and <a href="http://code.google.com/p/googleappengine/issues/list">began taking requests on their issue tracker</a> for what language to support next.  So, it was no surprise that <a href="http://googleappengine.blogspot.com/2009/04/seriously-this-time-new-language-on-app.html">support for Java was announced last week</a> as part of an <a href="http://code.google.com/appengine/docs/java/overview.html">&#8220;Early Look&#8221;</a> at the feature. </p>
<h2>I qualified for signup!</h2>
<p>The <a href="http://code.google.com/appengine/">Google App Engine page</a> indicated that access would be limited to the first 10,000 developers who signed up, but I was able to get approved for access after signing up over the weekend, even though Java support was launched last Wednesday on April 8th.  Google has since expanded the &#8220;early Look&#8221; <a href="http://googleappengine.blogspot.com/2009/04/early-look-at-java-language-support.html">to accommodate a total of 25,000 developers</a>, so be sure to sign up if you can!</p>
<p>The choice of Java as the next language to support was no big surprise, as indicated by <a href="http://java.dzone.com/news/will-google-app-engine-ever-su">many</a> <a href="http://news.cnet.com/8301-17939_109-10074158-2.html">articles</a> speculating on the matter.</p>
<p>Furthermore, Java is one of the most popular languages out there, both outside and inside Google, making it a logical choice.  This is seen by the numerous Java projects Google has created/supported, such as <a href="http://code.google.com/webtoolkit/">Google Web Toolkit</a> and <a href="http://code.google.com/p/google-guice/">Google Guice</a>.  Additionally, Java is second to none when it comes to a viable developer ecosystem, which has resulted in great open source projects such as <a href="http://www.jboss.com/">JBoss</a>, the <a href="http://commons.apache.org/">Apache Commons</a> collections, and other libraries/frameworks that have provided great tools to any Java developer, allowing them focus on developing their application instead of worrying about lower-level problems.  There are also a great many websites out there running on J2EE, such as <a href="http://www.linkedin.com/">LinkedIn</a> and numerous corporate websites.</p>
<h2>App Engine as a enabler for free/cheap Java hosting</h2>
<p>However, this hasn&#8217;t translated into the availability of cheap web hosting for J2EE/Java development.  Typically, web hosting for a shared-server solution will be only a few dollars per month if you&#8217;re using a scripting/interpreted language like <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym>, Python or Perl.  If you want to develop Java web applications though, you&#8217;ll likely have to pay much more due to the complexity and overhead of the hosting provider having to run a Java VM.</p>
<p>As outlined in <a href="http://newfoo.net/2009/04/08/google-app-engine-will-change-java-web-development.html">this somewhat overly optimistic article</a>, Google&#8217;s support for Java in App Engine has the potential to change the game by offering a cheap/low-cost, or in most cases, a free solution to allow developers to begin creating J2EE/Java-based web applications.  This will have the effect of encouraging greater adoption of J2EE as a server-side solution.  In my opinion, the high cost of Java web hosting has indeed hampered its adoption by the community, as compared to alternatives like <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym>, Python and Ruby.</p>
<h2>Hello, World</h2>
<p>As for me, I&#8217;m currently devoting my free time to experimenting on App Engine using Java.  So far, the <a href="http://code.google.com/appengine/docs/java/runtime.html">documention</a> and <a href="http://code.google.com/appengine/docs/java/gettingstarted/creating.html">tutorial</a> seem to be fairly well-written and easy to follow, and for the most part App Engine is using the standard Java APIs for providing most of their service functionality.  Furthermore, Google has made an <a href="http://code.google.com/appengine/docs/java/tools/eclipse.html">excellent Eclipse plugin</a> for App Engine Java support, which provides not only the SDK, but also a built-in development server/Jetty-based servlet container for local testing, but also the tools necessary to upload your application to Google&#8217;s servers directly from the IDE.  Another reason why <a href="/blog/2008/02/10/eclipse-the-best-and-only-ide-youll-ever-need/">Eclipse is the best IDE</a> out there.</p>
<p>I hope to have something working within a few days, at least to test the service and play around with its capabilities.  Overall, I&#8217;m very impressed!</p>
<hr/>Copyright &copy; 2010 <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/2009/04/15/google-app-engine-for-java-first-thoughts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScript Event Delegation</title>
		<link>http://unitstep.net/blog/2009/02/19/javascript-event-delegation/</link>
		<comments>http://unitstep.net/blog/2009/02/19/javascript-event-delegation/#comments</comments>
		<pubDate>Fri, 20 Feb 2009 03:47:44 +0000</pubDate>
		<dc:creator>Peter Chng</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[XHTML]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[events]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[user interface]]></category>
		<category><![CDATA[event delegation]]></category>

		<guid isPermaLink="false">http://unitstep.net/?p=720</guid>
		<description><![CDATA[JavaScript Event Delegation is a technique you may have heard of.  It&#8217;s a different way of using event handlers that offers clear benefits and is becoming more popular amongst web developers.  I&#8217;ll give a brief overview of event delegation in JavaScript, along with why you should consider it.  Note that this tutorial [...]]]></description>
			<content:encoded><![CDATA[<p>JavaScript Event Delegation is a technique you may have <a href="http://www.danwebb.net/2008/2/8/event-delegation-made-easy-in-jquery">heard of</a>.  It&#8217;s a different way of using event handlers that offers clear benefits and is becoming more popular amongst web developers.  I&#8217;ll give a brief overview of event delegation in JavaScript, along with why you should consider it.  Note that this tutorial will use the great <a href="http://jquery.com">jQuery</a> library (v. 1.3.1) for most examples.</p>
<h3>Delegation</h3>
<p><a href="http://en.wikipedia.org/wiki/Delegation_pattern">Delegation</a> is a fairly well-known design pattern.  In short, it is a way for a method to produce its result simply by calling a method on another object, thus <em>delegating</em> responsibility to that object to provide the functionality needed by the method.  For example, a <code>Cashier</code> object could store a delegate object called <code>Calculator</code>.  Calling <code>Cashier.addToTotal(value)</code> would simply delegate to the contained object, calling <code>Calculator.addToTotal(value)</code>.  </p>
<p>How is delegation different than <em>inheritance</em>?  With inheritance, the subclass inherits all of the functionality/behaviour of the parent class.  You may not want or need this; in the preceding example, it would not make sense to have <code>Cashier</code> extend from <code>Calculator</code> simply because we wanted the <code>addToTotal()</code> behaviour/functionality.  Delegation allows the behaviour advertised by a certain object/class to be provided by another.</p>
<h3>Traditional Event Handling</h3>
<p>In order to understand event delegation in JavaScript, we should first look briefly at how events are handled traditionally.  When I talk of <em>traditional event handling</em>, I am referring to the model that most will know.  In this model, functions are <strong>individually</strong> bound to events of certain elements.  For example, to make all links turn bold upon clicking them (and prevent them from being followed), we could use some JavaScript like this:</p>
<pre><code>window.onload = function()
{
  links = document.getElementsByTagName('a');
  for (var i = 0; i &lt; links.length; ++i)
  {
    links[i].onclick = makeBold;
  }

}

function makeBold()
{
  this.style.fontWeight = 'bold';
  return false;
}</code></pre>
<p>The key point with this example is that the function <code>makeBold()</code>, our <em>event handler</em>, is <strong>bound to each and every</strong> <code>a</code> element.  From a resource point of view, this is may be a bad thing because the more event handlers that are attached, the more memory that is used, in general.</p>
<p>Of course, I promised I&#8217;d be using jQuery, and doing so cleans up the above code substantially, as well as making it cross-browser compatible: (Besides adding a ton of other abilities and making life easier)</p>
<pre><code>jQuery(function()
{
  jQuery('a').click(makeBold);
});

function makeBold(e)
{
  e.preventDefault();
  jQuery(this).css('font-weight', 'bold');
}</code></pre>
<p>While this code is cleaner, it still does basically the same thing as above, that is, the event handler function <code>makeBold()</code> is bound to <strong>each</strong> matched element, that is, each <code>a</code> element.</p>
<p>As a final note, don&#8217;t confuse my use of the term <em>traditional</em> with <a href="http://www.quirksmode.org/">Peter-Paul Koch&#8217;s</a> excellent guide to JavaScript event registration, where he uses the term <a href="http://www.quirksmode.org/js/events_tradmod.html"><em>traditional</em> to refer to one <em>method</em> of event registration</a>, distinct from inline registration and the later <a href="http://www.w3.org/" class="ubernym uttInitialism"><acronym class="uttInitialism" title="World Wide Web Consortium">W3C</acronym></a> and Microsoft &#8220;Advanced&#8221; event registration models.</p>
<h3>Event handling using delegation</h3>
<p>By contrast, <strong>event delegation</strong> uses a single (or comparatively few) event handlers to implement the behaviour required.  This takes advantage of two key features of JavaScript events, namely <strong><a href="http://www.quirksmode.org/js/events_order.html#link3">event bubbling</a></strong> and the <strong><a href="http://docs.jquery.com/Events/jQuery.Event#event.target">target event</a></strong>.</p>
<p><strong>Event bubbling</strong> is a model for how events take place on the page.  It grew out of a need to resolve the order in which events were triggered on ancestor and descendant elements.  For example, assume that I have two event handlers, one attached to the &#8220;click&#8221; event of a <code>div</code> and another attached to the &#8220;click&#8221; event of an <code>a</code> element <strong>within</strong> that <code>div</code>.  If I click the <code>a</code> element, which event fires first?  Event bubbling is one way to solve that question: It states that the event on the <strong>inner</strong> element happens <em>first</em>, and then the event &#8220;bubbles&#8221; upwards to trigger events on ancestor or container elements.  There is another opposing model that works in the opposite way, but bubbling seems to be better supported and is more relevant for this article.</p>
<p>Here&#8217;s a crude diagram of event bubbling, using a pseudo-<a href="http://www.w3.org/TR/CSS21/box.html"><acronym class="uttInitialism" title="Cascading Style Sheets">CSS</acronym> box model</a> of sorts:</p>
<p class="image">
<img src="http://unitstep.net/wordpress/wp-content/uploads/2009/02/javascript-event-delegation.png" alt="Event Bubbling Diagram" title="Event Bubbling Diagram" width="302" height="228" class="size-full wp-image-747" /><br />
Event bubbling diagram
</p>
<p>The <strong>event target</strong> is the DOM element that issued the event, or the originating element.  This is why I believe it&#8217;s a confusing term, since it would make more sense to called it the <em>event source</em>.  But I digress.  The <a href="https://developer.mozilla.org/En/DOM/Event">event object</a>, passed to an event handler as an argument (or available via <code>window.event</code>, though jQuery normalizes this) contains a property, <code>event.target</code>, that allows you to get the reference to the &#8220;target&#8221; element that the event started bubbling up from.</p>
<h3>How it&#8217;s implemented</h3>
<p>All of this is typically accomplished by registering a single event handler to a &#8220;container&#8221; element that holds all of the elements we wish to react to events for.  When an event is triggered on one of the inner elements, it &#8220;bubbles up&#8221; to the container element, where it triggers the event handler function.  From there, we can inspect the source of the event (confusingly called the <em>event target</em>) and then react accordingly.</p>
<p>This is where the delegation aspect comes into play.  Since the container element may hold many inner elements, it is unlikely that we would want the same behaviour for each element when an event was triggered on it.  For example, we might want certain <code>a</code> elements to trigger one action when clicked, while wanting another set of <code>a</code> elements to trigger another action.  We&#8217;d typically differentiate these links by using separate class names or by context and then attaching event handlers as appropriate.</p>
<p>Using event delegation, process is similar, but instead of attaching multiple event handlers we have one on the overall parent element.  When this event handler is triggered, we determine which element triggered the event and then based on this, delegate the remainder of the processing to another function.  An example would be helpful now, as our previous examples with making some text bold weren&#8217;t too useful.  Here&#8217;s the <a href="http://www.w3.org/MarkUp/" class="ubernym uttInitialism"><acronym class="uttInitialism" title="eXtensible HyperText Markup Language - HTML reformulated as XML">XHTML</acronym></a> fragment for the container and elements.</p>
<pre><code >&lt;div class="container"&gt;
&lt;ul class="top"&gt;
  &lt;li&gt;
    &lt;a href="#" class="expandList"&gt;Item A - Click to toggle&lt;/a&gt;
    &lt;ul class="hide"&gt;
      &lt;li&gt;Sub-item 1&lt;/li&gt;
      &lt;li&gt;Sub-item 2&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;a href="#" class="expandList"&gt;Item B - Click to toggle&lt;/a&gt;
    &lt;ul class="hide"&gt;
      &lt;li&gt;Sub-item 1&lt;/li&gt;
      &lt;li&gt;Sub-item 2&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href="#" class="remove"&gt;Item C - Click to remove&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="#" class="remove"&gt;Item D - Click to remove&lt;/a&gt;&lt;/li&gt;
&lt;/div&gt;</code></pre>
<p>And here&#8217;s the JavaScript:</p>
<pre><code>jQuery(function()
{
  jQuery('div.container').click(handleEvent);
});

function handleEvent(e)
{
  // Obtain the source element through event.target.
  var target = jQuery(e.target);

  // Now decide what to do with it.
  if (target.is('a.expandList'))
  {
    // We use Function.call() to set the context for the `this` keyword.
    return expandList.call(target, e);
  }
  else if (target.is('a.remove'))
  {
    return remove.call(target, e);
  }
  else
  {
    // Otherwise, allow the default action to take place.
    return true;
  }
}

function expandList(e)
{
  e.preventDefault();

  // The `this` keyword now references the jQuery object representing the
  // target, since that is what we set the context to.
  jQuery(this).parent('li').find('ul.hide').slideToggle('fast');
}

function remove(e)
{
  e.preventDefault();
  jQuery(this).parent('li').fadeOut('normal', function(){jQuery(this).remove()});
}</code></pre>
<p>With this example, the steps are clearly outlined.  First, we attach the overall event handler to the container element; events that take place on its inner or children element will bubble up to it.  When an event is received, we inspect <code>event.target</code> to determine the origin and based on that, &#8220;hand off&#8221; to another function to carry out the proper behaviour. </p>
<p>With some standardization of the <acronym class="uttInitialism" title="Cascading Style Sheets">CSS</acronym> class names you use and the associated event handler function names, you can clean up this code to reduce duplication and turn it into a design pattern of sorts.  In fact, that&#8217;s <a href="http://www.danwebb.net/2008/2/8/event-delegation-made-easy-in-jquery">exactly what Dan Webb has done</a>.</p>
<h3>More advantages of event delegation</h3>
<p>Besides potentially using less resources by having less event handlers bound, event delegation brings one other significant advantage: <strong>The ability to have event handlers &#8220;auto bind&#8221; to new DOM elements</strong>.  For example, let&#8217;s say we were to dynamically update the DOM and add more list items to our previous example; this sort of action happens frequently during Ajax operations where you want to present new content to the user.  </p>
<p>In the &#8220;traditional&#8221; event handling model, the new elements <strong>would not automatically respond to events</strong> as you would like.  This is because the events were individually bound to each element.  This is <a href="http://docs.jquery.com/Frequently_Asked_Questions#Why_do_my_events_stop_working_after_an_AJAX_request.3F">a well known problem</a>.  However, in event delegation, since there&#8217;s only one event handler bound to the <strong>container or ancestor element</strong>, the newly-created elements will respond to the event properly! This is because an event on them &#8220;bubbles&#8221; up to the container element just as for the original elements.</p>
<h3><a href="/projects/javascript-event-delegation/javascript-event-delegation.html">Demo of Event Delegation</a></h3>
<p>Perhaps <a href="/projects/javascript-event-delegation/javascript-event-delegation.html">a little demo</a> is needed.  With this demo, you can see both the implementation of event delegation as well as the effect of adding new elements.</p>
<h3>Drawbacks of event delegation</h3>
<p>I&#8217;ve already talked about some of the benefits (fewer bound event handlers, so less resources used and the ability to adapt with DOM changes), but it&#8217;s worthwhile to iterate over some of the drawbacks.  </p>
<ol>
<li>Firstly, not all elements &#8220;bubble up&#8221; in the way described.  The <code>blur</code>, <code>focus</code>, <code>change</code> and <code>submit</code> are notable exceptions so you will not be able to use event delegation with these events in the manner described in this article.</li>
<li>Furthermore, the code developed to maintain event delegation can be more complicated to understand than with just using the traditional model.  Indeed, there is an initial investment time everyone must make to get going.  This should obviously be considered since code maintenance is always important.</li>
<li>Because there&#8217;s one event handler being called for all events on inner/descendant elements, there can be some performance implications.  If you&#8217;re calling expensive functions within this event handler, the event processing could slow down significantly.  Careful optimization may be required.</li>
</ol>
<p>However, some of these drawbacks can be mitigated by using solutions developed by the jQuery community.  Even though event delegation is somewhat new, there are already plugins available that take a lot of the grunt-work out of event delegation, abstracting away the details and making things easier for you.  Even jQuery itself also supports event delegation through a built-in function as of v1.3.  Here are some options for pre-built solutions:</p>
<ul>
<li><a href="http://www.danwebb.net/2008/2/8/event-delegation-made-easy-in-jquery">Dan Webb&#8217;s Delegate Plugin</a><br />
This is a fairly straightforward way to implement delegation and it&#8217;s easy to setup and understand.</li>
<li><a href="http://docs.jquery.com/Events/live#typefn">jQuery&#8217;s built in <code>live()</code> function</a><br />
This supports a subset of events but is good enough for most uses.</li>
<li><a href="http://plugins.jquery.com/project/livequery">The Live Query plugin</a><br />
This is your best bet if you need the most functionality, though I haven&#8217;t personally tried it out yet.</li>
</ul>
<h3>Conclusion</h3>
<p>Delegation nicely solves the problem of having to rebind events after adding new elements to the DOM.  For that reason alone, I&#8217;ve started to use in my work more often.  At its heart, it&#8217;s a useful design pattern, but should be only with full understanding of the pros and cons.  I hope you enjoyed reading this article!</p>
<h3>References</h3>
<ol class="note less">
<li><a href="http://www.danwebb.net/2008/2/8/event-delegation-made-easy-in-jquery">Event Delegation Made Easy</a></li>
<li><a href="http://usabletype.com/weblog/event-delegation-without-javascript-library/">Event delegation without a JavaScript library</a></li>
<li><a href="http://www.sitepoint.com/blogs/2008/07/23/javascript-event-delegation-is-easier-than-you-think/">JavaScript Event Delegation is Easier than You Think</a></li>
<li><a href="http://docs.jquery.com/Frequently_Asked_Questions#Why_do_my_events_stop_working_after_an_AJAX_request.3F">Why do my events stop working after an <acronym class="uttAcronym" title="Asynchronous Javascript And XML">AJAX</acronym> request?</a></li>
</ol>
<h4>Revisions</h4>
<ul class="note less">
<li>2009-02-20: Added a crude diagram of event bubbling</li>
</ul>
<hr/>Copyright &copy; 2010 <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/2009/02/19/javascript-event-delegation/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Getting Xdebug to work with Apache/XAMPP to debug PHP</title>
		<link>http://unitstep.net/blog/2009/01/26/getting-xdebug-to-work-with-apachexampp-to-debug-php/</link>
		<comments>http://unitstep.net/blog/2009/01/26/getting-xdebug-to-work-with-apachexampp-to-debug-php/#comments</comments>
		<pubDate>Tue, 27 Jan 2009 03:00:11 +0000</pubDate>
		<dc:creator>Peter Chng</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[guides]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[tutorials]]></category>

		<guid isPermaLink="false">http://unitstep.net/?p=661</guid>
		<description><![CDATA[
I&#8217;ve written about Eclipse and how useful it can be, with its extensible plugin-based system. It&#8217;s so useful that I use it everyday for almost any language &#8211; Java, PHP, JavaScript to name a few.  It&#8217;s even great for things like CSS and XHTML. 
PHP is currently my favourite &#8220;hobby&#8221; language and has been [...]]]></description>
			<content:encoded><![CDATA[<p class="image align-right"><a href="http://xdebug.org/"><img src="http://unitstep.net/wordpress/wp-content/uploads/2009/01/xdebug-logo.png" alt="xdebug-logo" title="xdebug-logo" width="200" height="116" /></a></p>
<p>I&#8217;ve written <a href="/blog/2008/02/10/eclipse-the-best-and-only-ide-youll-ever-need/">about Eclipse</a> and how <a href="/blog/2008/01/19/using-assemblas-trac-with-eclipse-mylyn-xml-rpc-access/">useful it can be</a>, with its extensible plugin-based system. It&#8217;s so useful that I use it everyday for almost any language &#8211; Java, <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym>, JavaScript to name a few.  It&#8217;s even great for things like <acronym class="uttInitialism" title="Cascading Style Sheets">CSS</acronym> and <a href="http://www.w3.org/MarkUp/" class="ubernym uttInitialism"><acronym class="uttInitialism" title="eXtensible HyperText Markup Language - HTML reformulated as XML">XHTML</acronym></a>. </p>
<p><acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> is currently my favourite &#8220;hobby&#8221; language and has been for some time.  While I like <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym>, one of the things that hasn&#8217;t been straightforward with it is setting up a proper debug session, where you can step through code.  This contrasts heavily with a language like Java, which has always had strong developer tools.  This has resulted in a mass of third-party tools aimed at facilitating <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> debugging.  A while ago, a reader emailed me asking about this very topic, so I decided to put together how-to detailing my experience with the topic and how I went about learning it.</p>
<h2>Xdebug for <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> and XAMPP</h2>
<p>The debugger I&#8217;ll be using will be <a href="http://www.xdebug.org/">Xdebug</a>. Because <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> provide no built-in debugging tools, there are many third-party options for debugging. (See the &#8220;Debugging Tools&#8221; section of <a href="http://www.smashingmagazine.com/2009/01/20/50-extremely-useful-php-tools/">this article</a> for more) However, Xdebug seems to be one of the more popular ones, and <a href="http://www.eclipse.org/pdt/">Eclipse PDT</a> already has support for it.</p>
<p>This guide also assumes use of <a href="http://www.apachefriends.org/en/xampp.html">XAMPP</a>, the great all-in-one solution for quickly setting up a web development environment and to get your code running on the server. XAMPP is great for hitting the ground running, though you&#8217;ll probably not want to use it in a production environment &#8211; though you likely won&#8217;t be debugging there either.  Nevertheless, the instructions provided here should work even if you&#8217;ve setup Apache and <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> separately on your own.</p>
<h2>Getting started</h2>
<p>The first thing you&#8217;ll want to do is head over the <a href="http://www.xdebug.org/download.php">Xdebug</a> page and download the appropriate Zend extension of Xdebug corresponding to the version of <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> you&#8217;re running.  Save the file into your <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> extension path/folder.  Now you&#8217;ll have to edit your <code>php.ini</code> file to begin using the plugin.  The plugin basically exposes or provides an interface for the client debugger (running in Eclipse or your IDE) to attach to the server and debug/trace through the code that&#8217;s running on it.  If you&#8217;re from the Java world, you&#8217;ll know this as &#8220;remote debugging&#8221;, which is provided by most J2EE application servers.</p>
<p>You&#8217;ll also want to have downloaded <a href="http://www.eclipse.org/pdt/">Eclipse PDT</a> have that installed as your IDE, if you haven&#8217;t already done so.  <a href="http://www.zend.com/en/products/studio/">Zend Studio for Eclipse</a> also works, since it&#8217;s based on Eclipse PDT, and offers quite a few more features, out of the box.</p>
<h2>Setting up Xdebug</h2>
<p>You should have already saved the Xdebug extension DLL file to your <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> extension folder.  Record down the full path of it.  Now, open up your <code>php.ini</code> file and go down to the <code>[XDebug]</code> section, or create it if it&#8217;s not there.  Uncomment or add the following lines:</p>
<pre><code>;; Only Zend OR (!) XDebug
zend_extension_ts="D:\XAMPP\php\ext\php_xdebug.dll"
xdebug.remote_enable=On
xdebug.remote_host="localhost"
xdebug.remote_port=9000
xdebug.remote_handler=dbgp</code></pre>
<p>The <code>zend_extension_ts</code> should point to location of your Xdebug extension DLL that you downloaded earlier; modify as appropriate.</p>
<p>Then, you <strong>should disable the Xdebug entry in the list of dynamic extensions</strong>. This is confusing, but since we are already setting up Xdebug as a Zend extension, we don&#8217;t need another entry.  Disable the Xdebug dynamic extension by ensuring the following line is commented out, like below:</p>
<pre><code>;extension=php_xdebug.dll</code></pre>
<p>There is one last very important step you need to do, particularly if you are running XAMPP.  <strong>Current versions of Xdebug are incompatible with the Zend optimizer that is enabled by default in XAMPP, so you must disable that if you want Xdebug to work</strong>.  If you don&#8217;t, you&#8217;ll notice that Apache will crash every time you try to load it with Xdebug enabled.  To disable the Zend optimizer, find the <code>[Zend]</code> section in <code>php.ini</code> and comment out all of the entries under it, like so: (This is an example, there may be more to comment out)</p>
<pre><code>[Zend]
;zend_extension_ts = "D:\XAMPP\php\zendOptimizer\lib\ZendExtensionManager.dll"
;zend_extension_manager.optimizer_ts = "D:\XAMPP\php\zendOptimizer\lib\Optimizer"
;zend_optimizer.enable_loader = 0
;zend_optimizer.optimization_level=15
;zend_optimizer.license_path =</code></pre>
<p>You should be able to start Apache now without troubles.</p>
<h2>Configuring Eclipse for <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> debugging</h2>
<p>The next part will be configuring Eclipse as a debugging client.  Since the code will be executing on the web server (Apache), you&#8217;ll need Eclipse to &#8220;hook in&#8221; using the Xdebug protocol.  Thankfully, configuring Eclipse is fairly straightforward.</p>
<p>Open up Eclipse&#8217;s preferences and go to <strong>PHP -> Debug</strong>, and ensure that XDebug is selected as the <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> debugger.  This sets the default for debugging sessions and lessens the configuration required for each debug session.  You can also make sure that the default web server is <code>localhost</code> if that&#8217;s the case, which it&#8217;ll likely be for a lot of people doing development.</p>
<p><strong>Note that if you are running Zend Studio</strong>, you&#8217;ll need to <a href="http://www.maxhorvath.com/2008/08/how-to-enable-the-xdebug-debugger-in-zend-studio-for-eclipse.html">follow the steps in this article to enable Xdebug support</a>.  It seems that some versions of Zend Studio by default disabled support for the Xdebug plugin in lieu of their own Zend Debugger. </p>
<p class="image">
<a href="http://unitstep.net/wordpress/wp-content/uploads/2009/01/php-debug-1.jpg"><img src="http://unitstep.net/wordpress/wp-content/uploads/2009/01/php-debug-1-300x241.jpg" alt="php-debug-1" title="php-debug-1" width="300" height="241" class="alignnone size-medium wp-image-695" /></a>
</p>
<p>Now you can select a file from a project you&#8217;d like to debug.  In my case, I&#8217;ve selected <code>src/demo/index.php</code> from my <a href="/blog/2008/03/29/a-challenge-response-ajax-php-login-system/">Challenge-Response <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> Login System</a> project.  Open the file, and then go to the <strong>Run Menu</strong> and select <strong>Debug Configurations&#8230;</strong> or <strong>Open Debug Dialog</strong>.</p>
<p class="image">
<a href="http://unitstep.net/wordpress/wp-content/uploads/2009/01/php-debug-2.jpg"><img src="http://unitstep.net/wordpress/wp-content/uploads/2009/01/php-debug-2-300x202.jpg" alt="php-debug-2" title="php-debug-2" width="300" height="202" class="alignnone size-medium wp-image-697" /></a>
</p>
<p>Double click the the &#8220;<acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> Web Page&#8221; entry on the left side bar to create a new debug profile.  Here, I&#8217;ve named it &#8220;CHAP-PHP&#8221;.  You should see a dialog like the one above.  Make sure the &#8220;Server Debugger&#8221; is again set to Xdebug and that the <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> Server is set to the localhost configuration you set up previously.  </p>
<p>Then you have to select the file you want to debug.  Click on &#8220;Browse&#8221;, and you&#8217;re confusingly taken to another view of your Eclipse projects; simply select the same file as before &#8211; you have to select a specific file, and not just a project or folder.</p>
<p>After that, you&#8217;ll need to adjust the <acronym class="uttInitialism" title="Uniform Resource Locator">URL</acronym> mapping.  You&#8217;ll probably need to uncheck &#8220;Auto Generate&#8221;, and then <strong>enter the <acronym class="uttInitialism" title="Uniform Resource Locator">URL</acronym> that corresponds to the <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> file you&#8217;re debugging</strong>.  Here, I&#8217;ve manually entered <code>/projects/CHAP/trunk/src/demo/</code> as the <acronym class="uttInitialism" title="Uniform Resource Locator">URL</acronym> fragment that triggers execution of the script.</p>
<p>If you want the debugger to stop right at the first line to allow you to immediately begin stepping through code, check &#8220;Break at First Line&#8221;. (It may be checked by default) Otherwise, uncheck it if you only want the debugger to stop at the breakpoints you&#8217;ve specified in Eclipse, which is the normal behaviour most developers will expect. </p>
<p>You should now be able to click &#8220;Debug&#8221;, and a debug session will launch, opening up the <acronym class="uttInitialism" title="Uniform Resource Locator">URL</acronym> you&#8217;ve specified and allowing you to step through code.  If you don&#8217;t like Eclipse using its own internal web browser (which appears just be a front for IE), you can configure which web browser you&#8217;d like it to launch URLs with by opening up Preferences and then going to <strong>General -> Web Browser</strong> and changing the setting to use an external web browser of your choice.  Personally, Firefox is my preference.</p>
<h2>Start your debugging engines!</h2>
<p>You can now get acquainted with stepping through code, which in my opinion, is one of the best ways to learn! When you launch a debug session, Eclipse should prompt you to switch to a new &#8220;perspective&#8221;, which is just a different layout of Eclipse&#8217;s internal windows that many believe better suit debugging through code.  </p>
<p class="image">
<a href="http://unitstep.net/wordpress/wp-content/uploads/2009/01/php-debug-3.jpg"><img src="http://unitstep.net/wordpress/wp-content/uploads/2009/01/php-debug-3-300x227.jpg" alt="php-debug-3" title="php-debug-3" width="300" height="227" class="alignnone size-medium wp-image-698" /></a>
</p>
<p>You&#8217;re provided with an informative view of the script your currently debugging, along with the highlighted line that execution has paused on.  You can set debug breakpoints by double-clicking in the left margin of your source code view window; debug breakpoints show up as blue circles here.  The buttons at the top (green &#8220;Play&#8221;, red &#8220;Stop&#8221; and others) provide control over execution of the code, allowing you to step through code line-by-line, step into functions/methods and return from them.  I encourage you to experiment with all of the controls and get acquainted with the keyboard shortcuts.</p>
<p>Another panel also shows all the current variables available to the script as well as their values.  This is useful since you now do not need to <code>echo</code> anything to output or change any of the code to see values.  </p>
<p>When you&#8217;re done, you can just click the red &#8220;stop&#8221; button to disconnect from the server and end the debug session.  If you&#8217;ve completely stepped through a script, you will not be automatically disconnected from the server.  Instead, the debug client in <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> will patiently wait to debug the script again the next time it is executed.  This is useful to know, since you can just go back to the <acronym class="uttInitialism" title="Uniform Resource Locator">URL</acronym> in your web browser and reload the page to trigger the debug session to resume again. </p>
<h2>Conclusion</h2>
<p>I hope you found this useful, as when I was starting out trying to get a <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> debug session to work, it was somewhat frustrating. As always, I welcome your comments, suggestions and questions below via the comments form!</p>
<h3>References</h3>
<ol class="less note">
<li><a href="http://stackoverflow.com/questions/206788/why-does-xdebug-crash-apache-on-every-xampp-install-ive-tried">Why does xdebug crash apache on every XAMPP install I’ve tried?</a></li>
<li><a href="http://xdebug.org/docs/">Xdebug: Documentation</a></li>
<li><a href="http://www.maxhorvath.com/2008/08/how-to-enable-the-xdebug-debugger-in-zend-studio-for-eclipse.html">How to enable the Xdebug debugger in Zend Studio for Eclipse</a></li>
<li><a href="http://devzone.zend.com/article/2930-Debugging-PHP-applications-with-xdebug">Debugging <acronym class="uttInitialism" title="PHP: Hypertext Preprocessor">PHP</acronym> applications with Xdebug</a></li>
</ol>
<hr/>Copyright &copy; 2010 <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/2009/01/26/getting-xdebug-to-work-with-apachexampp-to-debug-php/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Handling mutable fields in Java</title>
		<link>http://unitstep.net/blog/2008/12/14/handling-mutable-fields-in-java/</link>
		<comments>http://unitstep.net/blog/2008/12/14/handling-mutable-fields-in-java/#comments</comments>
		<pubDate>Mon, 15 Dec 2008 02:11:27 +0000</pubDate>
		<dc:creator>Peter Chng</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[mutability]]></category>
		<category><![CDATA[objects]]></category>

		<guid isPermaLink="false">http://unitstep.net/?p=604</guid>
		<description><![CDATA[In Java, a mutable object is one whose state can be altered after it has been instantiated.  An immutable object is one whose state is fixed after instantiation; that is, the data represented by the object cannot be changed in that object.  Perhaps the most well-known immutable type is the built in String [...]]]></description>
			<content:encoded><![CDATA[<p>In Java, a <em>mutable</em> object is one whose state can be altered after it has been instantiated.  An <em>immutable</em> object is one whose state is fixed after instantiation; that is, the data represented by the object cannot be changed in that object.  Perhaps the most well-known immutable type is the built in <a href="http://java.sun.com/javase/6/docs/api/java/lang/String.html">String</a> class; while there are methods on the String class that seemingly alter its state (such as <code>toUpperCase()</code> and <code>trim()</code>), in actuality these methods return a <em>new</em> String object if changes had to be made.  In this article I&#8217;ll discuss how mutability will affect how you expose private fields in objects.</p>
<h2>Pop Quiz</h2>
<p>Consider the following code fragment.  We create a <code>MapContainer</code> object, and then get the contained map, which is guaranteed to have a certain value associated with the key &#8220;today&#8221;.  We then alter the value associated with this key, using our <em>local reference</em> to returned map.  We then query the <code>MapContainer</code> object and get the contained map again.  What is the value associated with the key &#8220;today&#8221; in this map?</p>
<pre><code>final MapContainer mapContainer = new MapContainer();
final Map&lt;String, String&gt; map = mapContainer.getKeyValuePairs();

final String today = map.get("today");
assert null != today;
System.out.println(today);  // Returns the current date-time.

// Change the value using our local reference.
map.put("today", "tomorrow");

final Map&lt;String, String&gt; mapAgain = mapContainer.getKeyValuePairs();
System.out.println(mapAgain.get("today")); // What is output?</code></pre>
<p>Don&#8217;t waste too much time on this problem, as it&#8217;s a trick question.  The answer actually depends on the implementation of <code>MapContainer</code>.  Depending on how it&#8217;s implemented, the second output could be unchanged from the first <strong>or</strong> be changed to the new value of &#8220;tomorrow&#8221;.</p>
<h2>It&#8217;s all in the getters</h2>
<p>Let&#8217;s take a look at the code for <code>MapContainer</code>.  </p>
<pre><code>import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class MapContainer
{
  final private Map&lt;String, String&gt; keyValuePairs;

  public MapContainer()
  {
    this.keyValuePairs = new HashMap&lt;String, String&gt;();
    this.keyValuePairs.put("today", new Date().toString());
  }

  public Map&lt;String, String&gt; getKeyValuePairs()
  {
    return keyValuePairs;
  }
}</code></pre>
<p>We have a simple constructor that initializes the <code>keyValuePairs</code> Map and adds one value for the current date-time.  But the real &#8216;key&#8217; (no pun intended) to solving the problem is looking at the getter for the field.  As you can see, it simply returns a reference to the private field.  <strong>Under this implementation, a caller is able to alter the contents of the private field/Map even though no public &#8220;set&#8221; methods are available</strong>.  Why is this? For two reasons: In Java, objects are passed/returned by reference, and <code>HashMap</code> is a mutable object.  Thus using this implementation, the second output from our original code fragment is &#8220;tomorrow&#8221;, since the caller has altered the contents of the Map through the returned reference.</p>
<p>Furthermore, the original reference returned from the getter is not independent either; if some other code were to call the get method on the <code>MapContainer</code> object and make changes to the Map, those changes would also be reflected in the original returned reference!</p>
<p>How can we &#8220;fix&#8221; this? We simply have to ensure that the getter for the field returns a reference to a <em>copy</em> of the private Map.  This is easy since there is a <a href="http://java.sun.com/javase/6/docs/api/java/util/HashMap.html#HashMap(java.util.Map)">constructor for <code>HashMap</code></a> that accepts an existing Map.  Here&#8217;s the altered code:</p>
<pre><code>import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class MapContainer
{
  final private Map&lt;String, String&gt; keyValuePairs;

  public MapContainer()
  {
    this.keyValuePairs = new HashMap&lt;String, String&gt;();
    this.keyValuePairs.put("today", new Date().toString());
  }

  public Map&lt;String, String&gt; getKeyValuePairs()
  {
    <strong>return new HashMap&lt;String, String&gt;(keyValuePairs);</strong>
  }
}</code></pre>
<p>With these changes, the private Map cannot be altered by a caller and thus the second output will remain changed in our first code fragment example.</p>
<h2>To change, or not to change?</h2>
<p>It should be noted that sometimes you <em>may want to allow</em> callers to alter the backing data structure that you return from a get method.  For example, some of the data structures from the <a href="http://java.sun.com/javase/6/docs/api/java/util/Collection.html">Java Collection Framework</a> have getters that return references that can be used to alter the state of the original object.  A good example is the <a href="http://java.sun.com/javase/6/docs/api/java/util/HashMap.html#entrySet()"><code>entrySet()</code></a> method of the <code>HashMap</code> object. </p>
<p>But in my opinion, these examples are the exception rather than the rule.  In general, you do not want to allow callers to be able to alter the state of private fields directly since this violates information-hiding principles.  If there is some change a caller needs to make to your object, it&#8217;s best accomplished through a set method since this allows you to control the changes and prevents unwanted/unexpected situations.  If you do decide to allow callers to directly alter the state of private fields, it&#8217;s best to explicitly document this in the JavaDoc.</p>
<h2>Mutability and safety</h2>
<p>Note that in this example the field used was a <code>HashMap</code> object, which was mutable.  If the field consisted of an immutable object, like a <code>String</code>, you would not have to worry about making a copy before returning it.  This is because if the object is immutable, you do not have to worry about a caller changing its state because this is impossible to do!  This is why immutable objects are much easier to deal with in multithreaded/concurrent environments.</p>
<p>Note that mutability has nothing to do with the <code>final</code> keyword in Java, contrary to <a href="http://mindprod.com/jgloss/mutable.html">this definition</a>.  Simply marking a field as &#8220;<code>final</code>&#8221; will not magically change a mutable object into an immutable one.  As we saw earlier, whether an object is mutable or not depends entirely on its implementation, the details of which should be expressed in the JavaDoc for that class.  The <code>final</code> keyword only ensures that you cannot reassign that field/variable to completely new reference or object; it <strong>does not</strong> ensure that you can&#8217;t change the state of the object already referenced.</p>
<hr/>Copyright &copy; 2010 <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/12/14/handling-mutable-fields-in-java/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting Feedback with UserVoice</title>
		<link>http://unitstep.net/blog/2008/11/30/getting-feedback-with-uservoice/</link>
		<comments>http://unitstep.net/blog/2008/11/30/getting-feedback-with-uservoice/#comments</comments>
		<pubDate>Sun, 30 Nov 2008 23:12:11 +0000</pubDate>
		<dc:creator>Peter Chng</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[feedback]]></category>
		<category><![CDATA[social]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[usability]]></category>
		<category><![CDATA[user interface]]></category>
		<category><![CDATA[web2.0]]></category>
		<category><![CDATA[customers]]></category>
		<category><![CDATA[users]]></category>
		<category><![CDATA[uservoice]]></category>

		<guid isPermaLink="false">http://unitstep.net/?p=580</guid>
		<description><![CDATA[
When developing any application, getting proper user feedback during the early stages is essential if you want to have the application suit your customers&#8217; needs.  Often this is done with staged tests, but with web applications you can have the benefit of using an online method of retrieving your users&#8217; opinions. 
However, doing so [...]]]></description>
			<content:encoded><![CDATA[<p class="image align-right"><img src="http://unitstep.net/wordpress/wp-content/uploads/2008/11/uservoice.jpg" alt="" title="uservoice" width="180" height="48" class="alignnone size-full wp-image-582" /></p>
<p>When developing any application, getting proper user feedback during the early stages is essential if you want to have the application suit your customers&#8217; needs.  Often this is done with staged tests, but with web applications you can have the benefit of using an online method of retrieving your users&#8217; opinions. </p>
<p>However, doing so can be tricky.  If you want to get feedback, you can implement your own system for soliciting it, however, this takes up extra time that could be used to further develop your core web application.  Alternatively, there are some existing online services that can provide survey-like questionnaires to users, but honestly, these present more trouble to the user than they&#8217;re worth.</p>
<p>When I first started using <a href="/blog/2008/11/15/stack-overflow-is-a-great-community-and-resource/">Stack Overflow</a>, I noticed that the feedback service they had been using, <a href="http://uservoice.com/">UserVoice</a>, was an elegant and functional solution to this problem.</p>
<p>UserVoice takes care of the problem for you, by providing you with an easy-to-use comment and feedback forum.  (It can also be a place where users can submit bug reports, as well) However, it&#8217;s more than just a forum: By allowing users to &#8220;vote&#8221; on particular topics, it allows clustering of the most popular ideas/requests, thus bringing them to your attention the most.  It also helps prevent duplicate topics from being submitted, and is a great &#8220;Digg-style&#8221; way of using the &#8220;wisdom of the crowds&#8221;, as they say.</p>
<p>There are some drawbacks, of course.  If you&#8217;re using it to allow users to submit bugs, I wouldn&#8217;t rely on it as your sole bug tracker.  Instead, I&#8217;d use it to receive the reports, then parse through and verify them before adding them to a proper bug tracker (like <a href="http://trac.edgewall.org/">Trac</a>) where they can be better integrated into your development work-flow.  Furthermore, if you have a popular site, the feedback forums can still become deluged in too many requests/ideas, but that is a problem no matter what type of system you&#8217;re using for feedback.  And, as mentioned before, the voting system helps to bring to your attention the most popular ones so that you can further make a value judgment.</p>
<p>I&#8217;ve since <a href="http://runtrackr.uservoice.com/">launched a feedback forum</a> for <a href="http://runtrackr.com">RunTrackr</a>, my side project for the past little while.   I encourage you to give UserVoice a try, since it&#8217;s so easy to get started &#8211; you&#8217;re literally up and running inside of two minutes.  At a minimum, give their home page a visit &#8211; it does a great job of explaining the process in a simple and easy-to-understand manner.</p>
<hr/>Copyright &copy; 2010 <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/11/30/getting-feedback-with-uservoice/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
