<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;C0AMRnY6eCp7ImA9WhRRFEk.&quot;"><id>tag:blogger.com,1999:blog-419616687741790880</id><updated>2011-11-27T18:56:27.810-06:00</updated><category term="annotations" /><category term="hibernate" /><category term="ejb glassfish jndi" /><category term="weblogic ssl certificate wildcard" /><category term="ddl" /><category term="java" /><category term="java double currency" /><title>Andrew Thompson's Blog</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://jandrewthompson.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://jandrewthompson.blogspot.com/" /><author><name>J Andrew Thompson</name><uri>http://www.blogger.com/profile/12235539661156258840</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_oSRqocz1gN0/StyDv14L20I/AAAAAAAAAJk/h3f9tpUyjOo/S220/jt.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>8</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/AndrewThompsonsBlog" /><feedburner:info uri="andrewthompsonsblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;CkMMQ3w5fip7ImA9Wx5WGEU.&quot;"><id>tag:blogger.com,1999:blog-419616687741790880.post-9213081499400351983</id><published>2010-09-30T14:13:00.008-05:00</published><updated>2010-09-30T16:01:22.226-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-30T16:01:22.226-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java double currency" /><title>Double Trouble</title><content type="html">You've heard it said: the cardinal rule of Java programming... &lt;i&gt;"Never use a double to hold currency"&lt;/i&gt;.  Ok, well it might not be the &lt;i&gt;cardinal&lt;/i&gt; rule, but its pretty important.  But every once in a while you think to yourself, "aww... just this once.  It won't hurt anything".  Let me save you the headache and explain why this is a terrible idea.  I'll also show you some alternatives for all your money problems (programmatically speaking, of course).&lt;br /&gt;
&lt;br /&gt;
Everyone knows that we humans use the base 10 numbering system.  It makes sense, ten fingers... base 10... viola.  But your computer was unfortunately created with only two fingers.  For those less familiar with the topic of bases in numbering systems, you can think of it as the 'roll-over' point when you're counting.  For base 10 (decimal), counting rolls over after you get to nine.  For base 2 (binary), counting rolls over after 1. For example...&lt;br /&gt;
&lt;pre class="brush: java"&gt;00 (0)
01 (1)
10 (2)
11 (3) &lt;/pre&gt;&lt;br /&gt;
Now, I'm not going to get into the nitty gritty of how your computer stores numbers for each of the common Java data types (browse some wikipedia articles if you're interested).  As a general rule, any whole number can be exactly represented using binary notation.  Any &lt;i&gt;fractional&lt;/i&gt; number is not guaranteed to have an exact representation in binary.  Just as 1/3 or PI cannot be precisely represented in decimal format, many fractional numbers also cannot be precisely represented in binary format.  Here's a good test to run if you aren't convinced:&lt;br /&gt;
&lt;pre class="brush: java"&gt;System.out.println(
  0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f + 0.1f
);
//Result: 0.8000001

System.out.println(
  0.1d + 0.1d + 0.1d + 0.1d + 0.1d + 0.1d + 0.1d + 0.1d
);
//Result: 0.7999999999999999
&lt;/pre&gt;You would expect adding 0.1 eight times would give you exacly 0.8, but the results can sometimes surprise you.  You can imagine the havoc this could cause if you are attempting to perform calculations on money stored as Doubles or Floats.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Solution #1:&lt;/b&gt;&lt;br /&gt;
Only deal with cents.  This means multiplying your decimal number by 100 and storing it as a Long.  This is a safe operation on currency because, even though your initial decimal value is not exactly represented in binary format, it will be properly rounded by the JVM when converting it to a Long.  However, be sure to do this &lt;b&gt;before&lt;/b&gt; any other calculations are performed on it.  If not, you &lt;strike&gt;could&lt;/strike&gt; &lt;b&gt;will&lt;/b&gt; introduce rounding errors. &lt;br /&gt;
&lt;pre class="brush: java"&gt;double amount = 100.01d;
long amountInPennies = (long)(amount * 100);
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;Solution #2:&lt;/b&gt;&lt;br /&gt;
Use BigDecimal.  This type can safely handle currency represented as dollars and cents because it essentially employs solution #1 for us behind the scenes.  It either detects, or you can provide it, the precision that you require.  The easiest (and safest) way to construct a BigDecimal is with the String constructor.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: java"&gt;BigDecimal num = new BigDecimal("100.01");
&lt;/pre&gt;&lt;br /&gt;
It will detect a number with two decimal places (hundredths) and will internally multiply that number by 100, storing the result as a whole number.  The BigDecimal class provides methods for all common arithmetic operations you may need to perform.  This guarantees that you won't be plagued by the rounding errors and inaccuracies inherent in doubles and floats.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/419616687741790880-9213081499400351983?l=jandrewthompson.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ZqS5h8DTSWX7Wy6x82nFwU4-vAY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZqS5h8DTSWX7Wy6x82nFwU4-vAY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ZqS5h8DTSWX7Wy6x82nFwU4-vAY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZqS5h8DTSWX7Wy6x82nFwU4-vAY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewThompsonsBlog/~4/ZrHEWDbWTqc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jandrewthompson.blogspot.com/feeds/9213081499400351983/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jandrewthompson.blogspot.com/2010/09/double-trouble.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/419616687741790880/posts/default/9213081499400351983?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/419616687741790880/posts/default/9213081499400351983?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AndrewThompsonsBlog/~3/ZrHEWDbWTqc/double-trouble.html" title="Double Trouble" /><author><name>J Andrew Thompson</name><uri>http://www.blogger.com/profile/12235539661156258840</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_oSRqocz1gN0/StyDv14L20I/AAAAAAAAAJk/h3f9tpUyjOo/S220/jt.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://jandrewthompson.blogspot.com/2010/09/double-trouble.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck4ERn06eSp7ImA9Wx5WGEs.&quot;"><id>tag:blogger.com,1999:blog-419616687741790880.post-4625278739255457517</id><published>2010-04-05T12:14:00.007-05:00</published><updated>2010-09-30T10:35:07.311-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-30T10:35:07.311-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="weblogic ssl certificate wildcard" /><title>Weblogic and Wildcard SSL Certificates</title><content type="html">&lt;p&gt;I've recently been working on setting up an instance of Weblogic 10.3 for a new app I'm working on.  This app makes several calls to a web service over SSL that is configured with a wildcard certificate.  That means the certificate was issues to *.mydomain.com.  This is a slick mechanism; it saves money and is easier to maintain all of your subdomains.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;&lt;br /&gt;
&lt;strong&gt;The Problem:&lt;/strong&gt; Weblogic doesn't handle wildcard certs out of the box.&lt;br /&gt;
When weblogic initiates a connection over SSL, it makes a call to the HostnameVerifier.  The default verifier simply ensures that the hostname you're connecting to and the name that the certificate was issued for match.  So you can see the problem with wildcard certs in this example.  The webservice is on ws.mydomain.com and the SSL certificate was issued to *.mydomain.com.  If you google this problem, you will probably find lots of 'solutions' that suggest you disable hostname verification, but this leaves you vulnerable to man-in-the-middle attacks.  &lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;&lt;br /&gt;
&lt;strong&gt;TheSolution: &lt;/strong&gt;You might also find a few who would suggest you create your own HostnameVerifier.  This is what we want, but I was unable to find any examples that actually show you how to do this!  So here I will show you my implementation.  Its not perfect, but I think it is certainly more than enough to get you started.  &lt;strong&gt;DISCLAIMER:&lt;/strong&gt; Most of the code is in a try/catch block.  You'll notice that my code returns true on an error.  Most likely, if your site has been compromised, the code will still run without exceptions and it should detect that the hostname and certificate don't match.  If this your production system and you're super paranoid, just have the catch block return false.&lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
&lt;pre class="brush: java"&gt;package com.andrewthompson.weblogic;

import java.io.ByteArrayInputStream;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.net.ssl.SSLSession;

import weblogic.security.SSL.HostnameVerifier;

/**
* Verify the hostname of outbound ssl connections. 
* 
* @author andrew.thompson
*
*/
public class WildcardHostnameVerifier implements HostnameVerifier 
{

public boolean verify(String hostname, SSLSession session)
{
try
{
Certificate cert = session.getPeerCertificates()[0];

byte [] encoded = cert.getEncoded();

CertificateFactory cf = CertificateFactory.getInstance("X.509");
ByteArrayInputStream bais = new ByteArrayInputStream(encoded);

X509Certificate xcert = (X509Certificate)cf.generateCertificate(bais);

String cn = getCanonicalName( xcert.getSubjectDN().getName() );

log.info("CN: " + cn);
log.info("HOSTNAME: " + hostname);

if(cn.equals(hostname))
return true;

Pattern validHostPattern = Pattern.compile("\\*\\.[^*]*\\.[^*]*");
Matcher validHostMatcher = validHostPattern.matcher(cn);

// Make sure the cert only has wildcard in subdomain.  We don't
//    want to confirm *.*.com now do we?  
if(validHostMatcher.matches())
{
String regexCn = cn.replaceAll("\\*", "(.)*");

log.info("REGEXCN: " + regexCn);

Pattern pattern = Pattern.compile(regexCn);
Matcher matcher = pattern.matcher(hostname);

if(matcher.matches())
{
log.info("Pattern MATCHES");
if(matcher.group().equals(hostname))
{
log.info("Group() matches hostname: " + matcher.group());
return true;
} else {
log.info("Group() doesn't match hostname: " + matcher.group());
return false;
}
} else {
log.info("Pattern DOESN'T MATCH");
return false;
}

}


} catch (Exception e ) {
e.printStackTrace();
return true;
}

return true;
}

/**
* Return just the canonical name from the distinguishedName 
* on the cert.
*  
* @param subjectDN
* @return
*/
private String getCanonicalName(String subjectDN)
{

Pattern pattern = Pattern.compile("CN=([-.*aA-zZ0-9]*)");
Matcher matcher = pattern.matcher(subjectDN);

if(matcher.find())
{
return matcher.group(1);
}

log.info("Couldn't find match for CN in subject");
return subjectDN;

}


private final static Logger log = Logger.getLogger(WildcardHostnameVerifier.class.getCanonicalName());

}
&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;&lt;br /&gt;
This is simply a matter of implementing the weblogic.security.SSL.HostnameVerifier interface.  You will find this class in the weblogic.jar of your server/lib dir.  &lt;br /&gt;
You'll notice that weblogic provides us with the SSLSession.  From here, we can extract the java.security.cert.Certificate.  We then use a CertificateFactory to transform this Certificate into an X509 certificate.  That allows us to pull some useful information out, such an the Subject Distinguished Name.  This is a string of key/value pairs; we are only interested in the Common Name or CN. So, we extract the CN with a regular expression pattern matcher.  If the hostname matches the CN, we're done.  If not, we check to see if the CN has a wildcard (*).  If so, we use another regular expression matcher to see if the hostname matches the CN with any subdomain. &lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;&lt;br /&gt;
Now, you just need to go into the weblogic console, select the SSL tab on your server.  Check 'Custom Hostname Verifier', enter the classname of your verifier, and make sure your class is on weblogic's classpath.&lt;br /&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/419616687741790880-4625278739255457517?l=jandrewthompson.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/CqzU1Ecw9sdMsBZWmEmpv7NE_k4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CqzU1Ecw9sdMsBZWmEmpv7NE_k4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/CqzU1Ecw9sdMsBZWmEmpv7NE_k4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CqzU1Ecw9sdMsBZWmEmpv7NE_k4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewThompsonsBlog/~4/LkeDsY0f5hk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jandrewthompson.blogspot.com/feeds/4625278739255457517/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jandrewthompson.blogspot.com/2010/04/weblogic-and-wildcard-ssl-certificates.html#comment-form" title="18 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/419616687741790880/posts/default/4625278739255457517?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/419616687741790880/posts/default/4625278739255457517?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AndrewThompsonsBlog/~3/LkeDsY0f5hk/weblogic-and-wildcard-ssl-certificates.html" title="Weblogic and Wildcard SSL Certificates" /><author><name>J Andrew Thompson</name><uri>http://www.blogger.com/profile/12235539661156258840</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_oSRqocz1gN0/StyDv14L20I/AAAAAAAAAJk/h3f9tpUyjOo/S220/jt.jpg" /></author><thr:total>18</thr:total><feedburner:origLink>http://jandrewthompson.blogspot.com/2010/04/weblogic-and-wildcard-ssl-certificates.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck8ASXsyfyp7ImA9Wx5WGEs.&quot;"><id>tag:blogger.com,1999:blog-419616687741790880.post-4935022639705371630</id><published>2009-12-17T11:10:00.010-06:00</published><updated>2010-09-30T10:34:08.597-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-30T10:34:08.597-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ejb glassfish jndi" /><title>Access a Remote EJB From a Stand-Alone Client</title><content type="html">Here, I will explain how you can access an EJB from outside a j2ee container or server.  This could be a simple java-main application, or a unit test.  The basic idea behind this process is application server agnostic, but these specific instructions will target Glassfish v2.1.&lt;br /&gt;
&lt;br /&gt;
&lt;font size="3"&gt;&lt;span style="font-weight:bold;"&gt;The Basics&lt;/span&gt;&lt;/FONT&gt;&lt;br /&gt;
&lt;br /&gt;
In general, you always gain access to a jndi tree via the javax.naming.InitialContext.  The no-arg constructor will by default look for a file on the classpath called 'jndi.properties'.  This file specifies an application server-specific InitialContextFactory class, used to initialize the tree.  You can also specify options such as the host and port to connect to.&lt;br /&gt;
&lt;br /&gt;
The appserv-rt.jar that ships with glassfish contains a default jndi.properties file with the basic options already configured for you.&lt;br /&gt;
&lt;br /&gt;
&lt;font size="3"&gt;&lt;span style="font-weight:bold;"&gt;Ok, lets actually do something...&lt;/span&gt;&lt;/FONT&gt;&lt;br /&gt;
&lt;br /&gt;
Assuming you have an EJB with a @Remote interface running on glassfish on localhost.  The registered name in jndi for this ejb is 'my-ear/MyEjb/remote'.  Create a new empty maven project.  Add the following dependencies to your pom:&lt;br /&gt;
&lt;font size="1"&gt;(I would recommend using my &lt;a href="http://monsoon-events.googlecode.com/svn/trunk/repo/"&gt;repository&lt;/a&gt; as Sun doesn't provide all the necessary dependencies for this in the core maven repositories.) &lt;/font&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: html"&gt;&lt;dependency&gt;
&lt;groupid&gt;com.sun&lt;/groupid&gt;
&lt;artifactid&gt;appserv-rt&lt;/artifactid&gt;
&lt;version&gt;2.1&lt;/version&gt;
&lt;/dependency&gt;
&lt;/pre&gt;&lt;br /&gt;
Now create a new class with a 'main' method.  Here's an example:&lt;br /&gt;
&lt;pre class="brush: java"&gt;public static void main(String[] args) throws Exception
{
InitialContext ctx = new InitialContext();
MyRemoteInterface service = (MyRemoteInterface)ctx.lookup("my-ear/MyEjb/remote");

Object result = service.getResult("john");

System.out.println(result);
}
&lt;/pre&gt;&lt;br /&gt;
You will also need to include MyRemoteInterface into your new project if you haven't already done so.  Ok, thats it!  Run your application and you should see the result object printed to your console.&lt;br /&gt;
&lt;br /&gt;
Now, lets assume you want to connect to Glassfish on a server other than localhost&lt;br /&gt;
&lt;br /&gt;
Create a new file called 'jndi.properties' and put it in your 'src/main/resources' directory.  Add the following to this file:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: html"&gt;org.omg.CORBA.ORBInitialHost=myhostname
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
We've just overriden the default host (provided by sun's jndi.properties') with a host of our own choosing.  If you wanted to change the port to connect to:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: html"&gt;org.omg.CORBA.ORBInitialHost=myhostname
org.omg.CORBA.ORBInitialPort=3700
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Well, that's about it for now.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/419616687741790880-4935022639705371630?l=jandrewthompson.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/cPVcvAwhYbvAgrh34nXCQMuHN8k/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cPVcvAwhYbvAgrh34nXCQMuHN8k/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/cPVcvAwhYbvAgrh34nXCQMuHN8k/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cPVcvAwhYbvAgrh34nXCQMuHN8k/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewThompsonsBlog/~4/FkhvJdzp7Bo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jandrewthompson.blogspot.com/feeds/4935022639705371630/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jandrewthompson.blogspot.com/2009/12/access-remote-ejb-from-stand-alone.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/419616687741790880/posts/default/4935022639705371630?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/419616687741790880/posts/default/4935022639705371630?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AndrewThompsonsBlog/~3/FkhvJdzp7Bo/access-remote-ejb-from-stand-alone.html" title="Access a Remote EJB From a Stand-Alone Client" /><author><name>J Andrew Thompson</name><uri>http://www.blogger.com/profile/12235539661156258840</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_oSRqocz1gN0/StyDv14L20I/AAAAAAAAAJk/h3f9tpUyjOo/S220/jt.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://jandrewthompson.blogspot.com/2009/12/access-remote-ejb-from-stand-alone.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0IEQnk5fSp7ImA9WxBSEEo.&quot;"><id>tag:blogger.com,1999:blog-419616687741790880.post-4863767067160753501</id><published>2009-10-28T08:46:00.014-05:00</published><updated>2009-12-17T11:38:23.725-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-17T11:38:23.725-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="hibernate" /><category scheme="http://www.blogger.com/atom/ns#" term="ddl" /><category scheme="http://www.blogger.com/atom/ns#" term="annotations" /><title>How To Generate DDL Scripts from Hibernate</title><content type="html">One of the nice things about using Hibernate in your persistence layer is that it can automatically make updates to your database schema for you.  This is nice in development, but oftentimes you need to have the ddl script file.  Lucky for us, Hibernate ships with the SchemaExport class.  This is what hibernate uses to make updates to your database.  I'll show you how we can hijack it and use it for our own purposes as well.&lt;br /&gt;&lt;br /&gt;Here we go.  As it seems a lot of developers are migrating towards Hibernate annotations and EJB JPA, the following code assumes your classes are configured with annotations.  This simple class takes the name of the package where you have your domain objects stored and generates ddl for mysql, oracle and hsql.  &lt;br /&gt;&lt;pre class="brush: java"&gt;&lt;br /&gt;package com.jandrewthompson;&lt;br /&gt;&lt;br /&gt;import java.io.File;&lt;br /&gt;import java.net.URL;&lt;br /&gt;import java.util.ArrayList;&lt;br /&gt;import java.util.List;&lt;br /&gt;import org.hibernate.cfg.AnnotationConfiguration;&lt;br /&gt;import org.hibernate.tool.hbm2ddl.SchemaExport;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * @author john.thompson&lt;br /&gt; *&lt;br /&gt; */&lt;br /&gt;public class SchemaGenerator&lt;br /&gt;{&lt;br /&gt;  private AnnotationConfiguration cfg;&lt;br /&gt; &lt;br /&gt;  public SchemaGenerator(String packageName) throws Exception&lt;br /&gt;  {&lt;br /&gt;    cfg = new AnnotationConfiguration();&lt;br /&gt;    cfg.setProperty("hibernate.hbm2ddl.auto","create");&lt;br /&gt;  &lt;br /&gt;    for(Class&amp;lt;Object&amp;gt; clazz : getClasses(packageName))&lt;br /&gt;    {&lt;br /&gt;      cfg.addAnnotatedClass(clazz);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt; &lt;br /&gt;  /**&lt;br /&gt;   * Method that actually creates the file.  &lt;br /&gt;   * @param dbDialect to use&lt;br /&gt;   */&lt;br /&gt;  private void generate(Dialect dialect)&lt;br /&gt;  {&lt;br /&gt;    cfg.setProperty("hibernate.dialect", dialect.getDialectClass());&lt;br /&gt;  &lt;br /&gt;    SchemaExport export = new SchemaExport(cfg);&lt;br /&gt;    export.setDelimiter(";");&lt;br /&gt;    export.setOutputFile("ddl_" + dialect.name().toLowerCase() + ".sql"); &lt;br /&gt;    export.execute(true, false, false, false);&lt;br /&gt;  }&lt;br /&gt; &lt;br /&gt;  /**&lt;br /&gt;   * @param args&lt;br /&gt;   */&lt;br /&gt;  public static void main(String[] args) throws Exception&lt;br /&gt;  {&lt;br /&gt;    SchemaGenerator gen = new SchemaGenerator("org.jthompson.myapp.domain");&lt;br /&gt;    gen.generate(Dialect.MYSQL);&lt;br /&gt;    gen.generate(Dialect.ORACLE);&lt;br /&gt;    gen.generate(Dialect.HSQL);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Utility method used to fetch Class list based on a package name.&lt;br /&gt;   * @param packageName (should be the package containing your annotated beans.&lt;br /&gt;   */&lt;br /&gt;  private List&lt;Class&gt; getClasses(String packageName) throws Exception&lt;br /&gt;  {&lt;br /&gt;    List&lt;Class&gt; classes = new ArrayList&lt;Class&gt;();&lt;br /&gt;    File directory = null;&lt;br /&gt;    try &lt;br /&gt;    {&lt;br /&gt;      ClassLoader cld = Thread.currentThread().getContextClassLoader();&lt;br /&gt;      if (cld == null) {&lt;br /&gt;        throw new ClassNotFoundException("Can't get class loader.");&lt;br /&gt;      }&lt;br /&gt;      String path = packageName.replace('.', '/');&lt;br /&gt;      URL resource = cld.getResource(path);&lt;br /&gt;      if (resource == null) {&lt;br /&gt;        throw new ClassNotFoundException("No resource for " + path);&lt;br /&gt;      }&lt;br /&gt;      directory = new File(resource.getFile());&lt;br /&gt;    } catch (NullPointerException x) {&lt;br /&gt;      throw new ClassNotFoundException(packageName + " (" + directory&lt;br /&gt;          + ") does not appear to be a valid package");&lt;br /&gt;    }&lt;br /&gt;    if (directory.exists()) {&lt;br /&gt;      String[] files = directory.list();&lt;br /&gt;      for (int i = 0; i &lt; files.length; i++) {&lt;br /&gt;        if (files[i].endsWith(".class")) {&lt;br /&gt;          // removes the .class extension&lt;br /&gt;          classes.add(Class.forName(packageName + '.'&lt;br /&gt;              + files[i].substring(0, files[i].length() - 6)));&lt;br /&gt;        }&lt;br /&gt;      }&lt;br /&gt;    } else {&lt;br /&gt;      throw new ClassNotFoundException(packageName&lt;br /&gt;          + " is not a valid package");&lt;br /&gt;    }&lt;br /&gt;  &lt;br /&gt;    return classes;&lt;br /&gt;  }&lt;br /&gt; &lt;br /&gt;  /**&lt;br /&gt;   * Holds the classnames of hibernate dialects for easy reference.&lt;br /&gt;   */&lt;br /&gt;  private static enum Dialect &lt;br /&gt;  {&lt;br /&gt;    ORACLE("org.hibernate.dialect.Oracle10gDialect"),&lt;br /&gt;    MYSQL("org.hibernate.dialect.MySQLDialect"),&lt;br /&gt;    HSQL("org.hibernate.dialect.HSQLDialect");&lt;br /&gt;  &lt;br /&gt;    private String dialectClass;&lt;br /&gt;    private Dialect(String dialectClass)&lt;br /&gt;    {&lt;br /&gt;      this.dialectClass = dialectClass;&lt;br /&gt;    }&lt;br /&gt;    public String getDialectClass()&lt;br /&gt;    {&lt;br /&gt;      return dialectClass;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It should be pretty easy to modify this code to suit your needs.  If you are using hibernate xml configuration, just swap out the AnnotationConfiguration class for org.hibernate.cfg.Configuration.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/419616687741790880-4863767067160753501?l=jandrewthompson.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/6ZbJ9OdMHxRtpZlxVTA8kP1ans0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6ZbJ9OdMHxRtpZlxVTA8kP1ans0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/6ZbJ9OdMHxRtpZlxVTA8kP1ans0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6ZbJ9OdMHxRtpZlxVTA8kP1ans0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewThompsonsBlog/~4/iuelbLjyWKI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jandrewthompson.blogspot.com/feeds/4863767067160753501/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jandrewthompson.blogspot.com/2009/10/how-to-generate-ddl-scripts-from.html#comment-form" title="16 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/419616687741790880/posts/default/4863767067160753501?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/419616687741790880/posts/default/4863767067160753501?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AndrewThompsonsBlog/~3/iuelbLjyWKI/how-to-generate-ddl-scripts-from.html" title="How To Generate DDL Scripts from Hibernate" /><author><name>J Andrew Thompson</name><uri>http://www.blogger.com/profile/12235539661156258840</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_oSRqocz1gN0/StyDv14L20I/AAAAAAAAAJk/h3f9tpUyjOo/S220/jt.jpg" /></author><thr:total>16</thr:total><feedburner:origLink>http://jandrewthompson.blogspot.com/2009/10/how-to-generate-ddl-scripts-from.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUMAQno6eSp7ImA9WxNVE0w.&quot;"><id>tag:blogger.com,1999:blog-419616687741790880.post-5346877130926121197</id><published>2009-10-22T13:43:00.013-05:00</published><updated>2009-10-23T10:57:23.411-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-23T10:57:23.411-05:00</app:edited><title>Event Driven Programming with Java - Monsoon</title><content type="html">I've recently been involved on an Adobe Flex project at work.  One of the things that I've really come to enjoy about Flex is its powerful event framework.  For instance, component A can say that it throws an OnSave event.  Component B says it listens for OnSave events.  Neither component has to know anything about each other, but when component A throws the event, B will automatically handle it.&lt;br /&gt;&lt;br /&gt;If you've been around Java for any length of time, you may have done some AWT or Swing development.  Here, we have a similar concept of events, but each listener has to register itself with whatever object might throw that event.  In the end, you end up with a tightly coupled web of connections and dependencies that, if not managed correctly, can quickly become a nightmare to maintain.&lt;br /&gt;&lt;br /&gt;Enter Monsoon.  I know that there are other event frameworks available, but could not find any that did exactly what I wanted (granted I didn't search that hard).  I also thought this would be an interesting challenge.  The idea is that all of the event plumbing is handled automatically via Java 1.5 Annotations.  An 'event' in this system can be any java object (POJO).  Methods that dispatch and listen for events both have the @Event annotation.  The return object from a dispatch method is used as the method parameter of the listening method.  For Example:&lt;br /&gt;&lt;br /&gt;&lt;div class="code panel" style="padding:3px;"&gt;@Event(name="saveUser", type=EventType.DISPATCHER)&lt;br /&gt;public User save()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;return user;&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="code panel" style="padding:3px;"&gt;@Event(name="saveUser", type=EventType.LISTENER)&lt;br /&gt;public void onSave(User user)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;//do something with user&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;If you're using Spring, configuration is trivial.  Just include an 'EventBeanPostProcessor' bean in your spring config.&lt;br /&gt;&lt;br /&gt;&lt;div class="code panel" style="padding:3px;"&gt;&amp;lt;bean class="org.jthompson.monsoon.spring.EventBeanPostProcessor"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;property name="managedBeanNames"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;list&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&amp;gt;dispatcher&amp;lt;/value&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;value&amp;gt;listener&amp;lt;/value&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/list&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Otherwise, you'll need to use the included ObjectFactory to generate your objects if you aren't using spring.&lt;br /&gt;&lt;br /&gt;&lt;div class="code panel" style="padding:3px;"&gt;&lt;br /&gt;Dispatcher dispatcher = (Dispatcher)factory.generateProxy(new Dispatcher());&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Monsoon will automatically discover the connections between dispatchers and listeners for you.  If you register three object that listen for a particular event, they will all be triggered automatically.&lt;br /&gt;&lt;br /&gt;This is still in an early phase of development and there is a lot of work yet to do.  However, if you find it useful or interesing in the least please let me know!&lt;br /&gt;&lt;br /&gt;You can get the latest version of Monsoon via maven here:&lt;br /&gt;&lt;a target="_blank" href="http://monsoon-events.googlecode.com/svn/trunk/repo/org/jthompson/monsoon/"&gt;http://monsoon-events.googlecode.com/svn/trunk/repo&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You can also browse the source code at my googlecode page:&lt;br /&gt;&lt;a href="http://code.google.com/p/monsoon-events/"&gt;http://code.google.com/p/monsoon-events/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/419616687741790880-5346877130926121197?l=jandrewthompson.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/f8qeh8L9Liy8Cy19M93WgJDAcbs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/f8qeh8L9Liy8Cy19M93WgJDAcbs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/f8qeh8L9Liy8Cy19M93WgJDAcbs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/f8qeh8L9Liy8Cy19M93WgJDAcbs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewThompsonsBlog/~4/VdG6fds8Yy4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jandrewthompson.blogspot.com/feeds/5346877130926121197/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jandrewthompson.blogspot.com/2009/10/event-driven-programming-with-java_22.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/419616687741790880/posts/default/5346877130926121197?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/419616687741790880/posts/default/5346877130926121197?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AndrewThompsonsBlog/~3/VdG6fds8Yy4/event-driven-programming-with-java_22.html" title="Event Driven Programming with Java - Monsoon" /><author><name>J Andrew Thompson</name><uri>http://www.blogger.com/profile/12235539661156258840</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_oSRqocz1gN0/StyDv14L20I/AAAAAAAAAJk/h3f9tpUyjOo/S220/jt.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://jandrewthompson.blogspot.com/2009/10/event-driven-programming-with-java_22.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUQBQXc6fyp7ImA9WxNVEU8.&quot;"><id>tag:blogger.com,1999:blog-419616687741790880.post-7285392734229352556</id><published>2009-10-21T07:12:00.002-05:00</published><updated>2009-10-21T07:15:50.917-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-21T07:15:50.917-05:00</app:edited><title>Alyssa's Bed</title><content type="html">I've recently started working on my latest project; a toddler bed for our little girl.  I didn't really want to spend a ton of money on a plastic/toy like bed that would only last a short time.  Plus, I thought it would be nice to have an heirloom piece that might get passed down through the family.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_oSRqocz1gN0/St77UJkqDsI/AAAAAAAAAKQ/qc2T32GlraE/s1600-h/bed2.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 200px; height: 168px;" src="http://3.bp.blogspot.com/_oSRqocz1gN0/St77UJkqDsI/AAAAAAAAAKQ/qc2T32GlraE/s400/bed2.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5395025727222058690" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I usually start out a new design on graph paper the old fasioned way.  You know, with a pencil, ruler, t-square and compass.  I'll then transfer any curves and such that I may need to full-scale cardboard templates.  This time I decided to use CAD  software to help with the design.  I discovered that I can print full-scale patterns on my printer in sections, then tape then together.  Man, that was easy!  I'll post the files here later if anyone is interested.&lt;br /&gt;&lt;br /&gt;As of now, I've got my plans and my cut list complete.  I also rough sketched out each part on the lumber I plan to use to make the most efficient use of the stock (maple).  Pics coming soon...&lt;br /&gt;&lt;br /&gt;&lt;a href="http://jandrewthompson.googlepages.com/bed.pdf"&gt;alyssa's bed.pdf&lt;/a&gt;&lt;br /&gt;&lt;a href="http://jandrewthompson.googlepages.com/bed.dwg"&gt;alyssa's bed.dwg&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/419616687741790880-7285392734229352556?l=jandrewthompson.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/JPh0sX3ACKWIR4HDMP3xzT4D1UA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JPh0sX3ACKWIR4HDMP3xzT4D1UA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/JPh0sX3ACKWIR4HDMP3xzT4D1UA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JPh0sX3ACKWIR4HDMP3xzT4D1UA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewThompsonsBlog/~4/BWa9PbNFiC4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jandrewthompson.blogspot.com/feeds/7285392734229352556/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jandrewthompson.blogspot.com/2009/10/alyssas-bed.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/419616687741790880/posts/default/7285392734229352556?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/419616687741790880/posts/default/7285392734229352556?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AndrewThompsonsBlog/~3/BWa9PbNFiC4/alyssas-bed.html" title="Alyssa's Bed" /><author><name>J Andrew Thompson</name><uri>http://www.blogger.com/profile/12235539661156258840</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_oSRqocz1gN0/StyDv14L20I/AAAAAAAAAJk/h3f9tpUyjOo/S220/jt.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_oSRqocz1gN0/St77UJkqDsI/AAAAAAAAAKQ/qc2T32GlraE/s72-c/bed2.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://jandrewthompson.blogspot.com/2009/10/alyssas-bed.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMDSXg_cSp7ImA9WxNRE0o.&quot;"><id>tag:blogger.com,1999:blog-419616687741790880.post-6655761091852140263</id><published>2009-09-07T21:28:00.006-05:00</published><updated>2009-09-07T21:37:58.649-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-07T21:37:58.649-05:00</app:edited><title>VW's Do Float</title><content type="html">How do I know this?  Unfortunately... personal experience.  My daily driver is a 1967 Volkswagen Beetle.  Driving home from work, I ran into some flash flooding.  Needless to say, I wound up drifting across an intersection in about a foot and a half of water.  I was pretty lucky that there was no major damage done.  I did suffer from a squeaky starter bushing for a while; easily fixable with a dab of wheel bearing grease.&lt;br /&gt;&lt;br /&gt;I did however have about 3 inches of water on my new floor pans.  When I welded them in last summer, I sealed them with 3M Fast-N-Firm seam sealer.  I now realize that was a mistake.  The stuff gets real brittle and doesn't seal worth a darn.  I chipped away the old sealant and used TigerSeal.  This is some really nice stuff.  It goes on easy, is polyurethane based, and is very flexible.  I'll definitely be using more of this stuff in the future&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/419616687741790880-6655761091852140263?l=jandrewthompson.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Xxn0mL2gZqM3mkeyC3Yk7yADn1s/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Xxn0mL2gZqM3mkeyC3Yk7yADn1s/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Xxn0mL2gZqM3mkeyC3Yk7yADn1s/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Xxn0mL2gZqM3mkeyC3Yk7yADn1s/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewThompsonsBlog/~4/FQefPHtx-9o" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jandrewthompson.blogspot.com/feeds/6655761091852140263/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jandrewthompson.blogspot.com/2009/09/vws-do-float.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/419616687741790880/posts/default/6655761091852140263?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/419616687741790880/posts/default/6655761091852140263?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AndrewThompsonsBlog/~3/FQefPHtx-9o/vws-do-float.html" title="VW's Do Float" /><author><name>J Andrew Thompson</name><uri>http://www.blogger.com/profile/12235539661156258840</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_oSRqocz1gN0/StyDv14L20I/AAAAAAAAAJk/h3f9tpUyjOo/S220/jt.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://jandrewthompson.blogspot.com/2009/09/vws-do-float.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk8AQn88eSp7ImA9WxVVGE8.&quot;"><id>tag:blogger.com,1999:blog-419616687741790880.post-3318380998909266926</id><published>2009-03-11T15:58:00.001-05:00</published><updated>2009-03-11T21:27:23.171-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-11T21:27:23.171-05:00</app:edited><title>Get This Party Started</title><content type="html">I just thought of starting this blog as a place to track my various musings, hobbies, etc.&lt;br /&gt;&lt;br /&gt;I'm a programmer by trade, but an air-cooled VW mechanic, musician, woodworker, electrical engineer, welder (and whatever else happens to catch my attention)  in my free time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/419616687741790880-3318380998909266926?l=jandrewthompson.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/-yFr6Nw2dde9ow3uHL1cju-Mt9s/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-yFr6Nw2dde9ow3uHL1cju-Mt9s/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/-yFr6Nw2dde9ow3uHL1cju-Mt9s/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-yFr6Nw2dde9ow3uHL1cju-Mt9s/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/AndrewThompsonsBlog/~4/mcTehAPK8dE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jandrewthompson.blogspot.com/feeds/3318380998909266926/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://jandrewthompson.blogspot.com/2009/03/get-this-party-started.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/419616687741790880/posts/default/3318380998909266926?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/419616687741790880/posts/default/3318380998909266926?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AndrewThompsonsBlog/~3/mcTehAPK8dE/get-this-party-started.html" title="Get This Party Started" /><author><name>J Andrew Thompson</name><uri>http://www.blogger.com/profile/12235539661156258840</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_oSRqocz1gN0/StyDv14L20I/AAAAAAAAAJk/h3f9tpUyjOo/S220/jt.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://jandrewthompson.blogspot.com/2009/03/get-this-party-started.html</feedburner:origLink></entry></feed>

