Skip to content

All posts by moore - 57. page

How to get the GWT developer browser plugin

The Google Web Toolkit developer plugin, which integrates with a variety of browsers and lets you debug GWT code from within the Eclipse IDE, is astonishingly easy to get, but I haven’t found any great instructions, so I wrote this brief post.

You just need to start your IDE, start up any application in Development mode, and then visit the address the development mode server is running on in your browser (it will look something like this: “http://localhost:8080/host.html&gwt.codesvr=127.0.0.1:9997” if you are running off an external server–not sure what it looks like for folks using embedded jetty). It will send you to the ‘Missing Plugin’ page (or you can go there directly).

Some browsers are not supported (Safari on Windows is one I know of). The best list of supported browsers I was able to find was on the ‘Missing Plugin’ page; click the ‘plugins for other systems’ link.

BTW, this is different than the GWT plugin for Eclipse.

On becoming an employee

I made the choice a few months ago to become an full time employee.  After a number of years of contracting, this was not an easy choice.  However, the company for which I work, 8z Real Estate, was not a black box to me.  I had contracted for them off and on since 2005.  Still, this was a big step for me, and I just wanted to blog about some of my thoughts around it.

Key reasons I became an employee:

  • An opportunity to really focus on the technical side.  No more being worried about the next gig.  Becoming an employee makes it easier for an employer to offer more freedom (for example, to explore a different skill set) to an employee as well.
  • The chance to be part of a kickass team with good teammates and a great manager.
  • It is fun to be part of a growing company.  We have Beer Fridays and other social events.
  • Less stress about work in general, although, as Bob Lewis said, the only difference between an employee and a contractor is that the employee has the illusion of job security.
  • 8z is doing some pretty cool stuff with some pretty interesting data, and offers a valuable service to many many people.  I can’t tell you how many folks have told me they love COhomefinder, the flagship webapp that I work on.

What I miss about being a contractor:

  • Business development–it was fun and challenging to think about how I could help everyone I met, or how they could help me
  • Extreme flexibility of hours, including when and how much I worked.
  • Greenfield development is always nice.  I am constantly learning and so sometimes cringe when I see code I wrote years ago.
  • Being able to say ‘no’/fire a client.

What I don’t miss about being a contractor:

  • Waiting for invoices to roll in and/or reminding clients about outstanding invoices.
  • Thinking about the next gig before the current one is done.
  • Regular overcommitment–making hay while the sun shines is what I had to do, but I did over commit at times.  Work life balance is easier to achieve.
  • Paperwork.

I’ll be blogging about my work at 8z from time to time going forward, so I added an 8z category to this blog.

Useful Tools: StatsMix makes it easy to build a dashboard

I haven’t been to a BDNT lately, but still get their email announcements.  In August, all the 2010 TechStars folks presented, and were listed in the email.  I took a look at each company, and signed up when the company seemed to be doing something cool.  I always want to capture my preferred username, mooreds!

One that was very interesting to me was StatsMix; I signed up for their beta.  On Nov 1, I got invited to sign up.  Wahoo!

Statsmix lets users build custom dashboards.  I am developing an interest in web analytics (aside: if you are interested in this topic, I highly recommended Web Analytics 2.0, by Avinahsh Kaushik).  I’ve been playing with Piwik, an open source analytics toolkit, but Statsmix offers a slicker solution.

They have made it dead simple to create a custom dashboard for users.  They offer integration with, at this time, 29 services (twitter, mailchimp, youtube, Google Analytics, etc).  I could not find an up to date list of integration services outside of their webapplication!  The best I could find was this list from September.  While the integration interface is slick, the data integration is rudimentary.  For example, they will let you monitor the number of rows in a Google Spreadsheet, but nothing more (like rows in different columns, or the value in a particular cell–would be nice to see them integrate with Google Apps Scripting); you can track the number of likes on Facebook, but not the number of comments.

The real power of StatsMix comes from the ease of integration with your own custom stats.  They offer an API which is accessible via REST.  This means that you can push information from your database to a beautiful looking dashboard with shell scripts and a cron job.  Very cool!  It would be nice to see a plugin for Magento or other ecommerce vendors; I recently had a client, The Game Frame, that would have been a great fit for this type of dashboard, since it aggregates beyond what the ecommerce software provides.

Other cool features:

  • The whole UI is beautiful and farily intuitive.
  • The dashboard supports custom date ranges.
  • They will send you an email of stats every day, and apparently have some kind of limited version you can pass onto clients.  I didn’t play with the email feature at all, though it is extremely useful.

However, all is not perfect.  Some issues with StatsMix include:

  • As mentioned above, the integration with third party services leaves something to be desired.  What they offer is a nice start, but it’d be great to see them create some kind of marketplace where developers could build solutions.  For example, the twitter widget only tracks the number of followers.  From the TWitter API, it appears to be pretty easy to track the number of mentions, which could be a useful metric.
  • It wasn’t clear how to share a dashboard, though that may be an upcoming feature.
  • The terms of use are, as always, pretty punishing.
  • Once you develop a number of custom metrics, you are tied to their platform.  That wouldn’t be so bad, except…
  • They are planning to charge for the service, but give no insight into what to expect.  There is a tab called ‘Billing’ but all it says is: “During our beta, StatsMix is free to use. After the beta, you’ll be able to manage your billing preferences on this page.”  If I was considering using this as part of my business, I would want much more insight into possible costs before I committed much time to custom metric buildouts.  I’m fine with them making money, just want more insight into this key aspect of their web app.

All in all, it is well worth a try.  If you to, let me know by posting a comment.  I have 5 invites to give out.

Tech folks can learn from rap stars about social media

At least, this one did.

I am just finishing watching this hour long interview with Chamillionaire, (found via Both Sides of the Table).  It’s long, but worth listening to.  It is very interesting to see some of the patterns that arise in entreprenuership, venture capital, and the music industry. The key takeaway for me is that the rise of the internet means you are not limited to going through gatekeepers like you used to be (and this is true for entrepreneurs and musicians–check out this interesting company I found out about at Boco last year for a nice intersection of the two).

This isn’t strictly due to the internet (Chamillionaire started with mix tapes), but the internet radically increases the scope and breadth of our reach.  All you have to do is put in the time, blood, sweat and tears, and you can build your audience.  And, most importantly, you can take that audience with you wherever you go (Chamillionaire will when he leaves Universal, and Dion Almaer will as he leaves Palm).

Other highlights/takeaways:

  • control your image–even when you hire or use other people’s services, it is still on you maintain quality
  • you have lots of gifts to give–find out what people want and will pay for
  • go beyond your normal boundaries–when promoting one of his hits, Chamillionaire searched out rappers from beyond the mainstream (NZ, Greece) and leveraged their talents, rather than sticking with pop
  • the best presentation in the world fails if you don’t hold the microphone correctly
  • quora sounds like a useful, for pay, collection of questions and answers

In addition, lots of echos of Gary Vaynerchuk’s great video on building personal brands (cursing).  The user questions (the host took 5-10 during the hour) added a nice touch.  This is the first time I have watched ‘This Week in Venture Capital’ and I found the ‘sponsor breaks’ to be a bit abrupt, but I suppose the host has to pay the bills.

Turning on hibernate query caching

Sometimes I write a blog post because I want to say something to others, other times because I want to help others, and sometimes I write one for myself.  This is one of the latter type of posts.

I find that nothing drives home a lesson I learned like writing out the solution on my blog, and more than one time I’ve searched my blog because I remember I had written about a topic of current interest in the past.

If you want hibernate, a java ORM tool, to cache your query results, there’s a section in the hibernate manual. Like most of the hibernate documentation, it’s quite good.  One thing that caught me up, though, is that I thought that all queries were cached, as soon as you had set up the correct configuration in your hibernate xml files and marked your objects as cacheable.

However, this is not the case,  as I learned when I turned on the mysql query log and looked at the calls the interesting web application was making.  I did quite a bit of searching, but the answer was in the same section that told me how to set up the configuration (as well as in this forum post).

…most queries do not benefit from caching or their results. So by default, individual queries are not cached even after enabling query caching. To enable results caching for a particular query, call org.hibernate.Query.setCacheable(true).

Doh!  Following these instructions decreased the page load time for some heavy query pages from 8 seconds to 0.5 seconds (the second time the page was loaded).  Impressive indeed, though the production environment might not see such drastic improvements.

One additional note–you can use query caching for SQLQueries (like group operations) by telling hibernate what the type is of each returned value.  If you don’t use addScalar, but you do mark a SQLQuery as cacheable, you’ll get a java.lang.ArrayIndexOutOfBoundsException when that code executes.  More here.

These articles were helpful to me as I navigated Hibernate caching, above and beyond the reference documentation:

Update on GWO for a non profit

Well, after a week or two of data collection, the GWO experiment I had set up for the WILD Foundation caused an issue–apparently it was preventing a javascript shadowbox from working. I didn’t want to get into troubleshooting a javascript component that I had never used on pages I had never seen, so I recommended turning off the experiment to see if that solved the issue.

It did. I knew there was a way to include the GWO javascript just where it was used, on the home page, but I got busy, and by the time I was able to do this, they were hip deep in a website rework. I’ve been involved in website redesigns with too many cooks in the kitchen, so I just asked them to let me know when the dust has settled so I can restart the experiment.

Lessons learned:

  • sometimes volunteer projects take a long time to get to results, and almost definitely will take longer than you plan
  • other opportunities can spring out of volunteering–I showed Emily some space available via another non profit I’m involved in, and she’s looking at possibilities for a fundraiser there.  This never would have happened if I hadn’t volunteered previously
  • the process opened up some ideas for the non profit around changing the home page to highlight things they wanted to focus–sometimes, any perspective from outside an organization is useful

    I’ll let you know when I get a chance to re-enable GWO on the WILD site, but I thought I’d give an update.

    Avoid primitive object wrappers as return values for GWT javascript overlays

    Just a warning, if you build javascript overlay types, you should make sure to only use primitives and strings as primary members of your overlay classes.  I’ve already written about overlay types once before, and here’s the GWT documentation.  If you dig a bit deeper in the GWT documentation, you see this quote:

    JavaScript non-string objects always marshal as JavaScriptObject$

    I was using a java.lang.Double as the return value for one of my overlay objects, and it was fine until I tried to do any math on it.  Nothing would seem to turn the value into a Double or a double, yet no exceptions were thrown.  After some sleuthing in web mode, it turned out that the value returned when I was trying to parse it was NaN, even though when I output it to the screen, the value looked like a double.  I guess it was being treated as a JavaScriptObject$.

    Easily enough fixed, just make sure that you don’t use any objects wrappers of primitives in an overlay type.

    Namespace Collisions, NS_ERROR_XPC_CANT_CONVERT_WN_TO_FUN and GWT

    So, the abstraction layer provided by GWT just leaked–well, more of a flood than a leak.

    I am working on a site that is pulling in an html fragment which included some javascript code via an XML HttpRequest.  This new code will make paging the results of a search quicker, hopefully leading to happier users.  For reasons too obscure to go into, I was creating a variable named ‘r1’ which I was then adding to the DOM.  The name was completely arbitrary, and was due to laziness (hey, why type 3 characters when you can type 2?).

    Fast forward to today, when we’re getting ready to launch the update.  Occasionally, but not often, code that GWT was executing was throwing an exception.  One of the other developers found it because some functionality was disabled.  Here’s what that exception looked like:

    exception: (NS_ERROR_XPC_CANT_CONVERT_WN_TO_FUN): Cannot convert WrappedNative to function
    QueryInterface: function QueryInterface() {
    [native code]
    }
    result: 2153185293
    filename: http://stageserver/gwt/2B17113CD349EDFD95DC846F38AB0857.cache.html
    lineNumber: 4268
    columnNumber: 0
    inner: null
    data: null
    initialize: function initialize() {
    [native code]
    }

    Now, usually, the first thing I do when I see an exception is to recompile the GWT with -style DETAILED instead of -style OBF and see where the error occurs.  However, when I did that, I didn’t see the error message any more.

    OK, I added more debugging.  If I added a certain number of alert statements, the error message was nowhere to be found.  OK, go back to the previous code.  Try different pages, different browsers.  Sometimes the exception reared its head, other times it didn’t.  It appeared on some browsers and not others. Sprinkled alerts throughout the code, found the exact line where the exception was being thrown.  All that line did was create a click listener.

    Nothing really clear on google; however, this post was useful in pointing to the error message being a collision between a function name and a DOM element.  Searching the GWT google group was not helpful.   I tried using the Firebug debugger, but on obfuscated source, it was not helpful to me.

    These kind of bugs make me want to tear out my hair.  Hardly reproducible bugs are no fun. However, I finally found the issue (if I hadn’t, I’d still be working and wouldn’t be posting, that’s for sure).

    How I finally solved it:  I was getting a line number.  I finally edited the generated GWT .cache.html file and added some newlines.  This would let me find out exactly which function was really causing the issue.

    And, lo and behold, the problematic function was named ‘r1’.

    Changing the name of the DOM element fixed this issue. Beware short named javascript DOM elements when working with GWT.

    Hope this helps you.

    GWT Marketplace

    Two years ago, I surveyed the state of GWT widgets.  It was pretty fragmented and a bit confusing.  While I haven’t been paying very close attention, I don’t think things have changed much.

    I was browsing around the GWT google group, and found this interesting announcement.

    I’m a huge fan of GWT and the only problem I have with it is not really a problem with GWT but with the fact that there isn’t a centralized place for registering component and associated tools AFAIK.  I have created an application to do this which is available at http://gwtmarketplace.appspot.com/

    I visited the marketplace and while it is currently in its infancy, it could be very useful. If you have GWT code that you want to share with the world, consider registering it. I added gwt-crypto, which I help maintain.

    My experience implementing GWO for a non profit, part 2

    I was finally able to get access to the wild.org server via FTP (previous cliffhanger resolved).  After cautioning me to be very careful (“please proceed with caution and help keep wild.org from blowing up…warnings from my IT guy”) Emily handed over FTP access.

    I proceeded very carefully.

    We had already had discussions about what we were going to vary to test the donation button.  Pictures, location of button, text of button, and text around button were the major variables.  One of the hard things about GWO is deciding what to test–the possibilities are infinite.  Even with our handful of variables, we ended up dropping some options and still have 100 variations to test!

    Actually installing GWO was pretty easy.  The only wrinkle was the fact that the goal was a click of a button and not another page.  This post was helpful.  One item that that post didn’t cover was validation–GWO doesn’t let you start an experiment if the program can’t verify that the script tags are installed correctly.  Since we were doing a non standard install, I gimmicked up a goal page for validation, then added the goal tracking to the onclick event as described in the post.

    So, the experiment is currently running on The WILD Foundation homepage.  It’s been running for about a week, and has only 1 non test conversion.  I worry that we are not testing big enough changes (a donate lightbox, rework the entire front page), but I think it makes sense to let the test run for a few weeks and see what kind of data we get.