I only tell you what to do because I love you

Intelligentsia to release Anticon-inspired coffee: http://bit.ly/97GuWG . If I drink this, does it mean I can rap like doseone? [jeff_devine]

Enterprise Software will not be missed

On Wednesday, I’m on a call with Big Vendor #1, and they are very interested in expanding their business with my employer. They are sure that upgrading to their premium API makes sense, so I ask my typical line of “techie” questions about REST vs SOAP and I get the typical, “We’ll talk to our tech people and get back to you.”

In their follow-up email, they send me a high-level PowerPoint and provide a URL I should “send to my techies and see what they think.” Clearly I must not know my ass from a compiler.

On Thursday, I’m in a meeting with Even Bigger Vendor #2, and they are very interested in expanding their business with my employer. Surely using their newly acquired rules engine will solve all my company’s risk-management needs. My concern that they were providing a technological solution for a business problem that doesn’t exist didn’t stop them at all. They spent the rest of the meeting speaking down to me as if I was clearly a techonlogist who could never understand “Real World” business problems.

My years of experience in P&C Insurance and intimate knowledge of my company’s problems were trumped by Vendor #2’s countless years selling Websphere to investment banks.

Both vendors followed up the very next day, eager to know how soon we could move forward. Neither vendor took the time to get to know me, my place in the company and what I could offer to better position them. Why would I ever give them the keys to the kingdom?

When it comes to vendors, relationships are everything. An Enterprise Software company, whose only connection to a customer is its army of faceless, apathetic sales team, will not survive in the long run.

Anyone with an idea, a credit card, and the passion to succeed has access to world-class infrastructure. Regardless of your opinion of what cloud computing is or is not: it is a new paradigm, giving anyone the ability to compete on the same level as established players.

It isn’t the silver bullet nor does it guarantee success, but it does change the game. It will take time, years perhaps, but the Enterprise Software industry doesn’t stand a chance.

Acquisitions may buy you people and technology, but you can never acquire agility or passion.

The Cloud Computing Consultant

Hilarious video about the state of cloud computing. It’s certainly a little inside baseball, but if you follow this stuff, you’ll love it.

Simple-Build-Tool or: How I RTFM and stopped hating on Maven

Tonight I was supposed to see WHY? at Le Poisson Rouge but for some completely unknown reason, I felt I would be better served staying in and working.

I’m trying to prototype a Scala-based REST API that gets called by a GWT front-end. My Scala is extremely weak but Martin Kleppmann’s Yes/No/Cancel had a great write-up accomplishing the aforementioned task using Jersey and Scala. Unfortunately for me, I’ve mangled my java environment trying to get GWT to run on Snow Leopard and I was having no luck getting Martin’s Maven POM to work.

Already regretting my decision to pass on the concert, I wasn’t going to waste my entire night cursing at Maven. Instead I took this opportunity to use Martin’s examples but apply them to Simple Build Tool. The following is how I RTFM and started learned how to use SBT. I’d love feedback so please look it over or follow along and let me know if there is a better way to go about this.

First, start a new project by creating a directory for the project and running sbt from within this new directory. When SBT is run with no action specified and it doesn’t detect a project structure, it prompts to create a new project. I used the following, mostly taking the default values:

     Name: api
     Organization []: com.jeffdevine
     Version [1.0]:
     Scala version [2.7.5]:
     sbt version [0.5.3]:

The initial process downloads any dependencies needed and creates a default project structure:

    lib/
    project/
          boot/
          build.properties
    src/
          main
              resources/
              scala/
          test
              resources/
              scala/
    target/

My initial needs for prototyping the REST API are Jetty and Jersey, so I configured SBT to manage these dependencies by adding the file ./project/build/ApiProject.scala (note: build is a new directory):

import sbt._
 
class ApiProject(info: ProjectInfo) extends DefaultWebProject(info)
{
   val snapshots = "Java.net Repository" at "http://download.java.net/maven/2/"
   val jetty6 = "org.mortbay.jetty" % "jetty" % "6.1.14" % "test->default"	
   val jersey = "com.sun.jersey" % "jersey-server" % "1.1.2-ea" % "test->default" 
   val jsr311 = "javax.ws.rs" % "jsr311-api" % "1.1-ea" % "compile->default"
}

From the SBT interactive session, execute reload to recompile the project definition and update to download all the specified dependencies.

Back to Martin’s example, I slightly modified his Scala code and saved it in ./src/main/scala/Hello.scala:

package com.jeffdevine.api
import javax.ws.rs._
 
@Path("/hello")
class Hello {
  @GET @Produces(Array("text/html"))
  def doGet = "<html><body><p>Hello? You could be seeing Why? right now...</p></body></html>"
}

The last bit is to tell Jetty what to do by creating a file in ./src/main/webapp/WEB-INF/web.xml (note: you’ll need to create the directory structure webapp/WEB-INF):

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  <servlet>
    <servlet-name>Example REST API</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>com.sun.jersey.config.property.packages</param-name>
      <param-value>com.jeffdevine.api</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Example REST API</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
  <session-config>
    <session-timeout>30</session-timeout>
  </session-config>
</web-app>

Back in SBT, execute jetty-run, and within a few seconds, jetty is serving the API on http://localhost:8080/hello. Firing off a GET request returns the HTML

     Hello? You could be seeing Why? right now...

Executing jetty-stop will kill the server, and jetty-restart restarts jetty, picking up any code changes.

While this is a basic example that could use a test case or two, it has given me what I need to start prototyping and I no longer feel like a schmuck for skipping tonight’s concert… which would have gone something like this: