Friday, September 24, 2010

Disabling JSESSIONID in Jetty context XML

The following snippet shows how to deploy a web application/.war via a Jetty context XML file with JSESSIONID disabled.

<Configure id="cs" class="org.mortbay.jetty.webapp.WebAppContext">
  <Set name="contextPath">/</Set>
  <Set name="war">/foo/bar/myapp.war</Set>
  <!-- Turn off JSESSIONID -->
  <Get id="sh" name="sessionHandler"/>
  <Ref id="sh">
      <Get name="sessionManager">
          <Set name="sessionURL">none</Set>
      </Get>
  </Ref>
</Configure>

To be clear: you'd save this as foo.xml and place it in $JETTY_HOME/contexts and your app would be deployed.

If you want JSESSIONID disabled when working with the maven-jetty-plugin or when embedding Jetty, check out Alex's post on removing JSESSIONID.

Saturday, September 18, 2010

Used Car Research: TrueDelta

A friend recently pointed me to a great site for used car reliability information called TrueDelta. These guys collect repair and fuel economy data from over 70,000 cars around North America. From this data they publish a realistic picture of how cars truly perform out in the wild. The data is updated quarterly, so you always have an up to date picture on how a car performs. Really cool idea.

Anyone with a car can join and contribute data to the research. If you're participating, you get free access to all the reports, so it's well worth it. It takes a minute or two to join, and a minute or two each quarter to submit some basic data (number of repairs, odometer, etc.). It's not a big time investment, and the reward could be very valuable next time you're buying a car. If you don't want to participate you can buy your way in for cheap, too.

Sign up today and make more informed decisions next time you have to buy a car.

Wednesday, September 15, 2010

Using a custom WebAppClassLoader in Jetty

I recently ran into a situation where I wanted to log details about what Jetty's class loader was doing for one of our web apps. There is a hook in WebAppContext to provide your own WebAppClassLoader implementation, which was just what I needed, so I proceeded to write LoggingWebAppClassLoader (source below). The trouble was: where do I actually get a chance to insert my custom implementation?

It's easy enough to do this if you're embedding Jetty in your app:

// Scala code 
val context = new WebAppContext()
val lwacl = new LoggingWebAppClassLoader(context)
context.setClassLoader(lwacl)
...

Unfortunately we're not embedding, but just deploying a .war to an existing Jetty server. I messed around with this at length, and eventually asked on StackOverflow. The answer there got me on the right path, though I had a few other issues along the way.

Here's how I got it working:

  • Changed my deployment technique to Jetty's context deployer ($JETTY_HOME/contexts) instead of just copying .war files into $JETTY_HOME/webapps.
  • Wrote myapp.xml (see below) to define the context. It's in here that you can configure Jetty to use the custom WebAppClassLoader.
  • Copied the jar file containing my LoggingWebAppClassLoader class into $JETTY_HOME/lib so the class is available to the context deployer.

Of course it seems pretty straight-forward now that I've figured it out :) The biggest issue was that I didn't know much about deploying via Jetty contexts. They seem to have a lot of advantages over the vanilla war deployer in that you can easily tweak any Jetty internals at deploy time. Downside is "programming" in XML...

myapp.xml (Jetty context):
<Configure id="mycontext" class="org.mortbay.jetty.webapp.WebAppContext">
  <Set name="contextPath">/</Set>
  <Set name="war">/foo/myapp.war</Set>
  <Set name="classLoader">
      <New class="fully.qualified.name.LoggingWebAppClassLoader">
          <Arg><Ref id="mycontext"/></Arg>
      </New>
  </Set>
</Configure>
LoggingWebAppClassLoader.java:
import java.io.IOException;
import org.mortbay.jetty.webapp.WebAppContext;
import org.mortbay.jetty.webapp.WebAppClassLoader;

public class LoggingWebAppClassLoader extends WebAppClassLoader {
  public LoggingWebAppClassLoader(ClassLoader parent, WebAppContext context) throws IOException {
      super(parent, context);
  }
  public LoggingWebAppClassLoader(WebAppContext context) throws IOException {
      super(context);
  }

  private void log(String s) {
      System.out.println(s);
  }

  @Override
  public void addClassPath(String classPath) throws IOException {
      log(String.format("addClassPath: %s", classPath));
      super.addClassPath(classPath);
  }

  @Override
  public Class loadClass(String name) throws ClassNotFoundException {
      log(String.format("loadClass: %s", name));
      return super.loadClass(name);
  }
}

Saturday, September 11, 2010

Monit notifications using Google Gmail SMTP

I had to do a bunch of fiddling around to figure this out, hence a quick blog post.
The situation: I want monit to send me email notifications and I don't have (or want) an SMTP server running on the box. Furthermore, like many ISPs, my ISP won't allow outbound connections to port 25 anyway.
Solution: as a Gmail user, I can use Google's SMTP servers for sending mail.
You need monit version >= 4.10 for this to work. I got it working on Ubuntu Jaunty 9.04 and Lucid 10.04 just fine. Here is the set mailserver syntax to make it happen:
set mailserver smtp.gmail.com port 587
    username "someuser@gmail.com" password "password"
    using tlsv1
    with timeout 30 seconds
References:

Thursday, September 2, 2010

How to sell a used car in Ontario

I recently sold my car privately. I thought I'd write about the process to help others, or to help myself if I need to refer back some day. The government has lots of info on the process, but sometimes a real person's experience is still useful.

Background:

  • I live in Ontario, so this is all Ontario-centric
  • I had no liens against the car
  • The car was in excellent condition (not a salvage or rebuild)

The steps I took to sell the car:

  1. Got the UVIP from the Government
  2. Cleared up lien issue
  3. Made a "brochure" page with detailed info about the car
  4. Posted ads
  5. Received responses; found a buyer
  6. Preparation for final sale
  7. Completed sale

UVIP

The UVIP is an official document showing that you own the car, and whether there are liens against the car. It also provides a "bill of sale" page that you fill out to complete the sale. The UVIP took about five days to arrive, but they say to allow two weeks. I ordered mine online, but you can also walk into a ServiceOntario location. It's $20.

One piece of info that the UVIP mentions is the "brand" (not to be confused with "make", e.g. Toyota) of the car. My buyer asked what that meant, so you may want to familiarize yourself with it. In short, it says whether the car was ever severely damaged and then rebuilt. If your "brand" is something other than "None", you probably need to be very aware of it. Details here.

Liens

I initially had a car loan, but it was paid off some time ago. The UVIP, however, still showed that GMAC had a lien against my car! I was surprised about this. I called up GMAC and got them to issue a letter stating that they had no further interest in the car, and they did that. I think this is a common practice. It may be (speculation) that they don't bother clearing the lien when you're done paying. Anyway, keep this in mind since it added another week of waiting around for documentation.

Brochure Page

Because I am a nerd, I made a simple Google Sites page listing all the details I could think of about the car, a bunch of pictures, the price, and how to contact me. I sent this to all interested buyers, and on Facebook, etc. This is obviously an optional part of the process, but it may help market the car, and should at least save you typing up answers to the same questions each time someone contacts you.

Posting Ads

I posted ads on two services: Kijiji and Auto Trader (trader.ca). Both are free, but Kijiji is the far superior experience, in my opinion. I got way more "leads" from Auto Trader, but at least 50% of them were scammers. I eventually sold the car through Kijiji.

AutoTrader side-rant

AutoTrader is frustrating. Your ad is only up for seven days or so before it silently expires. Eventually, someone from a call centre phones you up to try to upsell you to the AutoTrader print version. They wanted something like $140 to put my ad in the print version! I politely declined. In their defense, you can re-post your ad online over and over again for free, suffering only the inconvenience.

The biggest frustration was that each time I posted my ad it was rejected at least once before finally being admitted. The first time I tried it was my fault: I tried to put a link in the ad, which they don't allow. Subsequent attempts to post it were rejected stating it was a dealer ad. I couldn't figure this out at first, but eventually I realized what it was: I mentioned the name of the dealership where I bought the car years earlier. I don't know if they are just scanning for keywords, but it was pretty clear I wasn't a dealer. Each time you have to explain why your ad is legit there is a two to eight hour turnaround time via email. Just a clunky experience, but necessary to endure because they attract a lot of potential buyers due to their brand.

Ad Responses

At least 50% of ad responses I got via email (especially from the Auto Trader ad) were scams. The common one is: "I'd like to buy your car, but I can't come see it for [insert lame/amusing/creative reason]. I will pay you via PayPal and my 'courier' will come pick it up." It's usually easy to spot these scams, but here are some common things I noticed in scammer responses:

  • no phone number
  • phone number with international area code
  • generic text in emails like "I'd like to buy your item"
  • suspicious name that sounds auto-generated: "Kelvin Eric", "Alex Matt"

If it's a real buyer, they'll talk to you on the phone and come see the car in person. Anything else is highly suspicious. I found a legitimate buyer after about six weeks.

Preparing for Sale

After the buyer and I agreed on a price, he asked me if I would get the car e-tested and certified (safety certified). This had not crossed my mind before since the car was only four years old, and with very few kilometers on it. It's not required that the seller do these things, but it's certainly a sign of good faith, so I was game. I got the e-test done at Oil Changers ($40), and a local mechanic in Kitchener did the safety inspection ($90). For finding a mechanic to do the inspection, just make sure they are an official "Motor Vehicle Inspection Station," recognized by the government.

You could get the e-test and safety inspection done before finding a buyer, but both expire. The e-test is good for 12 months, so that's not a problem, but the safety inspection is only valid for 36 days, so keep that in mind.

Completing the Sale

The biggest question I had during this process was how I'd accept payment for the car in a safe way. I wasn't selling a beater, so it was a large sum of money to change hands. Cashier cheques and bank drafts are often faked, personal cheques are out of the question, and accepting that much in cash might be the most suspicious of all! I came across this that suggested going with the buyer to his or her bank and getting the bank draft right then and there. Seemed nearly foolproof, so this is what I did. After meeting my buyer I felt I could trust him, so I felt like a bit of a jerk for making him jump through this hoop. I just wasn't willing to accept any risk on the transfer of this much money. On the day of the actual sale we took a trip over to a nearby branch of his bank, went up to the teller together, and they issued me the draft (and gave him a receipt that showed the draft was issued).

Interestingly, when I first suggested this as a way to do the payment, my buyer got a bit nervous. Never having heard of this before, he thought I might be trying to pull something on him! I didn't expect that kind of reaction. I explained my motivation, and sent him the About.com link (above) and he was ok with it. If I was doing it all over I might advertise up front that I require buyers to pay this way.

Payment in hand, there were a few things left to do:

  • Fill out the vehicle transfer bit on my vehicle permit
  • Give the vehicle transfer bit of the permit to the buyer, keep the "plate portion" for myself
  • Fill out the bill of sale in the UVIP
  • Take the plates off my car (yes, the buyer drives away with no plates; he has 6 days to get some put on)
  • Hand over the car and keys
The process was a bit stressful at times, but I ultimately got the price I was looking for, so it was worth it.