FALLBACK – Indicates placeholders should be resolved against any local properties and then against system properties

NEVER – Indicates placeholders should be resolved only against local properties and never against system properties

OVERRIDE – Indicates placeholders should be resolved first against system properties and then against any local properties

ENVIRONMENT – Indicates placeholders should be resolved against the current Environment and against any local properties. This is the default.

The location is an optional parameter so depending on your needs you can skip configuring it.

There are some other optional parameters available including:

ignore-resource-not-found – Specifies if failure to find the property resource location should be ignored. Default is “false”, meaning that if there is no file in the location specified an exception will be raised at runtime.

ignore-unresolvable – Specifies if failure to find the property value to replace a key should be ignored. Default is “false”, meaning that this placeholder configurer will raise an exception if it cannot resolve a key. Set to “true” to allow the configurer to pass on the key to any others in the context that have not yet visited the key in question.

A system property can then be utilized like this:

<property name="username" value="#{systemProperties.username}"/>

The # is not a mistake; this indicates that the bean systemProperties should be used.

IntelliJ 9 (codenamed Maia) looks promising with lots and lots of great features. There seems to be an endless list of newly supported technologies, tweaks, and usability features.

Maia has been superb in Mac OSX Snow Leopard. Unfortunately, my Ubuntu 9.04 desktop is an entirely different story.

A big feature of Maia that I’m looking forward to is background file indexing. It sounds like a great idea, be able to edit and browse projects instantly while you wait for the indexing to finish. The catch is advanced browsing and editing features are not available until after indexing finishes.

Both in OSX and Linux I ran into issues with the background file indexing.

Comparatively, my experience with background file indexing with OSX was less severe, so I’ll start there. Like when I normally load a project with IntelliJ, a loading dialog pops up with a status bar and I can watch the name of files zoom by as they’re being indexed. Unlike previous versions of Intellij, there’s a button to put the indexing into the background.

Instantly I click the button. I mean, why waste time, right? Unfortunately browsing was completely unusable with everything being sloooooow. In IntelliJ’s defense, I have only booted up IntelliJ once so far on my Mac. And this is a pre-release. (I usually just leave IntelliJ running and beyond this, everything has been wonderful).

The issues with Ubuntu were a bit more troubling. To my surprise, the background indexing did not bring the UI to a screeching halt like it did on my Mac. What I wasn’t prepared for was worse.

With background indexing appearing to run smooth, I was pumped to get the most out of the new feature. Immediately I dug into the directory with the project’s JSPs. Annoyingly every minute or so the listing of files would disappear and be rebuilt. After a few times, I realized the background indexing would finish then start right back up in a minute.

This restarting of the background indexing went on for about a half hour I was busy with some activities that didn’t require a PC so I just let it do its thing hoping it would stop. Of course the constant indexing did not stop. The directory listing did not stop reloading.

Giving up, I restarted IntelliJ and everything loaded just fine every time since.

The next two problems showed up intermittently in Linux.

Firstly, on more than one occasion and seemingly randomly. If I had two files in two tabs, selecting the unselected tab would do nothing except show that the second tab was selected. The displayed file contents would not show up. I could open up additional files and switch to them just fine, but I could never get the other file’s contents to show up even then. The tab issue occurred on more than one occasion. Closing and reopening the misbehaving tabs fixed the issue each time.

The next issue was more troubling: I would simply lose the ability to edit files. I could type until I was blue in the face and text would not show up. The inability to edit files cropped up frequently and was not solvable without restarting IntelliJ.

After poking around at IntelliJ IDEA 9 M1 on Linux I gave up and reverted back to using IntelliJ 8. I am still successfully using IntelliJ 9 M1 on OSX, but my usage has been very light lately due to other events.

I sincerely hope IntelliJ 9 gets to a stable point. IntelliJ is such a time saver I really do not want to program in Java with anything less feature full.

Bottom line: The new features in Maia are wonderful. Feel free to download and use Maia, just don’t expect to be throwing out IntelliJ 8 just yet.

Test failures

It was so simple, I guess it just had to fail:

Caused by: java.lang.UnsupportedOperationException: ERROR: GWT.create() is only usable in client code! It cannot be called, for example, from server code. If you are running a unit test, check that your test case extends GWTTestCase and that GWT.create() is not called from within an initializer or constructor.
at com.google.gwt.core.client.GWT.create(GWT.java:85)
at com.google.gwt.user.client.ui.UIObject.(UIObject.java:140)
… 23 more

By using GWTMockUtilities.disarm in the setup and GWTMockUtilities.restore in the teardown, I made some progress by ended up with this error instead:

The solution

The solution is right there in the stacktrace from Google.

I extended GWTTestCase but continued to get the same errors. The reason is simple enough, but has bitten me a a couple of times before. GWTTestCase is written using the old JUnit 3 style tests. My tests were using TestNG annotations which tells TestNG to run the tests as TestNG tests. Consequently the setup and teardown methods in GWTTestCase never get called. JUnit acts the same way if you mix and match JUnit 3 and 4 style test declarations.

It’s been a frustrating experience with UnsatisfiedLinkErrors and NoClassDefFoundErrors, but I eventually got what should be a simple unit test working. And it sucks that my seemingly innocent unit test have so many dependencies. It also stinks that GWT must be started up to run the tests resulting in a feedback loop increase of 10-15 seconds.

Bad comments can be a little bit of a problem, even if they appear harmless.

In some projects (most?) comments multiply like tribbles creeping up everywhere. Sometimes the comments are especially useful but other times comments useless are destructive to maintainability. Contrary to some beliefs, bad and inaccurate comments are not mostly harmless.

Bad comments take many forms. There are four forms that I think could be considered anti-patterns:

1. Programming 101 comments

No doubt this sort of commenting is useful to students in a class, but in the real world even non-Java programmers can figure this one out. Programming 101 comments are most commonly used by students and recent graduates after learning a new language feature or library.

3. Comment Me! comments

“Comment Me!” comments are the lazy man’s way of commenting. If you’re getting paid by the number of lines or the number of comments, than this type of commenting is great. Otherwise, it’s a waste of your time to put them and a waste of time for the person who has to read this junk.

Don't let your code look like this.

4. Code memorial comments

Rather than letting bad or good code die and receive a proper burial in your favorite code repository, these comments are embalmed and enshrined for all to see. When old code is enshrined, it takes away precious screen real estate from the living code.

I’ve heard several defenses of this anti-pattern. Requirements keep changing, we’ll just have to put it back. Make it easy to put it back.

I suspect the reason for holding onto dead code is deeper than any of that. Imagine spending hours or days working on a problem. No doubt it can be emotional to throw away your hard work.

Delete the old code anyhow. The new found cleanliness will be extremely liberating. Besides, you can always lay flowers by its grave in your version control system’s history.

5. I WAS HERE comments

Comments can take on the form of being a replacement for version control features (like CVS’ annotate command). These can take on forms similar to this:

// ARL 010109 begin
... some code here ...
// ARL 010109 end

There are several problems with I WAS HERE comments. First, it clutters code unnecessarily. Second, it duplicates functionality that already exists in version control systems. Third, it’s error prone.

the cake is a lie.

The comment is a lie.

Comments always lie. If not now, they will soon. Often code changes but the comments do not. I have seen countless cases of comments that lied literally the second they were committed.

Bad/incorrect documentation is worse than no documentation. I suppose Stack Overflow isn’t exactly the best place to a consensus, but the comments and stories are interesting. In my not-so-humble opinion, misleading documentation – especially that that appears authoritative – really sucks.

We ran into an interesting and less than informative error when configuring Maven with our Hudson installation. Maven worked great, as expected, but the Sonar plugin stopped working and were causing builds to fail.

The error message wasn’t terribly helpful:

FATAL: hudson.tasks.Maven$MavenInstallation.forNode(Lhudson/model/Node;Lhudson/model/TaskListener;)Lhudson/tasks/Maven$MavenInstallation;
java.lang.NoSuchMethodError: hudson.tasks.Maven$MavenInstallation.forNode(Lhudson/model/Node;Lhudson/model/TaskListener;)Lhudson/tasks/Maven$MavenInstallation;
at hudson.plugins.sonar.SonarPublisher.getMavenInstallationForSonar(SonarPublisher.java:204)
at hudson.plugins.sonar.SonarPublisher.executeSonar(SonarPublisher.java:213)
at hudson.plugins.sonar.SonarPublisher.perform(SonarPublisher.java:177)
at hudson.model.AbstractBuild$AbstractRunner.performAllBuildStep(AbstractBuild.java:372)
at hudson.model.AbstractBuild$AbstractRunner.performAllBuildStep(AbstractBuild.java:360)
at hudson.model.Build$RunnerImpl.post2(Build.java:183)
at hudson.model.AbstractBuild$AbstractRunner.post(AbstractBuild.java:345)
at hudson.model.Run.run(Run.java:943)
at hudson.model.Build.run(Build.java:112)
at hudson.model.ResourceController.execute(ResourceController.java:93)
at hudson.model.Executor.run(Executor.java:119)

Backing up Hudson

While there is a backup plugin for Hudson. The plugin would be ideal, but in case just installing the plugin screws something up, best do a manual backup.

The easiest way to manually backup Hudson is to just copy your Hudson working directory. However, space is limited for us, so a backup that was more selected was necessary. This script seemed to backup the most important configuration files (it wouldn’t make for a pretty recovery, but it’d work):

Hudson the Butler can’t make up his mind; it’s claiming success before imploding on itself.

Hudson recuperated

Skimming around and very annoyed my butler had blatantly lied to me, I noticed hudson.war was sitting at only 2 MB. Yah, that can’t be right.

Luckily the fix was easy: Hudson was successfully fixed by manually downloading the newest hudson.war and replacing the messed up version.

It turns out I really did not need to backup Hudson. Though naturally if I hadn’t backed up Hudson I will have needed my backup!

Upgrading to Hudson 1.317 solved the mysterious java.lang.NoSuchMethodError error. I would not have thought configuring a Maven installation rather than using Hudson’s default would cause issues. Go figure.

When it comes to unit testing you might find yourself wanting to test private methods. Here’s four solutions, some much better than others.

1. Don’t test private methods (refactor!)

If you find yourself needing to test private methods, you’re code is trying to tell you something – listen up!

Unit tests should test the behavior of classes and not the implementation details. Unit tests should be able to naturally cover your private methods. If you find this difficult or impossible to do, consider it a code smell.

Testing implementation will become a barrier to refactoring since you will be unable to change the implementation without updating tests. As Charles Miller put it “The amount of work you have to do to improve your code becomes the amount needed to change the private methods, _plus_ that required to change the tests. As such, you’re less likely to make the improvement.”

If you choose to test private methods keep in mind you are likely taking on some technical debt.

Pros: You’re not testing private methods. Best solution. Results in better design.Cons: Can sometimes be tricky to implement, especially in legacy applications.

2. Use reflection

Thanks to reflection, access levels are more of a suggestion than a requirement. With a little bit of code, we can access any private method (or field for that matter).

A big negative to this method is maintainability. In fact this just happened to me today: I refactored out a private method and as expected the test failed. Unlike other solutions (like the package level solution below), the failure was at runtime – not compile time.

Pros: Relatively easy and quick. Does not break encapsulation. Cons: Tests become busier. More difficult to keep tests updated with production code. Security settings could prevent this technique from working.

3. Use package level access

This solution is very easy, simply remove private to get the (default) package level access. As long as your tests are in the same package as the production code, no problem. Since it’s good practice for your unit tests to be in the same package (but in a separate source folder), this works well.

Right out of college, this was the first way I learned to handle these situations. Almost everything method was package level. It never really smelled quite right, but the postives out weighed the negatives. In hindsight it might not have been the best solution, but there are far worse things.

Pros: Quick and easy. Cons: Breaks encapsulation. Classes become a little noisier (although not as bad as using public).

4. Mix production and test code

This is the worst of all the solutions, so I hesitate to even bring it up. By making your test class an inner class in your production code, your tests will have access to private methods. Unfortunately this solution leaves your production code dependent on your test code.

Challenge: is there a legitimate reason to do this? I can’t think of one.

Pros: At least you’re writing tests! Weaksauce, I know. Cons: Production code contains more than production code.

Quick update: Chad Bradley informed me that it is possible to test private methods using Groovy. I would be hesitant to use the technique without knowing for certain if it’s a bug that will get fixed or an actual language feature.

The forkmode attribute is the big one here. Possible values are “perTest” (default), “perBatch”, and “once”.

It turns out that because “perTest” is the default; meaning forking is done for each test class. While that might be what you want, it can make your tests significantly slower. Using the “once” option instead means forking happens just once; all your tests will be ran together in a single JVM.

After switching the forkmode to “once”, our test running time plummeted to 33 seconds for a net gain of 4.5 minutes. As Borat would say, “very niiiice”. (In this case 33 seconds is still longer than it should be, but that’s for another post).

Having the tests run each in its own JVM also covers up problems. You can create whatever sort of mess you like and it’ll all be swept away before the next test runs. While going through a setting the forkmode to “once” I found a database connection leak in some test code. This sort of problem would be much more visible if all the test code was running in a single JVM and reminded me of Martin Fowler’s advice on testing resource pools.

From a little bit of googling, I found several people running into this problem or something very similar. Frustratingly, not a whole lot of solutions. One solution that did not work (but was confirmed by some to do the trick) was to run the OC4J standalone server with the following parameters: