Sunday, October 11, 2009

The Most Awesome Funeral (for cheap!)

According to the world wide web of internets, the average funeral in the U.S. costs between $6,000 and $11,000. Thats a lot of money. And pretty lame really. Thats not going to get you a sweet marble building or statue or phallus or anything.

But you know what costs a lot less, and is a lot more awesome? A sky burial. But you can't be lame and just leave your body anywhere. So, if you were to ship a 150lbs body to Thimphu, Bhutan (probably the closest place to Tibet UPS delivers to) it'd cost you a little over $1,500. So then I assume you could hire a Sherpa for a grand or two. And presto, for between $2,500 and $3,500 you get to be buried in one of the most awesome places in the world in one of the most awesome ways.

Sunday, August 9, 2009

Firebox and new IPs

Trixie trixie bastards. So we gots some static ip's that are chillin behind our Firebox. The firebox itself has a dedicated ip.

0800 - Everything is working.
0830 - 1030 - Movin servers to new lo-cal.
1030 - 1100 - Reassign machine ips and tweak firebox.
1100 - 1930 - Not a god damn thing works.

So here is what we knew during this time:
- All machines could go out to the internets
- All servers were serving up their wares
- Internal pinging worked, outgoing pings worked
- 1 ip, behind the firebox on a drop, could be reached from external internets
- NONE of the simple firebox -> forward to machine from external sources worked
- All newly assigned ips worked, you could connect a server directly to the outside and bam
- Firebox logs showed incoming requests, denied, can't find destination
- All destinations were clearly mapped. No trickery. Come in on external ip xyz and forward to internal abc
- a trace route would die on the failing ips would die after the isp hop

So why? ARP CACHING!!!! Dirty, dirty, dirty girl. So what happened was this: We got assigned new ips. One went to the firebox and the rest behind it. The firebox was aggressive and broadcast saying "yo, here I be." The rest, chilling behind the firebox, did not. So, our isp was not able to properly route these requests.
The fix? Set every machine or ip on the open to the world to let it broadcast, then toss it back behind the firebox like a fat chick. ARP cache fixed.

This is why I'm not a network guy. This crap is lame. NullPointerExceptions are much easier. Or so I hear, since I've never had one.

Sunday, June 28, 2009

Comcast offers 50 Mbps...for an hour and a half a month.

Let me preface this by saying I hate comcast. They don't show up for apointments, don't respond to emails, and just all around suck. Problem is they don't have any competition where I live (oh please FiOS...please!!).

So Comcast has been running ads on tv around here lately offering service with up to 50 Mbps for $99 a month. But this made me think of a few years back when people accused Comcast of throttling their speeds, which Comcast denied and eventually conceded "yeah maybe but but... 9/11... AMERICA... Terrorists!". Anyway, that'll never pan out because Comcast spends more on lobbyist than you or I do, but I digress.

So what meaningful came from the throttling incident? Well, as of Oct 1 2008 Comcast limits your monthly incoming traffic to 250 GB per second. But whats get me is this, you can pay extra to get 50 Mb per second, but only get 250 Gb a month. 1 Gb = 1024 Mb, so, if you were to sit on some traffic that heavy, you'd run up your limit in 85.33 minutes. Stupid Comcast.

Thursday, June 18, 2009

cl.exe results in mspdb80.dll was not found error

cl is the Visual C++ Compiler that comes with Visual Studio. So today I needed to compile me some C code. Ok, lets do this. Path not found. Easy enough, add C:\Dev\Tools\VisualStudio\VC\bin to my path. "mspdb80.dll was not found" error. Bullocks.

Most of the internet chatter was about running vcvars32(which calls vsvars32) or vcvarsall which SHOULD HAVE set the environment variables, but did not. Maybe it was a bad install or maybe maybe maybe. Too much work. Don't need another rabbit hole.

So all you need to do is set another path var to C:\Program Files\Common Files\Microsoft Shared\VSA\8.0\VsaEnv (or wherever your mspdb80.dll is located). In like Flynn.

So you wanna use cl? To sum it up set two new path vars
C:\{visual-studio}\VC\bin
C:\Program Files\Common Files\Microsoft Shared\VSA\8.0\VsaEnv

Monday, June 15, 2009

Vignette, Ahh Poor Vignette

Man. I really don't like configuring and implementing COTS software. Its usually sold to someone who thinks it'll solve problems A, B and C when in fact they're only real problem is X. And they spent half a million. Or more. A lot more.

Well, I had the privilege of vomiting for 6 months working with Vignette products (although, I'll admit it was work). Now, Vignette products aren't terrible. At one time they could have been called cutting edge. Too bad that time was circa 1993. And the coding concepts are good. The code isn't. God no. The code is the definition of spaghetti code. See, Vignette bought up a lot of little chunks of code and then tried to play God. The kind of God that made the Platypus. And they did.

So, what made me have these flashbacks? Two things. First, my co-worked pointed out to me a few weeks back that someone had actually purchased Vignette. Oh boy. If you own stock in OpenText...hmm. If their intention is to 'cherry-pick' through Vignettes code they might as well have purchased a JDK 1.0 for dummies book and gone through the code in the accompanying cd. Then they should have gone looking for code in a dumpster behind a Taco Bell. But eh, at least they didn't buy AOL.

But thats not what rubs me. What really did it is again today I got another spam mail from Vignettes Education Services. From which I've already tried to unsubscribe. Months ago. See, I got a similar email a while back which prompted me to hit the handy unsubscribe link at the bottom. That tried to send an email to unsubscribe_me@marketing.vignette.com, which of course is an invalid email address. So I sent an email to their general support saying essentially 'wtf mate'. The lady said she unsubscribed me. Which I believed. Until today. And yes, the unsubscribe link in the email is still set to unsubscribe_me@marketing.vignette.com.

Monday, May 18, 2009

Screw experts-exchange

If you post on experts-exchange you're a dick, plain and simple. Even the crappiest of programmers can attest to the fact that they've used the internets a million and one times to help them code. Anytime you're trying to do anything you search and read blogs and forums and and all that. If there is any example of how free information benefits real business it'd be computer programming.

So why does experts-exchange show up all the time on my searches? Well, I have a theory and it involves a fat nerd living in his moms basement, too much mountain dew and manga and not enough social interaction with those of the opposite sex. God that site pisses me off.

Friday, May 8, 2009

JAXB xjb & too many nodes

As I went into a while ago, you can use xjb to customize JAXB bindings. Today I learned of a tragic shortcoming. So say you have this snippet
<jaxb:bindings xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
 version="1.0">
 <jaxb:bindings schemaLocation="train.xsd" node="//xsd:element[@name='car']">
  <jaxb:property name="cars" />
 </jaxb:bindings>
</jaxb:bindings>
In that example there was a complexType with the name train, which contained an element with the name car which corresponded to the complexType car. All is right in the world. But what if there was another element somewhere, probably in some other complexType that contained a car? Well, that'd be kosher unless you were trying to customize the bindings with the above snippet. Instead you'll end up seeing
[ERROR] Error while parsing schema(s).Location [ file:/C:/Dev/Workspace_Netbeans /my-project/src/main/resources/train.xjb{5,80}].com.sun.istack.SAXParseException2: XPath evaluation of "//xsd:element[@name='widget']" results in too many (2) target nodes
There was an enhancement request put in years ago for XPath to be able to match multiple nodes, but like Bill O'Reilly releasing a softcore romance novel I wouldn't hold my breathe. Oh wait.

Thursday, April 16, 2009

Reading a directory of files into a database

When trying to test software nothing beats real data. Well, except beer. But anyway, large, real, and freely available datasets are unfortunately hard to come by. Thank god for jskill. Because of him (and nerds around the world for getting it together) us other nerds can play with a 500 million plus dataset of Enron emails.

My use for the data was to test an LSI system, but the sky's really the limit when it comes to what you could use it for. Its tar'd for 367mb and unzipped its 2.54gb (on disk).

The code itself isn't too much. I started with the fat kid approach and just barreled through the files. I pretty much yoinked this guy for the file traversal. The two things the code pads are single quotes and backslashes.

I ran it and it took about 7.5 hours to grind on through. I showed it to The Funk and he almost piddled with glee and said "Commons IO". Maaan I'm going to name my firstborn CommonsIO. I threw in prepared statements and we're in business.

To get setup with the database here is a creation script. My column names (and how I pull out the first line) are kind of unique for the software I'm using, but the idea is there.
DROP TABLE IF EXISTS `enron`.`tbl_enron`;
CREATE TABLE  `enron`.`tbl_enron` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `itemId` varchar(256) NOT NULL,
  `data` longtext NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
So here is an example email from the dataset (the attachments aren't provided).
Message-ID: <18782981.1075855378110.JavaMail.evans@thyme>
Date: Mon, 14 May 2001 16:39:00 -0700 (PDT)
From: phillip.allen@enron.com
To: tim.belden@enron.com
Subject: 
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
X-From: Phillip K Allen
X-To: Tim Belden <Tim Belden/Enron@EnronXGate>
X-cc: 
X-bcc: 
X-Folder: \Phillip_Allen_Jan2002_1\Allen, Phillip K.\'Sent Mail
X-Origin: Allen-P
X-FileName: pallen (Non-Privileged).pst

Here is our forecast

 
And then finally the baby maker..
/**
 * Loader.java
 *
 * Created on Apr 19, 2009
 *
 * @author Kevin
 */

package com.noviidesign.enron;

import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Iterator;
import org.apache.commons.io.FileUtils;


/**
 * Loader.java does the following thangs...
 */
public class Loader {

    public static void main(String[] args) {

        System.out.println("connecting to db");

        Connection connection = null;
        try {
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/enron", "root", "password");
        } catch (SQLException ex) {}

        PreparedStatement preparedStatement = null;
        try {
            preparedStatement = connection.prepareStatement("INSERT INTO tbl_enron (itemId, data) VALUES (?, ?);");
        } catch (SQLException ex) {}

        System.out.println("connected.  now procressing");

        Iterator iterator = FileUtils.iterateFiles(new File("C:\\Documents and Settings\\Kevin\\Desktop\\enron_mail_030204\\maildir"), null, true);
        while (iterator.hasNext()) {

            String file = null;
            try {
                file = FileUtils.readFileToString((File) iterator.next());
            } catch (IOException ex) {
                System.err.println("Bullocks! " + ex);
            }

            String itemId = null;
            if (file.contains("Date"))
                itemId = file.substring(0, file.indexOf("Date") - 2);

            //find \ and pad \\ for insertion
            file = file.replaceAll("\\\\", "\\\\");
            //find ' and pad \' for insertion
            file = file.replaceAll("\'", "\\\'");

            try {
                preparedStatement.setString(1, itemId);
                preparedStatement.setString(2, file);
                preparedStatement.executeUpdate();
            } catch (SQLException ex) {
                System.out.println("SHIT! " + itemId + " " + ex.getErrorCode());
                System.err.println(ex);
            } catch (Exception ex) {
                System.out.println("SHIT! " + itemId);
                System.err.println(ex);
            }
        }

        try {
            preparedStatement.close();
        } catch (SQLException ex) {}

        System.out.println("WOOT DONE PROCESSING!  closing connection");

        if (connection != null) {
            try {
                connection.close();
            } catch (Exception e) { }
        }

        System.out.println("le finished");
    }
}

Thursday, April 9, 2009

Reading in XML with JAXB

A bit ago I covered dynamic class creation with xjc and maven. Now for the kinda-second-part-but-doesn't-really-have-to-be, how to read in an xml file into your beans.

So based off of the xsd file I created in the aforementioned, here is my xml file representing a train. Cho chooo mother fucker.
<?xml version="1.0" encoding="UTF-8"?>
<train xmlns="http://www.noviidesign.com/xjcexample/train" name="Pepper Jack" id="pepper_jack" color="gray">
  <car name="Car 1" id="car1" maxPassengers="50" />
  <car name="Car 2" id="car2" maxPassengers="75" />
  <car name="Car 3" id="car3" maxPassengers="75" />
</train>
Pretty simple. If you wanted you could have multiple trains within one file, or multiple files with one train in each and just add some looping to your code. Once again I assume you just have this xml files in your src/main/resources folder.

And here is the code. Not much to it.
InputStream xmlFile = this.getClass().getResourceAsStream("/trains/pepperjack.xml");

JAXBContext jc;
try {
  jc = JAXBContext.newInstance("com.noviidesign.xjcexample");
  Unmarshaller u = jc.createUnmarshaller();
  JAXBElement<train> root = (JAXBElement<train>) u.unmarshal(xmlFile);
  Train train = root.getValue();

  System.out.println("Train id: " + train.getId());
  System.out.println("Train name: " + train.getName());
  System.out.println("Train color: " + train.getColor());

  for(Car car : train.getCars()){
      System.out.println("Car id: " + car.getId());
      System.out.println("Car name: " + car.getName());
      System.out.println("Car max passangers: " + car.getMaxPassengers());
  }
} catch (JAXBException ex) {
  logger.error("Exception in jaxb parsing:", ex);
}
The only thing to be aware of here is the line where you get the new JAXBContext instance. I pass it the context path (where you'll find the Train and Car classes), but you can also pass it an array of classes, a classloader, or combination of them.

And this is all you'll need in your pom. (you will be using maven...)
<dependencies>
   <dependency>
      <groupId>javax.xml.bind</groupId>
      <artifactId>jaxb-api</artifactId>
      <version>2.0</version>
   </dependency>
</dependencies>
<plugin>
Thats it. Simple like your mom.

Friday, March 27, 2009

JAXB xjc & maven2

I'm a fan of the Metro Web Services products (JAX-WS and JAXB). Not a fanboy, but a fan. I am a fanboy of maven though, and if you're not you just suck. Its the sauce that makes the world go round. That said, more often than not when using an xml to java compiler you don't have a need to have it automated. An ant task would suffice. And there are a bunch of great resources out there on that. But sometimes you want/need new classes based on an ever changed xml schema. WOOT MAVEN!

So first you'll need the plugin. Unfortunately as of now its not in a maven repo (which I think is mostly due to the minimal need for maven automation), but you can download the plugin here and add it to your local repo or local/companies repository.

Now you need some stchuff in your pom.
<plugin>
<groupId>com.sun.tools.xjc.maven2</groupId>
<artifactId>maven-jaxb-plugin</artifactId>
<version>1.1</version>
<executions>
   <execution>
       <goals>
           <goal>generate</goal>
       </goals>
   </execution>
</executions>
<configuration>
   <generatePackage>com.noviidesign.xjcexample</generatePackage>
   <includeSchemas>
       <includeSchema>**/*.xsd</includeSchema>
   </includeSchemas>
   <includeBindings>
       <includeBinding>*.xjb</includeBinding>
   </includeBindings>
   <strict>true</strict>
   <verbose>true</verbose>
   <removeOldOutput>true</removeOldOutput>
</configuration>
</plugin>
This will remove your old classes and creating code whenever you run a maven goal.

Now when you run this you should have your *.xsd schema in your /resources folder (for a webapp). I also have an *.xjb file in the plugin configuration above. First, lets look at what an xsd schema would look like that'd need the xjb file.
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.noviidesign.com/xjcexample/train" xmlns:tns="http://www.noviidesign.com/xjcexample/train" elementFormDefault="qualified">
 <element name="train" type="tns:train" />
 <complexType name="train">
  <sequence>
   <element name="car" type="tns:car" minOccurs="1" maxOccurs="unbounded" />
  </sequence>
  <attribute type="string" name="name" use="required" />
  <attribute type="string" name="id" use="required" />
  <attribute type="string" name="color" use="required" />
 </complexType>
 <complexType name="car">
  <attribute type="string" name="name" use="required" />
  <attribute type="string" name="id" use="required" />
  <attribute type="string" name="maxPassengers" use="required" />
 </complexType>
</schema>
Now this schema is just for example purposes but should get the point across. If needed you can find more information than you could care about on xml schemas on le internet. So, now when the classes are created you'll have the following
package com.noviidesign.xjcexample;

import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "train", propOrder = {"car"} )
public class Train {

 @XmlElement(required = true)
 protected List car;
 @XmlAttribute(required = true)
 protected String color;
 @XmlAttribute(required = true)
 protected String id;
 @XmlAttribute(required = true)
 protected String name;
 
 public List getCar() {
  if (car == null) {
   car = new ArrayList();
  }
  return this.car;
 }
 
 public String getColor() {
  return color;
 }
 
 public void setColor(String value) {
  this.color = value;
 }
 
 public String getId() {
  return id;
 }
 
 public void setId(String value) {
  this.id = value;
 }
 
 public String getName() {
  return name;
 }
 
 public void setName(String value) {
  this.name = value;
 }
}

package com.noviidesign.xjcexample;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "car")

public class Car {

 @XmlAttribute(required = true)
 protected String id;
 @XmlAttribute(required = true)
 protected String maxPassengers;
 @XmlAttribute(required = true)
 protected String name;
 
 public String getId() {
  return id;
 }
 
 public void setId(String value) {
  this.id = value;
 }
 
 public String getMaxPassengers() {
  return maxPassengers;
 }
 public void setMaxPassengers(String value) {
  this.maxPassengers = value;
 }
 
 public String getName() {
  return name;
 }
 
 public void setName(String value) {
  this.name = value;
 }
}
So nothing mind blowing, just some regular ol' classes w/some xml annotation. But what I don't like is in Train.java we have protected List car; and subsequently public List getCar(); I'd much rather have List cars; and public List getCars(); And this is where our *.xjb file comes in. It'd look as follows
<jaxb:bindings xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
 version="1.0">
 <jaxb:bindings schemaLocation="train.xsd" node="//xsd:element[@name='car']">
  <jaxb:property name="cars" />
 </jaxb:bindings>
</jaxb:bindings>
And thats really it. Now again you'd usually do this with an ant task, but if you have a need for maven hopefully this will help get you going in the right direction.

In a bit I'll cover how to read in xml into your classes you created.

Thursday, March 26, 2009

Regi's American Bistro

So it was my birfday earlier this week and Rani wanted to take me out to dinner. Fat kid won't object. Where to go? I was feeling kind of beat from work so I decided to keep it local, we'd hit up Thai Arroy which has arguable the best Thai food this side of the mississippi. Or something. Anyway, we walked there to find it closed. Damn Mondays and their closings. So we'll settle for some pretty decent Mexican food from Blue Agave. Also closed on Mondays.

So by this point I'm getting annoyed at our luck (or should I have taken a hint?). So I say "I've always wanted to try Regi's" to which I was told "I've been there and it was terrible". Well, being the smart one I is I decided "mneh, might as well try" and being my birthday, Rani didn't object. Unfortunately.

So, we got seated at their outside but enclosed by some plastic tent thingy and heated with heaters thing area. It was kinda cool actually. So we got the lobster mac & cheese and crab dip. I never did find any lobster in the mac and cheese but it had chunks of tomato in it and was pretty good (or maybe I was just starving). The crab dip was so-so. For the main course we got the turkey and brie sandwhich and a special that had arctic char in it. The turkey brie sandwhich was pretty lame, but the arctic char was alright. It had a cucumber and vinigar salad bed which was tastie taste.

And then came dessert. I don't know if I was more annoyed at the dessert or our waiter. We were there for maybe and hour and a half and saw him three or so times. MAN. I needs me some more water, but he's no where to be found. And we had to hunt him down after we paid to find our leftovers (not because they were that good but because they meant free lunch for the next day). And then there was the dessert. Red velvet cake. It had some cream cheese frosting. And tasted like a twinkie. Thats immediately what I thought when I took a bite. This tastes like a twinkie...except I remember liking twinkies as a kid...and I don't like this. After about four bites between us it was abandoned.

Regi's...I may be back. What? Yeah well, IF it were a nice day out and IF I wanted to sit outside and IF I wanted to have a few drinks while doing so and IF I maybe also wanted an assumable mediocre salad while I did it...then yeah, I might go back. So I guess I'll probably never be back because there are other places around that I could do that at that wouldn't suck.

Friday, March 20, 2009

8,600 reasons to not buy an HP Printer

I'll make this short and sweet.  I'm the 'computer guy' in the family and my sisters laptop is running slow.  So here I am doing my best Karen Carpenter impression (with the help of the o so slick Revo Unistaller) and I get to HP - Shop for Supplies.  Sometimes you find stuff such as TeaTime.exe (a process of Spybot) and you're like 'wtf mate' and bust out the Goog.  Well, being the astute nerd that I is I know that there is no reason that some hp related shopping thing needs to be installed.  So I kills it.  After the uninstall (byfar the best reason to use Revo) it tells me there are over 8600 leftover windows registry items.  Are you serious?!?  There is no reason for 1 to be on the machine let alone 8600.  Now there is sloppy programming.  And there is bad programming.  And then there is programming that I can only assume would be done to see how terrible you could make something.  I think this falls into the latter.

Take a step back.  Anyone who's seen an HP printer or any device for that matter has seen how bloated and bumtarded their software is.  Why do I need 17 different applications installed?  Why do they all need to search for updates?  But I've learned to make concessions in life.  But 8600 registry items for something that'll just say "OH SNAP YOUR OUTTA INK.  Go to hp.com and get more."  Jerks.