Saturday, January 05, 2013

Smart Phone, Dumb Person

I joined the community of annoying smartphone people with the purchase of my Motorola Atrix HD Android phone.

I'm very happy with the phone, but I was surprised by the weird world of phone marketing I found when trying to decide which phone I should get. I started my search with a small set of requirements for the phone:

  • Android Jelly Bean
  • AT&T
  • preferably Motorola - just because they're based in my old home state of Illinois. I guess Apple and Motorola are the only American phone manufacturers these days.

Anyway - pretty simple, right ? What I expected to find was some web pages on the Motorola or AT&T web sites with a lineup of Motorola's Android phones something like the Apple Store's iPhone page. The iPhone has a great approach to marketing - there's just one iPhone product line with the flagship iPhone 5, and the older 4s and 4 available at a discount. I expected Motorola might similarly have a couple different phone lines based on size or feature set, and one or two older generations available at a discount. Sadly for Motorola - it turns out Motorola offers separate product lines for each carrier! I just found this page that nicely lays out their product lines, but I somehow didn't stumble upon that page during my phone search, and I was amazed by how many different (but very similar) phones Motorola designed and manufactured. Motorola's phone branding is crazy - RAZR is exclusive to Verizon (Verizon apparently owns the "DROID" brand trademark too from the old days where iPhone was AT&T exclusive), ATRIX is AT&T, Electrify for U.S. Cellular, Sprint gets the Admiral and Photon, Triumph for Virgin Mobile ... I think these are all actually different phones - not just the same no-brand phone with a different carrier logo.

Motorola's per-carrier marketing is just crazy. It's already hard for Motorola to distinguish itself from the other Android handset manufacturers (htc, Sony, Samsung, LG, ...); it's crazy that Motorola has to muddy down its own brand in some misguided strategy by the carriers to differentiate themselves from each other. Nobody switches from Verizon to AT&T (or vice versa) because one has a slightly better Android phone than the other.

Actually - it looks like Samsung might be in the same messed up phone-per-carrier boat. This carrier-branding mess must drive Google crazy. The iPhone was trail blazing in so many little ways that people forget (visual voice mail, apps, ...) - the unified (across carriers) "iPhone" brand was one I never considered.

scala 2.10 netbeans ant fix

I just upgraded the scala install on my laptop from 2.9.x to the latest 2.10.0 release candidate, and was depressed to discover that broke my crazy netbeans derived ant build scripts (ugh!).

> ant clean
Buildfile: C:\Users\pasquini\Documents\Code\littleware\WIP\littleware\webapp\lit
tleId\littleId\build.xml

config-check:

download-ivy:

install-ivy:

resolveIfNecessary:

-pre-init:

-init-private:

BUILD FAILED
C:\Users\pasquini\Documents\Code\littleware\WIP\littleware\webapp\littleId\littl
eId\nbproject\build-impl.xml:50: The following error occurred while executing th
is line:
jar:file:/C:/Program%20Files/Scala/scala-2.10.0-RC5/lib/scala-compiler.jar!/scal
a/tools/ant/antlib.xml:5: taskdef A class needed by class scala.tools.ant.FastSc
alac cannot be found: scala/reflect/internal/settings/MutableSettings$SettingVal
ue
 using the classloader AntClassLoader[C:\Program Files\Scala\scala-2.10.0-RC5\li
b\scala-compiler.jar;C:\Program Files\Scala\scala-2.10.0-RC5\lib\scala-library.j
ar]

Total time: 2 seconds

Fortunately - the fix was easy. Scala 2.10.x pushes some classes that its ant task depends on to a new scala-reflect jar file, so I added that to the classpath in one of the xml blocks in nbproject/build-impl.xml, and I was back in business:

        <property name="scala.compiler" value="${scala.home}/lib/scala-compiler.jar"/>
        <property name="scala.library" value="${scala.home}/lib/scala-library.jar"/>
        <property name="scala.lib" value="${scala.home}/lib"/>
        <taskdef resource="scala/tools/ant/antlib.xml">
            <classpath>
                <pathelement location="${scala.compiler}"/>
                <pathelement location="${scala.library}"/>
                <pathelement location="${scala.lib}/scala-reflect.jar"/>
            </classpath>
        </taskdef>

Anyway - scala 2.10 looks to be a great release. A lot of people are excited about the "macro" system, but I've been working with the new akka actors, and also look forward to playing around with the futures and promises APIs.

Saturday, November 24, 2012

National Dog Show

The National Dog Show was on NBC last night, and was a lot of fun to watch if you're a dog lover like me. It's great to see people with their pets in positive relationships, and having fun together.

Of course it's much better to adopt from a shelter or breed-rescue organization than to pay a breeder or (much worse) pet store for a dog or cat. So many beautiful animals are killed every year for want of a home - it doesn't make sense to pay money to add to the pet population rather than adopt an animal that needs a home. Many shelter dogs are purebreds or close relatives too. Anyway, the Humane Society has a great little article: "The Top 5 Reasons to Adopt".

Saturday, November 17, 2012

R.I.P. Twinkie

The NYTimes had an article the other day reporting the planned liquidation of Hostess under Chapter 7 bankruptcy. Management decided to throw in the towel blaming a a failure to negotiate a contract with one of its workers' unions.

Unfortunately the article did not cover Hostess' history of mismanagement including private equity backed mergers and debt loading (this Forbes article has more detail); so the article's comment stream collected many posts bashing the union.

I know nothing about Hostess or its history, but ignorance has never stopped me from offering an opinion - I'd never say anything otherwise. Here's a copy of the comment I posted to the article:

It looks like Hostess failed, because it failed to develop compelling products. Twinkies and Wonder were once trail-blazing brands. A popular snack can demand large markups, but today people don't want to eat twinkies at any price. Management deserves blame for failing to adapt to a changing market.

Many older companies (Sony, H.P., ...) suffer similar problems in their markets. The company has outlived its visionary founders, and is left to stock holders and M.B.A.s who see the company as a collection of assets to manage for optimal profit rather than a vehicle for realizing the founders' dreams.

Saturday, November 10, 2012

Running Windows 8

A couple weekends ago I took advantage of Microsoft's $40- Windows 8 offer, and have a spanking new operating system running on my workhorse Dell 1557 laptop.

Running W8 is like having a new machine! It's always fun to see what these monster software companies (Microsoft, Google, Apple) can crank out.

The OS does suffer from multiple-personality disorder. The "RT" personality for new full-screen apps is well suited for a touch-tablet user or a user that spends all her time in a single-window application - reading a web page or whatever.

Fortunately - W8 also still has its old "desktop" personality - which is where I spend most of my time when coding - switching between multiple open windows (IDE's, browsers, shells, control panel, ...).

For either environment - if you install Windows 8 on a standard (non-table or non-touch) laptop, then you'll want to become familiar with the new WinKey+ keyboard shortcuts. I was much more comfortable and productive with W8 once I became comfortable with the WinKey+Tab,C,L,R,X,Z shortcuts.

So W8 is a little bit of a Frankenstein with pieces of different creatures stitched together into a monster, but I like it. It's new, looks great, and is a brave first step in a new direction by Microsoft.

Saturday, August 25, 2012

scala companion package

I wrote a scala trait the other day with a "companion package" instead of the usual "companion object". I was pretty happy with how the code came together, so thought I'd write a quick post to my poor neglected bLog.

I often write a scala trait that defines an interface to some tool that manages access to a data repository or manipulates data in some way. I usually define the interface traits to different tools provided by some module "bla" in a "bla.controller" sub-package. I define bla's data model in a "model" sub-package, and classes that simply support a tool's interface in the tool's companion object, so something like this:

package bla
package controller

trait Tool {
    def get( id:String ):model.Data
    def search( query:String ):Tool.SearchResult
    ...
}

object Tool {
    case class SearchResult( query:String, matches:Iterable[model.IndexEntry] ) {}

    object SomeEnum extends Enumeration {
       val A, B, C = Value
    }

    trait Builder {
       var creds:Credentials = null
       def creds( value:Credentials ):this.type = {creds = value; this }
       
       var endPoint:URL = new URL( "http://default.end.point" )
       def endPoint( value:URL ):this.type = { endPoint = value; this }

       ...
       def build():Tool
    }

    /** Factory necessary if not running in IOC container - ugh */
    object Factory extends Supplier[Builder] {
        def get():Builder = internal.SimpleTool.Factory.get()
    }
}

Anyway - that pattern works great most of the time, but the other day I was working on a tool with several supporting types in the companion object, and the Tool.scala file was growing fatter than I like. Fortunately - it turns out we can accomplish the same semantics as a companion object with a companion package like this:

package bla
package controller

trait Tool { ... }

package Tool {
    // ...
    object Factory extends Supplier[Builder] { ... }
}

The companion package approach has the advantage that we can split out some of the types defined in the companion package to their own files, so we could have a bla/DataHelper/Factory.scala like this:

package bla
package controller
package Tool

object Factory extends Supplier[Tool] { ... }

The companion package can define "static" constants in a package object, and we can move the tool-specific implementation classes to its own bla.controller.Tool.internal package rather than the shared bla.controller.internal package.

Finally - changing companion object code to the companion package pattern does not require changes to client code (code that uses Tool) - just a recompile.

Anyway - I like the way things fit together with the companion package pattern.

Wednesday, May 09, 2012

Extra S3 log parameters with AWS Java SDK

Amazon web services' S3 REST API supports custom access log information by adding custom query string parameters beginning with "x-" that S3 ignores but logs. Unfortunately custom query parameters are not directly supported in the AWS Java SDK, so we were planning to drop down to writing HTTP REST code for a recent project that required logging of some custom client-session parameters.

I hate working with HTTP, so I was glad when we figured out a workaround. The trick we came up with was to register a custom RequestHandler with our instance of the SDK's AmazonS3Client. The RequestHandler is an internal class in the API, so it's not included in the API documentation, but you can download the source code to see its simple interface:

/**
 * Interface for addition request handling in clients. A request handler is
 * executed on a request object before it is sent to the client runtime
 * to be executed.
 */
public interface RequestHandler {

    /**
     * Runs any additional processing logic on the specified request (before it
     * is executed by the client runtime).
     *
     * @param request
     *            The low level request being processed.
     */
    public void beforeRequest(Request request);

 /**
  * Runs any additional processing logic on the specified request (after is
  * has been executed by the client runtime).
  *
  * @param request
  *            The low level request being processed.
  * @param response
  *            The response generated from the specified request.
  * @param timingInfo
  *            Timing information on the request's processing.
  */
    public void afterResponse(Request request, Object response, TimingInfo timingInfo);

 /**
  * Runs any additional processing logic on a request after it has failed.
  *
  * @param request
  *            The request that generated an error.
  * @param e
  *            The error that resulted from executing the request.
  */
    public void afterError(Request request, Exception e);

}

So the RequestHandler's beforeRequest method can add parameters to a Request before it is processed by the underlying HTTP engine. The only trick is to determine which parameters to add to a particular Request, but it's easy to extend the SDK's API-level request objects (like S3's GetObjectRequest) with subtypes that add application-specific properties, then check for for those subtypes in the RequestHandler via the getOriginalRequest accessor.

Oracle Google Comments

For some reason I was inspired today to post a comment on the NYTimes Bits bLog's post on the Oracle-Google lawsuit. I thought I didn't make it through the Time's idiot filter, but they actually put my comment online. Crazy. Here it is again:


I think Google got itself into trouble, because rather than simply build on top of java (write code with the java language and libraries), and contribute to the java community; Google decided to "fork" java to make its own language that is nearly identical to java, but with various differences (security model, libraries, bytecode) at a time (pre-openJDK) that java was not open sourced. Often non-UI code (networking, database, ...) written in java can be easily recompiled for Android's "Dalvik" runtime, so Google gained instant access to the java developer community and programming tools; but the two systems are not the same.

There's something slimy about what Google did - forking java for Android without respecting the time and money Sun invested. Sun Micro sued Microsoft years ago when Microsoft released a version of java with incompatibilities to improve java on windows. Google was very careful to never call Android's runtime "java" to avoid the issues Microsoft ran into, but everybody thinks of Android as running java. Google should have just bought Sun Micro when it had the chance ...

Oracle is slimy too for trying to insinuate itself into the Android smart phone and tablet market. Oracle and Sun didn't have the vision of Apple, or the skill to imitate Apple quickly like Google; so now Oracle is trying to sue its way into the market.

Anyway - the best outcome when two corporate monsters fight is that they both get cut up and bleed ... ;-)

Friday, April 13, 2012

Steve Jobs - what a jerk!

I read Isaacson's Steve Jobs biography a couple months ago, and really enjoyed the read. One thing that surprised me - although I guess it's well known - was what an asshole Jobs was. He was just a really mean and selfish guy a lot of the time.

Of course Jobs was an amazing success on many levels, so everyone forgives him for being a jerk, and many argue that his acrimony contributed to his triumphs. On the other hand, many people also espouse the "No Asshole Rule" of management - which also makes sense, but it's ironic that a typical supported of the no asshole rule is an asshole.

Anyway - I think it's healthy to have at least one asshole; otherwise you wind up full of shit.

Tuesday, January 31, 2012

iptables NAT port forward 443 (https) to 8443

I recently wanted to setup port forwarding on an Ubuntu Linux server (AWS EC2) to redirect https traffic (port 443) to a Tomcat server listening for SSL connections on port 8443. I really did not want to learn anything about UFW or iptables - I just wanted to setup the forwarding and get on with my day, so I proceeded to Google away and read man pages and finally figured out the following commands after learning more than I wanted to learn - which was a complete waste, because I'll forget it all anyway:

sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-ports 8443

sudo iptables -t nat -A OUTPUT -p tcp --dport 443 -o lo -j REDIRECT --to-port 8443

The first command adds (-A) a rule to iptable's PREROUTING table to redirect incoming packets bound for port 443 over to port 8443. The second rule adds a similar rule to the OUTPUT table that redirects packets outgoing to port 443 on the loopback interface (-o lo).

Of course there's another trick - those rules disappear on reboot unless we save them somewhere. If you're running UFW, then add the rules to /etc/ufw/before.rules. Otherwise one solution is to install the iptables-persistent extension (on Ubunutu: sudo apt-get install iptables-persistent), and save the rules to /etc/iptables/rules.v4.

I hate this sysadmin garbage ...

Wednesday, January 25, 2012

Simple Session Scope with Guice

I've been a big fan of the Guice dependency injection library for a while, but I missed support for session-scoped injection until I figured out a way to achieve the same effect using child injectors. I was inspired by the PicoContainer project that I stumbled upon several months ago. I haven't actually used PicoContainer, but it appears to actually be better thought out than Guice - implementing arbitrary dependency injection scopes and lifecycle management via hierarchies of IOC containers.

I had PicoContainer's hierarchy approach bouncing around in my head when I stumbled up Guice's createChildInjector method - which supports a similar approach to managing object scopes.

Long story short - I introduced the notion of a "SessionModule" that defines session-scoped bindings to littleware's module system in my development repository clone. Littleware's module system also uses OSGi in an unorthodox way to manage the application life cycle. I wish I would have known about PicoContainer earlier - it appears to implement a nice approach for a combined IOC and application life cycle container. At some point I need to take a look at Spring too - to steal ideas if nothing else!

Sunday, January 08, 2012

Youtube to the rescue!

I have this old yellow Kitchenaid blender that has been sitting in the cabinet collecting dust for the past year or so after the rubber coupler that mates the motor base with the pitcher's blade impeller melted when I left hot soup in the pitcher for too long. It was so frustrating to have this appliance with working motor useless from a melted piece of rubber - what a piece of garbage! I tried some ridiculous jerry rigs, tried to remove the part, googled "busted blender", and eventually just stuck the thing in a cabinet disgusted.

Anyway, happy ending, yesterday I was thinking again about the damn blender after watching America's Test Kitchen make some awesome gazpacho - trying to figure out how I could puree without a food processor or blender, when I decided to google "kitchenaid blender coupler" - something like that, and discovered a community of pissed off blender owners and their relief at discovering how to repair the busted rubber coupling! This YouTube video shows how to remove the part, and Amazon sells a replacement.

I'm waiting for my new coupler to arrive in the mail. I can't wait to give the repaired blender a try. It's like I'm getting a new blender for Christmas! I'll probably wind up blending my hand off or something like that now ... blood smoothie!

Thursday, November 24, 2011

Escaping Java classpath wildcard on Windows command line!

I had a ridiculous battle with a set of .bat scripts that I wrote to launch java command line applications on Windows. I'm working on a suite of related little tools that I bundle into a zip file with a bunch of .jar files under a /lib/ folder, and launch scripts under a /bin/ folder that each look something like this:

@echo off

if not defined JAVACMD set JAVACMD=java.exe
if defined JAVA_HOME set JAVACMD="%JAVA_HOME%\bin\java.exe"

%JAVACMD% "-Djava.util.logging.config.file=%~dps0..\config\logging.properties" -cp "%~dps0..\lib\*" run.my.App %*

So I'm trying to use the nifty java classpath * wildcard introduced with java 6, but I had a terrible time with windows insisting on expanding /lib/* in the shell regardless of how I tried to quote or escape the thing! I was driving myself crazy, when I finally got the genious idea to just add a semicolon, so /lib/*; doesn't look like a path to Windows Powershell or CMD (I guess), and the following works:

@echo off

if not defined JAVACMD set JAVACMD=java.exe
if defined JAVA_HOME set JAVACMD="%JAVA_HOME%\bin\java.exe"

%JAVACMD% "-Djava.util.logging.config.file=%~dps0..\config\logging.properties" -cp "%~dps0..\lib\*;" run.my.App %*

What an amazingly stupid waste of time!

Sunday, October 23, 2011

Java RMI over SSL and a single port

I was lucky with my latest freelance contract that the clients were happy to build on littleware to implement some of their back-end services, and they let me bill a little time to implement a few features - like securing the RMI-based procedure-calls over SSL. Fortunately java includes an RmiSSLSocketFactory, but there are a few integration tricks.

I outlined in a previous post how to configure RMI to export all its objects over a single firewall-friendly port. That was easy to do once I knew the trick. Unfortunately SSL has a few moving parts - some of which I disabled as I really just want the data going over the wire encrypted, and am less concerned over end-point certificate verification.

Anyway, in the end it's not too complicated - it's just a matter of knowing the tricks - which are annoying to track down. Most of the code is in littleware's LittleRemoteObject class that specializes java's UnicastRemoteObject. The server builds a RmiSSLServerSocketFactory using an SSLContext that loads a certificate from a keystore on the classpath. The client builds and RmiSSLClientSocketFactory with a no-op TrustStore that bypasses verification of the server's certificate.

One final trick - the server boots up its own RmiRegistry with its custom RmiSSLServerSocketFactory, and the client connects via LocateRegistry.getRegistry - which accepts the client's socket factory - (littleware's RemoteRetryHelper implements the client's connection). Littleware's client actually exposes its own API that integrates a cache and authentication building on top of the service API that the server exposes via RMI (I'm working on a REST implementation).

Anyway - a boring post about a technology nobody uses. Sweet!

Friday, September 09, 2011

Mishaps and Disasters

The last month and a half has been a parade of mishaps and disasters. The morning of July 27 I was looking forward to my flight out to California where I would join my old friends for a camping trip in the eastern Sierras. Our three dogs and I were walking through the front yard as we returned from our morning walk when we all realized we were being attacked by freakin' yellow jackets. I usually get along fine with stinging insects, but yellow jackets are freakin' mean if they decide you're too close to their nest, and we had a freakin' nest in some gopher holes in the front yard. Yellow jackets can sting repeatedly, and they do sting repeatedly - it's not like "sometimes they sting repeatedly, but usually just once" - I mean they just latch onto you, and repeatedly sting - freakin' mean! The dogs freaked out, but we managed to run to the back yard, and I spent the next hour dressed up for a Chicago winter in Alabama July trying to drown and burry that freakin' nest.

Anyway, we survived, and I was glad when I was finally sitting uncomfortably in coach flying to LAX. My friend Hiro organized a 4 day (3 night) backpacking trip. I packed light - just a few changes of cloths and enough food to keep me hiking through the freakin' arid eastern Sierras in late July. Hiro set me up with a tent and sleeping bag, and I rented a pack. We drove up 9000 ft outside of Bishop, and started hiking. I was such an idiot. Everybody got altitude sickness the first day - freakin' headaches and exhaustion, but that comes with the territory, and we made it over a high ridge the first day, and were on our way the second day on a much less taxing hike. By mid afternoon we were getting rained on pretty steadily, but I thought, "no problem, nice summer rain", but there's no such thing as a nice summer rain above 10000 feet. The rain didn't stop, then it turned to hale, and it got cold! Freakin' cold, and I was not the only one not prepared for rain or cold. Finally my friend, Mike, decided to hell with it, and put up his tent - by then it was a freakin' down pour of freezing rain that had been getting worse for hours. I was shaking like a leaf. Fortunately, my other friend, Steve, got his tent up, and let me crawl in. We both dove into our sleeping bags, and I felt much better for a while, but soon I was freezing again, and Steve noticed, "you don't have a matte under your bag ?". Frick - I just had the bag Hiro gave me. Freakin' Steve saved my life letting me sit on his matte. We sat with our faces jammed into the tent wall for about an hour when the rain finally stopped. Steve let me crash in his tent that night, and Hiro lent me an extra matte, so all was well, but we were all pretty annoyed when it started raining the next night, and I was especially upset, because my tent leaked. I was freakin' miserable in this mini tent with puddles all around me, but my friends, Stewart and Chika, took pitty on me, and I squeezed in with them. Everyone on that trip must hate me now.

So fun trip, and I made it home, and all was cool for a week or two, when Joanne's poor Aunt died, and we drove to Atlanta for the funeral - leaving our dogs at the kennel. We have three dogs that I love and spend a ton of time with, but they don't get along all the time, especially Ponzi and Moose, and especially when squeezed in close quarters - like our Volkswagon hatch-back driving to the kennel. We have a crazy system where Ponzi sits in the front passenger seat, and we have this fence thing separating the front seats from the back, and Joanne, Moose, and Shugs sit in the back. Anyway, that worked pretty well, and we made it to the kennel ok, and the dogs were all excited and nervous. I put Ponzi on the leash, and circled around back to let Moose and Shug out, and there's some confusion, and the next thing Ponzi and Moose were trying to bite each other's head off - literally. There's a lot of luck involved in separating two fighting dogs without coming away bleading yourself, but somehow I managed it. I noticed Ponzi holding his head to the side, but didn't see any obvious injury, so we left the boys at the kennel, and went to Atlanta for some family drama. Next afternoon we headed back, and found Ponzi with a very red eye - Moose must have got a tooth into Ponzi's eye. Freakin' mess. Fortunately Joanne got through to the Auburn Vet School, and Dr. Newcomer was good enough to let us squeeze in an appointment just after closing time. Ponzi's eye was ok - the surrounding tissue was injured, and Newcomer set us up with some eye ointment to help him heal. Soon after that I noticed we had a new nest of hornets in another gopher hole in the front yard. What the frick ?

Finally, Ponzi healed up, and I took the dogs to the park to run around - we did that twice a week. Kiesel park is a really cool park in Auburn. It used to belong to some farmer named Kiesel who raised cattle. I guess he donated the land to the city, and it's a great park with a cow fence all the way around, a little pavilion for concerts, a few miles of walking path along the parks edge, and several little woods separating parts of the path. Unfortunately, Shug has a love for going where he's not supposed to go, and a gift for finding gaps in the fence, and sure enough - soon after we arrived he ran across a stream, and under the fence, and into the woods across the street. I followed, and so did Ponzi. I nearly caught up with him when Shug decided to walk out into the road - in front of a GMC Jimmy. The next hour was a mess. Shug survived the accident - dragging himself to the side of the road. I tied him up there, so I could get the car, dragging Ponzi along and yelling for Moose, but when I drove back I couldn't find Shug - he had hidden in some bushes. Fortunately Moose showed up, and found Shug for me. I lifted my poor broken and bloody dog into the back of the Jeep. Moose and Ponzi amazingly didn't fight, and we headed to the vet school. I think it was only about 7am, but the vet school has an emergency service, and they took Shug in. I was a freakin' mess. Long story short, the vets were able to save Shug. He had a fractured right femur and another fracture on the left side of his pelvis, but the orthopedics crew was able to do some magic with a bunch of steel rods, pins, screws, wires, and plates. Shug is three weeks along his way to recovery now - so far so good. I enjoy keeping him company - writing code at the table next to his crate; hiding from whatever else is coming my way.

Oil Buffet

The other day I listened to a short discussion on the PBS News Hour podcast about the proposed oil pipeline from the Alberta tar sands mines to feed our oil hunger here in the U.S.A. The news hour likes to have little mini debates where they have a spokesperson from each side sit down and talk about an issue. The whole tar sands thing and global warming in general boils down to whether we should risk our environment for the economy, or risk the economy for the environment. Of course if the environment goes to hell, then the economy is screwed anyway; and the tar sands wouldn't be viable if the cost of a gallon of gas wasn't already heading north of $4, but whatever.

Anyway - one thing the pro-pipeline guy said (and many others too about this and similar issues) that frustrates me is that the Alberta tar sands will be developed whether the United States consumes the oil or not - the oil will just go to other markets, so we might as well take the oil, because there's no stopping China and India or wherever. I mean per capita we consume over 5 times the amount of energy as China, and 10 times the energy of India (thanks, Wikipedia!). Sure there are a lot more Chinese and Indians, but since we led the way to our energy-fat lifestyle; we ought to also lead the way to a more sustainable future. The cost of energy will go up, and we'll have to change the way we do things, but we'll be better off in the end.

The picture I have in my mind is of big old fat America at the energy buffet - freakin 500 pound energy fatty half blind from diabetes, blood pressure through the roof, butter for blood, zooming around the buffet in one of those fat-people scooters, because America can't walk more than a few steps without getting winded. So fatty America has already eaten 5 times the amount of food as any of the skinny Chinese at the buffet, and ten times more food than any of the Indians; but America is getting pissed off, because the buffet is starting to run out of food, and even though any one Chinese or Indian has eaten a lot less food than America, when you add up all the food that all the Chinese and Indians have eaten - that almost competes with the amount of food America has eaten, and America needs that food! Freakin' China and India! Now America notices Canada just set a giant chocolate cake on the buffet table. Is America going to freakin' go on a diet and start exercising and let China and India and Europe have the freakin' cake ? No way, baby!

Tuesday, July 26, 2011

Writing the Congressman

I got a little fired up about the debt ceiling nonsense, and decided to e-mail my Congressman, Mike Rogers. I always feel so empowered after writing a politician - which is ridiculous, because it has never made a difference.

Hello Congressman!

I'm writing today to complain about your part in the House majority's role in taking the United States to the brink of default. I cannot take your "Cut, Cap, and Balance" bill seriously. It is exactly in times of economic recession that we need the federal government to run a deficit - lowering taxes, bolstering the social safety net, and absorbing the lost revenue from a diminished tax base. Our short term debt increase is a result of the economic downturn and stimulus spending; it is not a result of "out of control" spending. Our long term debt mostly results from the projected increase in medicare spending. I know you understand this, so I find your press announcements disingenuous.

The debt ceiling should be raised as a matter of course, and not used as a gun to the nation's head to push through the minority agenda. Please do your part to ease the debt-ceiling grid lock. It would be great while your at it if you could help restore funding to the FAA, and contribute to the plans to save the postal service from bankruptcy.

Thanks for your service.

Cheers,
Reuben Pasquini

Sunday, July 24, 2011

Giving GWT a try

When I decided to implement a webapp browser for littleware's node database I began a debate with myself whether to implement the project in javascript or to give GWT a try. I have a little experience with javascript - I've enjoyed working with YUI on several projects, but javascript really sucks - no strict type checking, no module system, weirdo prototype object system ...

On the other hand - I feel like if I'm going to build a browser-based application, then I should develop with web technologies - javascript, HTML, CSS, ... It's great that GWT let's me develop in java, but it's a weird technology - not javascript, not really java - it's its own thing, but GWT is open source, has a community, is used and sponsored by Google (this blogger editor uses GWT), so might as well give it a try.

Anyway, I downloaded GWT and Eclipse, and was quickly running the demo application that the GWT Eclipse plugin creates in a new project. The demo is great for demonstrating GWT's remote service infrastructure and asyncrhonous support, but the simple UI assembly does not take advantage of GWT's new declarative UIBinder infrastructure. I want to use that UIBinder mojo, so I decided a good first task would be to refactor the demo to use UIBinder. I had a few false starts and a few different parts, but one part of the code replaces this html segment:


...
    <table align="center">
      <tr>
        <td colspan="2" style="font-weight:bold;">Please enter your name:</td>        
      </tr>
      <tr>
        <td id="nameFieldContainer"></td>
        <td id="sendButtonContainer"></td>
      </tr>
      <tr>
        <td colspan="2" style="color:red;" id="errorLabelContainer"></td>
      </tr>
    </table>
    ...
, and this java code:
	public void onModuleLoad() {
		final Button sendButton = new Button("Send");
		final TextBox nameField = new TextBox();
		nameField.setText("GWT User");
		final Label errorLabel = new Label();

		// We can add style names to widgets
		sendButton.addStyleName("sendButton");

		// Add the nameField and sendButton to the RootPanel
		// Use RootPanel.get() to get the entire body element
		RootPanel.get("nameFieldContainer").add(nameField);
		RootPanel.get("sendButtonContainer").add(sendButton);
		RootPanel.get("errorLabelContainer").add(errorLabel);
                ...
         }
with this UIBinder XML:
...
	<g:HTMLPanel>
		
    <table align="center">
      <tr>
        <td colspan="2" style="font-weight:bold;">Please enter your name:</td>        
      </tr>
      <tr>
        <td> <g:TextBox ui:field="nameField" /></td>
        <td> <g:Button ui:field="sendButton" /></td>
      </tr>
      <tr>
        <td colspan="2" style="color:red;"> <g:Label ui:field="errorLabel" /></td>
      </tr>
    </table>
		
	</g:HTMLPanel>
   ...
that pairs with this code:
public class DemoPanelView extends Composite {
	private static DemoPanelViewUiBinder uiBinder = GWT
			.create(DemoPanelViewUiBinder.class);

	interface DemoPanelViewUiBinder extends UiBinder<Widget, DemoPanelView> {
	}

	@UiField
	public Label errorLabel;
	@UiField
	public Button sendButton;	
	@UiField
	public TextBox  nameField;
...
Anyway I'm having fun with GWT, so I'll try to implement the database browser in GWT until I run into something that stops me ...

Sunday, July 03, 2011

Powershell Tabexpansion

There must be a better way to do this, but one of the funny things I do is setup variables in Powershell for paths that I frequently navigate to. So my profile.ps1 file has lines like this:
$GLOBAL:g1 = "C:\whatever\some\path"
$GLOBAL:l1 = "C:\whatever\some\other\path"
, and I issue a lot of commands like cd $g1
ls $l1
cp $l1/bla $g1
... that kind of thing.

One thing that drives me crazy is that I often want to do something with a sub-directory or file under a path referenced by one of my jump variables, but Powershell tabexpansion won't expand the variable for me ... until now! I finally decided to look into how to customize Powershell's tab expansion, and sure enough there's a TabExpansion function that I can override. This bLog post has the details.
Anyway, I defined my own TabExpansion function in profile.ps1 with a patch that just adds one line to the default function. The default has this regex-switch case that expands variable names:

            foreach ($_v in Get-ChildItem ($_varName + '*') | sort Name)
            { 
                $_nameFound = $_v.name
                $(if ($_nameFound.IndexOfAny($_varsRequiringQuotes) -eq -1) {'{0}{1}{2}'}
                else {'{0}{{{1}{2}}}'}) -f $_prefix, $_provider, $_nameFound
            }
, and my patch just adds a line to the end of the loop that also returns the value of the expanded variable:
            foreach ($_v in Get-ChildItem ($_varName + '*') | sort Name)
            { 
                $_nameFound = $_v.name
                $(if ($_nameFound.IndexOfAny($_varsRequiringQuotes) -eq -1) {'{0}{1}{2}'}
                else {'{0}{{{1}{2}}}'}) -f $_prefix, $_provider, $_nameFound
                $_v.value
            }
Now when I enter 'ls $g', then for each tab Powershell scrolls through a series of possible expansions: $g1, value of $g1, $gr, value of $gr, then back to $g1. If I want to list some sub-directory of $g1, then when the value of $g1 shows up, I just enter a '/' and start tabbing again to find the sub-directory. Hopefully that makes sense. Let me know if there's a better approach!

Saturday, June 04, 2011

Quick Powershell Background Function

My blogging energy is way low these days, but I'm forcing myself to throw together a quick post - whipping myself like that crazy albino masochist monk assassin in the DaVinci Code.

First, here's a handy function to change the background color of a powershell terminal. Just throw it into profile.ps1, and you're all set to colorMe 'DarkGreen' or whatever. I found the code at http://technet.microsoft.com/en-us/library/ee156814.aspx.

function colorMe( $color ) {
    (Get-Host).UI.RawUI.BackgroundColor = $color
}

Next, I'm working on a project now that involves a little SVG, and I was surprised to discover that my NetBeans IDE didn't recognize the file type. It turns out that NetBeans' SVG support is in its Mobility extension, so I'm all set now after installing that.