Getting a non-relative (absolute) URL for a Wicket page

Just a quick Wicket tid-bit I found today – generally with Wicket, when you create a BookmarkablePageLink or use “urlFor(…)“, the resulting URL is stated as a relative path, e.g. “../../something/mypage” (i.e. those that contain “..”).

Sometimes you need to get a “fully qualified” URL such as “/pages/something/mypage” or “http://localhost:8080/myapp/pages/something/mypage“.

Although there is nothing on the core Wicket objects to do this, there is a little utility included with Wicket which will allow you to convert a relative URL to an absolute URL – org.apache.wicket.protocol.http.RequestUtils

It’s dead simple to use – just call RequestUtils.toAbsolutePath(…) and pass in the relative URL as a string. Assuming the relative URL was generated from the current Wicket Page, it will convert from “../../something/mypage” to “http://localhost:8080/myapp/pages/something/mypage

Handy!

Posted in Java, Software Engineering, Wicket | Tagged Java, tips, web, wicket | 2 Comments

Guice / Java IoC best practices – using annotations for configuration

18 months ago I introduced Guice 2.0 into my workplace development team.

So far it has been doing a good job of making inversion of control / dependency injection approachable, light-weight and helpful for the whole team.

The biggest issue we’ve had with Guice has been unexpected bugs relating to object scoping misunderstandings.

These are bugs that originate from a mistake on the part of the developer, either forgetting or misunderstanding the scope of objects being interacted with and subsequently accessing the objects outside of their intended scope, or accessing the objects in a scope that turns out to be more expensive than intended (e.g. an object intended to be a singleton, being accessed with no scope and re-instantiated over and over).

What we’ve found is that as a standard it is best to use Guice’s annotation based configuration mechanism to configure objects in their “intended configuration”, rather than using “Guice modules”.

Let me give an example of the two mechanisms -

With module –

public interface MyService {
   void serviceOperation1();
   void serviceOperation2();
   void serviceOperation3();
}

public class MyServiceImpl implements MyService {
   @Inject
   public MyServiceImpl() {
   }
   public void serviceOperation1() {
      // ...
   }
   public void serviceOperation2() {
      // ...
   }
   public void serviceOperation3() {
      // ...
   }
}

public class MyServiceModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(MyService.class).to(MyServiceImpl.class).in(Scopes.SINGLETON);
    }
}

With annotations –

@ImplementedBy(MyServiceImpl.class)
public interface MyService {
   void serviceOperation1();
   void serviceOperation2();
   void serviceOperation3();
}

@Singleton
public class MyServiceImpl implements MyService {
   @Inject
   public MyServiceImpl() {
   }
   public void serviceOperation1() {
      // ...
   }
   public void serviceOperation2() {
      // ...
   }
   public void serviceOperation3() {
      // ...
   }
}

These two examples are functionally identical, the only difference is how the Guice injector gets bootstrapped.

The common argument for Guice modules over annotations is that the application configuration is kept separate from the code, and can be changed in one central location. On the face of it, that seems like a pretty good argument.

In practice though, few objects can be arbitrarily rescoped without affecting the assumptions on which they were built, particularly where they have dependencies on other objects which have implicit scope. The only way to guarantee everything works as intended is to use Provider<MyDependency> everywhere to make sure things can continue working even if you monkey with the scoping in some unexpected way.

To me that seems like code-pollution which has rapidly diminishing returns.

The argument for @annotation based configuration is simple – understanding the intended scope and default implementation of an interface / object is an important signal to a developer reading the code for the first time. The best place for that information is in the code where the developer is reading it.

And best of all, this isn’t an either-or decision.

The annotation based configuration only specifies the default configuration of your Guice application. If you specify a different scoping or binding in a Guice module, it will override anything specified using annotations.

So with this approach you retain the flexibility (and explicit definition) provided by modules, but still solve the “developer usability” issue of in-your-face scoping/bindings.

common
Posted in Java, Software Engineering | Tagged developer, Google, guice, Java, tips | Leave a comment

Java String “substring” – an example of lazy error messages…

What does this error mean?

Exception in thread “main” java.lang.StringIndexOutOfBoundsException: String index out of range: -1

That’s easy right? You’ve passed “-1″ as an argument to a Java String’s “substring” method.

Wrong.

Here’s some code that gives the same error -

"fred smith".substring(4, 3);

See the bug? The start index is after the end index (by 1 character).

To me, this is pretty poor API design. Neither of the arguments are out of bounds of the String’s length, so why raise a StringIndexOutOfBoundsException?

Worse, the index reported is neither of the indices passed.

And finally, the exact same error message is reported for another common mistake, e.g.

"fred smith".substring(-1, 3)

Here’s the offending code in Java’s core String.java –

    public String substring(int beginIndex, int endIndex) {
	if (beginIndex < 0) {
	    throw new StringIndexOutOfBoundsException(beginIndex);
	}
	if (endIndex > count) {
	    throw new StringIndexOutOfBoundsException(endIndex);
	}
	if (beginIndex > endIndex) {
	    throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
	}
	return ((beginIndex == 0) && (endIndex == count)) ? this :
	    new String(offset + beginIndex, endIndex - beginIndex, value);
    }

For what it’s worth, this should probably be an IllegalArgumentException, since the argument’s have nothing to do with being out of bounds of the string and are just illegal with respect to one another. This would also allow for a meaningful error message such as “Start index (4) is before end index (3)”.

It’s funny the stuff you find when fixing gnarly bugs :)

Posted in Java, Software Engineering | Tagged Java, soap-box | 2 Comments

Converting Ebook Formats – .mobi to .epub

As I recently blogged, I picked up an iPad, and have been using it (mainly) as an ebook reader.

I prefer using the Kindle app on the iPad to read ebooks, and the Amazon Kindle book store seems to have the best price/range as well.

But I recently had a situation where I had bought a digital copy of Programming in Scala: A Comprehensive Step-by-step Guide which only comes in PDF and “.mobi” versions. .mobi is the format used by the Kindle, so I thought “woo hoo” this should be easy, right?

Wrong.

It’s not possible to get .mobi books into the Kindle app that weren’t purchased from Amazon right now. I did some googling and found a number of forum posts recommending iPad/iPhone file system tools to drop the ebook into the Kindle folder. Unfortunately on Windows I wasn’t able to get these to show the Kindle app’s folder.

So I tried looking for another solution, and although the iBooks app isn’t as good as the Kindle app for reading, I figured converting the .mobi book to an .epub book for iBooks would be an easier task.

As it turns out, it was! Here’s how to do it -

The same process can also be used to convert books from/to other ebook formats.

  1. The key tool here is “Calibre” – an open source ebook management tool. Download a copy from http://calibre-ebook.com/
  2. Install it, I’ll assume that you’re installing on Windows and with the default settings.
  3. Start the program when installation is complete. When you’re prompted as below, choose “Apple” as your default reader.

  4. Once it’s loaded, use the “Add button to add the .mobi (or other format) book to Calibre.

    It should then show up in the list of books.

  5. Click the “Convert” button.

    When the conversion options dialog appears, use the default settings and click OK.

  6. You should see a “Job” appear in the Jobs monitor in the bottom right hand corner of the screen. Wait for the book to be converted and the Job count to return to zero.

  7. Right click the book and choose the “Save to disk -> Save only EPUB format to disk” option and choose where to save the resulting ebook.

  8. The “.epub” book can now be dragged from the file system to iTunes and synced on the iPad.

Calibre seems to be another great open source tool that I’ve never heard of. It’s a shame the ebook distributors such as Apple and Amazon can’t  settle on a single format, and/or provide better interoperability between their formats/devices, but I guess vendor lock-in is still the modus operandi for the time being.

Anyhow, open-source ftw!

Posted in IT | Tagged apple, ebook, off-topic, tips | 23 Comments