Archive for ‘Technology’

August 4th, 2011

It’s Official: I Dislike Maven

by Tim Cull

Apache Maven is a build tool and dependency management system for Java that aims to solve a lot of sticky problems. I’ve been trying to give it a fair chance because people I respect are fans of it, but after giving it many tries I’ve decided it’s official: I dislike it and will not recommend it to my clients.

Here are the reasons I dislike it. For me, any one of them is enough not to use it but all of them together makes the decision a no-brainer:

1) You can’t check your project out of source control and build it based soley on what’s in source control. This means if you have a project in production, lose all your developers, and then have to try to build it again you’re in for a world of hurt. This is not theoretical: I’ve worked on so many projects like this that it’s becoming a specialty of mine. I’ve worked on projects where nobody even knows the login to source control, much less would they know anything about a Maven repo.

2) It’s too hard to tell what’s going on, especially for newbies and even with a simple build. A newbie can only understand a basic Maven build if he first reads a ton of documentation and understands most of the Maven lifecycle.

3) Dependency resolution isn’t consistent. For example, “mvn dependency:tree” doesn’t always give you the same results as “mvn eclipse:eclipse” or “mvn package:single” when using the “jar-with-dependencies” descriptor of the Maven Assembly plugin. For example, on one project I work on I end up with jaxb jars when I run package:single and eclipse:eclipse, but they don’t show up anywhere when I run dependency:tree. This means I have to spend many, many hours figuring out where these Jaxb (or commons-collections, log4j, etc are other common ones) jars are coming from.

4) You are dependent on too much other infrastructure. In particular, you are dependent on (at best) a corporate or departmental Maven repo that needs care and feeding or (at worst) a public Maven repo. These kinds of things move/go down/get lost, etc. This is not theoretical: I worked on one project where an infrastructure team took down and decomissioned a corporate Maven repo without realizing it and even big boys like JBoss move their Maven repos unexpectedly.

5) Other people can mess with your dependent libraries on you. This means a build that works one day might not work the next day. Even though it isn’t best practice, I have seen with my own eyes in the real world where teams manually change jars in a Maven repo without making them new revisions. If you had the jars checked into source control and tagged/labeled then this would be impossible. This doesn’t only happen in private repos, it happens in public ones, too.

So, anyway, it’s Ant and SVN/Git for me. Sorry Maven.

May 4th, 2011

Makara Cloud is now OpenShift

by Tim Cull

I just got in my inbox a message about the Paas cloud platform formerly known as Makara. Redhat bought the company and has since rebranded it to OpenShift Flex. Looks like a cool offering: super-easy deployment of PHP, Python or Rails apps, or a more custom but complicated deployment of J2EE apps and higher-powered sites. Can’t wait to have an excuse to use it.

February 10th, 2011

Sorting a Table Using jQuery

by Tim Cull

So I recently had to create a sortable table using jQuery UI. I figured it should be easy because there’s a jQuery API specifically for making things sortable and there were plenty of Google hits on “jquery ui sortable table.”

But, it turns out, while it’s easy to find information on how to make things sort visually, it’s very difficult to find information on how to hook into the events so that you might actually do something useful with a sortable table.

I’ll spare you some of the suspense. To make a table sortable, just encase the rows you want sortable in a <tbody> tag, like this:

 <table width="100%" id="contents_table">
   <thead>
    <tr>
     <td class="contents_header"></td>
     <td class="contents_header">Name</td>
    </tr>
   </thead>
   <tbody class="sortable_table">
    <tr class="sortable_row" id="123">
     <td><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>
       <input type="hidden" name="old_order_123" id="old_order_123" value="0"/>
       <input type="hidden" name="new_order_123" id="new_order_123" value="0"/>
     </td>
     <td class="contents_value">Some Stuff</td>
    </tr>
    <tr class="sortable_row" id="456">
     <td><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>
       <input type="hidden" name="old_order_456" id="old_order_456" value="1"/>
       <input type="hidden" name="new_order_456" id="new_order_456" value="1"/>
     </td>
     <td class="contents_value">Some More Stuff</td>
    </tr>
  </tbody>
 </table>

And in your document ready function make sure you make it sortable:

<script>
$(document).ready(function() {
 $( "#contents_table tbody.sortable_table" ).sortable({
   update: handle_resort
 });
 $( "#contents_table tbody.sortable_table" ).disableSelection();
});
</script>

I won’t get too much into how that works because there’s plenty to find on Google.  But now, how do you know what rows were sorted and what the new order is? After much fiddling, I came up with this:

function handle_resort(event, ui){
  var i = 0;
  jQuery("tbody tr.sortable_row").each(function(i){
    var row = $(this).get()[0]; //this is the <tr> element
    var inputId = "new_order_" + row.id;
    var input = jQuery("#"+inputId);
    var inputElem = input.get()[0];//this is the <input name="new_order_nnn"/> element
    inputElem.value = i;
    i = i + 1;
  });
}

Maybe it’s because I’m a jQuery newbie, but I still have no idea what you use “event” or “ui” for.  But they are shown on every piece of example code out there and then summarily ignored.  This is one of my only frustrations with dynamic languages: if an API developer doesn’t provide enough documentation and hands you some objects, you have no idea what to do with them.

So, instead I gave all my rows a class that was easy to find.  Then, I grab them all and iterate through them in order.  I use a hidden <input> tag to stash this order for future reference when the user submits the form.  What examples there are out there instead make an AJAX call and serialize the rows, but I didn’t want so many round trips to my server for something as simple as resorting things.

There, I hope that saves you the hour and a half I had to spend.  Enjoy.

December 17th, 2010

Release the Chaos Monkey!

by Tim Cull

The Netflix tech blog has a nice post about their top 5 lessons learned from porting to AWS cloud. They list lessons that I’ve seen frequently in such things, especially “learn to deal with component failure” and “latency is variable” but the most striking thing I saw in there was the Chaos Monkey.

They only mentioned it briefly, but I thought it was both stunning and brilliant. They actually have a process in their (production? wasn’t clear) environment that wanders around randomly killing things, just to keep them honest and make sure failure really is tolerated. What a stroke of genius! Presumably, the Chaos Monkey is scheduled to only do its job during times when it’s convenient to deal with the fallout (ie. not at 3am, nor on Thanksgiving).

This is similar to running business continuity tests. At one of my old companies, we had a philosophy that if the continuity plan hadn’t actually been tested by failing over for realsies in the production environment then it wasn’t really a plan at all–it was just a piece of paper. Doing these tests was incredibly painful and risky, but it allowed us to learn our lessons at convenient times with the least risk to the business (usually weekends :( ) instead of at peak times. And learn lessons we did. Every. Single. Time.

December 14th, 2010

Beware: GAE does not support precise decimals

by Tim Cull

File this in the “is this 2010 or 1980?” department. I’m working on a financial app in Google App Engine and discovered that GAE doesn’t support precision decimals! How does something like that happen in a modern framework? It’s as if the last 30 years of computing never happened.

December 6th, 2010

Makara: Pretty Cool Cloud “PaaS”

by Tim Cull

I had the chance to check out Makara, a cloud-based platform as a service today. I was impressed; they’ve managed to make deploying scalable Java applications easy, which is no small feat. Anyone who has tried to set up a clustered Java web app can attest that it’s no fun and not an experience you want to repeat. But these guys seem to have figured it out, and they certainly impressed Red Hat enough to want to acquire them.

Plus, their model is so much better than other PaaS offerings like Google App Engine. With Makara, you’re not stuck on one infrastructure. You can deploy (in theory at least) to anything. I’d be interested to know if anyone has actually done that in practice, though.

December 1st, 2010

How to Kill a Language, One Small Step at a Time

by Tim Cull

I honestly don’t believe there is any collective, purposeful, evil intent at Oracle when it comes to Java.   But their actions since the merger with Sun sure make it seem that way.  Oracle is killing Java, one cut at a time.

The first big shot across the bow was Oracle suing Google over Android.  Even if Google did something wrong legally, it was still a stupid move.  After many other companies failed to get Java to thrive on phones (it’s been there for years, it just was clunky and had no developer community), Google finally succeeded with the first plausible challenger to the iPhone.  And, on top of it, the Android community is much more open which attracts even more developers.  So a thriving Android community can only be a good thing for Oracle, even if they don’t get licensing revenue from the runtime.  But the suit demonstrates that Oracle just doesn’t get it.

Then, there was JavaOne.  I covered it for InfoQ, but since we try to stay pretty neutral I didn’t say what I really thought: it was awful.  I’ve never been a fan of JavaOne because it’s too big, too much of a hassle, and too full of vendors.  But this year was even worse.  Adding it to the rest of the Oracle conference took it from merely too big to an absolute zoo.  And, it watered down the Java bit to just another Oracle add-on.  The biggest display in Moscone center, the one that took up the entire entry way when you came in, was about Larry’s yacht, and not technology.  Apollo Ohno was a speaker, as if any of us cared.  And the place was absolutely buzzing with “suits”.  The whole conference had Larry’s ego all over it.

Then James Gosling left, which isn’t a material impact on Java, but it is a symbolic one.

And now the Hudson flap is the last straw for me.  Here, Oracle took a fantastic, thriving open source project that doesn’t produce any revenue, and is squashing it over a pidily infrastructure tiff.  And they’re doing it in the worst way, by saying, basically, “I know this Java.net infrastructure is behind the curve, but we dictate that you should just suck it and use it anyway because we own the trademark.  So there.”  I can’t think of a faster way to kill a community that’s contributing freely.

Just get a clue please Oracle.  I’ve invested a lot of time in Java and would hate have to walk away from it completely.  As it is, I’m already steering greenfield stuff towards Ruby.  Maybe I should follow Nikita’s advice and learn Scala.

November 17th, 2010

Pizzigati Prize for Software in the Public Interest

by Tim Cull

There’s a little-known but lucrative prize out there for developers that make software that makes the world better: the Pizzigati Prize for Software in the Public Interest. Good to know sometimes the good guys win, too.

November 10th, 2010

New Article About Spring Social

by Tim Cull

So ever since I started writing for InfoQ, I’ve had a hard time keeping this blog up, too. But I promise I’ll hit the balance and manage to post to both. And soon.

In the mean time, I’m going to post highlights to my InfoQ stories here as well, just to keep things lively.

This week, I wrote a quick post about Spring Social, a new API from SpringSource to integrate Java applications with social networking sites. It’s pretty nifty, and using it feels a lot like using trusty old JdbcTemplate.

September 28th, 2010

Connecting Ruby to Microsoft SQLServer

by Tim Cull

There are many excellent posts out there about how to connect Ruby to Microsoft SQLServer. The problem I had is that none of them actually worked for me! So, I’m going to add my list of instructions to the noise in hopes it helps someone out there

The Setup

I’m using Windows 7 32-bit. The Ruby I have installed I got from http://rubyforge.org/frs/download.php/72075/rubyinstaller-1.9.1-p430.exe and looks like this:

ruby -v
ruby 1.9.1p430 (2010-08-16 revision 28998) [i386-mingw32]

Secondly, and this is very important, I have DevKit installed. I downloaded http://github.com/downloads/oneclick/rubyinstaller/DevKit-4.5.0-20100819-1536-sfx.exe and installed it according to the instructions on the DevKit wiki. Many of the tutorials out there neglect to mention that you must have DevKit installed in order to install some of the gems required.

The instructions I’m giving you here only work with *exactly* the setup I described. If you have a slightly different setup then this might not work. It’s very finicky. Even having a different one click installer can make it not work.

Step By Step From a Fresh Ruby Install

I installed my ruby to d:\Ruby191 with the one click installer. Then I extracted DevKit to d:\Ruby191\devkit and ran:


cd d:\Ruby191\devkit
ruby dk.rb init
ruby dk.rb review
ruby dk.rb install

When running “ruby dk.rb review” make sure it says it’s pointing to your Ruby install.
Next I downloaded dbi-0.4.3.gem, dbd-odbc-0.2.5.gem and ruby-odbc-0.99992.gem to my local file system.

Next, I ran exactly these commands. The versions and extra arguments matter!

set RUBY_HOME=D:\Ruby191
set LIBS=..\..\libs\ruby
gem install rake
gem install rubygems-update
gem install --include-dependencies rails
gem install deprecated --version=2.0.0 @rem the version matters. get exactly this one
gem install --local %LIBS%\dbi-0.4.3.gem
gem install --local %LIBS%\dbd-odbc-0.2.5.gem
gem install --local %LIBS%\ruby-odbc-0.99992.gem @rem this requires devkit

Lastly, I wrote this sanity check script and it worked:

require 'dbi'

# Replace MY_DSN with the name of your ODBC data
# source. Replace and dbusername with dbpassword with
# your database login name and password.
DBI.connect('dbi:ODBC:MY_DSN_NAME', 'username', 'password') do | dbh |
# Replace mytable with the name of a table in your database.
p "selecting getdate"
dbh.select_all('select getdate()') do | row |
p row
end
p "done"
end

So that’s it. Another of the many tutorials out there that will work on exactly one setup and probably not much more. Have fun!