Twittch Comments

I created Twittch 161 days ago. Shortly after launching the web site, I added the Google Friend Connect social bar, allowing people to “join” and leave comments.

So now, 52 comics later, the statistics are not impressive:

  • 38 total comments
  • zero spam (great!)
  • 9 of the comments were from me, replying to other comments
  • 1 comment was along the lines of “where did my last comment go?”

So basically, after 5+ months people left around 28 comments. Here are the Analytics stats:

  • 167,728 visits
  • 145,880 absolute unique visitors
  • 412,014 pageviews

I’m not sure how to explain it, because I receive far more comments here with WordPress and an annoying CAPTCHA that probably deters a lot of people from commenting. I considered replacing the Friend Connect Social Bar with their Comments gadget instead, but ultimately I decided to give Disqus a shot instead.

I will follow up after a few weeks (and some new comics) to let you know how it goes.

Minor Policy Change

I just received some odd comments on a blog entry I wrote more than a year ago. Looking back, I’m kind of mortified at what I wrote. I feel that way about a lot of stuff I write here.

Two things come to mind:

  1. This blog is highly extemporaneous. Think of it as a public journal, not a carefully edited research paper. (the name of this blog is the first clue)
  2. My opinions often change over time, or at least evolve. I know that code I wrote last week looks a lot different than code I wrote one or two years ago. (if your coding style never changes, you probably stopped learning, and are in trouble)

Thus, for anything older than 180 days, comments are closed. Going back that far seems silly because I might not even believe what I wrote back then. Oftentimes, a post is simply me working out my thought processes by writing about them.

Plus, most comments on old material are either spam or students asking HOWTO questions.

11 Questions for Jesse Wilson

Jesse Wilson created (the awesome) Glazed Lists and currently works for Google on projects such as Android and Guice. You can follow him on Twitter at @jessewilson.

1. How did you get started with computers? My mom made me go to a computer graphics daycamp when I was 12. I wanted to just stay home and play lego, but she made me go. I loved it! From there I picked up HTML, then Netscape 2-era JavaScript, and high school CS BASIC. Computer science at university was a natural next step.

2. What is your current job? Software Engineer. I work with Josh Bloch, Elliott Hughes and Bob Lee maintaining the Dalvik core libraries for Android. We do fun things like rewriting LinkedHashMap, and unfun things like fixing the X509 decoding in HTTPS.

3. What’s next for Glazed Lists, and what is your role in that project these days? For the most part, Glazed Lists is stable and complete. There’s been some interest in adding support for platforms like GWT, Android, and FX, but nothing is actively under development. I’m currently only a consultant to the project; it’s difficult to stay involved in a project that you aren’t using!

4. Would Java be better off today if Glazed Lists was an “official” part of the JDK, or had a formal JSR? Being in the JDK has severe disadvantages: an unpredictable release schedule, licensing problems, and a lack of competition. Consider java.util.logging, an absolutely horrible API that we’re all stuck with. Java would be better off if it were easier to adopt and manage third-party libraries. Often I’ll use a bad API that’s built-into the JDK to save the hassle of downloading a good open source alternative.

5. What’s the coolest thing you’ve coded? (like a clever little algorithm, or an application you are really excited about) I wrote a JMS-like message queue with an awesome API based around interfaces. To define a message, create an interface whose methods all return void. Message-senders simply call the interface, and message-receivers just implement it. Behind the scenes, these messages-as-method-calls are stored in a Bigtable. Everything was managed, fault-tolerant, distributed and fast.

6. What are your thoughts on learning multiple programming languages? Some developers get really hung up about syntax, which drives interest in languages with pretty “Hello World” examples but few tools and APIs. What gets me excited are the programming languages that go beyond syntax: Clojure has persistent collections; Noop is being designed for testability. But I haven’t used any alternative languages ’cause Java never really lets me down.

7. If you had the chance to work on whatever software project you wanted to for the next year, and money was no object, what kind of problem would you tackle? Ironically, I’ve got an idea for a programming platform. I’d like to build a programming language with structure rather than syntax. And one that is comprehensive: refactoring, versioning, collaboration, compilation, and deployment would all be an integrated part of the program’s development environment.

8. How is programming different today compared to when you started? In the 1990’s, all software was bad. It was hard to use, buggy, slow, and dumb. Think about fighting IRQ settings in Windows 95. Today’s software is generally easy-to-use and also easy to maintain. An individual developer has incredible resources at his disposal: APIs that can do almost anything, deployment targets like clouds and devices.

9. Has Java jumped the shark? What’s next, in your opinion? Java is still a productive language and platform; I haven’t seen anything that improves upon it enough for mainstream users to switch.

10. What is the biggest challenge facing programmers today? There are many, but a particularly tragic one is security. As we put more personal information into connected systems, they become more appealing targets for criminals. Attacks like the recent Twitter break-in are easy and we’re all vulnerable. Securing applications is very hard, and we don’t have the tools to even measure whether our applications are secure.

11. What are Timbits, and where can I get the best donuts in the world? Timbits are donut holes from Tim Horton’s, Canada’s ubiquitous community centre and cafe. Their double-chocolate is among the best donuts in the world; available at 3500 stores in the US and Canada.

Thanks, Jesse!

Roy T. Fielding on REST-*

Roy Fielding offers his opinion on the REST-* effort:

Quite frankly, this is the single dumbest attempt at one-sided “standardization” of anti-REST architecture that I have ever seen. It even manages to one-up the previous all-time-idiocy of IBM when they renamed their CORBA toolkit “Web Services” in a deliberate attempt to confuse customers into thinking they had something to do with the Web.

Ouch.

REST-*

REST-*.org arrived today. I think the name is highly unfortunate, immediately evoking bad impressions from WS-*.

REST Star

In their defense, they are doing many things right. These bullets come from their site:

  • Specifications may not require any field of use restrictions or fees to get access to a certification testsuite or to pass certification.
  • All source code for certification tests must be open sourced under the ASL 2.0 license.
  • Specifications must be discussed in the open on a public mailing list.
  • All drafts, source code, and any issue tracking system must be made available for anyone to read.
  • Specifications, source code, and certification efforts must be licensed under ASL 2.0.
  • etc…basically, don’t be like Sun and the JCP. (my take)

A big chunk of the fledgling web site is devoted to explaining how REST-* is different than WS-*. I do hope someone re-thinks the name.

Guice with GWT

This article shows how to configure Guice with server side code in Google Web Toolkit (GWT) applications1. I use Guice 2.0 with GWT 1.7.0.

Steps include:

  • Obtain the Guice JAR files
  • Extend GWT’s RemoteServiceServlet
  • Extend Guice’s GuiceServletContextListener
  • Extend Guice’s ServletModule
  • Set all RemoteService relative paths to GWT.rpc
  • Configure GuiceFilter and your context listener in web.xml
  • (optional, but good) Your remote service implementation classes no longer have to extend RemoteServiceServlet

Phew! That seems like a long list, but I want to ensure I list every step. This approach is based on the excellent GuiceRemoteServiceServlet by Pavel Jbanov. His initial work pointed me in the right direction, making this much easier.

Get Guice

Grab guice-2.0.zip from the Guice downloads page. This ZIP contains all of the required JARs. You may also want guice-2.0-src.zip.

To use Guice with GWT, you’ll need two JARs: guice.jar and guice-servlet.jar. Just drop these into your war/WEB-INF/lib directory.

Extend GWT’s RemoteServiceServlet

This code comes almost verbatim from Pevel Jbanov’s blog, with the modifications mentioned in the first comment on that page. Here is the source:

 @Singleton public class GuiceRemoteServiceServlet extends RemoteServiceServlet {   @Inject   private Injector injector;    @Override   public String processCall(String payload) throws SerializationException {     try {       RPCRequest req = RPC.decodeRequest(payload, null, this);        RemoteService service = getServiceInstance(             req.getMethod().getDeclaringClass());        return RPC.invokeAndEncodeResponse(service, req.getMethod(),         req.getParameters(), req.getSerializationPolicy());     } catch (IncompatibleRemoteServiceException ex) {       log("IncompatibleRemoteServiceException in the processCall(String) method.",           ex);       return RPC.encodeResponseForFailure(null, ex);     }   }    @SuppressWarnings({"unchecked"})   private RemoteService getServiceInstance(Class serviceClass) {     return (RemoteService) injector.getInstance(serviceClass);   } } 

All GWT RPC requests will go through this single servlet. Thus, your remote service implementation classes will not have to extend RemoteServiceServlet.

  • GuiceFilter will inject the Injector
  • The @Singleton annotation is required for Guice-managed servlets

Extend Guice’s GuiceServletContextListener

This step creates a Guice-friendly servlet context listener.

 public class MyGuiceContextListener extends GuiceServletContextListener {   @Override   protected Injector getInjector() {     return Guice.createInjector(       new MyServletModule(),       new AnotherOneOfMyModules(), etc...);   } }

You can hook up as many Guice modules as you want. The first, MyServletModule, replaces much of what traditionally goes in web.xml.

Extend Guice’s ServletModule

In order to use constructor injection with servlets, Guice must construct your servlet instances. Thus, you no longer list each servlet in web.xml. Here is a simple module:

 public class MyServletModule extends ServletModule {     @Override     protected void configureServlets() {         serve("/MyApp/GWT.rpc").with(GuiceRemoteServiceServlet.class);          // cannot use @ImplementedBy         bind(MyService.class).to(MyServiceImpl.class);     } }

Go check out the Guice ServletModule documentation for a full explanation.

You cannot use @ImplementedBy on the MyService interface. That’s because MyService is in GWT client code, and the MyServiceImpl is in GWT server code. Instead, the binding is configured in MyServletModule as shown.

Remember — this replaces most of what you typically place in web.xml.

Set all RemoteService relative paths to GWT.rpc

All of your GWT remote services will dispatch to the GuiceRemoteServiceServlet shown earlier.

 @RemoteServiceRelativePath("GWT.rpc") public interface MyService extends RemoteService {     ... }

Create the web.xml

In old-style GWT, you list your remote service implementations in the GWT module XML file (MyApp.gwt.xml). If you have any servlets listed there, you can remove them. Your GWT module should look something like this:

<module rename-to='MyApp'>   <inherits name='com.google.gwt.user.User'/>   etc...    <entry-point class='com.abc.whatever.client.MyEntryPoint'/> </module> 

Your web.xml should list the Guice filter and your custom Guice context listener.

  <web-app>   <filter>     <filter-name>guiceFilter</filter-name>     <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>   </filter>    <filter-mapping>     <filter-name>guiceFilter</filter-name>     <url-pattern>/*</url-pattern>   </filter-mapping>    <listener>     <listener-class>com.yourcompany.server.MyGuiceContextListener</listener-class>   </listener>    <!-- NOTE: List all Servlets in MyServletModule for Guice injection -->    <welcome-file-list>     <welcome-file>Css.html</welcome-file>   </welcome-file-list> </web-app> 

Clean up Remote Service Implementations

Your GWT remote service implementations do not have to extend RemoteServiceServlet any more.

Old code:

public class MyServiceImpl     extends RemoteServiceServlet implements MyService {   ... }

New code:

public class MyServiceImpl implements MyService {    private final AnInterface anInterface;    // Guice injection here!   @Inject   public MyServiceImpl(AnInterface anInterface) {     this.anInterface = anInterface;   }   ... }

Summary

Once all of the above pieces are in place, you can use normal Guice dependency injection in all of your GWT remote service implementation classes. This includes both constructor and setter injection.

Please let me know if you find any mistakes, and I’ll be sure to update this article.

1 To use Guice with GWT client code, check out the GIN project. (I have not tried GIN)

Updates

Sep 17, 2009

Changed: RPCRequest req = RPC.decodeRequest(payload); To this: RPCRequest req = RPC.decodeRequest(payload, null, this);

Learning Illustrator

I’m finding Adobe Illustrator to be quite inefficient and hard to learn. In comparison to Inkscape or Xara, Illustrator seems to require more keystrokes for similar tasks, and the GUI feels very picky about where I click. It is hard to explain, other than to say my mouse hand gets very sore when using Illustrator. I spend a lot more time very precisely trying to move the mouse to the right location, which is very tiring.

Today, I wanted to learn how to adjust Illustrator’s default marquee selection mechanism. In other drawing tools I’ve used, you drag a rectangle around a part of the drawing to select objects. The tool then selects whatever objects are completely enclosed in the rectangle.

Illustrator is different, however. Instead of selecting enclosed objects, it selects every object you touch with the rectangle. When I make comics, this is a constant irritation. I find myself dragging around a character’s whiskers, for example, and his whole head ends up selected. So then I have to painstakingly Shift-Click on other objects to de-select. This comes up repeatedly, and contributes to my hand getting so damn sore with Illustrator.

I’m not the only one to notice this behavior:

Another baffling omission in the product: A way to select multiple objects when they’re amidst others, by NOT having the marquee select everything it touches. There should be an option to select only the objects that are fully enclosed by the selection rectangle.

Corel Draw has always offered this, and in practice I never needed to turn it off. I can’t think of another UI feature that enhanced productivity more. What are Illustrator users doing as a workaround? Shift-clicking on things one at a time? Tedious and omission-prone!

I assumed this was a configuration option that I could switch, but as I learned, there is no way to change the behavior!

For now, I think the best workaround is to use layers more heavily. There are also some scripts that provide a way to de-select partially selected objects, though this requires digging through some menus for each selection, or setting up a custom keystroke (and remembering it).

Maybe I should switch to Windows 7 so I can use Xara. Or Linux so I can use Inkscape. I’m very frustrated that all of my favorite tools require specific operating systems. ** update: Unless one is willing to suffer with a less-than-ideal port, which I am not. **