How to increase the colour depth of Windows Remote Desktop (RDP) up to 24-bit

I use RDP to access my work PC on a daily basis and one of the limiting factors when doing web design has been the lack of colour depth - rather than the standard 24-bit (or higher) you get 15-bit due to using Remote Desktop (RDP). Although this is the default RDP server setting, you can increase it to 24-bit with a little Windows Registry hack.

NOTE: If you mess up your machine from hack your registry - please don't blame me, I'm only giving you the tool to do that damage...

Open regedit and browse to:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp

Over on the right-hand side you will see an attribute called "ColorDepth" which by default is set to 3 (or rather 0x00000003, it's a DWORD). Double-click that attribute and change the Value data field from 3 to 4, then click "OK", close regedit and reboot your PC.


Now if you increase the requested colour depth when connecting to this machine you should get a few more colours to play with!

Oh BTW Merry Christmas and a Happy New Year!

Technorati Tags: , , , ,

Fantastic service from StringsDirect guitar shop!

Late on Thursday night I broke one of my electric guitar strings and being a beginner I didn't have a pile of replacements to drop in straight away. I'd placed a couple of small orders with StringsDirect over the past few months and had such fast delivery that they were my first port of call. I placed an order for a couple of packs of handmade DR Strings (one Tite Fit and the other Hi-Beam) around midnight on Thursday night and what with the Christmas post service issues (along with various PO strikes) I had little hope that they would be with me before Christmas.

They arrived on Saturday morning, nicely packaged, all the correct bits I ordered - absolutely perfect! So if you need any guitar accessories, take an online trip to StringsDirect, they have loads of items and the delivery service is second to none!

As an aside, I picked DR Strings after Justin Sandercoe of www.justinguitar.com recommended them - his online guitar tuition site is second to none and I trust his judgement on products and accessories.

Now all StringsDirect need is an affiliate link programme... ;)

Technorati Tags: , , , , ,

How to get the Home & End keys working in Cygwin (RXVT)

Last year I blogged about how to get the Home & End keys working in remote Linux shells & terminals. Well now it's time to sort the Windows shell Cygwin out.

If your Home and End keys are producing funny characters on the command line rather than moving the cursor then the input codes of the keyboard need to be remapped.

Open your Cygwin terminal and create a file called .inputrc in your home directory, and add the following:

# Home Key
"\e[7~":beginning-of-line

# End Key
"\e[8~":end-of-line

# Delete Key
"\e[3~":delete-char

# Insert Key
"\e[2~":paste-from-clipboard
Now edit or create .bashrc in your home directory and add the following line to ensure the above .inputrc file is picked up:
export INPUTRC=$HOME/.inputrc
To see if all the above has worked, reopen your cygwin terminal and try it out! If it doesn't work then just delete the .inputrc file and remove the line from .bashrc.

Technorati Tags: , , , , , , ,

Create funky word images with Wordle

I was doing my daily Bloglines reading today when I can across this post from Dave Thomas which made me think "wow that really is quite pretty" (I am a techie after all, and who doesn't get excited when they see Ruby in a nice big font size?).

It was generated by a funky web application called 'wordle' which makes beautiful word clouds from words of your choosing. Point it at a blog, RSS feed, del.icio.us username or straight ol'piece of text and it creates the most wonderful word image map.

Here is one generated this morning when I pointed it at my blog:


Here is one from my mate Chris Routledge after he pointed it at the first chapter of his newly-published book "Cains: The Story of Liverpool in a Pint":



They are so nice I'm thinking of getting the image printed onto a t-shirt for that true geek factor!

Technorati Tags: , , , ,

RXVT - a better console for Cygwin (Unix on Windows)

If you use Windows for software development you will have probably come across Cygwin at some point, the Unix shell for Windows (well a bit of a fake console but it will have to do!).

The console out of the box is a bash shell running within a normal Windows cmd prompt box, which is ok but doesn't really give you all the features of a proper Unix shell, click and drag to select text, middle click to paste, decent scroll buffers, etc.

However there is a solution to these issues - scrap the silly Windows DOS box and run RXVT instead!

First off you will have to run the Cygwin installer again (don't worry it's quite clever and won't corrupt your current version of Cygwin) and select the rxvt terminal package to install. Then continue the installation as normal so that you are left with the Bash shell shortcut icon.

You will now need to replace the normal DOS box bash terminal with the new RXVT one. Right-click on the shell shortcut and change the "target" and "start in" fields to be the following:

Target: C:\cygwin\bin\rxvt.exe -e bash -login -i
Start in: C:\cygwin\bin\
Note: make sure you use your Cygwin installation location rather than just copying the above...

It should now look like this:


That will get a basic RXVT terminal running but let's add a few extra things to make it look more like a normal Unix shell. Open your new terminal (which will open in your Cygwin home directory) and create a file called .Xdefaults which contains the following:
Rxvt.reverseVideo:      true
Rxvt.scrollBar_right: false
Rxvt.saveLines: 2048
#Rxvt.font: "Lucida Console-12"
Rxvt.font: "Monaco-20"
If you cat the file it should look like this:


The above sets the background to be black like a normal shell, creates a pretty big console buffer and puts the scrollbar on the left (personal choice). It also sets the font to a rather large but cool Apple Monaco font, if you want a more normal font delete the Monaco font line and remove the comment '#' from the front of the other Rxvt.font line.

If you now exit your console and open it up again you should now feel much more at home. Oh and don't forget that middle-click pastes your copy buffer... ;)

Technorati Tags: , , , , , , ,

How to lose a Java object in a Collection (Set)

I was a little careless the other day, I lost one of my business objects in a Collection!

Or to be more precise a Java business object that I had placed in a Set could only be found by iterating through the contents of the Set, if I asked the contains(Object) method to find the object that I just added but it couldn't find it. Now the clue that I should have spotted sooner was that the rather plain add(Object) method I was calling was in fact on another application class and not directly on the Set.

What was happening was this other add(Object) was adding the object to the Set and then was adding the Set into the business object (it was doing this correctly as we wanted a parent-child relationship so that each knew about the other). The problem was that the hashCode method of the business object used it's reference to the Set to compute it's value.

When the object was added to the Set hashCode produced one value, once the Set was linked to the object, hashCode produced a different value. Because contains uses the object's hashCode to try and find the object in the Set it couldn't find it.

Swapping the order of events, i.e. link the Set first then add it to the parent Set ensured that the hashCode value was consistent and now the object could always be found.

So the moral of this story: be very careful when writing hashCode & equals methods and make sure you stop messing with the object the moment you add it to the Collection.

Technorati Tags: , , , ,

ClassNotFoundException when running JUnit unit tests within Eclipse (using Maven)

I've been using Eclipse & Maven for a while now and have the m2eclipse plugin installed so that Eclipse understands the Maven dependencies. I've never had any problems running unit tests within Eclipse until recently after I update the plugin. To see if you have this problem open any unit test within Eclipse and then run it as a JUnit test (or just CTRL-F11). It is fails with a 'ClassNotFoundException ' then you have this problem.

After obtaining the classpath that Eclipse was using to spawn off the unit test it was clear that Maven (or more correctly the Maven m2eclipse plugin) was the root of the issue. It intercepts the fork operation so that it can correctly build the classpath with all the appropriate dependencies, the only thing that was missing on the classpath was any reference to the project's Java class files!

The Maven project in question has the Java source and unit test classes in sub-modules and the Maven plugin wasn't adding these sub-modules to the classpath.

Note: Back up your .project and .classpath files before you perform the steps below.

After much web searching to no avail and then much headscratching I finally found the solution tucked away in the project's Maven settings. Right-click on the project in the left-hand pane and choose 'Properties' then click 'Maven' and you should be presented with the screen below:


Tick the 'Include Modules' box, click 'Apply', agree to Maven possibly trashing your project and wait...

You should now be able to run your unit tests again as it's put all the classes within the sub-modules encapsulated by the top-level POM on the classpath. I think this option must have changed from version 0.9.4 onwards of the m2eclispe plugin as my previous version 0.9.3 didn't suffer with this issue.

Technorati Tags: , , , , , , ,

Restoring disappeared context menu items in Eclipse

A recent problem we have had with Eclipse is where on one particular developer's PCs some of the options in the right-click context menu were not available. These options were also only not available on non-'build path' source folders. It was a very strange issue but we did manage to solve it:

Choose the 'Reset Perspective' option from the 'Window' menu to restore all the default options which includes the right-click context menus!

Technorati Tags: , ,

Why are User-Agents so confusing?

I colleague pointed me in the direction of a very funny and very true post from the WebAIM.org blog:

History of the browser user-agent string

The last part really points out the mess that the current browsers are in:

and Chrome called itself Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13, and the user agent string was a complete mess, and near useless, and everyone pretended to be everyone else, and confusion abounded
How is any website meant to know what rules to use now?

UPDATE: Here is a great resource for testing out different user-agents:

User Agent String.Com

Technorati Tags: , , ,

How to auto-fill lots of columns or cells with the same value in Excel

I had a spreadsheet recently (actually a CSV file which contained numerous columns of data. The values in the cells were either blank (empty) or the letter 'Y'. I needed to change all the blanks to 'N'.

Find and replace didn't work as you can't specify blank as a matching character (at least I couldn't find out how, please comment if you know!) and I didn't have the energy or time to manually update each cell. After some research I found that the answer was the 'Goto -> Special' options hidden within the 'Edit' menu.

Here's how to do it...

  • Select the columns and/or cells that you want to perform the special find within (hold down CTRL as you click the column headers or individual cells.

  • Click the 'Edit' menu and select 'Go To...':


  • Then click the 'Special...' button:


  • Then click the 'Blanks' option and click 'OK':

Any cells within your selection that contain blanks will now be selected leaving the other non-blank fields un-selected. If you now type and press ENTER it fills that first cell with what you typed and moves to the next blank cell. BUT here is the trick, if you type what you want in the cell and press CTRL+ENTER then all the blank fields will be filled with the entered values - pretty neat huh!

There are many more options within that Special pop-up and I've not really explored it at all but I have found out how you select all the non-number-only fields:

Remember, the 'Go to -> Special' helps you select the correct cells, the CTRL-ENTER auto fills them all with the value you enter in the first selected cell.

I found this information out from the rather useful Excel section of allexperts.com.

Technorati Tags: , ,

How to run individual JUnit unit test methods within Eclipse

Eclipse supports JUnit out of the box, and even has a handy keyboard shortcut for running all the test methods within a JUnit test class: CTRL-F11. You can also right-click within the unit test class, choose 'Run As' then 'JUnit Test'.

But what if you want to run just one of the many test methods with a particular test class? IntelliJ's IDEA has this option (you just right-click on the method name and run it) but Eclipse doesn't offer that feature.

One solution is to run all the tests within the test class (as described above) and then click on the particular test in the left-hand JUnit results window, right-click on the test and choose 'Run':


The other is to open the "Outline" view, and then right-click on appropriate unit test method, choose 'Run As' then 'JUnit Test':


That means that you don't have to run all the tests within a test class just to be able to run one of them. Now isn't that easier?

Technorati Tags: , , , ,

Using ampersands (&) without variable substitution in Oracle either direct or with SQL*Plus

Oracle uses the ampersand (&) symbol within a string to indicate a substitution variable. But what if you want to use an ampersand as part of a regular string such as 'Bob & Sons'?

There are two solutions that I know of and which one you use depends on the context in which you are running your SQL:

Dealing with the ampersand on an SQL level

To turn off interpreting the ampersand as a substitution variable it must be at the end of a string:
insert into companies values ('Bob &' || ' Sons');

Dealing with the ampersand when using SQL*Plus

To disable Oracle's variable substitution and therefore return & to the pool of standard characters you need to tell SQL*Plus to disable it:
set define off
Add that to the top of your Oracle SQL script or type it manually at the SQL*Plus prompt.

These tips plus many more can be found within the rather useful The Oracle (tm) Users' Co-Operative FAQ.

Technorati Tags: , , , , ,

Hibernate HQL problems with database views and deleted rows within the same transaction

I found an interesting Hibernate view-related issue yesterday when deleting some data from a table within a single transaction.

Let me set the scene a little - we have a People table which has one row per person. We have a FamilyTree database view which displays family trees using the People table as one of it's sources (it's quite a complex view with functions and the like but you get the picture).

I was writing some unit tests around the area of deleting people. I used the view to get a list of people, deleted a person from the People table and then used the view to ensure that the person was gone. All of this was done with Hibernate-annotated domain objects and some JPA-based DaoSupport style classes - the standard Spring/Hibernate way.

What I found was that when we were within a single transaction (i.e. within a unit test or within a web controller using the OpenSessionInView) and we delete from the table, the 'deleted row' is still visible and therefore incorrect. If you looked at the SQL trace you would find that the DELETE SQL statement was never flushed to the database as Hibernate is trying to be lazy and only perform such actions when it really has too.

As there are no annotations for telling Hibernate that this entity is actually backed by a view rather than a table, there is no way to tell Hibernate that it must flush changes to the People table when we access the FamilyTree view! This was (roughly) the code that was failing:

List results = getJpaTemplate().find("FROM FamilyTree ft WHERE ft.parent = ?", parent);
return results.get(0).getPerson();

As the HQL doesn't make a reference to the People table or the person relationship within the FamilyTree entity, Hibernate does not know that it needs to flush any outstanding People changes before it performs the SELECT. To prove this if we add a simple SELECT * FROM people between the row delete and the view access then the delete is flushed and so the view displays the correct information.

This didn't seem to be the cleanest of solutions so I tried changing my HQL query of the FamilyTree view to return a Person entity like so:
List results = getJpaTemplate().find("SELECT ft.person FROM FamilyTree ft WHERE ft.parent = ?", parent);
return results.get(0);
As we have explicitly mentioned in the HQL that we want the person child object of the entity Hibernate is forced to flush any outstanding People changes before it performs the SELECT!

I know that using database views within Hibernate is considered 'advanced' but it would would be nice to have some kind of @ReliesOn annotation to cover these edge cases. We now have to try and remember this strange behaviour whenever we deal with views.

I'm no expert on Spring and Hibernate so I may have got the wrong end of the stick completely - if that is the case then please comment on the right way to solve this problem as I would love to learn!

Technorati Tags: , , , , , ,

Fantastic Contraption - a great flash game for anyone with an engineering mind

I've found a flash game that I just have to share! It's called Fantastic Contraption and it's brilliant fun for anyone with an engineering mind, it's just so addictive.

The goal is to transport a red ball from it's starting point into a red goal area using your 'contraption' - your self-built vehicle made out of wheels, sticks and water power. Below is a screenshot of my 'flatbed' truck in mid-flow:



Give it a go but don't try it at work, you will not be able to do anything else for the rest of the day!

I found this via the Arantius blog, thanks Anthony Lieuallen!

Technorati Tags: , , , , , ,

How to test Exceptions and verify Mock Objects using EasyMock

Let's say you are unit testing, using EasyMock to verify the behaviour of your code under test and now you want to test that your method throws a particular exception:

@Test(expected = SQLException.class)
public void parseThrowsException() throws SQLException {
ResultSet mockResultSet = createMock(ResultSet.class);
expect(mockResultSet.next()).andThrow(new SQLException());
mockResultSet.close();

replay(mockResultSet);

ResultReporter reporter = new ResultReporter();
reporter.parse(mockResultSet);

verify(mockResultSet);
}
As you can see this is another test from my previous EasyMock post on how to use EasyMock's expect method when unit testing. We are now testing that when we call the next method it throws an SQLException (to simulate the database going down).

We expect that the next method call will throw an exception and then we are expecting that close will be called. If you run this test then you will find that it passes with green flying colours - but there's a problem, this is the implementation of the parse method:
public boolean parse(ResultSet results) throws SQLException {
return results.next();
}
As you can see it never calls the close method of the passed in ResultSet - so the test should have failed. It passes because the test has exited before it gets to verify the mock ResultSet for expected behaviour.

The way around this is to use an elegant try/finally block around the code under test like this:
try {
ResultReporter reporter = new ResultReporter();
reporter.parse(mockResultSet);

} finally {
verify(mockResultSet);
}
If you make this change to the above test then it fails as expected, now I just need to fixed the code... So you now know how to test for thrown exceptions and ensure that your mock objects are verified as well!

Technorati Tags: , , , , ,

Setting up HD/Progressive Scan on a Sony PlayStation 2 (PS2) with Component cables

I recently upgraded my television from a Philips 28" widescreen tube to a 1080p Panasonic 42" plasma. My old Sony PlayStation 2 was now looking a little weak when upscaled to 42" so I decided to invest in some component cables to take advantage of the best output that the PS2 had to offer as well as enabling "Progressive Scan Mode" in some supporting games (Guitar Hero 2 for example).

Here are my step by step instructions on how to HD-enable your PlayStation2.

Buy a quality component cable

My PS2 came with some SVIDEO-style connectors and a SCART block to plug them in to. The image quality on my old TV was fine but needless to say on a 42" HD plasma things looked a little different!


I spent a lot of time reading all sorts of reviews of PS2 component cables and it seemed that people were having mixed results with the cables in the £5-£15 bracket. After some searching about I found a PS3 to 5 RCA (component) cable from IXOS which also works with the PS2 (they use the same AV connector):


It's the IXOS XPP104 which is strangely not listed under their PS2 section but under their PS3 section instead (although it does state on the page that it's the "XPP104 PS2 & PS3 Component Video + Analogue Audio" cable). I bought mine from Sound & Vision for £30.

Tell your PlayStation that you are about to use component connections

Power up the PS2 with no disc in the drive so that you get the "Browser/System Configuration" screen:


Press down on the controller until the screen changes to the "Component Video Out" option and select "Y Cb/Pb Cr/Pr" rather than "RGB", then press circle to go back and then power off your PS2:

Plug it into the component sockets of your TV

Find the video and audio component sockets on the back of your TV:


Plug the Green/Blue/Red non-audio cables into the Y/Pb/Pr sockets:


Plug the Red & White audio cables (clearly marked AUDIO on the IXOS cables) into the Audio In sockets:


Then plug the other end into the back of your PS2.

That's the tricky bit done so now pop in your favourite game to see what it looks like. Even without enabling the in-game progressive scan option I immediately noticed a much clearly steadier picture with no combing (scroll down to the tomato) which I was experiencing before the cable upgrade.

Some newer games have an option to enable "Progressive Scan" - Guitar Hero 2 is one such game. Here are a couple of shots of my TV's info display before and after enabling progressive scan:





I also read that if your game does not have an in-game option you can hold Triangle and "X" at the same time while booting up the game but this didn't work for me.

It's made a world of difference to my PS2 image quality so I think the £30 was money well spent! Oh and Wikipedia has a pretty decent list of PS2 games that support HD as well...

Technorati Tags: , , , , , ,

Write simpler equals & hashCode Java methods using EqualsBuilder & HashCodeBuilder from Apache Commons

Last week I posted about how to implement a Hibernate-safe equals() method using instanceof and accessors (getters) in Eclipse. This showed that you don't want to be comparing the member variables directly but should use the accessor methods to protect against Hibernate's use of proxy objects.

My old colleague Guy Francis pointed out that rather than using Eclipse's generated (lengthy and rather ugly) equals and hashCode methods I should take a look at the Apache Commons EqualsBuilder and HashCodeBuilder.

Both of these builders have a very useful reflection-based equals/hashcode method but that does a deep internal comparison of member variables so that is no good for use with Hibernate objects. One use that they don't really explain clearly (and hence the reason for this blog post) is whether you can use accessor (getter) methods instead of direct variable access when using these builders...

...well you can!

You create a new EqualsBuilder object inside your equals method, append access to any properties of your object that make it unique and then call the isEquals method to test the properties. You do a very similar thing for hashCode. This is my new version of last week's methods now using these builders rather than Eclipse's generated code:

@Override
public boolean equals(Object obj) {
if (obj instanceof Person) {
Person other = (Person) obj;
EqualsBuilder builder = new EqualsBuilder();
builder.append(getId(), other.getId());
builder.append(getName(), other.getName());
return builder.isEquals();
}
return false;
}

@Override
public int hashCode() {
HashCodeBuilder builder = new HashCodeBuilder();
builder.append(getId());
builder.append(getName());
return builder.toHashCode();
}
They are not only smaller and simpler, they are also much less error-prone and it's very clear which object properties are used to see if an object is 'equal'. I'm going to be using these builders from now on for all my equals and hashCode methods!

Technorati Tags: , , , , ,

How to implement a Hibernate-safe equals() method using instanceof and accessors (getters) in Eclipse

When coding in Java you often want to check to see if two objects are 'equal'. This might range from a check to see if just one attribute is the same (the ID for example), or a complete comparisons of all attributes all the way up to ensuring that two objects are referencing the same instance of a particular class.

There is a lot of information out on the internet about how to write a correct equals() method (and the corresponding hashCode()) but I think Joshua Bloch's explanation from his excellent Effective Java book is the best.

Here are some tips that I learnt the hard way today when trying to test some JPA/Hibernate-backed objects for equality:

  • Don't use the default settings of Eclipse's built-in generator for equals() and hashCode() - it generates equals methods based on checking whether the two objects are from the same class (using getClass()), Hibernate proxies everything so this will never match

  • Don't use Eclipse's built-in generator at all - it's alternative option to "Use 'instanceof' to compare types" is more correct than it's default but still doesn't work for Hibernate classes

  • Do ensure that instanceof is used when ever checking if two objects have a similar background, the Hibernate proxies seem to respect this check so the proxies are instances of the classes that they proxy.

  • Do ensure that you use the accessors (getters) when getting the member variable values rather than the variables directly as the values maybe lazy loaded so id may actually return null whereas getId() will return the actual value from the database.
Feel free to use Eclipse's generator (with the instanceof option selected) as a starting point (I do) but don't forget to add in the extra bits described above.

So go from this:
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Person))
return false;
final Person other = (Person) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
to this:
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Person))
return false;
final Person other = (Person) obj;
if (getId() == null) {
if (other.getId() != null)
return false;
} else if (!getId().equals(other.getId()))
return false;
if (getName() == null) {
if (other.getName() != null)
return false;
} else if (!getName().equals(other.getName()))
return false;
return true;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
result = prime * result + ((getName() == null) ? 0 : getName().hashCode());
return result;
}
A blog post from wenhu on the subject as well as some information from my colleagues were the sources for this post and the remedy to today's headache!

Technorati Tags: , , , , , , ,

Hibernate Tip: How to view the values of Bind Variables

If you use Hibernate then you will have probably wanted at some point to see the underlying SQL that was being run. One solution is to enable SQL logging by increasing the Log4J logging levels of the org.hibernate packages.

There are two issues with this technique though:

  1. At DEBUG level you see the SQL but all bind variables are displayed as a ?
  2. At TRACE level you get everything and the kitchen sink, SQL, bind variables, results, etc. - it's very verbose!
Wouldn't it be nice if you could see the SQL and the bind variables without all the other Hibernate excessive tracing? Well my ex-colleague and good friend Andy Kayley has blogged about a solution that he found recently - check out his blog post:

How to Print Out Bind Variables in Java Prepared Statements

I've not tried it yet, but the next time I need to see the bind variable values I certainly will be!

Technorati Tags: , , , , , ,

How to use EasyMock's expect method when unit testing

I recently blogged about getting started with EasyMock - a simple framework for taking the pain out of creating and using mock objects when unit testing your java code.

In the example I showed that we were expecting the next() method to be called and we wanted the mock ResultSet to return false:

expect(mockResultSet.next()).andReturn(false);
What I didn't explain was that you use the expect() method when you are expecting the mock to return a value. If the method doesn't return a value (such as ResultSet.close()) then there is no need to wrap it in an expect() method call:
mockResultSet.close();
Remember: any methods that you call on your mock prior to the replay() method call are setting up it's expectations not actually calling the methods. After the replay() method is called the mock is in 'live' mode, recording activity and returning any predefined values when it's methods are called.

So here is the same example with the additional expected close() method call:
public class ResultReporterTest {

@Test
public void parseReturnsFalseIfPassedAnEmptyResultSet() throws SQLException {

ResultSet mockResultSet = createMock(ResultSet.class); // 1

expect(mockResultSet.next()).andReturn(false); // 2
mockResultSet.close();

replay(mockResultSet); // 3

ResultReporter reporter = new ResultReporter();
assertFalse(reporter.parse(mockResultSet));

verify(mockResultSet); // 4
}
}
Technorati Tags: , , , ,

Getting started with Java Mock Objects using EasyMock

If you are familiar with unit testing and test driven development then you are most probably aware of Mock Objects.

The EasyMock website states that:

A Mock Object is a test-oriented replacement for a collaborator. It is configured to simulate the object that it replaces in a simple way. In contrast to a stub, a Mock Object also verifies whether it is used as expected.
Mock Objects were introduced at XP 2000 by Tim Mackinnon, Steve Freeman and Philip Craig with the Endo-Testing: Unit Testing with Mock Objects paper.

So how do you use them? Basically you want to test some code that depends on a number of other objects. Some of these objects might have unwanted side effects like talking to a database, or accessing an external URL.

Rather than passing in the real implementation (with the above side effects) you would pass in a mock or stub instead. The mock can be pre-wired to expect a number of calls to it's methods from the code under test and will record these calls for verification later. Typically these mock objects were written by hand and so have fairly simple implementations, EasyMock removes that hard work by using Java's proxy mechanism to do most of the heavy lifting for you.

EasyMock has four stages:
  1. createMock - Create the mock based on an existing interface or class
  2. expect - Record the method calls that you expect your code under test to call indicating what you expect to be returned, if valid
  3. replay - Set the mock into 'playback' mode which switches the mock into 'real' mode and starts recording method calls and returning objects as set up in the previous stage
  4. verify - make sure that the right methods were called in the right order
Note: The standard download of EasyMock out of the box only supports creating mocks based on interfaces, if you also want to make mocks based on classes then you also need to download EasyMock Class Extensions. Then you don't use:
import static org.easymock.EasyMock.*;
you use this instead:
import static org.easymock.classextension.EasyMock.*;
And now for an example...

Let's assume we are developing a reporting object which manipulates the output of a database query. It's going to parse through a JDBC ResultSet object and do something with the results. We want the parse() method to return false if there are no rows within the ResultSet:
class ResultReporter {

boolean parse(ResultSet results) throws SQLException {
if (!results.next()) {
return false;
}

// do something with the results

return true;
}
}
So how do we test this method? We could run an SQL query against a database and then pass the ResultSet in but that would be slow and rely on external resources. We could handcode a mock version - but have you seen how many methods the ResultSet interface has?!? Or we could use EasyMock to help us out:
public class ResultReporterTest {

@Test
public void parseReturnsFalseIfPassedAnEmptyResultSet() throws SQLException {

ResultSet mockResultSet = createMock(ResultSet.class); // 1

expect(mockResultSet.next()).andReturn(false); // 2

replay(mockResultSet); // 3

ResultReporter reporter = new ResultReporter();
assertFalse(reporter.parse(mockResultSet));

verify(mockResultSet); // 4
}
}

Technorati Tags: , , , , , , , , ,

How to enable Line In Pass Through to your speakers with Realtek Audio on Windows XP

If you are having problems hearing anything after you have plugged a sound source into the 'Line In' socket of a Realtek soundcard (or motherboard onboard sound) then read on...

Plug your MP3 player (or other sounds source) into the 'Line In' socket and then go to the control panel and start the 'Realtek HD Sounds Effects Manager'. If you click the 'Audio I/O' tab you should see something like:



The highlighted part indicates that the Realtek HD Audio Manager knows that you have plugged a 'Line In' device in. You should now be able to record what is being played but you most probably won't be able to hear it!

A lot of audio cards give you the option of passing the line in through to the line out so that you can hear it on your speakers but this isn't the case with the Realtek audio.

What you have to do is ensure that the 'Rear Blue In' channel is not muted and has some volume as well as the 'Line In':



It took quite a bit of messing about to find this out, but it makes sense when you look back at the first screenshot and see that the line in socket is the blue socket. Why they can't label the 'Read Blue In' as 'Line In' I don't know!

Technorati Tags: , , , ,

Searching in Eclipse without the annoying CTRL-F Find Box

I've been using IntelliJ's IDEA IDE for the past few years for any Java development work. I've recently moved to a new company who are standardising around Eclipse so I'm slowly getting used to it's way of working and it's many different keyboard shortcuts.

Inline code searching is a big plus in my book and my good friend Bill Comer has figured out how to do it - read his post on In line searching in Eclipse & IE7.

If you just want to know the answer then here it is:

CTRL-J


Technorati Tags: , , , ,

Colour Linux & Cygwin console searches with Colourised Grep

Grep is a wonderful tool useful for searching for all kinds of stuff but sometimes what you are searching for gets lost:



To get your console shell to add a little colour to your grep search terms add the following to your .bashrc or .profile or the like:

export GREP_OPTIONS='--color=auto'
export GREP_COLOR='1;33'
Now if you perform the same search again your output should be a little clearer:



And as an added bonus this works on Cygwin (the Windows Unix shell) as well as Linux!

Technorati Tags: , , , , , ,

Ever had your DVD or CD drive completely disappear in Windows XP?

I recently installed DaemonTools so that I could fire up an Ubuntu ISO without burning it to disk first but it didn't seem to work properly so I uninstalled it. That is when the problems started, my DVD drive completely disappeared from XP - it wasn't in Windows Explorer and didn't show up via Device Manager either!

I tried the "Add Hardware" wizard via the Control Panel but that didn't recognised my drive either so I was starting to get rather worried. After a search on the net I came across a thread on Annoyances.org regarding "all my CD rom drives suddenly dissappeared". This pointed to a solution script from the rather talented Doug Knox who has a script available to restore CD-Roms and DVDs in Windows.

Follow the above link and then save the page with the script on it to your desktop, then just double-click the script and it should pop up the following message:



Now just reboot and your DVD/CD drive should have been restored!

Technorati Tags: , , , , ,

My excuse for why I didn't blog much in March...

The goal from the beginning for this blog was to write a post a week, that's the incentive that kicks me each week nagging me to write a post even though sometimes I don't want to. I've seen a number of blogs simply fade into the past after a month or two once the initial novelty has worn off - writing informative well-versed (I hope!) posts is a difficult thing to do in one's free time.

I managed the grand total of one post in March but I did have a valid excuse: I had the "new job search" machine on full throttle and was spending every evening pouring over JobServe and various job blog sites. If I wasn't searching for jobs on the internet then I was either preparing for face-to-face interviews or being telephone interviewed and I just didn't have the bandwidth to blog as well.

I'm pleased to say that I accepted a new development position a few weeks ago and so I'm finally leaving the mobile telecoms industry after ten years (wow, I've only just realised that it's been that long!) and I'm moving into the financial services industry.

I'm still going to be doing Java web server-side stuff so I'm not out of my comfort zone but I'm really looking forward to learning a whole new dictionary of terminology as well as working with an excellent team of people...

Technorati Tags: , , , ,

Ever wanted to test your website on every version of Internet Explorer (IE)?

If you develop websites then you will be well aware of the browser incompatibilities that cause a whole world of pain when you are trying to get something to look the same in all browsers.

Normally you will be testing against IE 6 or 7, Firefox and Safari. Due to IE 7 introducing a load of new behaviour you would also want to test it on IE 6 but you can't have two different versions of IE installed on any one PC. You could turn to a number of virtualised Windows instances with different versions of IE installed but that sounds like a lot of work to me ;-)

What if you could install a simple program and then have the following versions of IE available?:

  • Internet Explorer 3.0
  • Internet Explorer 4.01
  • Internet Explorer 5.01
  • Internet Explorer 5.5
  • Internet Explorer 6.0
Here you go then: MultipleIEs

A blog post about installing multiple versions of IE on your PC by TredoSoft was the source of my information and it's got a lot more information about how it works and what doesn't.

Technorati Tags: , , , ,

How to control another PC without a KVM using Synergy

If you sometimes have your laptop next to your desktop PC you might find that you are hopping from one keyboard/mouse/trackpoint to the other. After a while this gets a little uncomfortable so wouldn't it be cool if you could use your desktop PC's mouse and keyboard on your laptop? Synergy is one such utility, this is how the Synergy team describe it:

Synergy lets you easily share a single mouse and keyboard between multiple computers with different operating systems without special hardware. It's intended for users with multiple computers on their desk since each system uses its own display.
Download Synergy from sourceforge and install it as normal on both you desktop PC (the server) and your laptop (the client). On your desktop PC, start Synergy (Start -> Programs -> Synergy -> Synergy) you will be presented with the following screen:



Click "Share this computer's keyboard and mouse (server)" then click "Configure..." to set up the layout of the screens. Your now presented with this screen:



The first thing you have to set up are the "Screens", these are the computer names that you have given to your desktop and laptop, in my case "cubik" is my desktop and "laptop" is my laptop (funny that!):



To select which PC you are controlling at any one time synergy lets you simply move your mouse to the edge of the screen in the direction of the other PC, your mouse pointer will then disappear from one screen and magically appear on the other! To enable this you need to set up the "Links".

Links are the descriptions of the layout of your machines, i.e. is your laptop on the left or right of your main screen - in my case I have my laptop to the left:



Once you have made your choices via the drop-down lists click the little "+" sign to add that link. You now need to set up the opposite of that link so that you can get control back to your desktop again:



Click "Ok" and then click "Start" to start the server (your desktop PC) listening for connections. Over on the other PC (your laptop) start Synergy and click "Use another computer's shared keyboard and mouse (client)" and type the name of the other PC in the box, in my case I enter "cubik" as that's the name of my desktop PC. Now click "Start" to attempt to connect to your server.

If everything is ok then you should be able to move your mouse over to the left-hand side of your desktop PC's screen and the mouse (and therefore the keyboard) will hop over onto your laptop's screen so that you can control that instead. If you want to return control back to your desktop PC then simply move the mouse pointer to the right-hand side of the laptop screen and the mouse will jump back again!

If you get stuck for any reason on the wrong PC, just right-click on the Synergy icon in the system tray and choose "Quit".

One added bonus is that your copy buffer transfers over to the other PC, try it out - select some text on one screen, then to copy it, mouse over onto the other screen and to paste it. This even works when switching from one screen running Windows to another screen running Linux!

Technorati Tags: , , ,

My all new Ruby Database Script Runner - now with Objects!

Back in December I blogged about how to access ActiveRecord & Migrations outside of Ruby on Rails. It was a little to scriptish for my liking so I've refactored it in a couple of classes instead.

Before you had to copy the code to a new file and add your database migration inside the Script.run method. I've now broken this up into a DatabaseScript class that extends ActiveRecord's Migration and has the guts of how and where to run any database commands and then any number of script classes that do the actual work.

The classes that you write on a day to day basis are now similar in style to the standard Rails Migrations:

require 'database_script'

class UniqueScriptName < DatabaseScript
def self.run
# your migration code goes here
end
end
For example I want to update my_table and set all the updated column for all rows to be true:
require 'database_script'

class UpdateMyTable < DatabaseScript
def self.run
execute('update my_table set updated = true')
end
end
If you want to use a specific database connection (rather than one of the standard Rails ones development, testing, production) then add the following method in the above class:
  def self.database_connection_details
<<-YAML
custom:
adapter: ????
database: ????
username: ????
password: ????
YAML
end
This is what the DatabaseScript class looks like:
require 'active_record'

class DatabaseScript < ActiveRecord::Migration; end

def self.script_name(script_file)
return *script_file.scan(/(.*).rb/).first
end

def script_class(script_name)
script_name.camelize.constantize
end

script_name = script_name($0)
require script_name
script_class = script_class(script_name)

# to run this within the context of a Rails app then pass your environment on the command line:
# ruby <script name>.rb development
database_type = ARGV[0]

if database_type.nil?
database_yaml = script_class.database_connection_details
else
# if you have a Rails project then place your scripts in db/script
database_yaml = IO.read('../../config/database.yml')
end

databases = YAML::load(database_yaml)

database_type = databases.keys[0] if database_type.nil?

ActiveRecord::Base.establish_connection(databases[database_type])
script_class.run
Technorati Tags: , , , ,

A great new Oracle database resource

My colleague Mark Lishman has recently started blogging about all things Oracle over on Lishblog. He really knows his stuff and has a habit of explaining it so that mere database mortals such as myself can understand it.

He's only just started but already has an excellent post on how to use external tables in Oracle. This is really handy when you have a massive CSV file and want to query it but can't be bothered to write in input script in Ruby or something because you will be scrapping it soon.

He's a great Oracle DBA and his blog will no doubt be well worth subscribing to!

Technorati Tags: , , , ,

How to restore "Escape closes windows" shortcut in Pidgin (using Ubuntu Linux)

I use Gaim/Pidgin as my IM client as it can connect to all other IM services (AIM, MSN, Yahoo, GTalk, etc.) but keeps them all within one tidy app. My favourite feature is that when you want to close a conversation window you simply just hit 'Esc' and it's gone. A collegue asked recently why his Escape shortcut was not working any more after an upgrade to Ubuntu Gutsy.

It appears from Pidgin's release notes that this 'feature' was changed in version 2.0.0 (5/3/2007):

Removed "Escape closes windows;" default key binding is now Ctrl-W
This hadn't happened to my version (I'm also running Gutsy) but I had to get to the bottom of it. After a little searching in .purple (the home of Pidgin's user configuration) within my home directory I was able to find the following uncommented in my accels file:
(gtk_accel_path "
/Conversation/Close" "Escape")
In my collegue's ~/.purple/accels file he just had to change <Control>w to be Escape and then it all started working again!

Technorati Tags: , ,

Has Althea UK Ltd. gone bust? (aka Bathrooms Italia / Period Bathrooms)

Note: This is a non-technical post that I'm making to see if anyone else is searching for information regarding any outstanding bathroom orders - if so, please leave a comment so we can pool our collective wisdom!



We placed an order through Bathrooms Italia for a new bath back in January and after repeated phone calls inquiring about the whereabouts of the bath we have found this morning that the site appears to not be avilable anymore and they are not answering their phone - 01845 577 432.

After a little digging about it appears that Period Bathrooms are also not answering their phone - 01274 660 770. Both of these companies seem to be public consumer websites for Althea UK Ltd., their number is the same as Bathrooms Italia - 01845 577 432 which is never answered.

A quick search on Credit Gate shows the following suspect activity:

  • REGISTERED OFFICE CHANGED ON 22/01/08 FROM:KC HOUSE, BRETTON STREET DEWSBURY WEST YORKSHIRE WF12 9BJ

  • SECRETARY'S PARTICULARS CHANGED ON 21/01/2008

Due to this I've already contacted my credit card company to report they I've paid for an item that I expect to never receive!


Update: I've just had a call from Clearwater (a supplier to Althea) that they have been advised that Althea and therefore their derivatives have gone into receivership!

Technorati Tags: , , ,

A hint when working with Rails Migrations and legacy databases (ID columns)

Had an interesting problem recently when writing some Rail migrations scripts for an old non-Rails MySQL database. After writing the migration and running it via Rake we found that it was erroring with a complaint about the primary key.

We checked that the table had an id column, it did but instead of id it was ID. ActiveRecord is very specific in what it looks for and so was not viewing this ID column as the primary key that it required when adding new rows to the table.

A quick lookup in the ActiveRecord documentation pointed out the solution: use set_primary_key in your ActiveRecord class:

class SomeLegacyTable < ActiveRecord::Base
set_primary_key :ID
end
Technorati Tags: , , , ,

How to use logrotate with Apache's Tomcat (and any other Java process)

Logrotate is an excellent utility for managing log files that can start grow into an unmanageble size, Tomcat's catalina.out is one such file.

Most of the solutions (scroll down to the 'Rotate the logs' section) for managing catalina.out, or other log files generated by Tomcat or any Java process for that matter, don't mention the copytruncate option:

Truncate the original log file in place after creating a copy, instead of moving the old log file and optionally creating a new one, It can be used when some program can not be told to close its logfile and thus might continue writing (appending) to the previous log file forever. Note that there is a very small time slice between copying the file and truncating it, so some logging data might be lost. When this option is used, the create option will have no effect, as the old log file stays in place.
This basically means that you don't have to configure your logrotate script to restart Tomcat just so you can tidy up your log files - it trades off uptime against completeness of log records.

I found out about this from the Mission Data Blog in their post titled 'managing disk space with logrotate'. Is definitely worth taking a good look through the man page for logrotate to see if there are any other gems you can take advantage of for your setup.

Technorati Tags: , , ,

An update to my Thunderbird TNEF script for opening winmail.dat

Back in July I blogged about Opening winmail.dat (TNEF) files in Thunderbird (on Ubuntu). Well a colleague at work has 'refined' my script so that rather than it create a folder on your desktop it simply opens Nautilus to display the contents of the attachment.

This is the new version of the script:

#!/bin/bash

LOCATION=/tmp/winmail_$$.dat

mkdir $LOCATION
/usr/bin/tnef -C $LOCATION --save-body -f $1

nautilus $LOCATION
The interesting part of this script for me is the $$ - this special script variable is the process ID (PID) of the currently running script, so it makes a temporary file called winmail_<current process id>.dat. Other than that it's pretty similar to my original script apart from opening Nautilus at the end.

Now it's even easier to open and extract files from winmail.dat files!

I found out the reason for the $$ from here.

Technorati Tags: , , , ,

Poor performance after upgrading Ubuntu to 7.10 'Gutsy Gibbon'

I recently upgraded my desktop to Gutsy Gibbon using aptitude rather than the graphical Update Manager and noticed that the performance of the machine had dropped significantly.

Running htop highlighted the problem, evms and udevd were fighting for disk I/O, bringing the system to it's knees. After a quick search I found that most users can safely remove EVMS as it's normally used for RAID and other complex drive setups:

The Enterprise Volume Management System (EVMS) is a project that attempts to provide a single, unified system for managing storage and filesystems. Rather than managing individual disks, partitions and filesystems; LVM Physical Volumes, Volume Groups and Logical Volumes; RAID arrays (both software and hardware) etc. yourself, using EVMS you can address them in one consistent way.
The support for the EVMS package has been dropped by the Ubuntu team but if you didn't use the Update Manager to do the migration to Gutsy it won't have been removed.

To remove EVMS manually (please make sure you aren't currently using it as it could be dangerous to your data if you are and then you remove it) simply run:
sudo aptitude remove evms
This will remove the EVMS package and then rebuilt the kernel image so please be patient

You are then only a reboot away from a faster running system!

Technorati Tags: , , , , ,

One suggestion re: Forbidden access via Apache Proxies

If you are getting the following error when configuring Apache 2.2's proxy support (mod_proxy):

HTTP error code 403 Forbidden
then you might want to take a look inside the error.log for your site. If you see an error message like this:
[warn] proxy: No protocol handler was valid for the URL /SomeUrl.
If you are using a DSO version of mod_proxy, make sure the proxy submodules are included in the configuration using LoadModule.
Then you might want to check that you have more than just mod_proxy enabled. Mod_proxy is more of a virtual module relying on other modules to perform the proxying work depending on the type required. A common mistake is to have enabled mod_proxy but not enabled mod_proxy_http.

With Ubuntu or Debian you can enable them with the following two commands:
a2enmod proxy
a2enmod proxy_http
Otherwise you will have to make manual symbolic links to them yourself.

Technorati Tags: , , , , , ,

A hidden gotcha regarding bash linked to sh (shell) in Ubuntu (Linux)

I was having some problems recently regarding settings inside a user's .bashrc file. When the user logged in their settings were not being picked up. I checked in /etc/passwd and saw that the user's shell was sh which was a symbolic link for bash. I assumed that because the shell was linked to bash it would have bash's behaviour - picking up .bash_profile, .bashrc, etc.

A search of bash's man page proved me wrong:

If bash is invoked with the name sh, it tries to mimic the startup behavior of historical versions of sh as closely as possible.
I.e. if it's called sh it works like sh!

Technorati Tags: , , , ,