Friday, August 28, 2009

Why My GroovyConsole Wouldn't Open

For a few weeks now, I've been wondering why I couldn't launch the pretty version of GroovyConsole on my home computer, but could on my work computer. It turns out this is a bug: http://jira.codehaus.org/browse/GROOVY-3655. Groovy needs the 32 bit JDK to launch. Nore more batch hack, I can now launch the GroovyConsole.exe directly. (Though they still haven't built this for the updated versions -- I assume they're holding off for the 1.7 release).

Problem was, at work I need to use HermesJMS which needs JAVA_HOME to be the 64 bit version (doesn't make sense, but it works). What to do? Fortunately, HermesJMS uses a batch file for its invocation, so just add
JAVA_HOME=C:\Progra~2\Java\jdk1.6.0_16
to line 23 (or anywhere in the beginning, really). Done.

Thursday, August 27, 2009

Answered: Using variables in XmlSlurper’s GPath

Yesterday I asked this question about using variables with XmlSlurper. I got an answer that works (although I don't see it anywhere in the documentation or the book Groovy in Action. Below is the example the answerer gave.
def xmltxt = """
<file>
<record name="some record" />
<record name="some other record" />
</file>
"""

def xml = new XmlSlurper().parseText(xmltxt)
String foo = "record"
return xml."${foo}".size()

Wednesday, August 26, 2009

Test Oriented Development

The other day I had an idea. Probably a bad idea, but its something I feel more comfortable with than diving straight into TDD. The rules are
  1. You are encouraged to write the test first, but are not forced to.
  2. You may not write more than one method without a test.
This way, you write tests as you are writing code, you might write all your test first, but you will never write too much code that isn't tested (assuming you don't cram it all into one gigantic, godlike method). I dub it TOD (Test Oriented Development).

Friday, August 21, 2009

Integration Testing

My colleagues and I have been learning a lot about testing this week. One of my friends' thoughts are here. He asks the question of whether it is a unit test if the method in question calls other methods. I agree with him and would argue that no, it is not, since the culprit is unclear if the method fails (until you go into debugger). Arguably, this could be worst for code that is properly refactored. This is something I don't think code coverage tools will help you recognize.
StackOverflow has some good definitions of unit and integration testing here, and here. I like Michael Feathers' definition:
A test is not a unit test if:
  • It talks to the database
  • It communicates across the network
  • It touches the file system
  • It can’t run at the same time as any of your other unit tests
  • You have to do special things to your environment (such as editing config files) to run it
Josh Brown, a colleague of mine, also suggests adding:
  • the code under test uses an external framework or library (Hibernate, Spring, some internal library, etc.)
  • the code under test calls other methods (that you didn't mock)
I wholeheartedly agree with both of these.

I had a case that was interesting to me. I was working on some code that I've become the caretaker of to get it better tested (a good thing too, as a bug was discovered). The project takes big files and chunks them into smaller files. It handles any xml or delimited file. The way I was testing it was to take different types of files, chunk them then merge them and make sure the record counts stayed the same. This isn't really (even if I had more granular asserts) a unit test. It relies on an external resource (the sample files) and involves multiple methods. Someone else suggested unit tests using files loaded through classpath, which I disagreed with since they're not really unit tests. Those File objects should be mocked (or possibly stubbed if using Groovy).

I did attempt to make these an integration test with FailSafe. I decided against this when I figured out that I could not override the behavior to not run the integration test on deploys. In my opinion, these should not be run on deploy, integration-test should be later in the Maven lifecycle. The reason for this is that deploys are often done across different environments and the whole idea with integration tests is that they depend on external resources. An example of this is a project my friend is working on, which works with the dev database, where it would be fine to run the integration tests on deploy, but when it is deployed to prod, we definitely don't want to modify our production database as part of running tests. To continue to be able to access the QA environment or dev environment would mean adding special firewall rules. What's more, when I set the configuration to skip the tests, it ran the tests anyway (maybe this is why it's alpha?). According to their documentation, it shouldn't have even run the unit tests. I just don't feel quite comfortable deploying something so young and apparently unstable into production code. Maybe someday this will change. There are some other suggestions here. The page he links to from Codehaus states that there are rumors of a future version of Maven supporting integration tests with a src/it/java and its own integration-test phase. Its kinda surprising that with so many organizations using continuous integration and it not being something all that new.

In the end, I decided to do what others have done, which is to have the integration tests in a separate module that is only built if the argument is passed for it.
The parent pom should have
<profiles>
<profile>
<id>integration-testing</id>
<activation>
<property>
<name>it</name>
<value>true</value>
</property>
</activation>
<modules>
<module>sampleProject-integration</module>
</modules>
</profile>
</profiles>
Also, do not list it in the modules section. This way, the integration module will only be built (and the associated surefire tests run) when the -Dit argument is present. I think for most projects, this makes sense for most projects, though I'm still a little torn on the issue. While Failsafe lets you still build even if the integration test fails, doesn't this defeat the purpose of continuous integration? This is especially the case if your integration tests depend on resources that may be going up and down all the time, it doesn't make much sense to run something every time if half the time you just ignore the results anyway. I also wonder how practical this is for organizations that have resources on multiple subnets, where a deploy from one environment to another can result in failed integration tests not because of any problem with the code, but because of a technical failure.

The next part (and for me, the harder part) will be mocking out (and maybe stubbing with Groovy's metaclass) the pieces needed so I can isolate the methods in the classes for unit tests, as there currently aren't any for this project. I'll post any interesting results I get from that. For other initiates, such as myself, I've found this article helpful: http://martinfowler.com/articles/mocksArentStubs.html.

Tuesday, August 18, 2009

GW2 Update (well, sorta)

Yesterday ArenaNet put the Test Krewe page back up and gave some small hints at forthcoming GW2 news. They've posted a shiny swf on their homepage to be: http://www.guildwars2.com/, created a facebook page: http://www.facebook.com/GuildWars2, and a twitter account: http://twitter.com/guildwars2. All indicators that they're preparing to release some news. Probably nothing as dramatic as a date yet, but we should at least get a trailer and some concept art. Maybe even some discussion about the professions (my prediction is that it will be the core professions from GW1 or very similar, based on the fact the shaping of the world has cut off Tyria from Cantha and Elona).
The related GWGuru page is here: http://www.guildwarsguru.com/forum/showthread.php?t=10395760. Mostly people are excited (those that haven't left the game anyway) though some other pages lurking on the internets weren't as generous.
Am I peeing my pants excited? No. But as I've said, I do think little tidbits, even if they're contrived and only give the illusion of progress (which I don't think these will be) are an important part of keeping a feeling of aliveness in the community.

Monday, August 17, 2009

The Taste of Cha

I've resumed my habit of regular consumption of green tea. Every time I do, I think of the legend of how green tea came about:

Bodhidharma set about meditating for nine years facing a wall. After five years he was so sleepy that he could not keep his eyelids open and fell asleep. When he woke up he was so angry about this that he cut of his eyelids and threw them on the ground. The eyelids grew into the first green tea plants. And from henceforth, tea has ever been the companion of monks for mediation (and apparently for geeks and programming as well).

It is said that "the taste of tea (cha) and the taste of Zen (Chan) are the same". In Japanese, the characters for 'tea' and 'eyelids' are both 'cha'.

mmmmmm.....cha tastes good.

Massive EMP

I've often wondered: If a massive EMP (from a nuke or whatever) were to go off, wiping out all our technological achievements (silicon chip designs, computer languages, etc), how long would it take for us to rebuild? Is the knowledge mostly inside us? Or are we standing on the soldiers of giants to such an extent, we would have to invent the wheel all over again?

Sunday, August 16, 2009

Substition in Java .properties

Though I ended up not using it for a project I'm working on, I was interested in using the java.util.Properties with substituted strings, as can be done in Ant and Maven. I came across this link to XProperties: http://www2.sys-con.com/ITSG/virtualcd/Java/archives/0612/mair/index.html

Friday, August 14, 2009

ArenaNet Fail

This is something that has been bugging me, and I'm sure several others over the past couple months. ArenaNet seems to be unable to meet deadlines or even keep up with routine maintenance.

The latest of ArenaNet's offenses has been the Test Krewe page. They enlist players to play around with updates on a test server before it was pushed out to the live one. Cool. The problem? Apparently they don't know how to write PHP! Basic form validation was completely absent, people who used hard returns, too many characters, or certain punctuation broke the page. Come on people, this is basic stuff. They took it down until it could be fixed the same day it was up (Aug 11) and its still down. Yet again, ANet kept the community in the dark. While there was a post by Regina Buenaobra buried in Guild Wars Guru, if you navigate to the page today, you will just get the message "We're sorry, the page you requested could not be found." How hard would it have been to put a message saying "We know this page is broke, we're fixing it". As usual, there is no time estimate whatsoever for when the page will be back up.

Another example of their apparent complete lack of even basic web dev skills was the whole Xunlai Tournament House fiasco. The page was taken down June 23 because of problems with the distribution of the points for May. It's now been 2 months and there is no word on its status. There are players who still haven't gotten their points. Another 'It'll be done when it's done' deals.

GW2 news, plz. I know, I know, everyone who plays Guild Wars would love to have some tasty morsel of information regarding Guild Wars 2 and ArenaNet doesn't want to jump the gun (though I think they already did by suggesting a beta in 2008 then reneging on it). I think especially in the light that there won't be a beta, players would much appreciate a blog or something where once or twice a month SOMETHING is posted about GW2. Maybe its an idea they have for a profession. Maybe its some kind of rough sense of progress (1/2, 2/3, etc). It doesn't have to be much. It doesn't have to be written in stone. Just something to let us know we aren't forgotten, and that GW2 is still making progress.

While this is a problem that is not unique to Guild Wars, I'd really like to see community involvement. Take a look at GuildWarsGuru, there are several threads full of ideas people have for making the sequel kickass. Why not find a way to incorporate these in some way? Maybe even respond to some of them?

It seems to me that ANet is short-staff and/or over-tasked and anachronistic in its communication. I know they're probably working on a tighter budget than some other game companies (though their quarterly report shows increased sales (up 51%), and growth in Guild Wars), but would it really be that expensive to be more open with your customers?

I'm kinda mad.


---Oh, and $20 is too much for character renames.

Thursday, August 13, 2009

My First iGoogle Theme

I experimented with making my own iGoogle theme
here
The interface they have is rather limiting (couldn't choose the color black for background) than their API, may experiment with that next.

Friday, August 7, 2009

Groovy & CXF JAXB

I was working on making an existing application a mule service, when I ran into the snag that Groovy classes, when exposed as an parameter to the service method, which throws an error when JAXB attempts to deserialize the object to xml (for creating the wsdl). Every Groovy object possesses a property called metaclass that cannot be serialized because it is an interface. At the time, I solved this problem by wrapping the Groovy stuff with Java, to expose only what I wanted. Another way I could have done it would have been to have the Groovy class implement a Java class.

I later found out a third method, when I attended a brown bag session where a colleague gave a talk about using JAXB. Today, I found this link, which describes exactly that. Annotations can be used to override the default JAXB behavior to exclude that messy Groovy stuff. I haven't experimented with this yet (since I've already got my service working and there was no compelling reason to do it in Groovy instead of Java), but I wonder which of these three solutions would be the cleaner solution. I don't have a really strong opinion on this, but its probably preferable to have extra annotations than to have extra classes. Extra wrapping classes just result in more boilerplate code for the next guy down the road to wade through, at least annotations would only add a few lines (one line I believe in the case of CXF). Allegedly, just adding the annotation
   
@XmlAccessorType(XmlAccessType.FIELD)
to your class will resolve the issue. Has anyone else done this? How did you resolve the issue?

Thursday, August 6, 2009

@version JavaDoc Tags

Another comment that came up in my code review yesterday was why I had an @version 1.0 in my JavaDocs for the class I wrote. My reasoning was that, according to Sun's documentation, the author and version tags are required (though obviously it won't throw a compiler error or anything like that, it may throw an error in Sun's Doc Check tool). This launched a discussion about whether the version tag should indicate revisions in the version control system (in our case svn) or release tags of the software. The practice varies from shop to shop, but my initial reaction (despite Suns' practice) considered tags to be logical, since that would indicate API changes. However, @since I suppose is what really should be used, and a colleague pointed out that changing all the classes to match whatever release is current hides the fact that some classes (particularly abstract data classes) may not have changed at all.

My own conclusion out of this was to use svn keyword substitution to set the tags. I used my favorite svn client, TortoiseSVN, to set the properties. You can either set it as a global setting (which will add the property to new and imported files) or on particular files (need to do for files that already exist). This matches Sun's practice of tying @version to their source control system.

While on the subject of JavaDoc, I was mocked for pointing out a spelling mistake in a JavaDoc comment. In my view, JavaDoc is a special class of comment. Whereas internal comments can contain all the mistakes and profanity you want, JavaDocs are something your client might actually see, and thus should be treated just the same as a mistake like
System.out.println("Pleez enter your name: ");
String name = bufferedReader.readLine();
Am I wrong?
As a quick way of setting Subversion properties for use in Javadoc, I usually create a script with this in it:
for file in $(find ${1}/*/src -maxdepth 10 -name *.java); do if [ -z `svn proplist ${file} | grep -o "svn:keywords"` ]; then svn propset svn:keywords "Author Date Revision Id" ${file}; fi; done

Pieces Parts

The term 'pieces parts' is popular here at OCLC, as a way of describing components, modules, and the like. Is this the case anywhere else? Or is this one of our unique quirks?

Wednesday, August 5, 2009

Things I Learned From My First Code Review

Here's some interesting ideas I saw in my first code review at OCLC

instead of setting to a non-null in constructor to prevent null from being returned, check before it is returned by
doing this
public String getSomeString() {
  return (headerTag == null) ? new String() : headerTag;
}
instead of this
String foo = new String();
...
public String getSomeString() {
  return foo;
}

for String concantenation, StringBuffer is faster than String (http://java.sun.com/developer/JDCTechTips/2002/tt0305.html). Unlike Strings, which are immutable, StringBuffers are mutable.

surround your log4j debug log statements in an
if (log.isDebugEnabled()) {
  log.debug("message here")
}
so that the string isn't needlessly constructed (http://logging.apache.org/log4j1.2/faq.html#2.3)

avoid NPEs in comparisons, do:
String foo = "Some_String";
if (foo.equals(someString)) { ... }
instead of:
if (someString.equals("Some_String")) { ... }