<?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>Smartkey - Java Software Consultancy &#187; Tool support</title>
	<atom:link href="http://blog.smartkey.co.uk/category/development/tool-support/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.smartkey.co.uk</link>
	<description></description>
	<lastBuildDate>Tue, 13 Dec 2011 15:03:46 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Searching for files in an Ant script</title>
		<link>http://blog.smartkey.co.uk/2011/09/searching-for-files-in-an-ant-script/</link>
		<comments>http://blog.smartkey.co.uk/2011/09/searching-for-files-in-an-ant-script/#comments</comments>
		<pubDate>Tue, 06 Sep 2011 11:17:19 +0000</pubDate>
		<dc:creator>Steve Neal</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Tool support]]></category>
		<category><![CDATA[Ant]]></category>
		<category><![CDATA[Ivy]]></category>

		<guid isPermaLink="false">http://blog.smartkey.co.uk/?p=934</guid>
		<description><![CDATA[This is a simple technique for determining whether or not files matching a given pattern exist within your project. Unlike the available task, this does not require that you need to know the exact name of the file when creating the build file. It is therefore very useful for checking existence of generated/downloaded artefacts.
I&#8217;ll demonstrate [...]]]></description>
			<content:encoded><![CDATA[<p>This is a simple technique for determining whether or not files matching a given pattern exist within your project. Unlike the <code>available</code> task, this does not require that you need to know the exact name of the file when creating the build file. It is therefore very useful for checking existence of generated/downloaded artefacts.</p>
<p>I&#8217;ll demonstrate the technique with an Ant target that I wrote to check whether Ivy had downloaded any jars that had the pattern SNAPSHOT in their name:</p>
<pre class="brush: php">
&lt;target name=&quot;ivy-count-snapshot-jars&quot; depends=&quot;init&quot; if=&quot;ivy.present&quot;&gt;
    &lt;resourcecount property=&quot;ivy.snapshot.count&quot;&gt;
        &lt;fileset dir=&quot;${ivylib.dir}&quot; includes=&quot;**/*SNAPSHOT*.jar&quot;/&gt;
    &lt;/resourcecount&gt;
    &lt;condition property=&quot;ivy.snapshot.present&quot;&gt;
        &lt;not&gt;
            &lt;equals arg1=&quot;${ivy.snapshot.count}&quot; arg2=&quot;0&quot;/&gt;
        &lt;/not&gt;
    &lt;/condition&gt;
&lt;/target&gt;

&lt;target name=&quot;ivy-check-snapshot-jars&quot;
        depends=&quot;ivy-count-snapshot-jars&quot;
        if=&quot;ivy.snapshot.present&quot;&gt;
     &lt;echo&gt;WARNING: Project uses ${ivy.snapshot.count} SNAPSHOT jar(s).&lt;/echo&gt;
&lt;/target&gt;
</pre>
<p>The first target does most of the work and is used to count the number of jar files with &#8216;SNAPSHOT&#8217; in their name; it also sets a property if the count is not zero.</p>
<p>The second target is the main one that should be used to perform the check. It depends on the first target (ensuring that the count is done first) and will only then run if the first target sets the &#8216;ivy.snapshot.present&#8217; property. Thus the warning message will only get echoed if there are snapshot jars in the project.    </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smartkey.co.uk/2011/09/searching-for-files-in-an-ant-script/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Mockito to Unit Test Java Applications</title>
		<link>http://blog.smartkey.co.uk/2010/02/mockito-unit-test-java/</link>
		<comments>http://blog.smartkey.co.uk/2010/02/mockito-unit-test-java/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 18:39:26 +0000</pubDate>
		<dc:creator>Steve Neal</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Java Programming]]></category>
		<category><![CDATA[Tool support]]></category>
		<category><![CDATA[Google Code]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Mockito]]></category>
		<category><![CDATA[Test]]></category>
		<category><![CDATA[Unit Testing]]></category>

		<guid isPermaLink="false">http://blog.smartkey.co.uk/?p=604</guid>
		<description><![CDATA[If you&#8217;ve spent any time writing unit tests then you&#8217;ll know that it&#8217;s not always straight-forward. Certain things are inherently hard to test. In this post I&#8217;ll show you the basic principles of creating mock objects with a little help from the Mockito mocking tool.
One common problem faced when unit testing is how to test [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve spent any time writing unit tests then you&#8217;ll know that it&#8217;s not always straight-forward. Certain things are inherently hard to test. In this post I&#8217;ll show you the basic principles of creating mock objects with a little help from the <a href="http://www.mockito.org">Mockito</a> mocking tool.</p>
<p>One common problem faced when unit testing is how to test one object when it is dependant on another object. You could create instances of both the object under test and the dependent object and test them both together, however testing aggregated objects is not what unit testing is about &#8211; unit tests should test individual objects for their correct behaviour, not aggregations of objects! Moreover, this approach just won&#8217;t work if the dependent object hasn&#8217;t even been implemented yet.</p>
<p>A common technique for handling dependencies in unit tests is to provide a surrogate, or &#8220;mock&#8221; object, for the dependent object instead of a real one. The mock object will implement a simplified version of the real objects methods that return predictable results and can be used for testing purposes. </p>
<p>The drawback of this approach is that in a complex application, you could find yourself creating a lot of mock objects. This is where frameworks like Mockito can save you a lot of time and effort.</p>
<h3>A Test Scenario</h3>
<p>To demonstrate what you can do with Mockito, we&#8217;ll examine how we might test an Account object that is dependant on a data access object (AccountDAO).  The account object can calculate the charges applicable in the current month by using the DAO to count the number of days overdrawn and then performing a simple calculation on the value obtained from that call. The method names on the classes we&#8217;ll use are self-explanatory:</p>
<p><img src="http://blog.smartkey.co.uk/wp-content/uploads/2010/02/AccountAndDAO1.png" alt="AccountAndDAO" title="AccountAndDAO" width="376" height="55" class="aligncenter size-full wp-image-648" /><br />
To test this thoroughly, we should test two things:</p>
<ol>
<li>that the account obtains the number of overdrawn days by calling the correct method on the DAO,</li>
<li>that the account calculates the correct fees based upon the value it gets back from the call.</li>
</ol>
<h3>Testing that the account calls the correct method on the DAO</h3>
<p>Using JUnit to run the test case, we could write something like this:</p>
<pre class="brush: java">
import static org.mockito.Mockito.*;

public class TestAccount {
    @Test
    public void checkAccountCallsDaoMethods() {
        //create the object under test
        Account account = new Account();

        //create a mock DAO
        AccountDAO mockedDao = mock(AccountDAO.class);	

        //associate the mocked DAO with the object under test
        account.setDAO(dao);

        //call the method under test
        long charge = account.calculateCharges();

        //verify that the &#039;countOverdrawnDaysThisMonth&#039; was called
        verify(mockedDao).countOverdrawnDaysThisMonth();
    }
}
</pre>
<p>Taking centre stage in all this is the Mockito class which has a bunch of static methods that are used within the unit test (note the static import on line 1). </p>
<p>The call to the &#8216;mock&#8217; method (line 10) creates a mock object that can be used in place of a real AccountDAO. The call to &#8216;verify&#8217; (line 19), will throw an exception if the &#8216;countOverdrawnDaysThisMonth&#8217; method was not called on the mock object. </p>
<p>It is worth noting here that this is a simple example which just demonstrates the basic principle of verification, it is also possible to use the verify method to check for parameter values and ranges in the method call too.</p>
<h3>Testing that the account performs its calculations correctly</h3>
<p>In the above example, we mocked the DAO but didn&#8217;t specify what any of the mocked methods should do. In this case, all methods will return sensible default values of: null, zero or false. More commonly we need to specify something other than these defaults when writing our tests:</p>
<pre class="brush: java">
import static org.mockito.Mockito.*;
import static junit.framework.Assert.*;
import org.junit.*;

public class TestAccount {
    private Account account;

    @Before
    public void setup() {
        AccountDAO mockedDao = mock(AccountDAO.class);

    	//specify that this method on the mock object should return 8
        when(mockedDao.countOverdrawnDaysThisMonth()).thenReturn(8);

        account = new Account();
        account.setDAO(dao);
    }

    @Test
    public void checkChargesWhenOverdrawn() {
        //call the method under test
        long charge = account.calculateCharges();

        //assert that the charge was £2 per day overdrawn
        assertEquals(charge, 16);
    }
}
</pre>
<p>The statement on line 18 specifies that whenever the &#8216;countOverdrawnDaysThisMonth&#8217; is called it should return a value of 8; overriding the default of zero.</p>
<p>Given that the correct charge is two pounds (or dollars) per day overdrawn, then the assertion on line 25 will pass if the account performed the correct calculation (8 x 2 = 16 right).</p>
<h3>Comments</h3>
<p>There&#8217;s loads more to Mockito than we&#8217;ve looked at here. It&#8217;s a neat testing tool that works great with JUnit or TestNG. I&#8217;ve found that it&#8217;s small enough to learn quickly and capable enough to be really useful. Give it a go and write a comment below to let me know what you think of it.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smartkey.co.uk/2010/02/mockito-unit-test-java/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Configuring MySQL on Mac OS X</title>
		<link>http://blog.smartkey.co.uk/2010/02/configuring-mysql-on-mac-os-x/</link>
		<comments>http://blog.smartkey.co.uk/2010/02/configuring-mysql-on-mac-os-x/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 14:41:03 +0000</pubDate>
		<dc:creator>Steve Neal</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Tool support]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://blog.smartkey.co.uk/?p=624</guid>
		<description><![CDATA[I found the documentation for MySQL a little rough around the edges recently when I needed to change a configuration setting for it &#8211; everything seemed spread around their comprehensive PDF documentation and it took me a little while to fathom my way through it. 
It&#8217;s not often that changes to MySQL configuration need to [...]]]></description>
			<content:encoded><![CDATA[<p>I found the documentation for MySQL a little rough around the edges recently when I needed to change a configuration setting for it &#8211; everything seemed spread around their comprehensive PDF documentation and it took me a little while to fathom my way through it. </p>
<p>It&#8217;s not often that changes to MySQL configuration need to be made. This post is, therefore, more a reminder to myself than anything else.</p>
<p>First locate the configuration file. On my Mac I found this empty configuration file had been created as part of the installation process:</p>
<p><code>/etc/my.cnf</code> </p>
<p>You&#8217;ll need super-user privileges to update it. I used:</p>
<p><code>sudo vi /etc/my.cnf</code></p>
<p>Enter the configuration settings you require. I wanted to update the maximum packet size so I entered:</p>
<p><code>[mysqld]<br />
max_allowed_packet=16000000<br />
</code></p>
<p>Then you should be able to stop MySql with:</p>
<p><code>mysqladmin -u root -p shutdown<br />
</code></p>
<p>Restart it using whatever start script you prefer. To make sure that your changes have taken effect you can print the server variables to the console with:</p>
<p><code>mysqladmin -u root -p variables<br />
</code></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smartkey.co.uk/2010/02/configuring-mysql-on-mac-os-x/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Ignoring Files and Directories in a Subversion Project</title>
		<link>http://blog.smartkey.co.uk/2009/12/ignoring-files-and-directories-subversion/</link>
		<comments>http://blog.smartkey.co.uk/2009/12/ignoring-files-and-directories-subversion/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 11:58:07 +0000</pubDate>
		<dc:creator>Steve Neal</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Tool support]]></category>
		<category><![CDATA[Ignore]]></category>
		<category><![CDATA[Subversion]]></category>

		<guid isPermaLink="false">http://blog.smartkey.co.uk/?p=566</guid>
		<description><![CDATA[Configuring Subversion to ignore files can sometimes cause confusion. Like most things though, if you understand the basic principles, then its not tricky at all. In this post I'll demonstrate just how you should go about ignoring files in a subversion project. ]]></description>
			<content:encoded><![CDATA[<p>Configuring Subversion to ignore files can sometimes cause confusion. Like most things though, if you understand the basic principles, then its not tricky at all. In this post I&#8217;ll demonstrate just how you should go about ignoring files in a subversion project.</p>
<p>There are two ways to ignore files in svn: global settings and local. Global settings configure the users environment with some rules for ignoring files, but generally the local ignores are more useful and will be discussed here.</p>
<p>Most projects have files that should be ignored and not included in the version repository. For example, in Java projects, the compiler output shouldn&#8217;t be included as these can be regenerated from the source anyway. You might also have temporary cache files being generated, or output from running unit tests that you don&#8217;t want to share too.</p>
<h3>Ignoring files and directories</h3>
<p>Each directory in a svn managed project has a sub-directory called .svn which contains configuration information that svn uses when working in that directory. To make svn ignore certain content within a directory you need to configure an <strong>svn:ignore</strong> property for it.</p>
<p>To demonstrate this let&#8217;s work with the following project directory structure:</p>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">myproject/build/classes</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">myproject/log.txt</div>
<pre style="font: normal normal normal 12px/18px Consolas, Monaco, 'Courier New', Courier, monospace;">myproject/log-2009-12-01.txt
myproject/log-2009-12-02.txt
myproject/build/classes</pre>
<p>First let&#8217;s tell svn to ignore the log files that have been created. I&#8217;m using SVN 1.5.4 on a Mac so I&#8217;ll demonstrate this using a command line but you could do much the same using a GUI tool like Tortoise:</p>
<pre>$ svn propset svn:ignore 'log-*.txt' myproject</pre>
<p>The above command has used the <strong>propset</strong> command to set the <strong>svn:ignore</strong> property value to <strong>log-*.txt</strong> for the <strong>myproject</strong> directory.</p>
<p>Note that it is possible to use a wild-card &#8216;*&#8217; as part of the file name. You can also use the &#8216;?&#8217; symbol to match a single character in a file name but svn does not currently support any more powerful matching features.</p>
<p><em>Importantly note also that the file name must be quoted in order that the literal value is passed to the svn command; without this the shell will process the wild-card and pass all matching file names instead.</em></p>
<p>You can inspect the value of this property using the propget command like this:</p>
<pre>$ svn propget svn:ignore myproject
log-*.txt</pre>
<p>An ignore property can also be applied to directories, causing all files and sub-directories within it to be ignored. To make svn ignore the classes directory and its contents we could use the command:</p>
<pre style="font: normal normal normal 12px/18px Consolas, Monaco, 'Courier New', Courier, monospace;">$ svn propset svn:ignore 'classes' myproject/build</pre>
<h3>Setting multiple ignore rules within a directory</h3>
<p>So far we&#8217;ve looked at how we can set an individual ignore rule within a directory using the <strong>propset</strong> command. Although both of the rules we&#8217;ve demonstrated have resulted in multiple files being ignored, either by using a wild card syntax or by specifying a directory whose content will also be ignored, we&#8217;ve not yet discussed is how these rules can be combined within a directory; for example: to ignore all log files and also a sub-directory:</p>
<pre>/myproject/log-2009-12-01.txt
/myproject/log-2009-12-02.txt
/myproject/classes</pre>
<p>The <strong>svn:ignore</strong> property is actually a list of file name patterns that svn must ignore. The propset command simply overwrites that list with a single line that includes the pattern you specify when you issue the command.</p>
<p>To create a list of file names that will be matched, use the <strong>propedit</strong> command instead:</p>
<pre>$ svn propedit svn:ignore myproject</pre>
<p>Your svn editor will then be started and you can edit the list of filenames that must be ignored. For our example it would need to look like this:</p>
<pre>log-*.txt
classes</pre>
<p>Note that each file name pattern must be on a separate line.</p>
<h3>Ignoring versioned files and directories</h3>
<p>You must be aware that the <strong>svn:ignore</strong> properties only apply to any files that are <em>not</em> under version control.</p>
<p>In practical terms this means if you accidentally add a file or directory to your version control, you will need to explicitly issue a svn delete command (rm) in order that svn will ignore the files.</p>
<p>Commands like <strong>add</strong> and <strong>import</strong> work recursively in svn, so it&#8217;s easy to accidentally add files like those mentioned above to a versioned project. For example if our log files were accidentally added we could issue this command to delete them from svn:</p>
<pre>svn rm log*.txt</pre>
<p>Note this time that the filename is not quoted as we want the shell to pass all log files to be deleted.</p>
<p>After committing the changes to the project, the files will no longer be managed by svn and the ignore properties will once again work.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smartkey.co.uk/2009/12/ignoring-files-and-directories-subversion/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A Unix Command to Recursively Delete all .svn Folders</title>
		<link>http://blog.smartkey.co.uk/2009/11/recursively-delete-svn-folders/</link>
		<comments>http://blog.smartkey.co.uk/2009/11/recursively-delete-svn-folders/#comments</comments>
		<pubDate>Wed, 25 Nov 2009 11:26:39 +0000</pubDate>
		<dc:creator>Steve Neal</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Tool support]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[Unix / Linux]]></category>

		<guid isPermaLink="false">http://blog.smartkey.co.uk/?p=554</guid>
		<description><![CDATA[I recently needed to check out a project from Subversion and then delete all of the .svn files from the project directories. Google found me a few different ways to do this, but none of them seemed to deal with a case where some of the directory and file names had spaces or quotes in them – as mine did. After a little experimenting, I figured out how some simple Unix commands that could be combined using pipes to do this.]]></description>
			<content:encoded><![CDATA[<p>I recently needed to check out a project from Subversion and then delete all of the .svn files from the project directories. Google found me a few different ways to do this, but none of them seemed to deal with a case where some of the directory and file names had spaces or quotes in them &#8211; as mine did.</p>
<p>After a little experimenting, I figured out the following commands could be combined as illustrated below:</p>
<p>From within the project root folder this command can be used to list all of the .svn directories:</p>
<pre>$ find . -type d -name .svn</pre>
<p>If your directory names don&#8217;t have spaces or quotes in them, then you could just pipe the find command directly into xargs and rm to delete them all:</p>
<pre>$ find . -type d -name .svn | xargs rm -rf</pre>
<p>If you do have spaces or quotes in your directory names, then you need to change the newlines returned from find into null characters (notice the -print0 flag), and make xargs use this to split the input into individual file names (see the -0 flag) rather than the newlines, spaces and quotes that it normally looks for:</p>
<pre>$ find . -type d -name .svn -print0 | xargs -0 rm -fr</pre>
<p>The above command will delete all directories named &#8216;.svn&#8217;, regardless of whether they have spaces, or quote characters in their names.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smartkey.co.uk/2009/11/recursively-delete-svn-folders/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Branching and Merging with Subversion (SVN)</title>
		<link>http://blog.smartkey.co.uk/2009/11/branching-and-merging-with-subversion-svn/</link>
		<comments>http://blog.smartkey.co.uk/2009/11/branching-and-merging-with-subversion-svn/#comments</comments>
		<pubDate>Sun, 01 Nov 2009 10:38:46 +0000</pubDate>
		<dc:creator>Steve Neal</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Tool support]]></category>
		<category><![CDATA[Subversion]]></category>

		<guid isPermaLink="false">http://blog.smartkey.co.uk/?p=291</guid>
		<description><![CDATA[Working in the head revision of a versioning system isn't a great idea. It's much better to work in a branch and to merge the changes once you're convinced they are stable. This post demonstrates how to do this with Subversion.]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s generally considered bad practice to work directly in the head revision (aka. the trunk) of an SVN managed project. Undoing changes committed in the head is difficult, and if there are a number of developers working on different features, then updates to the code will be visible to all and may cause problems.</p>
<p>It&#8217;s much better to work in a branch and to merge the changes once you&#8217;re convinced they are stable. This post demonstrates how to do this using the Subversion command line tools; however, the same principles would apply if you were using a GUI tool like Tortoise for example.</p>
<h3>Creating a branch</h3>
<p>Creating a branch is simple. You just copy the revision you want to make changes to into the branches folder of your project in the SVN repository, for example:</p>
<pre>svn copy http://svnserver/myproject/trunk http://svnserver/myproject/branches/stevescopy</pre>
<p>This will create a copy of the head revision in the project called &#8216;myproject&#8217; in a branch folder called &#8217;stevescopy&#8217; on the SVN server found at &#8217;svnserver&#8217;.</p>
<p>You may notice when doing this that the copy operation completes very quickly, this is because no files are actually copied, SVN just copies markers to file versions making branching a very cheap and fast operation to perform.</p>
<p>Next you should check out the branch before working on it in the usual manner. So, following the previous example, we could check out our branch using:</p>
<pre>svn co http://svnserver/myproject/branches/stevescopy .</pre>
<p>When working on the code in the branch, you should feel free to commit changes as frequently as you like. The changes that you make are now completely separate from the head revision.</p>
<h3>Merging changes back to the trunk</h3>
<p>When you&#8217;re ready to merge whatever updates you&#8217;ve been working on back into the trunk, you should first commit all changes in your branch. To do this, issue the SVN commit command from the working directory of your branch:</p>
<pre>svn commit -m 'committing the branch before merging'</pre>
<p>Next, in a separate directory, check out the version of the project that you want to merge your changes into.  In our case we want to merge our changes back into the head revision:</p>
<pre>svn co http://svnserver/myproject/trunk .</pre>
<p>Now we can perform the merge. The merge does not change the data held in the repository, instead it updates the local copy that we have just checked out. So, from the directory into which we just checked out the trunk, we should issue a command to merge the changes from our branch:</p>
<pre>svn merge http://svnserver/myproject/branches/stevescopy</pre>
<p>SVN will now update all the files in this working copy with the changes made in our branch. If there are conflicts (i.e. another user has updated the original trunk files since you checked them out) then SVN will detect this and it will ask you to resolve them. Once completed, you should check that your project builds and passes all of its tests before committing your merged copy back to the trunk:</p>
<pre>svn commit -m 'committing with updates from the stevescopy branch'</pre>
<h3>Cleaning up</h3>
<p>If you don&#8217;t plan to do any more work on the branch, you can delete it using something like this:</p>
<pre>svn rm http://svnserver/myproject/branches/stevescopy</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.smartkey.co.uk/2009/11/branching-and-merging-with-subversion-svn/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using the JForum SSO plug-in from Grails</title>
		<link>http://blog.smartkey.co.uk/2009/10/using-the-jforum-sso-plug-in-from-grails/</link>
		<comments>http://blog.smartkey.co.uk/2009/10/using-the-jforum-sso-plug-in-from-grails/#comments</comments>
		<pubDate>Mon, 19 Oct 2009 16:02:08 +0000</pubDate>
		<dc:creator>Steve Neal</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Tool support]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JForum]]></category>
		<category><![CDATA[SSO]]></category>

		<guid isPermaLink="false">http://blog.smartkey.co.uk/?p=279</guid>
		<description><![CDATA[How to apply Single Sign On (SSO) to JForum from within a Grails application.]]></description>
			<content:encoded><![CDATA[<p>In a <a href="http://blog.smartkey.co.uk/2009/10/secure-sso-for-jforum/" target="_self">previous post</a> I explained how the JForum SSO plug-in can be used to secure a JForum application.</p>
<p>In this post I&#8217;ll demonstrate how the same principle can be applied in a Grails application.</p>
<p>Basically, just about everything from the previous post is the same, except for how the filtering of requests and the sending of the cookies from the host application is performed.</p>
<p>In Grails it is simple to write web filters. Just create a Groovy class with a name that ends with &#8216;Filters&#8217; in your conf folder and add closures that define the filtering behaviour:</p>
<pre class="brush: java">
class MyFilters {
    def filters = {
        myFirstFilter(controller: &#039;*&#039;, action: &#039;*&#039;) {
            before = {
                  //code here is executed before the controller has been accessed
            }
            after = {
                  //code here is executed after the controller has been accessed
            }
            afterView = {
                  //code here is executed after the view has been rendered
            }
        }
    }
}
</pre>
<p>in this example, there is a single filter called &#8216;myFirstFilter&#8217; that will be applied to all actions on all controllers, which illustrates the three filtering points available in Grails.</p>
<p>So given a Grails application service called &#8216;userService&#8217; that returns us a domain object for the currently logged in user, then we could write a cookie sending filter which uses the SSO plug-in like this:</p>
<pre class="brush: java">
class SecurityFilters {
  def userService;

  def filters = {
    jForumSecureSSOCookie(controller: &#039;*&#039;, action: &#039;*&#039;) {
      after = {
        if (userService.getUser()) {
          def user = userService.getUser();
          def encryptedValues = SecurityTools.getInstance().encryptCookieValues(user.email, user.username);

          Cookie c = new Cookie(SecurityTools.FORUM_COOKIE_NAME, encryptedValues)
          c.maxAge = -1;
          c.path = &quot;/&quot;
          c.comment = &quot;SSO cookie for language spider forum&quot;
          response.addCookie(c)
        } else {
          //user is not logged in so kill the cookie
          //(removing cookies does not work reliably in all browsers)
          Cookie c = new Cookie(SecurityTools.FORUM_COOKIE_NAME, &quot;&quot;)
          c.maxAge = -1;
          c.path = &quot;/&quot;
          c.comment = &quot;SSO cookie for language spider forum&quot;
          response.addCookie(c)
        }
      }
    }
  }
}
</pre>
<p>Because, Grails runs in a Java environment, all other configuration, including the JAR file deployment remain as discussed in the previous post.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smartkey.co.uk/2009/10/using-the-jforum-sso-plug-in-from-grails/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Secure single sign on (SSO) for JForum</title>
		<link>http://blog.smartkey.co.uk/2009/10/secure-sso-for-jforum/</link>
		<comments>http://blog.smartkey.co.uk/2009/10/secure-sso-for-jforum/#comments</comments>
		<pubDate>Mon, 19 Oct 2009 14:32:28 +0000</pubDate>
		<dc:creator>Steve Neal</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Tool support]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[JForum]]></category>
		<category><![CDATA[Maven]]></category>
		<category><![CDATA[SSO]]></category>

		<guid isPermaLink="false">http://blog.smartkey.co.uk/?p=225</guid>
		<description><![CDATA[I recently developed a web application that used the excellent open source project JForum for its forum pages. The one thing that was missing from JForum though was a secure SSO module. In this article I&#8217;ll explain why the SSO solution bundled with JForum was not secure enough for our purposes and I&#8217;ll show you how [...]]]></description>
			<content:encoded><![CDATA[<p>I recently developed a web application that used the excellent open source project JForum for its forum pages. The one thing that was missing from JForum though was a secure SSO module. In this article I&#8217;ll explain why the SSO solution bundled with JForum was not secure enough for our purposes and I&#8217;ll show you how I solved this problem.</p>
<p>As the SSO code I wrote didn&#8217;t have any dependency on our applications classes, I decided to package and release it as a JAR file that anyone can use.  If you&#8217;d like to use it, then you can <a href="http://www.smartkey.co.uk/tools.html" target="_blank">download it from the tools page</a> on this website; instructions on how it words and how to configure JForum to use it are detailed below.</p>
<h3>Integrating JForum into an existing application</h3>
<p>JForum is indented to be used as either a stand-alone forum, or as an integrated solution for existing sites. The simplest way to integrate JForum with an existing application is simply to deploy it as a second named application under the same domain. For example, if your application is running on a server at:</p>
<pre>http://www.myapplication.com/</pre>
<p>then just run the JForum application under the same domain as a separate application, for example:</p>
<pre>http://www.myapplication.com/forum</pre>
<p>you can then just link to it from your web pages. Customise the JForum page templates to look like those from your own application and you&#8217;re almost done.</p>
<p>The last thing that you&#8217;ll want to do is automatically log users in to the forum once they&#8217;re logged into your application. If you don&#8217;t do this then your users will have to re-register with JForum just to use the forum pages! Fortunately, JForum ships with a simple SSO module. Unfortunately it&#8217;s not very secure.</p>
<p>If you&#8217;re running JForum on the same domain as the application your are integrating it with, then cookies set by one application will be visible to the other; as far as the browser can tell, its interacting with a single application. The standard SSO solution that ships with JForum exploits this fact and if your application sets a cookie with the user&#8217;s screen name and email address, JForum will automatically log them in to the forum pages for you.</p>
<p>This is a neat and simple solution but it does have a real security hole. If a hacker decides that they want to log into the forum and post messages as another user, then all they need to do is make their browser send a cookie with the name and email details of the users account they want access and JForum will then just log them into it. This is easy to do with something like Firefox&#8217;s firebug plug-in and doesn&#8217;t require any great skill.</p>
<p>JForum does provide an API with hooks for implementing your own SSO integration. In the JForum documentation, the example demonstrates how, in addition to receiving the user&#8217;s credentials (again via a plain text cookie), you could make calls to your database to access further user information. This does not address the security issue outlined above. Further work is required to achieve this.</p>
<h3>A more secure solution</h3>
<p>In the solution I developed, rather than sending a plain text user name to JForum in a cookie, an encrypted value is passed between the applications instead. By using a strong encryption algorithm it is possible to authenticate the user just once in the main application, and then send an encrypted token in the cookie that can be used to authenticate the user in JForum. This approach has the distinct advantage of preventing any hackers from being able to spoof user names by simply sending them in a cookie.</p>
<p>So, for example, if you encrypt your user&#8217;s name and email address before sending them in a cookie, anyone examining the cookie data will see something resembling:</p>
<pre>b259fa5bb42d8c53280c54bbb16d9b814574443d903eb85ba5594ef58b374c8d</pre>
<p>this can be decrypted by JForum and the users name and email address retrieved from it.</p>
<h3>Configuring and using the JForumSecureSSO plug-in</h3>
<p>The steps involved to use this plug-in are:</p>
<ol>
<li>Change the default encryption password used</li>
<li>Install the JAR file in each of the applications</li>
<li>Implement a cookie filter for your application</li>
<li>Configure JForum to use your encrypted cookie</li>
</ol>
<p>Lets look at these in more detail:</p>
<p><em>1. Change the default encryption password used</em></p>
<p>If you take a look in the META-INF folder in the jforum-secure-sso.jar file you&#8217;ll find a properties file that contains a property called security.password. The default value for this property is &#8216;change this&#8217;.</p>
<p>This property value is the password used by the encryption libraries as a seed for the encryption that is carried out on the cookie data. Update the JAR file by changing the password to a value that only you know &#8211; you should make this at least 16 chars long.</p>
<p>Note that you won&#8217;t use this password anywhere else in your application so you could just enter some random characters here.</p>
<p><em>2. Install the JAR file in each of the applications</em></p>
<p>Copy the JAR file with the modified password into the WEB-INF/lib folders of both your application and JForum too. This ensures that the encryption routines in the JAR files will now both be using your secret password when encrypting/decrypting the data.</p>
<p><em>3. Implement a cookie filter for your application</em></p>
<p>In order to ensure that an encrypted cookie is sent for any authenticated users, you&#8217;ll need to add a little functionality to your application.</p>
<p>There are a number of variations on how you might do this depending on the security system that you are using. For this reason, there are no classes in the JAR file that do this for you &#8211; time for you to cut a little code!</p>
<p>Generally, the best way to send the cookie will be from within a Web Filter. These are a standard feature since Servlet 2.3 specification and are are supported by all but the most antique application servers. The filter should be applied to all URLs that your application supports and will need to send an encrypted cookie, something like this:</p>
<pre class="brush: java">
import uk.co.smartkey.jforumsecuresso.SecurityTools;

//get your user&#039;s details from wherever they are available in  your application
User user = session.getAttribute(&#039;user&#039;);

//encrypt them using your secret password
String encryptedData = SecurityTools.getInstance().encryptCookieValues(user.getEmail(), user.getUserName());

//send the cookie using the predefined cookie name
Cookie c = new Cookie(SecurityTools.FORUM_COOKIE_NAME, encryptedData)
c.maxAge = -1;
c.path = &quot;/&quot;
response.addCookie(c)
</pre>
<p><em>4. Configure JForum to use your encrypted cookie</em></p>
<p>In the JForum configuration file, you&#8217;ll need to set the following properties to ensure that your data is loaded and used to log your users in using SSO:</p>
<pre class="brush: xml">
authentication.type=sso
sso.implementation=uk.co.smartkey.jforumsecuresso.JForumSecureSSO
sso.redirect=http://www.myapplication.com/login.jsp
</pre>
<p>More details of these settings are available at the JForum web site.</p>
<h3>Comments</h3>
<p>If you think this could be of use to you, then you can download the distribution files from our <a href="http://www.smartkey.co.uk/tools.html" target="_self">tools page</a>. This project has been tested to work with JForum 2.1.8 running on Tomcat 6 and is built using Maven. The source code is included in the distribution and is released using the same BSD license as JForum. If you&#8217;d like to add any functionality, I&#8217;ll be happy to include it in a future release.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smartkey.co.uk/2009/10/secure-sso-for-jforum/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>InteliJ IDEA is now open source!</title>
		<link>http://blog.smartkey.co.uk/2009/10/intelij-idea-is-now-open-source/</link>
		<comments>http://blog.smartkey.co.uk/2009/10/intelij-idea-is-now-open-source/#comments</comments>
		<pubDate>Fri, 16 Oct 2009 20:42:02 +0000</pubDate>
		<dc:creator>Steve Neal</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Tool support]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[IDEA]]></category>
		<category><![CDATA[IntelliJ]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://blog.smartkey.co.uk/?p=209</guid>
		<description><![CDATA[IntelliJ have open sourced IDEA. What does this mean to the Java and Groovy/Grails communities?]]></description>
			<content:encoded><![CDATA[<p>IntelliJ <a href="http://www.jetbrains.com/idea/nextversion/free_java_ide.html">announced today</a> that version 9 of their Java IDE &#8220;IDEA&#8221; will be open sourced.</p>
<p>Now I&#8217;ve got to admit to being a big fan of IDEA. I&#8217;ve been using it for years now, and as the IntelliJ people have been saying all along: &#8220;<em>it&#8217;s the best Java IDE that money can buy</em>&#8220;. Well now it looks like it may well be the best free Java IDE too!</p>
<p>If you&#8217;ve not tried it, then now might be the perfect time to download it and give it a go. I can guarantee that after you&#8217;ve invested a little effort in figuring out what it can do for you, your productivity will increase dramatically. And that&#8217;s what&#8217;s always been key for me: if the time I save using the tool costs me less than the license fee, then it&#8217;s a no-brainer: pay up and work more efficiently. It&#8217;s  a simple value-for-money decision.</p>
<p>So what can it do? Well, for example, can your IDE attach to your database, load the schema and then give you code completion in the SQL strings that you write when programming JDBC? Work with Hibernate instead? Then maybe you&#8217;d appreciate the code completion for your HQL queries and also in  your mapping files. Want a UML diagram generated from your source code? No problem. If you&#8217;re a fan of Spring, then you might like the graphical view of the dependencies in a Spring application context? Need to see if your Spring pointcut syntax is right? Then a keyboard shortcut to view the advised methods on your beans will help with that. I could go on and on, but you probably get the idea.</p>
<p>Now this is where things get a little complicated. The JavaEE and framework features I&#8217;ve listed above won&#8217;t be available in the open-source, or &#8220;community&#8221;, edition. The JavaEE support is reserved for those that are still prepared to pay for it. Fair enough you might say; if you want better JavaEE support in Eclipse you&#8217;ll likely choose to use MyEclipse which currently costs over $150 and offers some of the best support available for Web development in that IDE. And I&#8217;d have to agree with  you: you pays your money, you takes your choice.</p>
<p>Regardless of this, the features available in the community edition of IDEA still far exceed those available in most other free Java IDEs and, in my opinion, are more reliable and robust oot. IDEA not only provides Java coding support but also XML, Groovy and regular expression syntax too. Add to this Live Templates (a build in macro language for automating common code generation, like iteration over collections/arrays for example)  and you&#8217;ve got a feature set that will keep most Java developers very happy. For a complete comparison matrix of the features that are available in the community and the ultimate editions, <a href="http://www.jetbrains.com/idea/nextversion/editions_comparison_matrix.html" target="_blank">take a look at this link</a>.</p>
<p>This seems to me to be a very clever marketing decision by IntelliJ. They are clearly aware that their greatest barrier to mass adoption is not the quality of the IDE, but the price of a license, and that by releasing this edition of their application they have completely eliminated this.</p>
<p>Good move I say, and good luck.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smartkey.co.uk/2009/10/intelij-idea-is-now-open-source/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Packaging JavaME Applications with the Antic Ant task</title>
		<link>http://blog.smartkey.co.uk/2008/09/packaging-java-me-applications-with-the-antic-ant-task/</link>
		<comments>http://blog.smartkey.co.uk/2008/09/packaging-java-me-applications-with-the-antic-ant-task/#comments</comments>
		<pubDate>Tue, 13 Oct 2009 20:28:46 +0000</pubDate>
		<dc:creator>Steve Neal</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Java Programming]]></category>
		<category><![CDATA[Tool support]]></category>
		<category><![CDATA[Ant]]></category>
		<category><![CDATA[Antic]]></category>
		<category><![CDATA[Build]]></category>
		<category><![CDATA[JavaME]]></category>

		<guid isPermaLink="false">http://blog.smartkey.co.uk/?p=5</guid>
		<description><![CDATA[This article illustrates just how simple it is to correctly package a Java ME Midlet using Smartkey&#8217;s freely available Antic Ant task.
Packaging Midlets
Packaging Midlets can be a complex process. Firstly, there are requirements for two files to be created: a Jar and a Jad file. The Jar file will contain all of the classes and [...]]]></description>
			<content:encoded><![CDATA[<p>This article illustrates just how simple it is to correctly package a Java ME Midlet using Smartkey&#8217;s freely available Antic Ant task.</p>
<h3>Packaging Midlets</h3>
<p>Packaging Midlets can be a complex process. Firstly, there are requirements for two files to be created: a Jar and a Jad file. The Jar file will contain all of the classes and other resources that the application requires, and the Jad file will contain entries which describe the contents of the Jar. In both the Jar and the Jad files, there are a number of mandatory entries that must be made. Among other things, the manifest in the Jar must, for example, specify the application version and the Jad file must specify the exact size of the Jar file.</p>
<p>If any of the entries in either of these files is incorrect, then your application may not work on a some devices; and the only way to check that an incorrectly packaged application works on all devices is to test it on all devices. Very impractical &#8211; a far better solution, obviously, is to correctly package the application in the first place.</p>
<p>Antic is an Ant task that can be used in conjunction with any standard Ant release. Antic fills a gap in the standard Ant tasks&#8217; functionality and provides capabilities for packaging Java ME applications. All other related Java ME build functionality can automated with the standard Ant tasks.</p>
<h3>Using Antic in an Ant build files</h3>
<p>A typical Antic entry in a build file might look like this:</p>
<pre class="brush: xml">
&lt;taskdef name=&quot;antic&quot;
classname=&quot;uk.co.smartkey.util.anttasks.AnticTask&quot;
classpath=&quot;antic.jar&quot;
/&gt;

&lt;target name=&quot;package&quot; depends=&quot;compile&quot;&gt;
&lt;antic suiteName=&quot;Demo Suite&quot;
version=&quot;1.0&quot;
vendor=&quot;smartkey.co.uk&quot;
profile=&quot;MIDP-2.0&quot;
configuration=&quot;CLDC-1.1&quot;
jarName=&quot;demo.jar&quot;
jadName=&quot;demo.jad&quot;
jarURL=&quot;http://www.smartkey.co.uk/demo.jar&quot;&gt;

&lt;midlet name=&quot;First Midlet&quot; classname=&quot;MessageMidlet&quot;/&gt;
&lt;midlet name=&quot;Second Midlet&quot; classname=&quot;DisplayMidlet&quot;/&gt;

&lt;attribute name=&quot;message&quot; value=&quot;Hello World!!!&quot;/&gt;

&lt;fileset dir=&quot;${build}&quot; includes=&quot;**/*&quot;/&gt;
&lt;fileset dir=&quot;${images}&quot; includes=&quot;*&quot;/&gt;
&lt;/antic&gt;
&lt;/target&gt;
</pre>
<p>Above, we can see that before we can use Antic, we must use the Ant taskdef element to declare a new task that we will use in this build file; with this we must specify the name, class, and classpath for the task.</p>
<p>We then define an target named &#8216;package&#8217;. This target uses Antic to create a Jar file called &#8216;demo.jar&#8217;, and an associated Jad file called &#8216;demo.jad&#8217;. All mandatory entries for the Jar file&#8217;s manifest and the Jad file are specified at attributes on the Antic task.</p>
<p>Within the Antic task there are two of midlet elements to describe each midlet in the suite; in this particular example there are two, called &#8216;First Midlet&#8217; and &#8216;Second Midlet&#8217;. Attributes can also be specified for the midlet suite, this is shown on the next line. The last elements within the Antic task are filesets; these specify the files that must be added to the Jar file; there must be at least one fileset element here.</p>
<p>If you&#8217;d like to use Antic to build your own J2ME applications, then go to our <a href="http://www.smartkey.co.uk/tools.html">tools page</a> where you can download the current release.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smartkey.co.uk/2008/09/packaging-java-me-applications-with-the-antic-ant-task/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

