<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8205413125480841793</id><updated>2011-12-22T07:52:36.606-08:00</updated><category term='cooking'/><category term='couchdb'/><category term='google+'/><category term='javascript'/><category term='sms'/><category term='killer app'/><category term='networkmanager'/><category term='json-lib'/><category term='glassfish sjsas ssl java javaee'/><category term='garden'/><category term='maven'/><category term='social'/><category term='object graph'/><category term='api'/><category term='phone'/><category term='safety'/><category term='corn'/><category term='json.org'/><category term='netflix'/><category term='sdk'/><category term='spring'/><category term='grilling'/><category term='harvest'/><category term='nosql'/><category term='jackson'/><category term='facebook'/><category term='debug'/><category term='maven-gae-plugin'/><category term='document database'/><category term='motorcycle'/><category term='first friday'/><category term='flexjson'/><category term='java'/><category term='photography'/><category term='steak'/><category term='customer service'/><category term='restful'/><category term='adb'/><category term='fall'/><category term='cloud'/><category term='nexusone'/><category term='gae'/><category term='rest'/><category term='squash'/><category term='android'/><category term='captcha'/><category term='restlet'/><category term='jsog'/><category term='appengine'/><category term='phoenix art museum'/><category term='wireless'/><category term='call'/><category term='food'/><category term='twitter'/><category term='network'/><category term='pumpkin'/><category term='wicd'/><category term='ubuntu'/><category term='lensbaby'/><category term='json'/><category term='google'/><title type='text'>Jrod Blog</title><subtitle type='html'>Programming, System Administration, and everything else.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://jeffreyrodriguez.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://jeffreyrodriguez.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Jeff Rodriguez</name><uri>https://profiles.google.com/112699696841129477885</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-o4VSsXQXQ0Q/AAAAAAAAAAI/AAAAAAAAACU/JA6WfkBZ3F8/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>19</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8205413125480841793.post-759601526903687688</id><published>2011-11-15T17:13:00.001-08:00</published><updated>2011-12-06T13:12:44.017-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maven-gae-plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><category scheme='http://www.blogger.com/atom/ns#' term='gae'/><category scheme='http://www.blogger.com/atom/ns#' term='appengine'/><title type='text'>Automatically updating appengine-web.xml's version</title><content type='html'>If you're using AppEngine in Java land, you're probably using maven with maven-gae-plugin. If you're not, why aren't you?&lt;br /&gt;&lt;br /&gt;Anyway, since you already have a project version, why not leverage that in appengine-web.xml's version tag?&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: xml" title="pom.xml"&gt;&lt;br /&gt;&amp;lt;build&amp;gt;&lt;br /&gt;  &amp;lt;plugins&amp;gt;&lt;br /&gt;   &amp;lt;finalName&amp;gt;${project.artifactId}&amp;lt;/finalName&amp;gt;&lt;br /&gt;   &amp;lt;!-- Sets the version in appengine-web.xml --&amp;gt;&lt;br /&gt;    &amp;lt;plugin&amp;gt;&lt;br /&gt;      &amp;lt;groupId&amp;gt;com.google.code.maven-replacer-plugin&amp;lt;/groupId&amp;gt;&lt;br /&gt;      &amp;lt;artifactId&amp;gt;maven-replacer-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;      &amp;lt;version&amp;gt;1.3.9&amp;lt;/version&amp;gt;&lt;br /&gt;      &amp;lt;executions&amp;gt;&lt;br /&gt;          &amp;lt;execution&amp;gt;&lt;br /&gt;        &amp;lt;phase&amp;gt;package&amp;lt;/phase&amp;gt;&lt;br /&gt;        &amp;lt;goals&amp;gt;&lt;br /&gt;            &amp;lt;goal&amp;gt;replace&amp;lt;/goal&amp;gt;&lt;br /&gt;        &amp;lt;/goals&amp;gt;&lt;br /&gt;          &amp;lt;/execution&amp;gt;&lt;br /&gt;      &amp;lt;/executions&amp;gt;&lt;br /&gt;      &amp;lt;configuration&amp;gt;&lt;br /&gt;          &amp;lt;file&amp;gt;target/${project.artifactId}/WEB-INF/appengine-web.xml&amp;lt;/file&amp;gt;&lt;br /&gt;          &amp;lt;replacements&amp;gt;&lt;br /&gt;        &amp;lt;replacement&amp;gt;&lt;br /&gt;            &amp;lt;token&amp;gt;%%VERSION%%&amp;lt;/token&amp;gt;&lt;br /&gt;            &amp;lt;value&amp;gt;${project.version}&amp;lt;/value&amp;gt;&lt;br /&gt;        &amp;lt;/replacement&amp;gt;         &lt;br /&gt;          &amp;lt;/replacements&amp;gt;&lt;br /&gt;      &amp;lt;/configuration&amp;gt;&lt;br /&gt;    &amp;lt;/plugin&amp;gt;&lt;br /&gt;  &amp;lt;/plugins&amp;gt;&lt;br /&gt;&amp;lt;/build&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class="brush: xml" title="appengine-web.xml"&gt;&lt;br /&gt;&amp;lt;appengine-web-app xmlns="http://appengine.google.com/ns/1.0"&amp;gt;&lt;br /&gt;  ...&lt;br /&gt;  &amp;lt;version&amp;gt;%%VERSION%%&amp;lt;/version&amp;gt;&lt;br /&gt;  ...&lt;br /&gt;&amp;lt;/appengine-web-app&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And that's it. When you execute gae:run, gae:deploy, etc, the version will be set automatically.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8205413125480841793-759601526903687688?l=jeffreyrodriguez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreyrodriguez.blogspot.com/feeds/759601526903687688/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8205413125480841793&amp;postID=759601526903687688' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/759601526903687688'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/759601526903687688'/><link rel='alternate' type='text/html' href='http://jeffreyrodriguez.blogspot.com/2011/11/automatically-updating-appengine.html' title='Automatically updating appengine-web.xml&apos;s version'/><author><name>Jeff Rodriguez</name><uri>https://profiles.google.com/112699696841129477885</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-o4VSsXQXQ0Q/AAAAAAAAAAI/AAAAAAAAACU/JA6WfkBZ3F8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8205413125480841793.post-3825690298292082368</id><published>2011-11-07T12:33:00.000-08:00</published><updated>2011-11-15T18:59:11.551-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='captcha'/><category scheme='http://www.blogger.com/atom/ns#' term='call'/><category scheme='http://www.blogger.com/atom/ns#' term='api'/><category scheme='http://www.blogger.com/atom/ns#' term='cloud'/><category scheme='http://www.blogger.com/atom/ns#' term='sms'/><category scheme='http://www.blogger.com/atom/ns#' term='phone'/><title type='text'>Call Me CAPTCHA Launched!</title><content type='html'>I launched my new service last night, &lt;a href="http://www.callmecaptcha.com/" target="_blank"&gt;Call Me CAPTCHA&lt;/a&gt;. I've been hacking on this project for a little while in my spare time.&lt;br /&gt;&lt;br /&gt;Instead of trying to decipher more and more distorted random letters in a CAPTCHA image, why not leverage a system that's already fairly secure, ubiquitous, and easy to use: your phone. The distorted image CAPTCHA is already effectively broken, spammers can either use CPU cycles to break these or they can use humans for it. Yep, you can get paid to break CAPTCHAs; if you're running a bot, that's $2.00 per 1,000 CAPTCHAs.&lt;br /&gt;&lt;br /&gt;You've probably seen a phone-based CAPTCHA before. The first instance I can remember is MySpace, then Google, now sites like Bank of America's with "SafePass". Well, I'd call these companies "the big boys". But what if you're a smaller site that can't afford to build a system like this, or even a large site that would rather use an off-the-shelf service? There weren't really any options until Call Me CAPTCHA.&lt;br /&gt;&lt;br /&gt;If you've used reCAPTCHA before, you'll notice a lot of similarities; the APIs are very similar. reCAPTCHA is wildly popular, so I used them as a model for my system.&lt;br /&gt;&lt;br /&gt;So if you're unhappy with the protection afforded by image-based CAPTCHAs, and need something more robust and easier to use, head on over and check out &lt;a href="http://www.callmecaptcha.com/" target="_blank"&gt;Call Me CAPTCHA&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8205413125480841793-3825690298292082368?l=jeffreyrodriguez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreyrodriguez.blogspot.com/feeds/3825690298292082368/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8205413125480841793&amp;postID=3825690298292082368' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/3825690298292082368'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/3825690298292082368'/><link rel='alternate' type='text/html' href='http://jeffreyrodriguez.blogspot.com/2011/11/call-me-captcha-launched.html' title='Call Me CAPTCHA Launched!'/><author><name>Jeff Rodriguez</name><uri>https://profiles.google.com/112699696841129477885</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-o4VSsXQXQ0Q/AAAAAAAAAAI/AAAAAAAAACU/JA6WfkBZ3F8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8205413125480841793.post-3779998771767473793</id><published>2011-07-12T21:38:00.000-07:00</published><updated>2011-07-13T10:03:38.862-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google+'/><category scheme='http://www.blogger.com/atom/ns#' term='social'/><category scheme='http://www.blogger.com/atom/ns#' term='facebook'/><category scheme='http://www.blogger.com/atom/ns#' term='twitter'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='killer app'/><title type='text'>Google+ is Killer</title><content type='html'>It's very easy to group your friends in different groups. Groups are like the ubiquitous "label", but for your friends. Group friends by degree (best, good, proxy, acquaintance, etc), or by classification (family, extended family, friends, professional), or even by interest (hiking, photography, school)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I have a lot of friends that I would like to keep up with, but I don't have time to. Some of these are old circles of friends from high school, or an old job, or my long distance best friends. I touched base with two different groups today, people that I really like, but haven't talked to or seen for months. Hangouts make this really easy. Hangouts are basically like private chatrooms with video meets social networking. I can foresee hangouts becoming incredible tools for all kinds of things:&lt;br /&gt;&lt;br /&gt;Townhalls. I watched host the first townhall on Google+. If Google can really go to town with the Hangout technology, I can see the digital townhall becoming an incredible political tool. Imagine the power of being able to organize an actual town hall (moderation tools and all) for absolutely no cost.&lt;br /&gt;&lt;br /&gt;Hangouts could also be chat rooms. A really good example already exists; User Plane. It's basically IRC meets Hangouts.&lt;br /&gt;&lt;br /&gt;If posts become rich-text enabled with a WYSIWIG editor, the "Public" visibility option could become a good blog replacement.&lt;br /&gt;&lt;br /&gt;With the Android phone application, it's also an excellent microblogging platform.&lt;br /&gt;&lt;br /&gt;Google+ is a great new social tool, and if Google can play it's cards right, it could be the next killer social app.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Update: &lt;/span&gt;Actually, now that I think about it. Google+ is what Google Wave &lt;span style="font-weight:bold;"&gt;should&lt;/span&gt; have been.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Update 2:&lt;/span&gt; Circles are another powerful aspect of Google+. Now I can easily use the same social platform for my professional, and private faces. Google+ is a threat for Facebook &lt;span style="font-style:italic;"&gt;and&lt;/span&gt; LinkedIn.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8205413125480841793-3779998771767473793?l=jeffreyrodriguez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreyrodriguez.blogspot.com/feeds/3779998771767473793/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8205413125480841793&amp;postID=3779998771767473793' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/3779998771767473793'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/3779998771767473793'/><link rel='alternate' type='text/html' href='http://jeffreyrodriguez.blogspot.com/2011/07/google-plus-is-killer.html' title='Google+ is Killer'/><author><name>Jeff Rodriguez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-n_Uh7GUf3cs/Tndpa_3WnSI/AAAAAAAAGaQ/SxO70b7VhrQ/s220/abide.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8205413125480841793.post-8542440353743475063</id><published>2011-06-03T09:21:00.000-07:00</published><updated>2011-06-03T10:16:17.096-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='restful'/><category scheme='http://www.blogger.com/atom/ns#' term='rest'/><category scheme='http://www.blogger.com/atom/ns#' term='restlet'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='jsog'/><category scheme='http://www.blogger.com/atom/ns#' term='json'/><title type='text'>RESTful JSON web services with JSOG and Spring</title><content type='html'>Before I originally developed JSOG, we were using the json.org library and Restlet. Our needs were pretty basic, we were just GETting and POSTing JSON strings between services. Later we ended up using some JSONP.&lt;br /&gt;&lt;br /&gt;My biggest beef with Restlet is there doesn't seem to be a good way to unit test it. From what I can tell, the convention is to keep all your logic outside of Restlet and use it only to expose the REST interface. I'm also a heavy spring user, and it occurred to me very quickly that Restlet's integration with Spring was... complicated.&lt;br /&gt;&lt;br /&gt;So, instead of jumping through Restlet's hoops, JSOG now integrates very easily with Spring MVC. Note, there are two ways of &lt;a href="http://jsog.sourceforge.net/docs/spring_mvc.html"&gt;integrating JSOG with Spring&lt;/a&gt;. We're going to be using the "Flexible" approach, and we'll be using a JSON-specific DispatcherServlet that handles all &lt;b&gt;*.json&lt;/b&gt; requests. This basic example should show you how add RESTful services to your application.&lt;br /&gt;&lt;br /&gt;First, we'll need the dependencies. I'm using Maven; so here's what a minimal POM looks like.&lt;br /&gt;&lt;b&gt;pom.xml&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;project xmlns=&amp;quot;http://maven.apache.org/POM/4.0.0&amp;quot; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;         xsi:schemaLocation=&amp;quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;&lt;br /&gt;    &amp;lt;groupId&amp;gt;jsogws&amp;lt;/groupId&amp;gt;&lt;br /&gt;    &amp;lt;artifactId&amp;gt;jsogws&amp;lt;/artifactId&amp;gt;&lt;br /&gt;    &amp;lt;packaging&amp;gt;war&amp;lt;/packaging&amp;gt;&lt;br /&gt;    &amp;lt;version&amp;gt;1.0-SNAPSHOT&amp;lt;/version&amp;gt;&lt;br /&gt;    &amp;lt;name&amp;gt;jsogws&amp;lt;/name&amp;gt;&lt;br /&gt;    &amp;lt;url&amp;gt;http://maven.apache.org&amp;lt;/url&amp;gt;&lt;br /&gt;    &amp;lt;properties&amp;gt;&lt;br /&gt;        &amp;lt;spring.version&amp;gt;3.0.5.RELEASE&amp;lt;/spring.version&amp;gt;&lt;br /&gt;    &amp;lt;/properties&amp;gt;&lt;br /&gt;    &amp;lt;dependencies&amp;gt;&lt;br /&gt;        &amp;lt;dependency&amp;gt;&lt;br /&gt;            &amp;lt;groupId&amp;gt;net.sf.jsog&amp;lt;/groupId&amp;gt;&lt;br /&gt;            &amp;lt;artifactId&amp;gt;jsog&amp;lt;/artifactId&amp;gt;&lt;br /&gt;            &amp;lt;version&amp;gt;0.30&amp;lt;/version&amp;gt;&lt;br /&gt;        &amp;lt;/dependency&amp;gt;&lt;br /&gt;        &amp;lt;dependency&amp;gt;&lt;br /&gt;            &amp;lt;groupId&amp;gt;commons-io&amp;lt;/groupId&amp;gt;&lt;br /&gt;            &amp;lt;artifactId&amp;gt;commons-io&amp;lt;/artifactId&amp;gt;&lt;br /&gt;            &amp;lt;version&amp;gt;2.0&amp;lt;/version&amp;gt;&lt;br /&gt;        &amp;lt;/dependency&amp;gt;&lt;br /&gt;        &amp;lt;dependency&amp;gt;&lt;br /&gt;            &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;&lt;br /&gt;            &amp;lt;artifactId&amp;gt;spring-core&amp;lt;/artifactId&amp;gt;&lt;br /&gt;            &amp;lt;version&amp;gt;${spring.version}&amp;lt;/version&amp;gt;&lt;br /&gt;        &amp;lt;/dependency&amp;gt;&lt;br /&gt;        &amp;lt;dependency&amp;gt;&lt;br /&gt;            &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;&lt;br /&gt;            &amp;lt;artifactId&amp;gt;spring-context&amp;lt;/artifactId&amp;gt;&lt;br /&gt;            &amp;lt;version&amp;gt;${spring.version}&amp;lt;/version&amp;gt;&lt;br /&gt;        &amp;lt;/dependency&amp;gt;&lt;br /&gt;        &amp;lt;dependency&amp;gt;&lt;br /&gt;            &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;&lt;br /&gt;            &amp;lt;artifactId&amp;gt;spring-webmvc&amp;lt;/artifactId&amp;gt;&lt;br /&gt;            &amp;lt;version&amp;gt;${spring.version}&amp;lt;/version&amp;gt;&lt;br /&gt;        &amp;lt;/dependency&amp;gt;&lt;br /&gt;        &amp;lt;dependency&amp;gt;&lt;br /&gt;            &amp;lt;groupId&amp;gt;junit&amp;lt;/groupId&amp;gt;&lt;br /&gt;            &amp;lt;artifactId&amp;gt;junit&amp;lt;/artifactId&amp;gt;&lt;br /&gt;            &amp;lt;version&amp;gt;3.8.2&amp;lt;/version&amp;gt;&lt;br /&gt;            &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;&lt;br /&gt;        &amp;lt;/dependency&amp;gt;&lt;br /&gt;    &amp;lt;/dependencies&amp;gt;&lt;br /&gt;    &amp;lt;build&amp;gt;&lt;br /&gt;        &amp;lt;plugins&amp;gt;&lt;br /&gt;            &amp;lt;plugin&amp;gt;&lt;br /&gt;                &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;&lt;br /&gt;                &amp;lt;artifactId&amp;gt;maven-compiler-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;                &amp;lt;version&amp;gt;2.0.2&amp;lt;/version&amp;gt;&lt;br /&gt;                &amp;lt;configuration&amp;gt;&lt;br /&gt;                    &amp;lt;source&amp;gt;1.6&amp;lt;/source&amp;gt;&lt;br /&gt;                    &amp;lt;target&amp;gt;1.6&amp;lt;/target&amp;gt;&lt;br /&gt;                &amp;lt;/configuration&amp;gt;&lt;br /&gt;            &amp;lt;/plugin&amp;gt;&lt;br /&gt;            &amp;lt;plugin&amp;gt;&lt;br /&gt;                &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;&lt;br /&gt;                &amp;lt;artifactId&amp;gt;maven-war-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;                &amp;lt;version&amp;gt;2.1-beta-1&amp;lt;/version&amp;gt;&lt;br /&gt;                &amp;lt;configuration&amp;gt;&lt;br /&gt;                    &amp;lt;failOnMissingWebXml&amp;gt;false&amp;lt;/failOnMissingWebXml&amp;gt;&lt;br /&gt;                &amp;lt;/configuration&amp;gt;&lt;br /&gt;            &amp;lt;/plugin&amp;gt;&lt;br /&gt;        &amp;lt;/plugins&amp;gt;&lt;br /&gt;        &amp;lt;finalName&amp;gt;jsogws&amp;lt;/finalName&amp;gt;&lt;br /&gt;    &amp;lt;/build&amp;gt;&lt;br /&gt;    &amp;lt;repositories&amp;gt;&lt;br /&gt;        &amp;lt;repository&amp;gt;&lt;br /&gt;            &amp;lt;id&amp;gt;jsog.sourceforge.net&amp;lt;/id&amp;gt;&lt;br /&gt;            &amp;lt;url&amp;gt;http://jsog.sourceforge.net/m2-repo&amp;lt;/url&amp;gt;&lt;br /&gt;        &amp;lt;/repository&amp;gt;&lt;br /&gt;    &amp;lt;/repositories&amp;gt;&lt;br /&gt;&amp;lt;/project&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Well that's a fair chunk of configuration. Basically, we're importing JSOG from the JSOG maven repository. We also import the relevant Spring artifacts and Commons IO.&lt;br /&gt;&lt;br /&gt;Next up, we need to configure the DispatcherServlet.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;web.xml&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;&amp;lt;web-app xmlns=&amp;quot;http://java.sun.com/xml/ns/javaee&amp;quot;&lt;br /&gt;  xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;  xsi:schemaLocation=&amp;quot;http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd&amp;quot;&lt;br /&gt;  version=&amp;quot;3.0&amp;quot;&amp;gt;&lt;br /&gt;    &lt;br /&gt;    &amp;lt;!-- JSOG web services --&amp;gt;&lt;br /&gt;    &amp;lt;servlet&amp;gt;&lt;br /&gt;        &amp;lt;servlet-name&amp;gt;jsog&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;        &amp;lt;servlet-class&amp;gt;org.springframework.web.servlet.DispatcherServlet&amp;lt;/servlet-class&amp;gt;&lt;br /&gt;        &amp;lt;load-on-startup&amp;gt;0&amp;lt;/load-on-startup&amp;gt;&lt;br /&gt;    &amp;lt;/servlet&amp;gt;&lt;br /&gt;    &amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;        &amp;lt;servlet-name&amp;gt;jsog&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;        &amp;lt;url-pattern&amp;gt;*.json&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;    &amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/web-app&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here we map every &lt;b&gt;*.json&lt;/b&gt; request to the DispatcherServlet named "jsog".&lt;br /&gt;&lt;br /&gt;Now we need to configure the dispatcher servlet. We used the default configuration file name, in this case:&lt;br /&gt;&lt;b&gt;jsog-servlet.xml&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;br /&gt;       xmlns:context=&amp;quot;http://www.springframework.org/schema/context&amp;quot;&lt;br /&gt;       xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;       xsi:schemaLocation=&amp;quot;&lt;br /&gt;       http://www.springframework.org/schema/beans&lt;br /&gt;       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd&lt;br /&gt;&lt;br /&gt;       http://www.springframework.org/schema/context&lt;br /&gt;       http://www.springframework.org/schema/context/spring-context-3.0.xsd&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;!-- Look for controllers --&amp;gt;&lt;br /&gt;    &amp;lt;context:component-scan base-package=&amp;quot;jsogws.services.json&amp;quot;/&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;!-- All controllers managed by this servlet should use the JsogViewResolver --&amp;gt;&lt;br /&gt;    &amp;lt;bean id=&amp;quot;viewResolver&amp;quot; class=&amp;quot;net.sf.jsog.spring.JsogViewResolver&amp;quot;/&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;!-- We need this to consume JSOG that has been sent in the request body --&amp;gt;&lt;br /&gt;    &amp;lt;bean class=&amp;quot;org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter&amp;quot;&amp;gt;&lt;br /&gt;        &amp;lt;property name=&amp;quot;messageConverters&amp;quot;&amp;gt;&lt;br /&gt;            &amp;lt;list&amp;gt;&lt;br /&gt;                &amp;lt;bean class=&amp;quot;net.sf.jsog.spring.StringJsogHttpMessageConverter&amp;quot;/&amp;gt;&lt;br /&gt;            &amp;lt;/list&amp;gt;&lt;br /&gt;        &amp;lt;/property&amp;gt;&lt;br /&gt;    &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/beans&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In this configuration file, we tell the DispatcherServlet to look for "@Controller" annotated classes in &lt;b&gt;jsogws.services.json&lt;/b&gt;. Then we setup the JsogViewResolver, which tells Spring to create and use a JsogView whenever we return a JSOG object in a controller. (JsogView does the lion's share of the work). We also setup a MessageConverter so we can consume JSON.&lt;br /&gt;&lt;br /&gt;Note that at this point, most of this is pretty standard Spring stuff. The MessageConverter and ViewResolver are the most "abnormal" things in here: about 8 lines of boilerplate configuration.&lt;br /&gt;&lt;br /&gt;From this point, creating a JSON-based RESTful service is just about like creating any other RESTful service.&lt;br /&gt;&lt;br /&gt;Let's take a look at a Hello World example:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;HelloJsog.java&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package jsogws.services.json;&lt;br /&gt;&lt;br /&gt;import net.sf.jsog.JSOG;&lt;br /&gt;import org.springframework.stereotype.Controller;&lt;br /&gt;import org.springframework.web.bind.annotation.RequestBody;&lt;br /&gt;import org.springframework.web.bind.annotation.RequestMapping;&lt;br /&gt;import org.springframework.web.bind.annotation.RequestMethod;&lt;br /&gt;&lt;br /&gt;@Controller&lt;br /&gt;public class HelloJsog {&lt;br /&gt;&lt;br /&gt;    @RequestMapping(value="/hello.json", method=RequestMethod.GET)&lt;br /&gt;    public JSOG hello() {&lt;br /&gt;        return JSOG.object("Hello", "World!");&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @RequestMapping(value="/hello.json", method=RequestMethod.POST)&lt;br /&gt;    public JSOG hello(@RequestBody JSOG request) {&lt;br /&gt;        String name = request.get("name").getStringValue();&lt;br /&gt;        return JSOG.object("Hello", name);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This class defines two methods:&lt;br /&gt;One accepts a GET request and responds with an object: {"Hello", "World!"}.&lt;br /&gt;&lt;br /&gt;The other accepts a object via POST, that contains a "name" property. It returns an object with the name: {"Hello", "foo"}.&lt;br /&gt;&lt;br /&gt;That's all there is to creating RESTful JSON web services with JSOG and Spring. If you're wondering "what's RESTful about this?" Check out Spring's @PathVariable annotation. Wiring the rest together is elementary.&lt;br /&gt;&lt;br /&gt;A quick gotcha: When you send data to your services, you need to use the content type "application/json" and the encoding ISO-8859-1. These are modifiable through properties on the JsogViewResolver and StringJsogHttpMessageConverter.&lt;br /&gt;&lt;br /&gt;You also get JSONP for free. Append ?callback=foo and "foo" becomes your callback method. The name of this parameter is settable in JsogViewResolver, but will work with jQuery by default.&lt;br /&gt;&lt;br /&gt;Now your web services use the same framework style as everything else in your application, and can easily be unit tested.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Download&lt;/b&gt;&lt;br /&gt;&lt;a href="https://sites.google.com/site/jeffreyrodriguez/jsogws.tgz"&gt;jsogws.tgz&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8205413125480841793-8542440353743475063?l=jeffreyrodriguez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreyrodriguez.blogspot.com/feeds/8542440353743475063/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8205413125480841793&amp;postID=8542440353743475063' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/8542440353743475063'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/8542440353743475063'/><link rel='alternate' type='text/html' href='http://jeffreyrodriguez.blogspot.com/2011/06/restful-json-web-services-with-jsog-and.html' title='RESTful JSON web services with JSOG and Spring'/><author><name>Jeff Rodriguez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-n_Uh7GUf3cs/Tndpa_3WnSI/AAAAAAAAGaQ/SxO70b7VhrQ/s220/abide.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8205413125480841793.post-3285833356943969934</id><published>2011-05-26T11:14:00.001-07:00</published><updated>2011-05-26T11:16:33.790-07:00</updated><title type='text'>A trip down the number line</title><content type='html'>This was written by the Fark.com user Hector_Lemans, 2009-09-12 09:43:17 PM&lt;br /&gt;&lt;br /&gt;I've tried to track it down online, perhaps it was an article from somewhere else, but it looks like it's original. I'm cleaning out my Google notebook, and wanted to keep it here for posterity.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;I've always been fascinated by large numbers. As a child, I would occasionally play the "one-up" game with my friends. Perhaps you've played this game. Two kids disagree about something and one says "bet you a hundred bucks it's not!" The other one retorts "bet you a million bucks it is!" And so on into infinity...which we usually got to rather quickly. But there are quite a few numbers between 100 and infinity. I'd like to take you, dear reader, on a trip to visit a handful of those numbers in the hope that you too can share in my wonderment of big numbers. So grab a power-bar, put on some running shoes, and let's begin.&lt;br /&gt;&lt;br /&gt;Our journey will be entirely on the number line. As you may recall from grade school, the number line is a straight line with the counting numbers ticked off at regular intervals.&lt;br /&gt;&lt;br /&gt;We start at point zero and begin moving straight ahead. We haven't worked out in a while so we're kind of slow off the starting blocks, but fairly quickly we pass 1, then 2, then 10, then 20. Now we're picking up some speed! As we pass 100, we notice that about a quarter of the numbers we just passed by were bold. As it turns out, we are on a special number line that has all the prime numbers in bold. Prime numbers are numbers that can only be evenly divided by 1 and themselves. So, for instance, 37 is a prime, because there is no other number we can divide it by (besides 1 and 37) that will give us another whole number. The fact that our number line bolds all of these primes is merely a curiosity...for now.&lt;br /&gt;&lt;br /&gt;Fairly quickly, we pass 1,000; then 10,000; then 100,000. Now we pass the smallest of our big numbers: one million. A million dollars is what most people define as rich. Even a million pennies add up to $10,000 - not exactly chump change. You would need to flip a coin a million times before having a fair chance of getting 20 tails in a row. In other ways, though, one million isn't that big at all. One million seconds is just over 11 days. A million feet is only 190 miles - a few hours trip in the car. Ten good-sized novels contain a million words. Let's continue on.&lt;br /&gt;&lt;br /&gt;We pass 5 million, 50 million, 500 million, and still we are gathering speed. By the time we hit one billion, barely 5% of the numbers we pass are bold prime numbers. A billion seconds is 32 years. A billion feet is 190 thousand miles - that's over three-quarters of the way to the moon! On the other hand, a large drop of blood has about a billion red blood cells in it. Several thousand public companies in the US have a market capitalization of over a billion dollars. So let's continue on in our search for big numbers.&lt;br /&gt;&lt;br /&gt;50 billion, 500 billion, one trillion. Now we're approaching the high end of any numbers that come up in everyday conversation. The US debt stands at almost five trillion dollars. One trillion seconds is over 31,000 years - far older than recorded history and deep in the middle of the last ice age. One trillion feet is approximately the diameter of the earth's orbit around the sun. One light-year (the distance light travels in a year) is about six trillion miles. Alpha Centauri, our nearest neighboring star, is about 4.4 light-years distant. Going there in the space shuttle would take about 38,000 years. You would need to flip a coin at least a trillion times to have a fair chance of getting 40 tails in a row...but at 3 seconds a flip, that would take about 95,000 years. Think 3 seconds a flip is too fast? Take 5 seconds a flip and you're up to 160,000 years. On the other hand, one trillion drops of water is only a few hundred thousand gallons - a big pond. Most laptop computers can perform a trillion calculations in under half an hour. The average person is made up of about 50 trillion cells. Onward we go.&lt;br /&gt;&lt;br /&gt;We pass 100 trillion and on to a quadrillion. It's hard to make out the numbers as they whiz past us, but a bit less than 3% - every 30th number or so - is a prime. That's interesting. Going from zero to a million, the concentration of primes dropped by over 95%, but going from a million to a quadrillion drops the concentration down only two more percent. Obviously, the primes are thinning out, but at a greatly decreasing rate. Will we soon pass by the last one? Let's find out.&lt;br /&gt;&lt;br /&gt;We pass 100 quadrillion, then make our way into the quintillions. Our nearest neighboring galaxy, Andromeda, is about 15 quintillion miles away. We speed up a bit and find ourselves in the sextillions. At least, that is their official name. Another, more helpful way of visualizing these numbers is by scientific notation. Using this notation, one sextillion is 10^21. The little superscript 21 to the right of the 10 means we multiply the 10 by itself, 21 times. So 1,000 would be 10^3 (10 x 10 x 10), and 1,000,000 would be 10^6. Notice that the superscript also tells us how many zeros are in the number if written out in full.&lt;br /&gt;&lt;br /&gt;We pass the sextillions by and move on into the septillions (10^24). From high school chemistry class, you may recall a unit of measurement called the mole. One mole of any element has the same number of atoms: 6 x 10^23, or just under one septillion. One mole of gold is a bit less than half a pound. One mole of hydrogen gas weighs only a gram. Coincidently, the visible universe is also about 6 x 10^23 miles across, or 93 billion light-years. The earth weighs (if you could weigh the earth!) 10 septillion pounds.&lt;br /&gt;&lt;br /&gt;Fast and faster we go. The number line is a blur of gigantic numbers, with about every 100th one in bold. I say "about" because there doesn't seem to be any real pattern to how the prime numbers are spaced out - sometimes a couple primes will be within two or three numbers of each other, and other times there will be thousands of numbers between two consecutive primes. No matter, onward we must go.&lt;br /&gt;&lt;br /&gt;In no time at all, we are deep in the octillions (10^27). The human body contains approximately 7 x 10^27 atoms. If we divide that by the 50 trillion cells we estimated earlier, we find the average human cell contains over 100 trillion atoms. Think about that - each cell in your body is constructed of more atoms than there are bricks in the Great Wall of China!&lt;br /&gt;&lt;br /&gt;We put on a burst of speed and race past the next several large numbers. Nonillion (10^30), decillion (10^33)...the names don't mean much anymore. It's easier to just go by the scientific notation. We move on past 10^50 - approximately how many times you'd have to flip a coin to have a good shot at getting 150 tails in a row. As we move up to 10^70 and beyond, we start approaching the limits of anything physical these gigantic numbers can be compared to. The known universe has 10^80 atoms (give or take). If we assume the universe is a sphere, 93 billion light-years in diameter, that amounts to less than one atom per cubic foot! We live in a universe of mostly empty space.&lt;br /&gt;&lt;br /&gt;Huffing and puffing, we finally make it to a truly, incredible, gi-normous number: a googol. A one followed by a hundred zeros - 10^100. The name "googol" was coined by a professor's nine-year-old nephew when asked to think up a name for a really big number. Have we run out of primes yet? Not hardly - less than half a percent of the numbers we run across are primes, but that still works out to 1 out of every 230, on average. Now, take a deep breath and scarf down that power bar. To reach our last few big numbers, we're going to have to sprint.&lt;br /&gt;&lt;br /&gt;We blow past a googol and make our way up to 10^124. This is the number of particles you'd have if the universe were nothing but a solid mass of electrons - no empty space at all. We run past 10^155 and bump into some numbers used every day by millions of people! Notice how random those bold prime numbers always appear to be, no matter how far across the number line we go? Turns out, that randomness makes them perfect for encoding sensitive data - like a credit card number - and transmitting that information over the Internet. The actual process is quite complicated (as you might expect), but the essential steps are as follows: Two very large prime numbers are chosen and kept secret by the bank. These two primes are then multiplied together to form a huge composite number. This composite number is given to the person with the credit card, and is used to encode the credit card information, which is then sent back to the bank. The bank, having the original two primes the composite number came from, factors them out and retrieves the data. The beauty of the system is that the encoding using the huge composite number is a one-way process if you don't know the primes it is made of - factoring composite numbers with upwards of 155 digits is next to impossible, even with the fastest computers. So it doesn't matter if someone figures out the composite number you're using, they still can't decrypt an encoded message.&lt;br /&gt;&lt;br /&gt;From here on out, most of the interesting numbers we'll run across will be prime numbers. Mathematicians like to find and collect huge primes, like some sort of super nerdy baseball card collector. The late Samuel Yates collected what he called Titanic primes - prime numbers with more than 1,000 digits. Chris Caldwell, of the University of Tennessee, took up the torch after Yates' death in 1991 and stores a list of these large primes on the Internet, with a new category for prime numbers with more than 5,000 digits called Gigantic primes. Several of these primes are quite strange. One, that has 5,114 digits, is composed of only 1s and 0s. Another, with 6,400 digits, is all 9s except for one 8. Currently, the largest known prime, discovered on September 4th, 2006 is just shy of ten million digits long. As we reach it on the number line, we marvel at its size. Written in exponential notation (similar to scientific notation but the base number doesn't have to be ten), the current largest prime number is 2^32,582,657 - 1.&lt;br /&gt;&lt;br /&gt;And now, let us accelerate to a speed only possible in our mind's eye. Numbers blur together, numbers so big that just writing them down in full would be a problem in the real world...not enough paper! On and on we go. There it is, just up ahead - the number that will end our journey. We slow down from our impossibly fast pace and stop on the number line directly over this stupendous number. A googolplex - a one followed by a googol zeros. If the whole universe were nothing but paper and ink, you still couldn't even write down the number in full (never mind trying to imagine how big it is). This is the end of our journey, but we can look ahead and see even bigger numbers...a tiny select few are even in bold. We still haven't run out of primes! Do the primes ever end? Does this number line ever end? Does infinity really exist? Just because we can say a thing doesn't make it real or even possible - I can describe a universe in which 2 + 2 = 5 or a square is round, but that doesn't mean a place like that could exist...does it? If we squint our eyes and look really hard, we can see a number so large that no number appears to follow it. It's a number so large we can't even describe it in words. Is that the last number? Only one way to find out. Let's go...last one there is a rotten egg!&lt;br /&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8205413125480841793-3285833356943969934?l=jeffreyrodriguez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreyrodriguez.blogspot.com/feeds/3285833356943969934/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8205413125480841793&amp;postID=3285833356943969934' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/3285833356943969934'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/3285833356943969934'/><link rel='alternate' type='text/html' href='http://jeffreyrodriguez.blogspot.com/2011/05/trip-down-number-line.html' title='A trip down the number line'/><author><name>Jeff Rodriguez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-n_Uh7GUf3cs/Tndpa_3WnSI/AAAAAAAAGaQ/SxO70b7VhrQ/s220/abide.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8205413125480841793.post-8655217472107825780</id><published>2011-03-25T11:47:00.000-07:00</published><updated>2011-03-25T11:55:27.910-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nexusone'/><category scheme='http://www.blogger.com/atom/ns#' term='debug'/><category scheme='http://www.blogger.com/atom/ns#' term='sdk'/><category scheme='http://www.blogger.com/atom/ns#' term='phone'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><category scheme='http://www.blogger.com/atom/ns#' term='adb'/><title type='text'>Nexus One Debugging</title><content type='html'>I was having trouble getting ADB from the Android SDK to recognize my phone under Windows 7, here's how I fixed it.&lt;br /&gt;&lt;br /&gt;1. Start the Android SDK and AVD Manager.&lt;br /&gt;2. Select "Available packages" on the left.&lt;br /&gt;3. Navigate to: Third party Add-ons &gt; Google Inc. &gt; Google USB Driver package&lt;br /&gt;4. Click "Install Selected" and proceed through the dialogs.&lt;br /&gt;5. Connect your phone&lt;br /&gt;6. Start the "Device Manager" management application, and locate your phone.&lt;br /&gt;7. It should say it's not recognized, right click on your phone and click "Update Driver Software". &lt;br /&gt;8. Click "Browse my computer for driver software"&lt;br /&gt;9. Navigate to the android SDK directory ...\extras\google\usb_driver&lt;br /&gt;10. Proceed through the dialogs.&lt;br /&gt;&lt;br /&gt;For me, the driver is located in:&lt;br /&gt;C:\Program Files (x86)\Android\android-sdk\extras\google\usb_driver&lt;br /&gt;&lt;br /&gt;I then ran adb devices, and my phone was listed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8205413125480841793-8655217472107825780?l=jeffreyrodriguez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreyrodriguez.blogspot.com/feeds/8655217472107825780/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8205413125480841793&amp;postID=8655217472107825780' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/8655217472107825780'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/8655217472107825780'/><link rel='alternate' type='text/html' href='http://jeffreyrodriguez.blogspot.com/2011/03/nexus-one-debugging.html' title='Nexus One Debugging'/><author><name>Jeff Rodriguez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-n_Uh7GUf3cs/Tndpa_3WnSI/AAAAAAAAGaQ/SxO70b7VhrQ/s220/abide.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8205413125480841793.post-3819597776626461497</id><published>2011-03-15T13:51:00.001-07:00</published><updated>2011-03-15T14:12:34.316-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='customer service'/><category scheme='http://www.blogger.com/atom/ns#' term='netflix'/><title type='text'>Netflix's Phone-only support</title><content type='html'>Until recently, I had the 6-at-a-time Netflix account. I've become rather busy and just don't have the time to watch those DVDs anymore; they just sit around my place collecting dust. I didn't even watch the last batch I had, which sat around for probably a month.&lt;br /&gt;&lt;br /&gt;So I dropped my Netflix account down to the online-only service. Well, now you've gotta send those DVDs back with 7 days after your previous subscription expires. I've just been sitting on them anyway, so I opened and resealed the DVDs I had, and put them in the mailbox.&lt;br /&gt;&lt;br /&gt;Netflix kindly sent me the next DVDs in my queue, since I still have time on the previous month's subscription. Since I don't have time to watch them anyway, I'll just send them right back without ever removing the DVDs from their envelope.&lt;br /&gt;&lt;br /&gt;I don't have a huge complaint about that whole process. It would've been convenient if they had a way for me to say "don't ship me anymore DVDs". I'm not aware of a way to do so, but that's OK... minor annoyance.&lt;br /&gt;&lt;br /&gt;One way for me to stop them from shipping me new DVDs is to clear out my queue. Now, I have a full DVD queue plus a handful of saved movies; nearly 500 in total. Problem: There is no "Delete All" button, you have to click 500 little delete buttons. (This also seems to cause the queue to throw JS errors occasionally.)&lt;br /&gt;&lt;br /&gt;Now it won't help me right now, but maybe someone (me?) could benefit from a Delete All button in the future if it were implemented. So I hit the "contact us" button looking for a place to fire off a suggestion. That's when I found out there's no way to email Netflix, they only have phone support.&lt;br /&gt;&lt;br /&gt;I don't actually want to &lt;em&gt;talk&lt;/em&gt; to anyone. I want to send a suggestion. A quick missive "Can you please add a 'delete all' button to the queue?"&lt;br /&gt;&lt;br /&gt;An email can get forwarded around; hopefully to a UI team that could implement the feature at some point in the future.&lt;br /&gt;&lt;br /&gt;So, Netflix: Sometimes email is better. I'd rather have a choice.&lt;br /&gt;&lt;br /&gt;In the meantime, I guess @netflixhelps will have to do. Just keep suggestions to less than 140 characters.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8205413125480841793-3819597776626461497?l=jeffreyrodriguez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreyrodriguez.blogspot.com/feeds/3819597776626461497/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8205413125480841793&amp;postID=3819597776626461497' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/3819597776626461497'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/3819597776626461497'/><link rel='alternate' type='text/html' href='http://jeffreyrodriguez.blogspot.com/2011/03/netflixs-phone-only-support.html' title='Netflix&apos;s Phone-only support'/><author><name>Jeff Rodriguez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-n_Uh7GUf3cs/Tndpa_3WnSI/AAAAAAAAGaQ/SxO70b7VhrQ/s220/abide.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8205413125480841793.post-2475381544004163328</id><published>2011-03-13T13:01:00.000-07:00</published><updated>2011-03-13T13:17:08.727-07:00</updated><title type='text'>SCP: I've been doing it wrong all along</title><content type='html'>It's not something I have to do a lot, so it's never occurred to me that it might be a problem. If you're transferring a lot of small files with SCP, you're doing it wrong too.&lt;br /&gt;&lt;br /&gt;Here, I'm copying an old source code repository to my laptop from my desktop using SCP:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;jrodriguez@laptop:~/foo$ time scp -Cqr desktop:/tank/Secure/vcs scp&lt;br /&gt;&lt;br /&gt;real 1m49.188s&lt;br /&gt;user 0m0.328s&lt;br /&gt;sys 0m0.392s&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here I'm running the directory through tar and piping it's output through SSH, and back through tar on my side:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;jrodriguez@laptop:~/foo$ time ssh desktop tar zcC /tank/Secure/vcs . | tar zxC tar&lt;br /&gt;&lt;br /&gt;real 0m7.185s&lt;br /&gt;user 0m0.200s&lt;br /&gt;sys 0m0.144s&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That's 789 files totaling 6.6 MB.&lt;br /&gt;&lt;br /&gt;Lesson: If you're transferring a lot of small files, don't let SCP do it for you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8205413125480841793-2475381544004163328?l=jeffreyrodriguez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreyrodriguez.blogspot.com/feeds/2475381544004163328/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8205413125480841793&amp;postID=2475381544004163328' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/2475381544004163328'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/2475381544004163328'/><link rel='alternate' type='text/html' href='http://jeffreyrodriguez.blogspot.com/2011/03/scp-ive-been-doing-it-wrong-all-along.html' title='SCP: I&apos;ve been doing it wrong all along'/><author><name>Jeff Rodriguez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-n_Uh7GUf3cs/Tndpa_3WnSI/AAAAAAAAGaQ/SxO70b7VhrQ/s220/abide.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8205413125480841793.post-1517284651518909176</id><published>2011-01-18T14:14:00.000-08:00</published><updated>2011-01-18T14:42:06.611-08:00</updated><title type='text'>JavaScript Object Graph (JSOG) 0.31 Released!</title><content type='html'>JSOG has grown a lot since I first decided to create it. It's been growing quietly, adding features without much documentation available.&lt;br /&gt;&lt;br /&gt;Today, that's changed. New features that have been added, and documented:&lt;br /&gt;&lt;br /&gt;* JSOGPath expressions - Navigate an object graph by XPath-like expressions.&lt;br /&gt;* XmlJsogFactory - Convert an XML document to a JSOG.&lt;br /&gt;* BeanJsogFactory - Convert a JavaBean into a JSOG.&lt;br /&gt;* Spring support - Namespace extension for UrlBuilder, MVC integration.&lt;br /&gt;* Dynamic methods - Dynamically inject object graph values into a method.&lt;br /&gt;&lt;br /&gt;Head on over to the JSOG site and check out the new and improved &lt;a href="http://jsog.sourceforge.net/docs/index.html"&gt;User Guide&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8205413125480841793-1517284651518909176?l=jeffreyrodriguez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreyrodriguez.blogspot.com/feeds/1517284651518909176/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8205413125480841793&amp;postID=1517284651518909176' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/1517284651518909176'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/1517284651518909176'/><link rel='alternate' type='text/html' href='http://jeffreyrodriguez.blogspot.com/2011/01/javascript-object-graph-jsog-031.html' title='JavaScript Object Graph (JSOG) 0.31 Released!'/><author><name>Jeff Rodriguez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-n_Uh7GUf3cs/Tndpa_3WnSI/AAAAAAAAGaQ/SxO70b7VhrQ/s220/abide.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8205413125480841793.post-4149676652512497046</id><published>2010-06-13T01:26:00.000-07:00</published><updated>2010-06-14T09:32:33.962-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='flexjson'/><category scheme='http://www.blogger.com/atom/ns#' term='object graph'/><category scheme='http://www.blogger.com/atom/ns#' term='jackson'/><category scheme='http://www.blogger.com/atom/ns#' term='json.org'/><category scheme='http://www.blogger.com/atom/ns#' term='couchdb'/><category scheme='http://www.blogger.com/atom/ns#' term='nosql'/><category scheme='http://www.blogger.com/atom/ns#' term='jsog'/><category scheme='http://www.blogger.com/atom/ns#' term='json'/><category scheme='http://www.blogger.com/atom/ns#' term='json-lib'/><category scheme='http://www.blogger.com/atom/ns#' term='document database'/><title type='text'>JSOG - JavaScript Object Graph</title><content type='html'>So I had a project where I was creating a user preferences service. Because the environment in which the preferences service was to be operating is so chaotic (lots of changes are expected), I decided to use JSON as a way to store the user preferences. The service is a glorified document database, if you will.&lt;br /&gt;&lt;br /&gt;Now, working with JavaScript objects and arrays in JavaScript is pretty easy. There's a lot of implicit coercion taking place, it's a dynamic language after all. That doesn't translate to Java very well, however. I looked at JSON-lib, FlexJSON, Jackson, and the json.org library. None of them provided the functionality I was looking for. I want to easily navigate a JSON object graph, and manipulate the values within.&lt;br /&gt;&lt;br /&gt;Let's look at my particular use case for example. I had a JSON object for a user. Within that JSON object, I basically had the following: (Formatted for readability)&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;{&lt;br /&gt;  "services": {&lt;br /&gt;    "xyz": {&lt;br /&gt;      // XYZ specific preferences&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Except since things are so chaotic, I don't know if the "services" node exists, or if "xyz" exists.&lt;br /&gt;&lt;br /&gt;I'll demonstrate with Jackson here, but the process is basically the same for the other libraries I looked at.&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;In this example, we create the object from scratch:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ObjectNode prefs = nf.objectNode();&lt;br /&gt;&lt;br /&gt;ObjectNode services = nf.objectNode();&lt;br /&gt;prefs.put("services", services);&lt;br /&gt;&lt;br /&gt;ObjectNode xyz = nf.objectNode();&lt;br /&gt;services.put("xyz", xyz);&lt;br /&gt;&lt;br /&gt;xyz.put("foo", "bar");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;What does that same code look like in JSOG?&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;JSOG jsog = JSOG.createObjectNode();&lt;br /&gt;jsog&lt;br /&gt;   .get("services")&lt;br /&gt;       .get("xyz")&lt;br /&gt;           .put("foo", "bar");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A little more straight forward, but Jackson wasn't &lt;em&gt;that&lt;/em&gt; bad. What about a more complex example?&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;Instead of creating everything from scratch, what if we need to parse the existing preferences and add a value? If the JSON object doesn't contain "services", or "xyz" (which we're not sure of), we need to create those nodes.&lt;br /&gt;&lt;br /&gt;Let's parse a string, empty in this case, and build up the same object, and add a value to "xyz" called "baz" with value 42.&lt;br /&gt;&lt;br /&gt;Here's what you're facing with Jackson:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ObjectMapper om = new ObjectMapper();&lt;br /&gt;JsonNodeFactory nf = om.getNodeFactory();&lt;br /&gt;&lt;br /&gt;// Parse the JSON string&lt;br /&gt;JsonNode json = om.readTree("");&lt;br /&gt;&lt;br /&gt;// Get or create the prefs container object&lt;br /&gt;ObjectNode prefs;&lt;br /&gt;if (json.isObject()) {&lt;br /&gt;   prefs = (ObjectNode) json;&lt;br /&gt;} else {&lt;br /&gt;   prefs = nf.objectNode();&lt;br /&gt;   json = prefs;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Get or create the services object&lt;br /&gt;JsonNode servicesNode = prefs.path("services");&lt;br /&gt;ObjectNode services;&lt;br /&gt;if (servicesNode.isObject()) {&lt;br /&gt;   services = (ObjectNode) servicesNode;&lt;br /&gt;} else {&lt;br /&gt;   services = nf.objectNode();&lt;br /&gt;   prefs.put("services", services);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Get or create the xyz object&lt;br /&gt;JsonNode xyzNode = services.path("xyz");&lt;br /&gt;ObjectNode xyz;&lt;br /&gt;if (xyzNode.isObject()) {&lt;br /&gt;   xyz = (ObjectNode) xyzNode;&lt;br /&gt;} else {&lt;br /&gt;   xyz = nf.objectNode();&lt;br /&gt;   prefs.put("xyz", xyz);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Set the value&lt;br /&gt;xyz.put("baz", 42);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And here's JSOG doing the same thing:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;JSOG jsog = JSOG.parse("");&lt;br /&gt;jsog&lt;br /&gt;   .get("services")&lt;br /&gt;       .get("xyz")&lt;br /&gt;         .put("baz", 42);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Now&lt;/b&gt; we're talking! JSOG pulls off in 5 clean, clear, concise lines of code what took Jackson 38 LOC to do. JSOG does the implicit object creation or coercion for you, and to make things even easier, you get builder-style syntax!&lt;br /&gt;&lt;br /&gt;I want to point out that I'm not picking on Jackson here, this is a failing of &lt;em&gt;all&lt;/em&gt; the libraries I looked at. I think Jackson is actually one of the easier libraries to use, which is why I chose to use it for JSOG's serialization and deserialization.&lt;br /&gt;&lt;br /&gt;JSOG is &lt;a href="http://unlicense.org"&gt;Unlicensed&lt;/a&gt;. I've committed it to the public domain. I would love to see JSOG or an equivalent find it's way into each JSON library.&lt;br /&gt;&lt;br /&gt;Visit the &lt;a href="http://jsog.sourceforge.net/"&gt;JSOG site&lt;/a&gt;, hosted on SourceForge.net and give it a whirl. I suspect people working with CouchDB will *really* appreciate JSOG.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8205413125480841793-4149676652512497046?l=jeffreyrodriguez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreyrodriguez.blogspot.com/feeds/4149676652512497046/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8205413125480841793&amp;postID=4149676652512497046' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/4149676652512497046'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/4149676652512497046'/><link rel='alternate' type='text/html' href='http://jeffreyrodriguez.blogspot.com/2010/06/jsog-javascript-object-graph.html' title='JSOG - JavaScript Object Graph'/><author><name>Jeff Rodriguez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-n_Uh7GUf3cs/Tndpa_3WnSI/AAAAAAAAGaQ/SxO70b7VhrQ/s220/abide.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8205413125480841793.post-4789642792972004122</id><published>2010-04-14T19:26:00.000-07:00</published><updated>2010-04-17T19:14:22.573-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='safety'/><category scheme='http://www.blogger.com/atom/ns#' term='motorcycle'/><title type='text'>Basic Motorcycle Safety</title><content type='html'>So I've been going through the work to get a motorcycle, and I was reviewing the &lt;a href="http://en.wikipedia.org/wiki/List_of_findings_in_the_Hurt_Report"&gt;Hurt Report findings&lt;/a&gt;. I'd recommend going over them yourself, but here's the short-short version for my own reference and yours:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Cornering and intersections are deadly.&lt;/li&gt;&lt;li&gt;At intersections, expect oncoming traffic to turn in front of you.&lt;/li&gt;&lt;li&gt;Under/overbraking are common in the moments preceding an accident - get a bike with ABS/practice emergency stop drills.&lt;/li&gt;&lt;li&gt;Be as conspicuous as possible. Orange, yellow, and red colored clothing, helmets, and bike colors are a Good Thing. Keep your headlights on.&lt;/li&gt;&lt;li&gt;Wear a full face or modular helmet. Leathers will help you keep your skin where it belongs.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Take a motorcycle safety class.&lt;/li&gt;&lt;li style="font-weight: bold;"&gt;Pay attention!&lt;/li&gt;&lt;/ul&gt;These basic rules cover such an overwhelming percentage of accidents, and they're so simple to follow. Unless you're &lt;i&gt;trying&lt;/i&gt; to give your organs away, &lt;b&gt;follow them&lt;/b&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8205413125480841793-4789642792972004122?l=jeffreyrodriguez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreyrodriguez.blogspot.com/feeds/4789642792972004122/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8205413125480841793&amp;postID=4789642792972004122' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/4789642792972004122'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/4789642792972004122'/><link rel='alternate' type='text/html' href='http://jeffreyrodriguez.blogspot.com/2010/04/basic-motorcycle-safety.html' title='Basic Motorcycle Safety'/><author><name>Jeff Rodriguez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-n_Uh7GUf3cs/Tndpa_3WnSI/AAAAAAAAGaQ/SxO70b7VhrQ/s220/abide.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8205413125480841793.post-8955109971229024197</id><published>2010-03-08T18:51:00.000-08:00</published><updated>2010-03-08T18:58:37.593-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><category scheme='http://www.blogger.com/atom/ns#' term='phoenix art museum'/><category scheme='http://www.blogger.com/atom/ns#' term='first friday'/><category scheme='http://www.blogger.com/atom/ns#' term='lensbaby'/><title type='text'>Shooting with the Lensbaby Composer</title><content type='html'>The following two images are shot using the Lensbaby Composer. They were taken at the Phoenix Art Museum on the March First Friday.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://picasaweb.google.com/lh/photo/tFyo6AypkOsOMvY7RW0aHw?feat=embedwebsite"&gt;&lt;img src="http://lh3.ggpht.com/_yRSOQ6jUGrw/S5W4JmsPM-I/AAAAAAAAF3c/zcx14PZKCQk/s800/DSC_1530.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://picasaweb.google.com/lh/photo/2fnUJ-rJ6pm9CFE0tWLfEQ?feat=embedwebsite"&gt;&lt;img src="http://lh4.ggpht.com/_yRSOQ6jUGrw/S5W4Jw7DKnI/AAAAAAAAF3g/d-cvqjYO87w/s800/DSC_1534.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;These are using my 18-105mm lens, on the same night.&lt;br /&gt;&lt;a href="http://picasaweb.google.com/lh/photo/rmMhh8lN72NhMiVyxJPyfw?feat=embedwebsite"&gt;&lt;img src="http://lh6.ggpht.com/_yRSOQ6jUGrw/S5W4J8M9HGI/AAAAAAAAF3k/W1S1EEvn7qA/s800/DSC_1573.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://picasaweb.google.com/lh/photo/OYiE8Yx3LfdsCqxi8TVwMQ?feat=embedwebsite"&gt;&lt;img src="http://lh3.ggpht.com/_yRSOQ6jUGrw/S5W4KNtFpzI/AAAAAAAAF3o/zjtybVKKFL8/s800/DSC_1575.jpg" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8205413125480841793-8955109971229024197?l=jeffreyrodriguez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreyrodriguez.blogspot.com/feeds/8955109971229024197/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8205413125480841793&amp;postID=8955109971229024197' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/8955109971229024197'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/8955109971229024197'/><link rel='alternate' type='text/html' href='http://jeffreyrodriguez.blogspot.com/2010/03/shooting-with-lensbaby-composer.html' title='Shooting with the Lensbaby Composer'/><author><name>Jeff Rodriguez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-n_Uh7GUf3cs/Tndpa_3WnSI/AAAAAAAAGaQ/SxO70b7VhrQ/s220/abide.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_yRSOQ6jUGrw/S5W4JmsPM-I/AAAAAAAAF3c/zcx14PZKCQk/s72-c/DSC_1530.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8205413125480841793.post-6244951996000962206</id><published>2010-01-21T08:07:00.000-08:00</published><updated>2010-01-21T08:39:05.631-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wicd'/><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='wireless'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><category scheme='http://www.blogger.com/atom/ns#' term='networkmanager'/><title type='text'>Ubuntu's NetworkManager is Flaky</title><content type='html'>The &lt;a href="https://bugs.launchpad.net/ubuntu/+source/linux/+bug/291760"&gt;debate rages on&lt;/a&gt; as to what component is actually causing the problem: NetworkManager, wpa_supplicant, drivers, or something else. But the problem is clear: Frequent disconnects, particularly in an environment where multiple access points provide access over a single SSID.&lt;br /&gt;&lt;br /&gt;Either way, replacing NetworkManager with wicd resolves the problem.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;code&gt;sudo apt-get install wicd&lt;/code&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;After you've done that, &lt;code&gt;wicd-client&lt;/code&gt; will start in your tray on the next login.&lt;br /&gt;&lt;br /&gt;If you want, you can also configure it through the &lt;code&gt;wicd-curses&lt;/code&gt; interface. One oddity, though, is that the curses interface is case-sensitive.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8205413125480841793-6244951996000962206?l=jeffreyrodriguez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreyrodriguez.blogspot.com/feeds/6244951996000962206/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8205413125480841793&amp;postID=6244951996000962206' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/6244951996000962206'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/6244951996000962206'/><link rel='alternate' type='text/html' href='http://jeffreyrodriguez.blogspot.com/2010/01/ubuntus-networkmanager-is-flaky.html' title='Ubuntu&apos;s NetworkManager is Flaky'/><author><name>Jeff Rodriguez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-n_Uh7GUf3cs/Tndpa_3WnSI/AAAAAAAAGaQ/SxO70b7VhrQ/s220/abide.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8205413125480841793.post-4492337857812322367</id><published>2009-12-05T09:47:00.000-08:00</published><updated>2010-01-01T00:10:20.295-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='squash'/><category scheme='http://www.blogger.com/atom/ns#' term='fall'/><category scheme='http://www.blogger.com/atom/ns#' term='pumpkin'/><category scheme='http://www.blogger.com/atom/ns#' term='harvest'/><category scheme='http://www.blogger.com/atom/ns#' term='corn'/><category scheme='http://www.blogger.com/atom/ns#' term='garden'/><title type='text'>Fall harvest</title><content type='html'>My pumpkin vine is looking pretty bad after a really cold night, so I decided I'd better pick the pumpkins. I also harvested the butternut squash while I was at it.&lt;br /&gt;&lt;br /&gt;I'll include the pics of some of the corn I harvested earlier this year. The corn, by the way, is called Mirai sweet corn. It's a variety that produces extremely sweet ears, there was much rejoicing about it's taste. I actually harvested 6 ears of corn. I would've had more, but a lot of the seeds didn't germinate. I think that's because the soil was still a little 'raw' and the seeds didn't get enough water to germinate.&lt;br /&gt;&lt;br /&gt;Four of the six:&lt;br /&gt;&lt;a href="http://picasaweb.google.com/lh/photo/Q3V9QvHOS0wT54Wi48eODA?feat=embedwebsite"&gt;&lt;img src="http://lh4.ggpht.com/_yRSOQ6jUGrw/Sxqdeph3oFI/AAAAAAAAFvg/GDKghT7OyDQ/s400/100_2807.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;These three went to friends. I ate another recently.&lt;br /&gt;&lt;a href="http://picasaweb.google.com/lh/photo/eHDua9wGHffa8PIpqerKTg?feat=embedwebsite"&gt;&lt;img src="http://lh5.ggpht.com/_yRSOQ6jUGrw/SxqdeXgpl5I/AAAAAAAAFvc/RgiiMQsOoNg/s400/100_2805.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Today's harvest:&lt;br /&gt;&lt;a href="http://picasaweb.google.com/lh/photo/tn0AtiSdYFQom7qV_5JrrQ?feat=embedwebsite"&gt;&lt;img src="http://lh4.ggpht.com/_yRSOQ6jUGrw/Sxqdem8Xu0I/AAAAAAAAFvk/t-WhbYfZbsI/s400/100_2808.JPG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I still have a few pumpkins on the vine that aren't quite ready yet, we'll see if they survive the weather.&lt;br /&gt;&lt;br /&gt;Here are the current stats from the garden:&lt;br /&gt;Pumpkins - 89lbs&lt;br /&gt;Butternut Squash - 20.5lbs&lt;br /&gt;Corn - 6 ears&lt;br /&gt;&lt;br /&gt;Update 2010-01-01:&lt;br /&gt;The weather killed off the rest of the vines, so I had 5 pumpkins and two butternut squash that didn't fully develop. I did manage to harvest 1 more 9.5lb pumpkin, bringing the total to 98.5lbs.&lt;br /&gt;&lt;br /&gt;Ah well, the rabbits and chickens won't mind the leftovers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8205413125480841793-4492337857812322367?l=jeffreyrodriguez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreyrodriguez.blogspot.com/feeds/4492337857812322367/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8205413125480841793&amp;postID=4492337857812322367' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/4492337857812322367'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/4492337857812322367'/><link rel='alternate' type='text/html' href='http://jeffreyrodriguez.blogspot.com/2009/12/fall-harvest.html' title='Fall harvest'/><author><name>Jeff Rodriguez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-n_Uh7GUf3cs/Tndpa_3WnSI/AAAAAAAAGaQ/SxO70b7VhrQ/s220/abide.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_yRSOQ6jUGrw/Sxqdeph3oFI/AAAAAAAAFvg/GDKghT7OyDQ/s72-c/100_2807.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8205413125480841793.post-6974874818256745746</id><published>2009-10-26T22:52:00.001-07:00</published><updated>2009-10-26T22:53:57.449-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='steak'/><category scheme='http://www.blogger.com/atom/ns#' term='grilling'/><category scheme='http://www.blogger.com/atom/ns#' term='cooking'/><category scheme='http://www.blogger.com/atom/ns#' term='food'/><title type='text'>My Steak Method</title><content type='html'>I posted this on Fark a bit ago, and figured since I typed it all out I might as well save it for posterity's sake.&lt;br /&gt;&lt;br /&gt;1. The cut and quality of the meat are of significant importance. You really can't go wrong with a choice or prime T-bone. I like mine about 3/4 to 1" thick. Any bigger and it doesn't grill well.&lt;br /&gt;&lt;br /&gt;2. It has to be room temperature before it's put on the grill. Let it sit out for 15 minutes or so before you put it on the grill.&lt;br /&gt;&lt;br /&gt;3. Cooking time and temperature are important. I crank my grill up to high and do 3-4 minutes, flip, 3-4 minutes. That gives me a good rare-medium rare. Don't worry about any flames, it'll char the outside but won't be going for long enough to cause it to burn.&lt;br /&gt;&lt;br /&gt;4. It has to sit for a few minutes after it's taken off the grill, the inside of the steak will cook from the heat of the outer parts. Take it off the grill, THEN get out any plates/flatware. Get your sides together, take your time, I give it 3-5 mins.&lt;br /&gt;&lt;br /&gt;For seasoning, I use &lt;a href="http://www.mccormick.com/Products/GrillMates/Seasoning-Blends/Grill-Mates-Montreal-Steak-Seasoning.aspx"&gt;McCormic Grill Mates® Montreal Steak Seasoning&lt;/a&gt;. Work it on there with your hands so it sticks well, be generous but don't go overboard.&lt;br /&gt;&lt;br /&gt;Raw steak is shitty, rare-medium rare is fucking amazing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8205413125480841793-6974874818256745746?l=jeffreyrodriguez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreyrodriguez.blogspot.com/feeds/6974874818256745746/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8205413125480841793&amp;postID=6974874818256745746' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/6974874818256745746'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/6974874818256745746'/><link rel='alternate' type='text/html' href='http://jeffreyrodriguez.blogspot.com/2009/10/my-steak-method.html' title='My Steak Method'/><author><name>Jeff Rodriguez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-n_Uh7GUf3cs/Tndpa_3WnSI/AAAAAAAAGaQ/SxO70b7VhrQ/s220/abide.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8205413125480841793.post-1659906147937901297</id><published>2009-09-25T23:20:00.000-07:00</published><updated>2011-02-22T09:11:43.012-08:00</updated><title type='text'>S'Mars</title><content type='html'>The Smore meets the Rice Krispy Treat.&lt;br /&gt;&lt;br /&gt;1 jar of jet puffed marshmallow creme&lt;br /&gt;1 brick of graham crackers&lt;br /&gt;1 cup of chocolate chips, room temp&lt;br /&gt;1 stick of butter&lt;br /&gt;&lt;br /&gt;Crush the graham crackers (a plastic bag and rolling pin work wonderfully). Mix the marshmallow creme, graham cracker crumbs, and chocolate chips. It'll be somewhat stiff, but get the mixture to be fairly homogeneous. Melt the stick of butter in a separate bowl, I nuked mine for 1 minute and it was boiling a bit when I pulled it out. Pour the hot butter into the mixture and stir, it should start to stir more easily. At this point, the result should have a texture a lot like &lt;a href="http://en.wikipedia.org/wiki/Nickelodeon_compounds#Nickelodeon_Floam"&gt;Floam&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Put it in the fridge to solidify.&lt;br /&gt;&lt;br /&gt;The whole process takes, literally, 5 minutes or so.&lt;br /&gt;&lt;br /&gt;Modifications:&lt;br /&gt;Try different kinds of chips, peanut butter is particularly good.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=a-5OeddMHFs"&gt;Video&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8205413125480841793-1659906147937901297?l=jeffreyrodriguez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreyrodriguez.blogspot.com/feeds/1659906147937901297/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8205413125480841793&amp;postID=1659906147937901297' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/1659906147937901297'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/1659906147937901297'/><link rel='alternate' type='text/html' href='http://jeffreyrodriguez.blogspot.com/2009/09/awesomebars.html' title='S&apos;Mars'/><author><name>Jeff Rodriguez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-n_Uh7GUf3cs/Tndpa_3WnSI/AAAAAAAAGaQ/SxO70b7VhrQ/s220/abide.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8205413125480841793.post-1695612569493613173</id><published>2008-12-17T12:47:00.000-08:00</published><updated>2008-12-17T12:51:48.541-08:00</updated><title type='text'>Java XML validation, "Cannot find the declaration of element"?</title><content type='html'>Many thanks to &lt;a href="http://weblogs.java.net/blog/spericas/archive/2007/03/xml_schema_vali.html"&gt;Santiago Pericas-Geertsen&lt;/a&gt;, who blogged about this exact problem earlier this year. If you can't figure out for the life of you why your document won't validate, even though you know it's valid, try setting setNamespaceAware(true) on your DocumentBuilderFactory:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;factory.setNamespaceAware(true);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Chances are that's all you need and you'll be up and running.&lt;br /&gt;&lt;br /&gt;Programming is easy, it's all the gotchas that make it hard.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8205413125480841793-1695612569493613173?l=jeffreyrodriguez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreyrodriguez.blogspot.com/feeds/1695612569493613173/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8205413125480841793&amp;postID=1695612569493613173' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/1695612569493613173'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/1695612569493613173'/><link rel='alternate' type='text/html' href='http://jeffreyrodriguez.blogspot.com/2008/12/java-xml-validation-cannot-find.html' title='Java XML validation, &quot;Cannot find the declaration of element&quot;?'/><author><name>Jeff Rodriguez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-n_Uh7GUf3cs/Tndpa_3WnSI/AAAAAAAAGaQ/SxO70b7VhrQ/s220/abide.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8205413125480841793.post-6317756667753287209</id><published>2008-08-01T02:30:00.001-07:00</published><updated>2008-08-01T02:53:21.459-07:00</updated><title type='text'>Netbeans-Apache Commons library importer</title><content type='html'>I threw together a script to download the latest version of all the Apache Commons components, and create the library files used for Netbeans. It's a little rough and short on docs, but easy enough to use. Some components can't be downloaded and processed easily (those with -e) and the signature of betwixt can't be verified because it's key is out of date, so we force it's acceptance (-f)&lt;br /&gt;&lt;br /&gt;&lt;code&gt;cd ~&lt;br /&gt;mkdir JavaLibraries&lt;br /&gt;wget http://www.apache.org/dist/commons/KEYS -qO - | gpg --import&lt;br /&gt;./&lt;a href="http://jeffrey.rodriguez.googlepages.com/asfcommons2nb.pl"&gt;asfcommons2nb.pl&lt;/a&gt; --sig --dir JavaLibraries/Commons \&lt;br /&gt;-e daemon \&lt;br /&gt;-e httpclient \&lt;br /&gt;-e jci \&lt;br /&gt;-e latka \&lt;br /&gt;-e attributes \&lt;br /&gt;-f betwixt&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;When you're done, you'll want to copy the xml files from &lt;code&gt;JavaLibraries/Commons/Libraries/&lt;/code&gt;&lt;br /&gt;to &lt;code&gt;~/.netbeans/&lt;span style="font-weight: bold;"&gt;6.1&lt;/span&gt;/config/org-netbeans-api-project-libraries/Libraries/&lt;/code&gt;&lt;br /&gt;Replace the bold part with the appropriate version.&lt;br /&gt;&lt;br /&gt;It's pretty smart. It'll check to see that you have the current version and only update if you don't.&lt;br /&gt;&lt;br /&gt;I like Netbeans' library feature, but keeping up to date on things sucks. If you don't care about docs, Ivy would suffice, but I do want instant javadoc access. That's why I'm using an IDE!&lt;br /&gt;&lt;br /&gt;Anywho, it's public domain, feel free to send me enhancements or bugfixes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8205413125480841793-6317756667753287209?l=jeffreyrodriguez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreyrodriguez.blogspot.com/feeds/6317756667753287209/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8205413125480841793&amp;postID=6317756667753287209' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/6317756667753287209'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/6317756667753287209'/><link rel='alternate' type='text/html' href='http://jeffreyrodriguez.blogspot.com/2008/08/netbeans-commons-library-importer.html' title='Netbeans-Apache Commons library importer'/><author><name>Jeff Rodriguez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-n_Uh7GUf3cs/Tndpa_3WnSI/AAAAAAAAGaQ/SxO70b7VhrQ/s220/abide.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8205413125480841793.post-2860726196338046833</id><published>2008-03-19T17:03:00.000-07:00</published><updated>2008-03-20T12:47:25.281-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='glassfish sjsas ssl java javaee'/><title type='text'>CA signed SSL certs in glassfish, for lazy admins</title><content type='html'>So setting up CA signed SSL in Glassfish sucked, until I finally found the process for doing so. &lt;a href="http://javaevangelist.blogspot.com/2006/12/sun-java-system-application-server-9x.html"&gt;John Yeary&lt;/a&gt; outlines the process, but it's still manual and annoying.&lt;br /&gt;&lt;br /&gt;Never do more than twice anything you can script, and so here we go. The script below is designed to work with &lt;a href="http://www.cacert.org/"&gt;CACert.org&lt;/a&gt; certificates. Save it to your local  system and run it as a user who has access to write to the Glassfish installation.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#!/bin/sh&lt;br /&gt;# Copyright 2008 Jeff Rodriguez [jeffrodriguez.com]&lt;br /&gt;#&lt;br /&gt;# Licensed under the Apache License, Version 2.0 (the "License");&lt;br /&gt;# you may not use this file except in compliance with the License.&lt;br /&gt;# You may obtain a copy of the License at&lt;br /&gt;#&lt;br /&gt;#     http://www.apache.org/licenses/LICENSE-2.0&lt;br /&gt;#&lt;br /&gt;# Unless required by applicable law or agreed to in writing, software&lt;br /&gt;# distributed under the License is distributed on an "AS IS" BASIS,&lt;br /&gt;# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&lt;br /&gt;# See the License for the specific language governing permissions and&lt;br /&gt;# limitations under the License.&lt;br /&gt;&lt;br /&gt;/bin/echo "This script was designed to work with CACert.org."&lt;br /&gt;/bin/echo "It may work with other sites, YMMV."&lt;br /&gt;/bin/echo "USE AT YOUR OWN RISK."&lt;br /&gt;/bin/echo -e "\n\n"&lt;br /&gt;&lt;br /&gt;read -rp "SSL domain name [`hostname`]: " DOMAIN&lt;br /&gt;if [ -z "$DOMAIN" ]; then DOMAIN="`hostname`"; fi&lt;br /&gt;&lt;br /&gt;read -rp "AppServer domain directory [/home/`whoami`/SUNWappserver/domains/domain1]: " DIR&lt;br /&gt;if [ -z "$DIR" ]; then DIR="/home/`whoami`/SUNWappserver/domains/domain1"; fi&lt;br /&gt;&lt;br /&gt;read -rp "Keystore password [changeit]: " KSPASS&lt;br /&gt;if [ -z "$KSPASS" ]; then KSPASS="changeit"; fi&lt;br /&gt;&lt;br /&gt;# Make sure the domain directory is correct&lt;br /&gt;KS="$DIR/config/keystore.jks"&lt;br /&gt;if [ ! -e "$KS" -a ! -w "$KS" ]; then&lt;br /&gt;/bin/echo "Your keystore ($KS) is not writable."&lt;br /&gt;exit 1&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;# Handy alias&lt;br /&gt;KSCMD="keytool -keystore $KS -storepass $KSPASS"&lt;br /&gt;&lt;br /&gt;# Generate the key&lt;br /&gt;if ( ! $KSCMD -genkey -keyalg RSA -alias $DOMAIN -keypass $KSPASS -noprompt -validity 365 -dname "cn=$DOMAIN"); then&lt;br /&gt;/bin/echo "Failed to generate key."&lt;br /&gt;exit 1&lt;br /&gt;fi&lt;br /&gt;/bin/echo -e "\n\nA private key has been created in your app server's keystore."&lt;br /&gt;/bin/echo "If this script fails at any point, and you wish to start over, you must delete this private key with the command: "&lt;br /&gt;/bin/echo "$KSCMD -delete -alias $DOMAIN"&lt;br /&gt;read -sp "Press enter to continue." REPLY&lt;br /&gt;/bin/echo -e "\n\n"&lt;br /&gt;&lt;br /&gt;# Create the CSR&lt;br /&gt;if ( ! $KSCMD -certreq -v -alias $DOMAIN -file /tmp/$DOMAIN.csr); then&lt;br /&gt;/bin/echo "Failed to create certificate signing request."&lt;br /&gt;exit 1&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;/bin/echo "Below is your Certificate Signing Request (CSR)."&lt;br /&gt;/bin/echo "On the CACert.org website, go to Server Certificates -&gt; New. Paste the text below into the form and submit it."&lt;br /&gt;cat /tmp/$DOMAIN.csr&lt;br /&gt;rm -f /tmp/$DOMAIN.csr&lt;br /&gt;&lt;br /&gt;# Get the certificate&lt;br /&gt;/bin/echo -e "\n\nCACert will generate a signed certificate. Paste it here, finish with EOF (CTRL+D)."&lt;br /&gt;cat &gt; /tmp/$DOMAIN.crt&lt;br /&gt;&lt;br /&gt;# Fetch the CACert certificates&lt;br /&gt;/bin/echo "Before you can use your certificate, it has to be imported to the app server keystore. To do that, we first have to import the CACert.org certificates."&lt;br /&gt;read -rp "Would you like the script to automatically download the certificates? [y|N]: " DLCERTS&lt;br /&gt;&lt;br /&gt;if [ $DLCERTS = 'Y' -o $DLCERTS = 'y' ]; then&lt;br /&gt;wget -q --no-check-certificate -O /tmp/cacert_root.crt "http://www.cacert.org/certs/root.crt"&lt;br /&gt;wget -q --no-check-certificate -O /tmp/cacert_class3.crt "http://www.cacert.org/certs/class3.crt"&lt;br /&gt;else&lt;br /&gt;/bin/echo "You have chosen not to automatically download the certificates. To do this manually,"&lt;br /&gt;/bin/echo "Go to http://www.cacert.org/index.php?id=3"&lt;br /&gt;/bin/echo "Save the Class 1 PKI Key Root Certificate (PEM Format) as /tmp/cacert_root.crt"&lt;br /&gt;/bin/echo "Save the Class 3 PKI Key Root Certificate (PEM Format) as /tmp/cacert_class3.crt"&lt;br /&gt;read -sp "Press enter to continue." REPLY&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;if [ ! -e /tmp/cacert_root.crt -o ! -e /tmp/cacert_class3.crt ]; then&lt;br /&gt;/bin/echo "CACert certificates weren't found in /tmp. Either automatic download failed or you have not manually downloaded the certificates properly."&lt;br /&gt;exit 1&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;# Import the certificates&lt;br /&gt;if ( ! $KSCMD -import -v -alias cacert -trustcacerts -noprompt -file /tmp/cacert_root.crt); then&lt;br /&gt;/bin/echo "Failed to import CACert root certificate."&lt;br /&gt;exit 1&lt;br /&gt;fi&lt;br /&gt;if ( ! $KSCMD -import -v -alias cacert3 -trustcacerts -noprompt -file /tmp/cacert_class3.crt); then&lt;br /&gt;/bin/echo "Failed to import CACert class 3 certificate."&lt;br /&gt;exit 1&lt;br /&gt;fi&lt;br /&gt;if ( ! $KSCMD -import -v -alias $DOMAIN -trustcacerts -noprompt -file /tmp/$DOMAIN.crt); then&lt;br /&gt;/bin/echo "Failed to import domain certificate."&lt;br /&gt;exit 1&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;# Cleanup&lt;br /&gt;rm -f /tmp/cacert_root.crt&lt;br /&gt;rm -f /tmp/cacert_class3.crt&lt;br /&gt;rm -f /tmp/$DOMAIN.crt&lt;br /&gt;$KSCMD -delete -alias cacert&lt;br /&gt;$KSCMD -delete -alias cacert3&lt;br /&gt;&lt;br /&gt;# Final instructions for the user&lt;br /&gt;/bin/echo -e "\n\n"&lt;br /&gt;/bin/echo "The certificate has been imported into your app server keystore."&lt;br /&gt;/bin/echo "To use the certificate follow these last steps:"&lt;br /&gt;/bin/echo "  1. Go to your Admin Console (http://$DOMAIN:4848), Configuration, HTTP Service, HTTP Listeners, http-listener-2 (or whatever your SSL listener is)."&lt;br /&gt;/bin/echo "  2. On the SSL tab, set your Certificate Nickname to $DOMAIN, and click save."&lt;br /&gt;/bin/echo "  3. Restart the app server."&lt;br /&gt;/bin/echo "NOTE: Your certificate will expire in 1 year, you must update the certificate before then or browsers will receive SSL warnings; other programs may fail entirely."&lt;br /&gt;/bin/echo "Mark your calendar. No, really."&lt;br /&gt;/bin/echo -e "\n\n"&lt;br /&gt;/bin/echo "If something went, or goes wrong, it could prevent your app server from starting. One possible remedy is to locate your SSL http listener in $DIR/config/domain.xml and disable it."&lt;br /&gt;&lt;/pre&gt;&lt;span style="display: block;" id="formatbar_Buttons"&gt;&lt;br /&gt;Though supposedly, it's technically possible to use an existing private key and certificate, you'll shoot yourself in the face before you finish. Cut your losses and just start over with a new private key and cert. You'll have to pardon me if the script is a bit rough around the edges. Send patches my way if you like.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8205413125480841793-2860726196338046833?l=jeffreyrodriguez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeffreyrodriguez.blogspot.com/feeds/2860726196338046833/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8205413125480841793&amp;postID=2860726196338046833' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/2860726196338046833'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8205413125480841793/posts/default/2860726196338046833'/><link rel='alternate' type='text/html' href='http://jeffreyrodriguez.blogspot.com/2008/03/ca-signed-ssl-certs-in-glassfish-for.html' title='CA signed SSL certs in glassfish, for lazy admins'/><author><name>Jeff Rodriguez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-n_Uh7GUf3cs/Tndpa_3WnSI/AAAAAAAAGaQ/SxO70b7VhrQ/s220/abide.jpg'/></author><thr:total>3</thr:total></entry></feed>
