Skip to main content

Posts

Showing posts from 2007

Configuring Mac OS X Terminal

The post you're reading is ancient, and yet slightly inexplicably popular :) I've recently started blogging again in 2020 with some fresh content. Check out some of the new topics about blogging again , dynamic method invocation , and aapt2 . I recently installed Leopard (Mac OSX 10.5) on a new mac. There are a few factory settings I usually change on a new installation, although by far fewer than I do typically with Windows. One of them is the default keyboard configuration for Ctrl+Left Arrow, Ctrl+Right Arrow, Page Up, Page Down, Home, and End in Terminal. The default settings drive me a bit potty since I'm used to using Linux and emacs every day at work. Changing them is easy, fortunately. Just visit Keyboard under Settings in Terminal->Preferences , and modify the following keys, so that their action matches the value shown. You can edit the keystroke for an item by double clicking on it, selecting "send string to shell", and typing the indicated ke

Detecting Concurrent Changes with the Decorator Pattern

Recently, our bug tracking system started receiving reports of a ConcurrentModificationException . The API in question was only ever supposed to be used on one thread, and yet a caller somewhere was making modifications on a background thread. One thing that makes it tricky to diagnose this kind of problem is that a ConcurrentModificationException thrown during iteration only tells you that a concurrent modification was detected. But no information is present in the stack trace about where the rogue write actually happened. Wouldn't it be nice to have something like this? java.util.ConcurrentModificationException at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372) ... Caused by: java.lang.Throwable: List modified at ... at org.foo.SomeRogueCaller.writeOnTheWrongThread(SomeRogueCaller.java:30) It's pretty easy to do this using the decorator pattern . The basic idea is to write a decorator for java.util.List that records a stack trace when

San Francisco Walk: Bay Bridge to Golden Gate

I've really started to enjoy walking since I moved to San Francisco. A fun, but somewhat exhausting, walk I've done before was from the Bay Bridge to the Golden Gate Bridge. On Saturday, I wandered along the Embarcadero just to get coffee at the Ferry Terminal, but since it was a nice day, just kind of kept on going. Five and a half hours later, I arrived back home with slightly sore feet... Since I like to engage geek foo with such things, I plotted out the route of this walk (in blue; the red line is another long walk I took last year) on Google Maps: View Larger Map All in all, it was a great walk. Had some really nice euphoric moments. My iPod was playing uplifting songs, the sun was setting over the Golden Gate Bridge, and it felt pretty good to be living here...

Java Blooper #2 Solution: Must be a Better Way

Sorry for the delay in this week's blooper solution. On Monday we saw this code: boolean hasThing( List things, Thing thing ) { for ( int i=0; i < things.size(); i++ ) { if ( thing.equals( things.get( i ) ) ) { return true; } } return false; } Can we simplify this? Sure. It pays to know the class libraries well, and the collections framework in Java in particular: boolean hasThing( Collection things, Thing thing ) { return things.contains( thing ); } As well as being more compact, this idiom is safer if the collection is a synchronized wrapper (as pointed out by reader alex in the comments ). We were also able to specify the things parameter as a Collection rather than a List , following item 34 in EJ ("Refer to objects by their interfaces"), since we no longer need the ability to iterate items in the collection by index, which may well have been inefficient depending on whatever implementation of list was passed to us. Blog read

Java Blooper #2: Must be a Better Way...

The post you're reading is ancient, and yet slightly inexplicably popular :) I've recently started blogging again in 2020 with some fresh content. Check out some of the new topics about blogging again , dynamic method invocation , and aapt2 . It's Monday, which means it's time for another blooper ... What's wrong with this code? boolean hasThing( List things, Thing thing ) { for ( int i=0; i < things.size(); i++ ) { if ( thing.equals( things.get( i ) ) ) { return true; } } return false; } Update: Minor edit to add missing parenthesis from if statement that got "lost in translation" en-route to the blog :)

Java Blooper #1 Solution: Ternary Insanity

class Thing { private boolean _visible; boolean isVisible() { return _visible ? true : false; } } This code is unnecessarily using the ternary conditional operator when it's not needed. Occasionally developers get so captivated by the expressiveness of this operator that they find it tempting to use it when it's not really needed. In this particular example, it almost looks like the original writer forgot that the type of the _visible field was boolean anyway and could just be returned directly: class Thing { private boolean _visible; boolean isVisible() { return _visible; } }

The Ups and Downs

Great news first thing this morning... I'm now a permanent resident of the United States! The whole process was a lot less painful than I'd expected. It was a terribly exciting start to the day. In other news, I lost $1,000 in my portfolio today as the market continues to plummet. Ouch. My finger is twitching over the sell button ;)

Java Blooper #1: Ternary Insanity

The post you're reading is ancient, and yet slightly inexplicably popular :) I've recently started blogging again in 2020 with some fresh content. Check out some of the new topics about blogging again , dynamic method invocation , and aapt2 . From time to time, we all write code that could be clearer. Sometimes in the rush of solving a problem, we don't pay attention to the micro details of the code flowing from our fingertips. Other times, we refactor some existing code, and don't necessarily take the opportunity to clean up as much as we could. I find it useful sometimes when reading code to think about whether it could be rewritten in a more straightforward way, and if so whether any lessons can be learned about writing tight and expressive, and most importantly, readable code. Over the next few weeks, I'm going to blog weekly examples of some Java code bloopers that I've seen. All the examples are real and have been observed "in the wild".

More on email inbox bliss

So far my attempt to maintain an empty inbox is working out pretty well. One of the most effective things that worked was to get rid of folders. Previously, I was a folder freak: my email was "organized" into a bewildering, ever changing, hierarchy of folders. Rather than making it easier to find stuff, it was actually much harder. Before I could find something quickly, I had to try to figure out which folder I had decided to put it into. I draw a comparison between this and usage of, say, Google Search vs. a directory service like dmoz . Directory services categorize the web into a wonderful hierarchy. But in practice, it's almost always more effective to just search the conceptual single folder containing the whole web via google search. I now have a small number of folders. Apart from the inbox, trash, and sent folder, the remaining folders can be categorized as: A single @Respond folder . Messages that I need to respond to, but can't do so immediate

Google Code Project Hosting Gets Upgrades

The folks over at Google Code have been doing some sterling work in the last few weeks fixing various issues with its project hosting support. Here are some of my favorite fixes: Issue 250 : Issue summaries are unnecessary abbreviated . In the issue list, the summaries would be truncated arbitrarily. This was pesky on a large display, since there was plenty of space to see the whole summary. Issue 138 : projectname.googlecode.com should redirect to project page . So now you can go to jd-ant.googlecode.com as well as code.google.com/p/jd-ant . Issue 306 : IssueTracker: Provide a means of displaying more than 25 issues at a time . Now you see 100 issues at a time, which makes for less paging about in large issue lists. Glad to see these improvements. Google's project hosting is straightforward, fast, and very useful.

Asserting Control over the INBOX

Sometimes I'm a bit disorganized. Last week, after purging my INBOX of some 15,000 messages (discovering quite a few that I had read but not replied to in the process), I decided that it's finally time to assert control over my INBOX. It's not the first time I've tried this. The lofty goal of maintaining an empty INBOX is very appealing in theory, but it's easy to get lazy. Before you know it, you end up with thousands of disorganized messages again. The first step in this was turning down my "autocheck" frequency. I think a big part of the reason that I'm a bit disorganized is that email messages arrive in a constant stream throughout my day, and so I'm always processing them while doing other tasks. My approach now is to set aside 5-10 minute periods every hour or so specifically for triaging email. Any email I can respond to, or action, within that period, I do so immediately. Anything else, I add to my TODO list on the excellent Remember

Scary Statues

It may have something to do with that odd tradition they have in the USA of completely shutting down all decent television programs for a block of about four months in the summer and the result that my DVR is being seriously under-used at the moment, but I'm really getting into the latest series of the new Doctor Who. I've been an unabashed fan boy of Doctor Who since I was small enough to effectively hide behind our rather brown, early-eighties sofa in Edinburgh watching Tom Baker, Peter Davison, Colin Baker and Sylvester McCoy do their turns as the Gallifreyan time lord. I'm pretty sure it was the seed of my life long addiction to science fiction books and so-called telefantasy TV shows. When the series came back a few years ago, I was desperately excited. That excitement carried me through most of the first two series. Even though to be frank, some of the storylines and episodes were pretty poor, with the odd gem here and there ( Dalek , Father's Day , The E

Test From Adobe Contribute

Just a little test entry. I just took the plunge and upgraded my Macromedia Studio 8 to Adobe Creative Suite 3, so I'm testing out Adobe Contribute (which was completely dysfunctional in its previous incarnation with blogger). Seems pretty nice so far. Rather scarily, I'm sort of editing this blog entry in-place (or at least, that's the intent of the UI illusion it creates). Quite nifty. Notice that there's no spell checking though, which is definitely a step down from regular blog posting via an HTML form with Firefox. Boo.

Messing about with blogger

Was messing about with the blogger template a little. The banner at the top now shows my wee multi display setup in the office based on this original image: I think it's a bit over-cropped... will probably tweak it some more when I'm bored :)

Google Reader tracks funky hours...

Ah... the trends feature in Google Reader continues to remind me that I really must try harder to live in the times of day that most people regard as "normal":

Never underestimate the power of pictures

Suppose I whimsically decided to call my next little project something like "itikka". If you're the curious sort, you might wonder where that name comes from, and punch it into google to see what gives. Go on... give it a try ... I'll wait until you come back... With a bit of diligence (mainly clicking a few of those result links), you might have figured it out. OK.. try it again, but this time use Google Image Search . Instantly, you see: lots of pictures of insects (bugs). My next project might be a bug database or a bug finding tool, or something of that ilk. It may or may not be translated into Finish though ;) Pictures are powerful. P.s. I claim dibs on using this name for an application that involves bugs in any way. Even one that has some...

It's only polite to turn up for your BOF...

Just taking 5 minutes from wandering around at the JavaOne conference. Pulled myself out of the (very cool) battle bot arena in the afterdark party to go see Fabiano Cruz and Marcelo Mayworm talk about creating an OSGi based framework for Swing applications (BOF-3487). I was particularly interested in this BOF, because we've been thinking about OSGi in my group at work, and we're developing a very large and modular Swing application. Unfortunately, the speakers didn't turn up. Barring major catastrophe, that's just terribly rude . Speakers get a full free pass for the conference, and the least they can do in return is actually show up for their own sessions. Tsk ;) Needless to say, that was the only session evaluation I've filled out so far that's had many marks to the right of the center divide... More blogging on the conference to come... (I know... I've been remiss in blogging while here. I always forget how hectic things are. But I've got a bu

How pants relate to nine year old code

Rediscovered a heap of Java code I wrote 9 years ago the other day. Good grief - the passage of time is really apparent when you go surfing through code you haven't seen for such a long time... One of the little things I found distracting while surfing through the code was due to a language other than Java... I see that back then, I was still spelling in British English - dialogue instead of dialog, initialise instead of initialize. For example: AgentConfigDialogue.java . British English spellings for many words look strangely wrong to me now when I see them. I got into the habit of spelling things the American way years before I came to live here, mainly because the coding I do at work requires me to use American English. I suppose my roots are still there, since I do still seem to trip up people in the USA with occasional random Britishness (like saying I'll meet someone at "half two"). And I never probably will get comfortable with the "restroom&qu

Why Subversion is better than CVS for Java developers

Over on the JDeveloper forum , John Stegeman responds to a question about whether CVS or Subversion is better for Java development: ... "Subversion," especially if you are using ADF business components. My reason for saying this is that we initially tried CVS [in an environment where] the network was not the most reliable. We had some problems where the network would drop in the middle of the commit (not a JDev/CVS problem), and half of the changes would be committed to the repository, and half of them were not. In the case of the Business Components, having the XML files and Java source files out of synch was a major major problem. This particular problem is one that Subversion solves; with Subversion, either the whole commit happens or none of it happens, just like a good database. He makes a very good point. Atomic commits are one serious advantage Subversion has over CVS. In Java applications, where you tend to have a lot of files (as opposed to C where a lot of l

JavaOne 2007: This year's Bag-o-Stuff

Went down to Moscone today to register for the conference. Blimey, it's hot! Anyway, here are the contents of this year's backpack: You can already start playing "spot the Java geek" on the streets of San Francisco :) I like the fold-out conference schedule. Not sure if they had that last year and I just missed it, but it sure will come in handy. I've not been able to figure out what the mysterious white rubbery "holdzalot" thing from SAP is for... Apparently, you should move it frequently when it's on natural wood surfaces. I'll remember to do that. If I ever figure out what it is. More (unexciting) photos in my JavaOne 2007 Album ...

San Francisco Prepares for JavaOne 2007

For the first time ever, I'm planning to make like a tourist and actually use my camera this year at JavaOne... Was wandering around town today in search of a decent coffee and I happened to pass by the Moscone center, so I took a few of pictures of the JavaOne signage at the Moscone Center. Quiet before the storm... :) My JavaOne 2007 Album on Picasa has more. You can even subscribe to the RSS feed ...

Sessions for JavaOne

The last few months at work have been packed . We've been working to get a preview release of the next version of JDeveloper out to customers in time for JavaOne. Since we're planning to cut the final build within the next few days, some of the pressure will be off next week, and I can hopefully enjoy a few interesting technical sessions and BOFs at the conference. I was fortunate enough to have the opportunity to speak at the conference for three years in a row, but it's a bit of a relief not to be speaking at JavaOne this year. Speaking at the conference is great fun, and I hope to do it again in the future. But this year, it will be nice just to be an attendee for a change and not be stressing out about speaking the whole time... Here's the list I've signed up for so far - certainly won't make all of them, but I'll do my very best ;) Tuesday TS-1742 - Cool Things You Can Do with the Groovy Dynamic Language TS-3942 - JSR 269: The Swing Applica

Google Code Prettify

Up till now, I've been using Java2HTML to generate syntax highlighted Java code snippets for my blog. It's useful, but a little cumbersome to have to use a separate application and trim the HTML it generates for each snippet. The HTML it generates is also unavoidably gnarly, which makes tweaking the code after it has been published tedious. google-code-prettify solves this problem in a neat way - syntax highlighting is performed on the code using JavaScript in the browser. It seems to work pretty well: /** * Hi! */ final class HelloWorld { // The usual boring example public static void main( String[] args ) { System.out.println( "Hello Prettified World!" ); } }

Continuous notification for continuous integration

Someone on my team implemented a very useful little gadget that helps everyone keep an eye on our continuous integration build: Very useful - though I wish our team wouldn't cause the balloon to appear quite so often... <cough>. Pretty impressively, it was implemented using Java 1.6 - I knew that support had been added in 1.6 for tray icons, but this is the first time I've actually seen an application put it to use in a way that I find personally helpful :)

Tesco - They're Coming...

Heh... Tesco . They're nothing if not tenacious. Many moons ago, while still at secondary school , I worked as a checkout operator (beep... beep... beep...) for a Scottish grocery chain called William Lows . Tesco bought Lows in 1994 for the princely sum of 257 million pounds. Since I worked in the "flagship" Edinburgh store, the transformation from one retailer to another was tremendously visible. From then until I hopped over the pond exactly ten years later, Tesco was a permanent (if somewhat mundane) fixture of my life. The "Tesco Value" store brand (with its trademark white & blue striped labels ) will always remind me of my student days in St. Andrews . One student I knew had literally plastered an entire wall of his room with Tesco Value Baked Bean labels. Very artistic, to be sure, but it scares me to think about the sheer amount of methane production that resulted from such conspicuous bean consumption... Jumping forward, it only seems like

Preferential treatment? - netbeans

Well well... Bug 6182905 was open for 2.5 years, but now it's a NetBeans P1 issue (ala bug 6511815 ), and whoa... it suddenly got fixed. All Java applications are created equal, just some moreso than others. Personally, I'm just glad it got fixed at all... This one often crops up as one of our "random but frequent exceptions from Java core libraries". [This post is somewhat tongue in cheek in case you're wondering... Though I'm just a wee bit grumpy about the fact that apparently there's "almost no chance" bug 6510914 will ever get fixed... roll on open source java ;) ]

Beware the hashcode!

(With thanks to my colleague Armand "jojo" Dijamco) What does this code print? Map map =  new  HashMap () ;      Collection things =  new  HashSet () ; things.add (  map  ) ; System.out.println (  things.contains (  map  ) ) ;      map.put (  "foo" ,  "bar"  ) ; System.out.println (  things.contains (  map  ) ) ; Be wary of storing mutable objects in a HashSet , or using them as keys in a HashMap . An implementation side effect of using a collection that relies on hash codes is that making changes to the object in a way that alters its hash code will cause it to no longer be considered the same object. There's no way (short of removing and re-adding the item from the collection) to inform a collection that a mutable object needs to be re-hashed. Item 13 in Josh Bloch's Effective Java tells us to "Favor Immutability". He also tells us in item 8 to "Always override hashCode when you override equals". A corollary

Unit testing Swing components - impossible?

Testing Swing components seems to fill many developers with fear. "How can I unit test this thing?" they often ask, "it's full of icky event handling code and troublesome painting...". Frameworks such as Abbot are often the solution developers find for this problem. Essentially, many developers abandon the idea of writing regular unit tests for Swing components, and resort to "click simulators" which are frequently functional tests rather than unit tests. There is a lot you can do just to test regular Swing components using bog-standard JUnit (or Test-NG) tests. Consider the following fairly basic Swing component. package  org.dubh.blog; import  java.awt.Graphics; import  java.awt.event.MouseAdapter; import  java.awt.event.MouseEvent; import  java.util.List; import  java.util.concurrent.CopyOnWriteArrayList; import  javax.swing.JComponent; /**   * A user interface widget.   */ public final class  Widget  extends  JComponen

What's up with the 2.0?

Well... If I was being more accurate, this would really be 4.0. In the beginning, there was Brian Duff's Weblog over on Radio Userland (good grief, that wasn't even Web 1.0. You had to install a thick client application just to post. Yowzers), then I set up Orablogs , and moved over to there. Until fairly recently, I blogged (or rather, mostly didn't out of laziness) at blogs.oracle.com . So why move now? Well. I got a wee bit frustrated with the blog management software I was using - it had a troublesome tendency to mangle Java code in particular, which is something of a pain when you're trying to write a Java coding related blog. So far, I'm pretty happy with blogger.com 's interface. Another reason for the move is that I want to blog about more random stuff outside the world of Oracle. For instance, if I decide to play with Eclipse or JBoss (perish the thought), blogs.oracle.com doesn't really feel like the appropriate place. Even though my blog

Check parameters for validity... good advice!

I recently ran into a weird NullPointerException in part of our code: Exception in thread "main" java.lang.NullPointerException at org.dubh.blog.Graph$Vertex.access$000(Graph.java:17) at org.dubh.blog.Graph.getVerticesConnectedTo(Graph.java:14) at org.dubh.blog.Graph.main(Graph.java:26) Hmm... access$000 ? That's odd. The code looked something like this: 01   package  org.dubh.blog; 02   03   import  java.util.ArrayList; 04   import  java.util.HashMap; 05   import  java.util.List; 06   07   final class  Graph 08   { 09      private  HashMap _vertices =  new  HashMap () ; 10   11      public  List getVerticesConnectedTo (  Object vertexKey  ) 12      { 13        Vertex vertex =  ( Vertex )  _vertices.get (  vertexKey  ) ; 14        return  vertex.fromEdges; 15      } 16   17      private final class  Vertex 18      { 19       private final  List fromEdges =  new  ArrayList () ; 20     } 21      22      public static  void  main (  String