<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/atom10full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0"><id>tag:blogger.com,1999:blog-7774229</id><updated>2008-11-16T19:40:05.075-08:00</updated><title type="text">Space Program Blog</title><subtitle type="html">Knowledge of the Universe.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://blog.spaceprogram.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://blog.spaceprogram.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Travis Reeder</name><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>38</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><link rel="self" href="http://feeds.feedburner.com/SpaceProgramBlog" type="application/atom+xml" /><feedburner:emailServiceId>1704912</feedburner:emailServiceId><feedburner:feedburnerHostname>http://www.feedburner.com</feedburner:feedburnerHostname><entry><id>tag:blogger.com,1999:blog-7774229.post-7727298954608267170</id><published>2008-11-04T17:59:00.001-08:00</published><updated>2008-11-04T17:59:24.398-08:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2008-11-04T17:59:24.398-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Tips" /><title type="text">Deleting SVN Directories from a Project</title><content type="html">&lt;p&gt;Sometimes you just need to get rid of those pesky subversion folders because you can’t export or something so here’s the quick and easy way to do it in windows:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Be sure you can see hidden files and folders (Advanced folder settings) &lt;/li&gt;    &lt;li&gt;Open Windows Explorer in the root folder of your project &lt;/li&gt;    &lt;li&gt;Explorer &lt;/li&gt;    &lt;li&gt;In the search bar (or Ctrl+F for older versions of windows), type “.svn” &lt;/li&gt;    &lt;li&gt;Sort by name &lt;/li&gt;    &lt;li&gt;Delete all the ones that are folders (not the ones that are files) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Done.&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/SpaceProgramBlog/~4/442722706" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.spaceprogram.com/feeds/7727298954608267170/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7774229&amp;postID=7727298954608267170" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/7727298954608267170?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/7727298954608267170?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/SpaceProgramBlog/~3/442722706/deleting-svn-directories-from-project.html" title="Deleting SVN Directories from a Project" /><author><name>Travis Reeder</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.spaceprogram.com/2008/11/deleting-svn-directories-from-project.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7774229.post-3704904715585084689</id><published>2008-10-07T00:35:00.001-07:00</published><updated>2008-10-07T00:35:20.458-07:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2008-10-07T00:35:20.458-07:00</app:edited><title type="text">Callable and the Case of the Disappearing Exceptions
</title><content type="html">If you have a class that implements Callable, but you don't plan on using the Future that is returned after you call Executor.submit(), you may lose any exceptions that are thrown. They literally disappear into the void. No log whatsoever. &lt;br /&gt;&lt;br /&gt;So it is good practice to treat it a bit like you would with a Runnable and wrap the code in your call method with a try/catch to print the exception or log it somewhere.&lt;img src="http://feeds.feedburner.com/~r/SpaceProgramBlog/~4/413568634" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.spaceprogram.com/feeds/3704904715585084689/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7774229&amp;postID=3704904715585084689" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/3704904715585084689?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/3704904715585084689?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/SpaceProgramBlog/~3/413568634/callable-and-case-of-disappearing.html" title="Callable and the Case of the Disappearing Exceptions " /><author><name>Travis Reeder</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.spaceprogram.com/2008/10/callable-and-case-of-disappearing.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7774229.post-2147347583524554266</id><published>2008-10-02T16:02:00.001-07:00</published><updated>2008-10-02T16:02:15.804-07:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2008-10-02T16:02:15.804-07:00</app:edited><title type="text">How To Give a User Root Access on Linux</title><content type="html">&lt;p&gt;NOTE: I take no responsibility for using the following and do not recommend using it. &lt;/p&gt;  &lt;p&gt;But for those that want it:&lt;/p&gt;  &lt;pre&gt;usermod -G root username&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;This changes the user with ‘username’ to the root group and thus gives root access. &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;And remember, as Uncle Ben says, “with great power comes great responsibility”.&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/SpaceProgramBlog/~4/409701842" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.spaceprogram.com/feeds/2147347583524554266/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7774229&amp;postID=2147347583524554266" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/2147347583524554266?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/2147347583524554266?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/SpaceProgramBlog/~3/409701842/how-to-give-user-root-access-on-linux.html" title="How To Give a User Root Access on Linux" /><author><name>Travis Reeder</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.spaceprogram.com/2008/10/how-to-give-user-root-access-on-linux.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7774229.post-6325038035803072952</id><published>2008-10-01T13:16:00.001-07:00</published><updated>2008-10-09T18:51:33.830-07:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2008-10-09T18:51:33.830-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="jaxb" /><title type="text">Using JAXB Without Annotations</title><content type="html">&lt;p&gt;The latest JAXB included with JDK 1.6 is really a great addition to the JDK making it easy to send objects around in XML format without requiring any third party libraries. All you have to do is put an @XmlRootElement annotation on a class and then call:&lt;/p&gt;  &lt;p&gt;marshaller.marshal(Object, OutputStream);&lt;/p&gt;  &lt;p&gt;Example class using @XmlRootElement:&lt;/p&gt;  &lt;pre&gt;@XmlRootElement&lt;br /&gt;class MyClass {&lt;br /&gt;&amp;#160; String name;&lt;br /&gt;&amp;#160; String content;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;To read the object back in, you simply call:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;MyClass object = unmarshaller.unmarshal(InputStream);&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;But what if you are building a library that doesn’t know what the class is and doesn’t have the @XmlRootElement annotation?&amp;#160; Well it turns out that it’s &lt;em&gt;almost &lt;/em&gt;just as easy without it you just need to let JAXB know what class you expect. &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;First get the JAXBContext like this:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;JAXBContext context = JAXBContext.newInstance(object.getClass());&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;To marshal:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;marshaller.marshal(new JAXBElement(new QName(object.getClass().getSimpleName()), object.getClass(), object), out);&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;To unmarshal:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;JAXBElement o = unmarshaller.unmarshal(new StreamSource(inputStream), expectedType);&lt;br /&gt;MyClass object = o.getValue();&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;That’s it.&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/SpaceProgramBlog/~4/408583261" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.spaceprogram.com/feeds/6325038035803072952/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7774229&amp;postID=6325038035803072952" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/6325038035803072952?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/6325038035803072952?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/SpaceProgramBlog/~3/408583261/using-jaxb-without-annotations.html" title="Using JAXB Without Annotations" /><author><name>Travis Reeder</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.spaceprogram.com/2008/10/using-jaxb-without-annotations.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7774229.post-213001110782995380</id><published>2008-05-25T17:53:00.000-07:00</published><updated>2008-05-25T18:13:44.707-07:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2008-05-25T18:13:44.707-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="caching" /><category scheme="http://www.blogger.com/atom/ns#" term="Hibernate" /><category scheme="http://www.blogger.com/atom/ns#" term="JPA" /><title type="text">Warming Up the Hibernate Second Level Cache</title><content type="html">I recently ran into a problem where Hibernate took forever to load up a result set because it was executing two additional queries for every object in the list to get it's @ManyToOne references. With thousands of objects returned, this meant thousands of individual sql select queries!  I am using the JPA EntityManager throughout these examples.&lt;br /&gt;&lt;br /&gt;eg:&lt;br /&gt;&lt;br /&gt;public class MyEntity{&lt;br /&gt;   ....&lt;br /&gt;   @ManyToOne&lt;br /&gt;   public MyEntity2 getMyEntity2(){&lt;br /&gt;...&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   @ManyToOne&lt;br /&gt;   public MyEntity3 getMyEntity3(){&lt;br /&gt;...&lt;br /&gt;   }&lt;br /&gt; &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;I had to use these many-to-one references so fiddling with lazy loading wouldn't help my situation. I was already caching the result collection after the first load, but it still was taking minutes to load up the first time and there was less than a thousand results, what gives? But 1000 * 2 extra sql select queries is 2000 individual queries which is just not good. Even the Hibernate second level cache didn't help because it still needs the first load.&lt;br /&gt;&lt;br /&gt;There must be some way to make this startup faster right??&lt;br /&gt;&lt;br /&gt;So I starting thinking, "how can I get these things to load up in the fewest number of sql queries?".  Then it struck me, I'll warm up the cache by querying for all of the ManyToOne objects on startup, for instance:&lt;br /&gt;&lt;br /&gt;em.createQuery("select me2 from MyEntity2").getResultList();&lt;br /&gt;&lt;br /&gt;and&lt;br /&gt;&lt;br /&gt;em.createQuery("select me2 from MyEntity3").getResultList();&lt;br /&gt;&lt;br /&gt;Now when I run the original query for MyEntity, the result is almost immediate. I turned ~2000 database hits into 3!&lt;br /&gt;&lt;br /&gt;More Reading:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://ehcache.sourceforge.net/documentation/hibernate.html"&gt;Enabling the hibernate second level cache&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/SpaceProgramBlog/~4/298046561" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.spaceprogram.com/feeds/213001110782995380/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7774229&amp;postID=213001110782995380" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/213001110782995380?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/213001110782995380?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/SpaceProgramBlog/~3/298046561/warming-up-hibernate-second-level-cache.html" title="Warming Up the Hibernate Second Level Cache" /><author><name>Travis Reeder</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.spaceprogram.com/2008/05/warming-up-hibernate-second-level-cache.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7774229.post-8411173264189836697</id><published>2008-05-20T15:41:00.000-07:00</published><updated>2008-05-20T16:27:16.318-07:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2008-05-20T16:27:16.318-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Backup" /><title type="text">Automated, Real-time Hard Drive Backup</title><content type="html">As I've said before, &lt;a href="http://blog.spaceprogram.com/2006/01/mozy-has-nailed-remote-backups.html"&gt;I'm a big advocate of backup systems&lt;/a&gt; because I've gone through the hell of hard drive failures. A &lt;a href="http://www.cs.cmu.edu/%7Ebianca/fast07.pdf"&gt;2007 study&lt;/a&gt; by The Computer Science Department of Carnegie Mellon University states that:&lt;blockquote&gt;&lt;span style="font-style: italic;"&gt;We find that in the field, annual disk replacement rates typically exceed 1%, with 2-4% common and up to 13% observed on some systems. &lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;With statistics like that, you better believe it will happen to you some day.&lt;br /&gt;&lt;br /&gt;I currently use &lt;a href="http://www.mozy.com"&gt;Mozy&lt;/a&gt; for remote backup in case I throw my computer out the window because &lt;a href="http://avive.wordpress.com/2007/09/22/switching-to-mac-from-vista/"&gt;Vista has me so frustrated&lt;/a&gt;. Remote backups are great and a must have in my eyes (they also give you that warm fuzzy feeling), but they are not perfect. For instance, it could take weeks to actually recover your 50 gigs of data from a remote service. You will eventually get it all, but it won't be a quick recovery.&lt;br /&gt;&lt;br /&gt;Want zero down time?  Enter RAID. &lt;a href="http://www.accordancesystems.com"&gt;Accordance Systems&lt;/a&gt; has a really cool backup device called the &lt;a href="http://www.accordancesystems.com/Mainproducts.asp"&gt;ARAID&lt;/a&gt; that automatically and transparently backs up your hard drive by mirroring it. Now mirroring hard drives isn't anything new, but the cool part about the ARAID device is that it acts like a normal hard drive on your computer and you can simply add it to your box without having to do anything crazy like reformatting your hard drive or installing raid controllers to get it running. And if a hard drive fails, you won't be waiting weeks to recover, in fact you won't even have to stop working because the mirrored drive takes over.&lt;br /&gt;&lt;br /&gt;Here's the skinny on how it works:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;You shutdown your computer (or course)&lt;/li&gt;&lt;li&gt;Replace your master hard drive with the ARAID unit&lt;/li&gt;&lt;li&gt;Put your master hard drive in the top bay of the ARAID&lt;/li&gt;&lt;li&gt;Now you start up your computer and it runs like normal as if the ARAID weren't there&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Now you insert a second drive into the bottom tray (yes, you can do this while the drive is&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The ARAID will now synchronize the master drive to the second drive on the fly&lt;/li&gt;&lt;li&gt;Now you have a fully functioning mirrored RAID 1 array where your data is always backed up to the second drive so if one drive fails, the other takes over with no downtime.&lt;/li&gt;&lt;/ol&gt;This is pretty cool stuff, especially because they made it so easy to setup. I would definitely recommend using something like this along with a remote backup solution just in case your office burns to the ground.&lt;img src="http://feeds.feedburner.com/~r/SpaceProgramBlog/~4/294630481" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.spaceprogram.com/feeds/8411173264189836697/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7774229&amp;postID=8411173264189836697" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/8411173264189836697?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/8411173264189836697?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/SpaceProgramBlog/~3/294630481/automated-real-time-hard-drive-backup.html" title="Automated, Real-time Hard Drive Backup" /><author><name>Travis Reeder</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.spaceprogram.com/2008/05/automated-real-time-hard-drive-backup.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7774229.post-862911185287526626</id><published>2008-03-06T11:11:00.001-08:00</published><updated>2008-03-06T11:11:28.175-08:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2008-03-06T11:11:28.175-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dns" /><category scheme="http://www.blogger.com/atom/ns#" term="dynamic dns" /><category scheme="http://www.blogger.com/atom/ns#" term="amazon" /><category scheme="http://www.blogger.com/atom/ns#" term="ec2" /><title type="text">How To Set Up Dynamic DNS for your Amazon EC2 Instance</title><content type="html">&lt;p&gt;Here's a step by step to setting up dynamic dns for you EC2 instance. This is required because EC2 does not have static IPs (yet). &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;First of all, you need a dynamic dns account. You can get one at &lt;a href="http://www.dyndns.com"&gt;www.dyndns.com&lt;/a&gt; or my personal favorite, &lt;a href="http://www.zoneedit.com"&gt;www.zoneedit.com&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;After you sign up, be sure to add your domains to their system. &lt;/li&gt;    &lt;li&gt;&lt;a href="https://www.dyndns.com/support/clients/unix.html"&gt;Download dyndns client&lt;/a&gt;&amp;#160; &lt;ol&gt;       &lt;li&gt;run: wget &lt;a href="http://cdn.dyndns.com/ddclient.tar.gz"&gt;http://cdn.dyndns.com/ddclient.tar.gz&lt;/a&gt; &lt;/li&gt;        &lt;li&gt;The download includes Installation Instructions in the README, but the step by step is below &lt;/li&gt;     &lt;/ol&gt;   &lt;/li&gt;    &lt;li&gt;tar -zxvf ddclient.tar.gz &lt;/li&gt;    &lt;li&gt;cd ddclient-X.Y &lt;/li&gt;    &lt;li&gt;cp ddclient /usr/sbin/ &lt;/li&gt;    &lt;li&gt;mkdir /etc/ddclient &lt;/li&gt;    &lt;li&gt;nano -w /etc/ddclient/ddclient.conf &lt;/li&gt;    &lt;ol&gt;     &lt;li&gt;Then fill in config file: &lt;/li&gt;   &lt;/ol&gt; &lt;/ol&gt;  &lt;p&gt;&lt;strong&gt;FOR ZONEEDIT&lt;/strong&gt; &lt;/p&gt;  &lt;p&gt;# Basic configuration file for ddclient    &lt;br /&gt;#     &lt;br /&gt;# /etc/ddclient.conf     &lt;br /&gt;daemon=600     &lt;br /&gt;pid=/var/run/ddclient.pid     &lt;br /&gt;use=web, web=checkip.dyndns.org/, web-skip='IP Address'     &lt;br /&gt;login=[USERNAME     &lt;br /&gt;password=[PASSWORD]     &lt;br /&gt;protocol=zoneedit1     &lt;br /&gt;server=www.zoneedit.com     &lt;br /&gt;wildcard=YES     &lt;br /&gt;[YOUR DOMAIN(S), COMMA DELIMITED LIST] &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;FOR DYNDNS&lt;/strong&gt; &lt;/p&gt;  &lt;p&gt;# Basic configuration file for ddclient   &lt;br /&gt;#    &lt;br /&gt;# /etc/ddclient.conf    &lt;br /&gt;daemon=600    &lt;br /&gt;pid=/var/run/ddclient.pid    &lt;br /&gt;use=web, web=checkip.dyndns.com/, web-skip='IP Address'    &lt;br /&gt;login=[USERNAME    &lt;br /&gt;password=[PASSWORD]protocol=dyndns2    &lt;br /&gt;server=members.dyndns.org    &lt;br /&gt;wildcard=YES    &lt;br /&gt;[YOUR DOMAIN(S), COMMA DELIMITED LIST]    &lt;br /&gt;custom=yes, example.com&lt;/p&gt;  &lt;p&gt;&lt;a href="https://www.dyndns.com/support/kb/archives/using_ddclient_with_dyndns_services.html"&gt;More info on configuration&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Continuing on:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;cp sample-etc_rc.d_init.d_ddclient /etc/rc.d/init.d/ddclient &lt;/li&gt;    &lt;li&gt;/sbin/chkconfig --add ddclient &lt;/li&gt;    &lt;ol&gt;     &lt;li&gt;This makes it startup automatically next time you reboot&lt;/li&gt;   &lt;/ol&gt;    &lt;li&gt;/etc/rc.d/init.d/ddclient start      &lt;ol&gt;       &lt;li&gt;This is to start it the first time by hand &lt;/li&gt;        &lt;li&gt;DON'T RUN THIS until your server is fully setup if you are moving servers because people will start hitting this server after you run this &lt;/li&gt;     &lt;/ol&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;That's it, not too difficult and gives you a real domain name to point at your EC2 instance.&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/SpaceProgramBlog/~4/246914901" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.spaceprogram.com/feeds/862911185287526626/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7774229&amp;postID=862911185287526626" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/862911185287526626?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/862911185287526626?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/SpaceProgramBlog/~3/246914901/how-to-set-up-dynamic-dns-for-your.html" title="How To Set Up Dynamic DNS for your Amazon EC2 Instance" /><author><name>Travis Reeder</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.spaceprogram.com/2008/03/how-to-set-up-dynamic-dns-for-your.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7774229.post-1903966197103606304</id><published>2008-01-27T14:11:00.001-08:00</published><updated>2008-02-25T10:34:34.579-08:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2008-02-25T10:34:34.579-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="db4o" /><category scheme="http://www.blogger.com/atom/ns#" term="Databases" /><title type="text">Transparent Persistence is Here</title><content type="html">&lt;p&gt;The idea of not having to deal with storing your application's data has long been a pipe dream, but it seems that the folks behind the &lt;a href="http://www.db4o.com"&gt;db4o object database&lt;/a&gt; have made it a reality. I've written a &lt;a href="http://blog.spaceprogram.com/2006/05/say-goodbye-to-your-relational.html"&gt;couple&lt;/a&gt; of &lt;a href="http://blog.spaceprogram.com/2006/07/db4outil-aka-easiest-way-to-get.html"&gt;posts&lt;/a&gt; in the past about db4o and how easy it is to use and it appears to be getting easier and easier with Transparent Activation and Transparent Update. &lt;/p&gt;  &lt;p&gt;Transparent activation is basically just lazy loading objects in the object graph on an as needed basis. Transparent Update is the opposite; storing objects when they get dirty without you having to explicitly say so.&lt;/p&gt;  &lt;p&gt;You can check out the &lt;a href="http://db4o.com/about/news/release/2008_01_22.aspx"&gt;press release on Transparent Update here&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpaceProgramBlog/~4/238435453" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.spaceprogram.com/feeds/1903966197103606304/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7774229&amp;postID=1903966197103606304" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/1903966197103606304?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/1903966197103606304?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/SpaceProgramBlog/~3/238435453/transparent-persistence-is-here.html" title="Transparent Persistence is Here" /><author><name>Travis Reeder</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.spaceprogram.com/2008/01/transparent-persistence-is-here.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7774229.post-8131834637256375238</id><published>2008-01-10T18:34:00.001-08:00</published><updated>2008-01-10T18:34:09.990-08:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2008-01-10T18:34:09.990-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="REST" /><category scheme="http://www.blogger.com/atom/ns#" term="Web Services" /><category scheme="http://www.blogger.com/atom/ns#" term="Jersey" /><category scheme="http://www.blogger.com/atom/ns#" term="JAX-RS" /><category scheme="http://www.blogger.com/atom/ns#" term="tomcat" /><title type="text">Getting Started with JAX-RS and Jersey - Simple REST Web Services for Java</title><content type="html">&lt;p&gt;I came across the need &lt;a href="http://www.ecommstats.com/services/docs/"&gt;once again&lt;/a&gt; to build a public facing web services API and we all know that to be in the cool gang these days, you have to do it &lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"&gt;REST&lt;/a&gt; style. Now I've been a big fan of REST over SOAP (or any other type) for a long time for one simple reason: it's simpler. And simple is king in my books. Anyways, I decided to see if anyone had come up with a good, simple REST framework for java since there hasn't really been anything that I've found over the years. &lt;/p&gt;  &lt;p&gt;With a little digging, I found what I had been looking for and it goes by the name JAX-RS (&lt;a href="https://jsr311.dev.java.net/"&gt;jsr311&lt;/a&gt;). Now this is pretty bleeding edge, the buzz has just started in the past few months and there's not much around to help you out. But as you should see in the samples below, it's well worth checking out. &lt;/p&gt;  &lt;p&gt;Now lets get into the nitty gritty:&lt;/p&gt;  &lt;h4&gt;1. Download Jersey and add required jars to classpath&lt;/h4&gt;  &lt;p&gt;Jersey is the reference implementation, &lt;a href="https://jersey.dev.java.net/"&gt;get it here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Now you only need three jars from the Jersey download:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;asm-3.X.jar&lt;/li&gt;    &lt;li&gt;jersey.jar&lt;/li&gt;    &lt;li&gt;jsr311-api.jar&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;That's all you need. Compare that to Axis and this alone should make you want to switch.&lt;/p&gt;  &lt;h4&gt;2. Add the Jersey Servlet to web.xml&lt;/h4&gt;  &lt;p&gt;You can use a lightweight http server that comes with the JDK or Jersey, but who's gonna do that in the real world? So here is how to get it running in Tomcat.&lt;/p&gt;  &lt;p&gt;&lt;font color="#0080c0" size="1"&gt;&amp;lt;servlet&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;servlet-name&amp;gt;JerseyWebApplication&amp;lt;/servlet-name&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;servlet-class&amp;gt;com.sun.ws.rest.spi.container.servlet.ServletContainer&amp;lt;/servlet-class&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/servlet&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;servlet-mapping&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;servlet-name&amp;gt;JerseyWebApplication&amp;lt;/servlet-name&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;url-pattern&amp;gt;/rest/*&amp;lt;/url-pattern&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/servlet-mapping&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;h4&gt;3. Make a service bean&lt;/h4&gt;  &lt;p&gt;Now all you have to do is make service beans via JAX-RS annotations. This is remarkably easy. We'll start with the simplest Hello World example:&lt;/p&gt;  &lt;pre&gt;&lt;font color="#0080c0" size="1"&gt;@Path(&amp;quot;/helloworld&amp;quot;) // sets the path for this service&lt;br /&gt;public class HelloWorldBean {&lt;br /&gt;   @GET // This method will process GET &lt;br /&gt;               &lt;/font&gt;&lt;font color="#0080c0" size="1"&gt;// requests to the @Path value set above&lt;/font&gt;&lt;font color="#0080c0" size="1"&gt;&lt;br /&gt;   @ProduceMime(&amp;quot;text/html&amp;quot;) // content type to output&lt;br /&gt;   public String getClichedMessage() {&lt;br /&gt;       return &amp;quot;Hello World&amp;quot;;&lt;br /&gt;   }&lt;br /&gt;}&lt;/font&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;4. Run Tomcat and browse to /helloworld&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Startup tomcat with your /WEB-INF/web.xml, the 3 jars in /WEB-INF/lib, and your compiled HelloWorldBean in /WEB-INF/classes. Now browse to &lt;a href="http://localhost:8080/yourContext/rest/helloworld"&gt;http://localhost:8080/yourContext/rest/helloworld&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;You should see in your browser: Hello World.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;That should give you all the basics you'll need to get started. Next time I'll post how to easily send XML responses directly from your objects.&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/SpaceProgramBlog/~4/238435454" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.spaceprogram.com/feeds/8131834637256375238/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7774229&amp;postID=8131834637256375238" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/8131834637256375238?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/8131834637256375238?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/SpaceProgramBlog/~3/238435454/getting-started-with-jax-rs-and-jersey.html" title="Getting Started with JAX-RS and Jersey - Simple REST Web Services for Java" /><author><name>Travis Reeder</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">6</thr:total><feedburner:origLink>http://blog.spaceprogram.com/2008/01/getting-started-with-jax-rs-and-jersey.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7774229.post-6770396721521965324</id><published>2007-11-01T15:36:00.001-07:00</published><updated>2007-11-01T15:37:29.790-07:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2007-11-01T15:37:29.790-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="server" /><category scheme="http://www.blogger.com/atom/ns#" term="monitor" /><category scheme="http://www.blogger.com/atom/ns#" term="Facebook" /><title type="text">Monitor Your Servers in Facebook</title><content type="html">&lt;p&gt;If you have been thinking of an excuse to tell your boss why you need to use Facebook at work, here's your answer.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.facebook.com/apps/application.php?id=6540206257"&gt;&lt;img id="id" src="http://photos-b.ak.facebook.com/photos-ak-sctm/v43/109/6540206257/app_3_6540206257_6728.gif" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Monitor your web servers in Facebook! Get a notification when your site goes down and when it comes back up. Show your server status on your profile too so your friends can see if you're a network admin rockstar or not.    &lt;br /&gt;&lt;b&gt;Features&lt;/b&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Notifications via Facebook feed, email and SMS &lt;/li&gt;    &lt;li&gt;Checks every ten minutes &lt;/li&gt;    &lt;li&gt;10 second setup &lt;/li&gt;    &lt;li&gt;FREE! &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://www.facebook.com/apps/application.php?id=6540206257"&gt;Check it out here&lt;/a&gt;.&lt;/p&gt; &lt;img src="http://feeds.feedburner.com/~r/SpaceProgramBlog/~4/238435455" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.spaceprogram.com/feeds/6770396721521965324/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7774229&amp;postID=6770396721521965324" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/6770396721521965324?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/6770396721521965324?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/SpaceProgramBlog/~3/238435455/monitor-your-servers-in-facebook.html" title="Monitor Your Servers in Facebook" /><author><name>Travis Reeder</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.spaceprogram.com/2007/11/monitor-your-servers-in-facebook.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7774229.post-8990729778496157443</id><published>2007-10-16T22:20:00.001-07:00</published><updated>2007-10-16T22:20:37.607-07:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2007-10-16T22:20:37.607-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="server" /><category scheme="http://www.blogger.com/atom/ns#" term="scaling" /><category scheme="http://www.blogger.com/atom/ns#" term="amazon" /><category scheme="http://www.blogger.com/atom/ns#" term="s3" /><category scheme="http://www.blogger.com/atom/ns#" term="ec2" /><title type="text">New Scaling Out Blog at www.scalingout.com</title><content type="html">&lt;p&gt;I started a new blog focused on Amazon Web Services and cloud computing over at &lt;a href="http://www.scalingout.com"&gt;www.scalingout.com&lt;/a&gt;. It will cover the latest news about the industry and showcase how people are using EC2, S3, etc. Check it out, subscribe, let me know your thoughts. &lt;/p&gt; &lt;img src="http://feeds.feedburner.com/~r/SpaceProgramBlog/~4/238435456" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.spaceprogram.com/feeds/8990729778496157443/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7774229&amp;postID=8990729778496157443" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/8990729778496157443?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/8990729778496157443?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/SpaceProgramBlog/~3/238435456/new-scaling-out-blog-at.html" title="New Scaling Out Blog at www.scalingout.com" /><author><name>Travis Reeder</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.spaceprogram.com/2007/10/new-scaling-out-blog-at.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7774229.post-6645625095839919618</id><published>2007-10-02T14:46:00.001-07:00</published><updated>2007-10-02T14:48:18.941-07:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2007-10-02T14:48:18.941-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="joid" /><category scheme="http://www.blogger.com/atom/ns#" term="Single Sign On" /><category scheme="http://www.blogger.com/atom/ns#" term="OpenID" /><title type="text">How to Add OpenID Support to your Java Application</title><content type="html">&lt;p&gt;&lt;/p&gt;  &lt;p&gt;Here is a quick and easy step by step to add OpenID support to your application. We are using joid because it's the lightest weight implementation with the least number of dependencies (2 jars).&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Download joid from &lt;a href="http://code.google.com/p/joid/"&gt;http://code.google.com/p/joid/&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Copy joid.jar, log4j-*.jar, and tsik.jar to your lib directory (so they end up in WEB-INF/lib). &lt;/li&gt;    &lt;li&gt;Add OpenIdFilter to your web.xml (see below for how to add it) &lt;/li&gt;    &lt;li&gt;Add OpenId login form (see below for a sample jsp page) &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;After a user logs in, you can access the username that they're signed in as with:&lt;/p&gt;  &lt;p&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;String loggedInAs = OpenIdFilter.getCurrentUser(session);&lt;/span&gt; &lt;/p&gt;  &lt;p&gt;Simple huh? &lt;br /&gt;&lt;/p&gt; &lt;strong&gt;&lt;/strong&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="font-size:100%;"&gt;OpenIdFilter for web.xml&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color: rgb(0, 128, 192);font-size:78%;" &gt;&amp;lt;filter&amp;gt;   &lt;br /&gt;      &amp;lt;filter-name&amp;gt;OpenIdFilter&amp;lt;/filter-name&amp;gt;    &lt;br /&gt;      &amp;lt;filter-class&amp;gt;org.verisign.joid.consumer.OpenIdFilter&amp;lt;/filter-class&amp;gt;    &lt;br /&gt;      &amp;lt;init-param&amp;gt;    &lt;br /&gt;          &amp;lt;description&amp;gt;Optional. Will store the identity url in a cookie under "openid.identity" if set to true.&amp;lt;/description&amp;gt;    &lt;br /&gt;          &amp;lt;param-name&amp;gt;saveInCookie&amp;lt;/param-name&amp;gt;    &lt;br /&gt;          &amp;lt;param-value&amp;gt;true&amp;lt;/param-value&amp;gt;    &lt;br /&gt;      &amp;lt;/init-param&amp;gt;    &lt;br /&gt;      &amp;lt;!--    &lt;br /&gt;      &amp;lt;init-param&amp;gt;    &lt;br /&gt;              &amp;lt;param-name&amp;gt;cookieDomain&amp;lt;/param-name&amp;gt;    &lt;br /&gt;              &amp;lt;param-value&amp;gt;www.mydomain.com&amp;lt;/param-value&amp;gt;    &lt;br /&gt;              &amp;lt;description&amp;gt;Optional. Domain to store cookie based on RFC 2109. Defaults to current context.&amp;lt;/description&amp;gt;    &lt;br /&gt;      &amp;lt;/init-param&amp;gt;    &lt;br /&gt;      --&amp;gt;    &lt;br /&gt;  &amp;lt;/filter&amp;gt;    &lt;br /&gt;  &amp;lt;filter-mapping&amp;gt;    &lt;br /&gt;      &amp;lt;filter-name&amp;gt;OpenIdFilter&amp;lt;/filter-name&amp;gt;    &lt;br /&gt;      &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;    &lt;br /&gt;  &amp;lt;/filter-mapping&amp;gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="font-size:100%;"&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="font-size:100%;"&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="font-size:100%;"&gt;OpenID Login Form&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color: rgb(0, 128, 192);font-size:78%;" &gt;&amp;lt;%@ page import="org.verisign.joid.consumer.OpenIdFilter" %&amp;gt;   &lt;br /&gt;&amp;lt;%@ page import="org.verisign.joid.util.UrlUtils" %&amp;gt;    &lt;br /&gt;&amp;lt;%@ page contentType="text/html;charset=UTF-8" language="java" %&amp;gt;    &lt;br /&gt;&amp;lt;%    &lt;br /&gt;  String returnTo = UrlUtils.getBaseUrl(request); &lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color: rgb(0, 128, 192);font-size:78%;" &gt;    if (request.getParameter("signin") != null) {   &lt;br /&gt;      try {    &lt;br /&gt;          String id = request.getParameter("openid_url");    &lt;br /&gt;          if (!id.startsWith("http:")) {    &lt;br /&gt;              id = "&lt;/span&gt;&lt;a href="http:///"&gt;&lt;span style="color: rgb(0, 128, 192);font-size:78%;" &gt;http://"&lt;/span&gt;&lt;/a&gt;&lt;span style="color: rgb(0, 128, 192);font-size:78%;" &gt; + id;   &lt;br /&gt;          }    &lt;br /&gt;          String trustRoot = returnTo; &lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color: rgb(0, 128, 192);font-size:78%;" &gt;            String s = OpenIdFilter.joid().getAuthUrl(id, returnTo, trustRoot);&lt;br /&gt;          response.sendRedirect(s);    &lt;br /&gt;      } catch (Throwable e) {    &lt;br /&gt;          e.printStackTrace();    &lt;br /&gt;%&amp;gt;    &lt;br /&gt;An error occurred! Please press back and try again.    &lt;br /&gt;&amp;lt;%    &lt;br /&gt;      }    &lt;br /&gt;      return;    &lt;br /&gt;  }    &lt;br /&gt;%&amp;gt;    &lt;br /&gt;&amp;lt;html&amp;gt;    &lt;br /&gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;A Page I Want to Login To&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;    &lt;br /&gt;&amp;lt;body&amp;gt;    &lt;br /&gt;&amp;lt;h1&amp;gt;Login&amp;lt;/h1&amp;gt;    &lt;br /&gt;&amp;lt;p&amp;gt;    &lt;br /&gt;  This is a sample login page where a user enters their OpenID url to login.    &lt;br /&gt;&amp;lt;/p&amp;gt; &lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color: rgb(0, 128, 192);font-size:78%;" &gt;&amp;lt;%   &lt;br /&gt;  String loggedInAs = OpenIdFilter.getCurrentUser(session);    &lt;br /&gt;  if(loggedInAs != null){    &lt;br /&gt;%&amp;gt;    &lt;br /&gt;&amp;lt;p align="center"&amp;gt;    &lt;br /&gt;  &amp;lt;span style=" background-  padding:5px;"&amp;gt;You are logged in as: &amp;lt;%=OpenIdFilter.getCurrentUser(session)%&amp;gt;&amp;lt;/span&amp;gt; - &amp;lt;a href="logout.jsp"&amp;gt;Logout&amp;lt;/a&amp;gt;    &lt;br /&gt;&amp;lt;/p&amp;gt;    &lt;br /&gt;&amp;lt;%    &lt;br /&gt;  }    &lt;br /&gt;%&amp;gt; &lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color: rgb(0, 128, 192);font-size:78%;" &gt;&amp;lt;div style='margin: 1em 0 1em 2em; border-left: 2px solid black; padding-left: 1em;'&amp;gt;   &lt;br /&gt;  &amp;lt;form action="index.jsp" method="post"&amp;gt;    &lt;br /&gt;      &amp;lt;input type="hidden" name="signin" value="true"/&amp;gt;    &lt;br /&gt;      &amp;lt;b&amp;gt;Login with your OpenID URL:&amp;lt;/b&amp;gt; &amp;lt;input type="text" size="30" value=""    &lt;br /&gt;                                                name="openid_url"/&amp;gt;    &lt;br /&gt;      &amp;lt;input type="submit" value="Login"/&amp;gt;&amp;lt;br/&amp;gt;    &lt;br /&gt;      &amp;lt;i&amp;gt;For example: &amp;lt;tt&amp;gt;someone.bloghost.com&amp;lt;/tt&amp;gt;&amp;lt;/i&amp;gt;    &lt;br /&gt;  &amp;lt;/form&amp;gt;    &lt;br /&gt;&amp;lt;/div&amp;gt; &lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color: rgb(0, 128, 192);font-size:78%;" &gt;&amp;lt;p&amp;gt;   &lt;br /&gt;  &amp;lt;strong&amp;gt;Don't have an OpenID?&amp;lt;/strong&amp;gt; &amp;lt;a href="&lt;/span&gt;&lt;a href="https://pip.verisignlabs.com/"&gt;&lt;span style="color: rgb(0, 128, 192);font-size:78%;" &gt;https://pip.verisignlabs.com/"&lt;/span&gt;&lt;/a&gt;&lt;span style="color: rgb(0, 128, 192);font-size:78%;" &gt; target="_blank"&amp;gt;Go&amp;lt;/a&amp;gt;   &lt;br /&gt;  &amp;lt;a href="&lt;/span&gt;&lt;a href="http://www.myopenid.com/"&gt;&lt;span style="color: rgb(0, 128, 192);font-size:78%;" &gt;http://www.myopenid.com/"&lt;/span&gt;&lt;/a&gt;&lt;span style="color: rgb(0, 128, 192);font-size:78%;" &gt; target="_blank"&amp;gt;get&amp;lt;/a&amp;gt;   &lt;br /&gt;  &amp;lt;a href="&lt;/span&gt;&lt;a href="https://myvidoop.com/"&gt;&lt;span style="color: rgb(0, 128, 192);font-size:78%;" &gt;https://myvidoop.com/"&lt;/span&gt;&lt;/a&gt;&lt;span style="color: rgb(0, 128, 192);font-size:78%;" &gt; target="_blank"&amp;gt;one&amp;lt;/a&amp;gt;.   &lt;br /&gt;&amp;lt;/p&amp;gt; &lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;span style="color: rgb(0, 128, 192);font-size:78%;" &gt;&amp;lt;/body&amp;gt;   &lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpaceProgramBlog/~4/238435457" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.spaceprogram.com/feeds/6645625095839919618/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7774229&amp;postID=6645625095839919618" title="13 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/6645625095839919618?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/6645625095839919618?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/SpaceProgramBlog/~3/238435457/how-to-add-openid-support-to-your-java.html" title="How to Add OpenID Support to your Java Application" /><author><name>Travis Reeder</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">13</thr:total><feedburner:origLink>http://blog.spaceprogram.com/2007/10/how-to-add-openid-support-to-your-java.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7774229.post-8502479692178587758</id><published>2007-08-10T18:21:00.001-07:00</published><updated>2007-08-10T18:59:20.442-07:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2007-08-10T18:59:20.442-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="server" /><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="linux" /><category scheme="http://www.blogger.com/atom/ns#" term="ec2" /><category scheme="http://www.blogger.com/atom/ns#" term="jdk" /><title type="text">Downloading JDK to your Linux Server via SSH</title><content type="html">This is a pretty common problem that I'm sure almost every java developer has had to deal with. Due to Sun's licensing restrictions, you cannot simply use up2date, apt-get or yast to get the latest JDK. Even if you add the extra repositories for them to look at, it's usually not the latest JDK. On Windows, it's easy since you generally always have a UI via Remote Desktop. Linux is usually accessed via SSH so all you have is your shell command line which means you can't surf on over to Sun's Java site, click "Ok, I accept all the terms and conditions", and download it. So you end up downloading it on your local machine, then uploading it to your server via SCP. But this takes forever because you download 60 MB on your slow local connection, then upload it even slower (assuming your upload speed is slower than you download speed). So an hour later you finally get your jdk on the server.&lt;br /&gt;&lt;br /&gt;So is there a better, quicker way to do it?&lt;br /&gt;&lt;br /&gt;I'm glad you asked. Yes there most definitely is:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Go to jdk download site: http://java.sun.com/javase/downloads/&lt;/li&gt;&lt;li&gt;Click Download button on the distro you want (usually the basic JDK)&lt;/li&gt;&lt;li&gt;Accept the license agreement&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Right click&lt;/span&gt; the download link (usually the RPM in self extracting bin) and in the right click context menu choose Copy Link Location if using Firefox or Copy Shortcut in Internet Explorer.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Now you have the location of the download so go to your SSH shell where you are logged into your Linux server and use the following command:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;wget &lt;span style="color: rgb(0, 153, 0);"&gt;PASTE_FILE_LOCATION_HERE&lt;/span&gt; -O         jdk6-rpm.bin&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/li&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;You need the -O otherwise the filename length is too long&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Now install it:&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;         chmod a+x jdk6-rpm.bin&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;./jdk6-rpm.bin&lt;/span&gt;       &lt;/li&gt;&lt;/ol&gt;&lt;li&gt;         And finally, add JAVA_HOME to your environment variables:&lt;/li&gt;&lt;ol&gt;&lt;li&gt;create or edit .bash_profile file in /root and add "export         JAVA_HOME=/usr/java/latest"&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt;That's about it. Much much faster.&lt;img src="http://feeds.feedburner.com/~r/SpaceProgramBlog/~4/238435458" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.spaceprogram.com/feeds/8502479692178587758/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7774229&amp;postID=8502479692178587758" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/8502479692178587758?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/8502479692178587758?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/SpaceProgramBlog/~3/238435458/downloading-jdk-to-your-linux-server.html" title="Downloading JDK to your Linux Server via SSH" /><author><name>Travis Reeder</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.spaceprogram.com/2007/08/downloading-jdk-to-your-linux-server.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7774229.post-5270198575839374119</id><published>2007-06-15T10:27:00.001-07:00</published><updated>2007-06-15T10:37:05.447-07:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2007-06-15T10:37:05.447-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="scaling" /><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="caching" /><category scheme="http://www.blogger.com/atom/ns#" term="amazon" /><category scheme="http://www.blogger.com/atom/ns#" term="s3" /><category scheme="http://www.blogger.com/atom/ns#" term="web apps" /><category scheme="http://www.blogger.com/atom/ns#" term="ec2" /><title type="text">Third App Migrated to Amazon EC2</title><content type="html">A couple of days ago, I moved another application to &lt;a href="http://www.amazonaws.com/"&gt;Amazon Web Services&lt;/a&gt;. This is my third application I've setup on their infrastructure and I have to say, I think I'm addicted to the throwaway nature of Amazon Elastic Compute Cloud. I've got the whole long term, persistent storage thing nailed and can do quick recoveries so I am no longer worried about servers crashing... and boy that's a good feeling.&lt;br /&gt;&lt;br /&gt;On our previous dedicated servers, there's always a worry about having a server meltdown because there is no quick way to get a new one up and running. It could take a day or more. Now I just launch new servers for fun. ;)&lt;br /&gt;&lt;br /&gt;The big lessons learned:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Automate absolutely everything. So when something goes wrong, you run a script or two to get a new instance running. And practice, practice, practice doing emergency recoveries (I've had to recover from crashed instances several times now so I learnt this lesson the hard way).&lt;br /&gt;  &lt;/li&gt;&lt;li&gt;Scale early. As soon as you notice some performance or memory limitations, start adding more instances to spread out the load. Need performance, put your database on a separate server from app. Need redundancy, replicate your database on two servers. Need memory, fire up some more instances just for caching (memcached, ehcache, jbosscache).&lt;br /&gt;  &lt;/li&gt;&lt;li&gt;Keep your database as small as possible. Store as much data as possible on Amazon Simple Storage System (S3), NOT in your database and just store the S3 key to the data in your database. Consider putting any blob or large text fields in S3. This will make it much easier and faster to manage database backups, plus your database will perform better.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Are you an EC2 user? Let me know your experiences.&lt;img src="http://feeds.feedburner.com/~r/SpaceProgramBlog/~4/238435459" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.spaceprogram.com/feeds/5270198575839374119/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7774229&amp;postID=5270198575839374119" title="19 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/5270198575839374119?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/5270198575839374119?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/SpaceProgramBlog/~3/238435459/third-app-migrated-to-amazon-ec2.html" title="Third App Migrated to Amazon EC2" /><author><name>Travis Reeder</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">19</thr:total><feedburner:origLink>http://blog.spaceprogram.com/2007/06/third-app-migrated-to-amazon-ec2.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7774229.post-2095174053319678979</id><published>2007-06-04T10:52:00.000-07:00</published><updated>2007-06-04T11:07:00.174-07:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2007-06-04T11:07:00.174-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mysql" /><category scheme="http://www.blogger.com/atom/ns#" term="amazon" /><category scheme="http://www.blogger.com/atom/ns#" term="s3" /><category scheme="http://www.blogger.com/atom/ns#" term="ec2" /><title type="text">Amazon EC2 Ephemeral Storage (/mnt) and MySQL</title><content type="html">Amazon Elastic Compute Cloud (EC2) includes 160 GB of local storage. This storage is split into two partitions:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;~10 GB for your VM/AMI image instance which includes the OS and software.&lt;/li&gt;&lt;li&gt;~147 GB for your "ephemeral storage" which is where you should put your data or anything that is going to need a lot of space. This storage is in /mnt.&lt;/li&gt;&lt;/ol&gt;So in order to let your MySQL database grow, you'll need to put the data files in /mnt and the easiest way to do this is to make a symbolic link from the default MySQL data storage location (usually /var/lib/mysql) to a directory on /mnt. Be sure to do this immediately after installing MySQL so you won't run into any issues.&lt;br /&gt;&lt;br /&gt;Here is a step by step how to do it:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;mkdir /mnt/mysql&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Creates your new data directory&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;chown mysql:mysql /mnt/mysql&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Gives mysql ownership to the directory&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;/etc/init.d/mysql stop&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Stop MySQL before moving data files&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;           mv /var/lib/mysql/* /mnt/mysql&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Move your data files&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;           rmdir /var/lib/mysql&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Delete the old directory&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;           ln -s /mnt/mysql mysql&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Create a symlink to your new directory on /mnt&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;           /etc/init.d/mysql start&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Restart MySQL&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt;That's all she wrote. One last very important thing to remember: &lt;span style="font-weight: bold;"&gt;This storage is NOT reliable. If your instance is terminated or crashes, your data is lost forever! &lt;/span&gt;So always be sure to do regular backups to S3.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;img src="http://feeds.feedburner.com/~r/SpaceProgramBlog/~4/238435460" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.spaceprogram.com/feeds/2095174053319678979/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7774229&amp;postID=2095174053319678979" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/2095174053319678979?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/2095174053319678979?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/SpaceProgramBlog/~3/238435460/amazon-ec2-ephemeral-storage-mnt-and.html" title="Amazon EC2 Ephemeral Storage (/mnt) and MySQL" /><author><name>Travis Reeder</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://blog.spaceprogram.com/2007/06/amazon-ec2-ephemeral-storage-mnt-and.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7774229.post-59717970689360808</id><published>2007-05-11T01:05:00.000-07:00</published><updated>2007-05-11T01:11:44.764-07:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2007-05-11T01:11:44.764-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="jdk" /><title type="text">How To Fix LinkageError when using JAXB with JDK 1.6</title><content type="html">If you run across an error like this when trying to use JAXB:&lt;br /&gt;&lt;br /&gt;java.lang.LinkageError: JAXB 2.0 API is being loaded from the bootstrap classloader, but this RI&lt;br /&gt;(from  jar:file:/somedirectory/jaxb-impl.jar!/com/sun/xml/bind/v2/model/impl/ModelBuilder.class)  needs 2.1 API. Use the endorsed directory mechanism to place jaxb-api.jar in the bootstrap classloader. (See &lt;a rel="nofollow" href="http://java.sun.com/j2se/1.5.0/docs/guide/standards/"&gt;http://java.sun.com/j2se/1.5.0/docs/guide/standards/&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;It's actually a very simple fix, but painful enough to warrant a post. Put the jaxb-api.jar that you're trying to use into JDK_HOME/jre/lib/endorsed. If the endorsed directory doesn't exist, make it. This is apparently only a problem with JDK 1.6, not with JDK 1.5.&lt;img src="http://feeds.feedburner.com/~r/SpaceProgramBlog/~4/238435461" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.spaceprogram.com/feeds/59717970689360808/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7774229&amp;postID=59717970689360808" title="7 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/59717970689360808?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/59717970689360808?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/SpaceProgramBlog/~3/238435461/how-to-fix-linkageerror-when-using-jaxb.html" title="How To Fix LinkageError when using JAXB with JDK 1.6" /><author><name>Travis Reeder</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">7</thr:total><feedburner:origLink>http://blog.spaceprogram.com/2007/05/how-to-fix-linkageerror-when-using-jaxb.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7774229.post-5289322802582039460</id><published>2007-04-27T01:35:00.000-07:00</published><updated>2007-04-29T12:09:24.793-07:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2007-04-29T12:09:24.793-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="scaling" /><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="web apps" /><category scheme="http://www.blogger.com/atom/ns#" term="tomcat" /><title type="text">Liveness Rule #2: Asynchronize Everything for Writes</title><content type="html">And by everything, I mean at least as much as you possibly can. Writes are slow for all the same reasons brought up in the &lt;a href="http://blog.spaceprogram.com/2007/04/liveness-rule-1-cache-everything-for.html"&gt;caching post&lt;/a&gt;, and then some. With writes you can add more potential performance speed bumps to "database hit list", such as table locking or row locking depending on how the database handles it and disk write speeds.&lt;br /&gt;&lt;br /&gt;Caching works wonders on the Read side and because caching allows you to take the Read load off the database, it actually does help a lot to increase Write performance. What else can we do to increase liveness for operations that might take more than a fraction of a second? The answer: Go asynchronous.&lt;br /&gt;&lt;br /&gt;Good examples of things that should be asynced:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Sending mail notifications. This usually takes a significant amount of time, so you should always async this&lt;/li&gt;&lt;li&gt;Database updates that the user doesn't need to see a response for. For instance, logging, counters (how many times has the user viewed item X), etc? &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;How Do I Implement Asynchronous Ops?&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;If you're using Java, the &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/"&gt;java.util.concurrent&lt;/a&gt; package is your new best friend. This has everything you need to asynchronize things in a simple and elegant way. The classes you will be interested in are &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Executor.html"&gt;Executor&lt;/a&gt;, &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ExecutorService.html"&gt;ExecutorService&lt;/a&gt;, &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Executors.html"&gt;Executors&lt;/a&gt; (static factory methods). An Executor is essentially just a queue of tasks with a thread pool to dedicated to executing those tasks.&lt;/p&gt;&lt;p&gt;Here's a quick getting started guide to asynchronicity heaven:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Create the &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ExecutorService.html"&gt;ExecutorService&lt;/a&gt;:&lt;br /&gt;&lt;span style="color:#6600cc;"&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;ExecutorService executor = Executors.newFixedThreadPool(THREAD_POOL_SIZE);&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;Keep this available as a global variable, you can use this same &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Executor.html"&gt;Executor&lt;/a&gt; throughout your entire application if you want.&lt;/li&gt;&lt;li&gt;&lt;span style="color:#000000;"&gt;Now pull out any code you want to execute asynchronously into small tasks that implement Runnable. For example, an emailer task might look like this:&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;color:#6600cc;"&gt;public class EmailTask implements Runnable {&lt;br /&gt;private Email email; // the email we want to send.&lt;br /&gt;public EmailTask (Email email) {&lt;br /&gt;this.email = email;&lt;br /&gt;}&lt;br /&gt;public void run() {&lt;br /&gt;// SEND MAIL HERE&lt;br /&gt;}&lt;br /&gt;}&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Now when executing the event action, create a new instance of your Task class and pass it to the ExecutorService's execute command:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#6600cc;"&gt;EmailTask emailTask = new EmailTask(email);&lt;br /&gt;executorService.execute(feedRetrieverTask);&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Done! That task will execute at some point in the future and you can respond to your user immediately without making him/her wait.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;Another huge benefit of Asynchronizing things is that application automatically becomes more scalable and doesn't degrade as traffic goes up.&lt;/strong&gt; Lets say you did the above example synchronously and it took 2 seconds on average to send an email. That may be fine when you have a small number of users (although 2 seconds is way too long to make someone wait), but what happens if you have have 1000 users? That's a total of 33.3 minutes (2000 seconds) of waiting time just for 1000 users.  And lets say you have a maximum of 200 processing threads for your app server (Tomcat default). It won't take much to run out of processing threads if your traffic goes up, so now you have people waiting to get the application to respond at all. Pretty soon your app is on it's knees, dying a slow painful death. You can avoid all of these problems by taking a few extra seconds to implement it like I've shown above. &lt;/p&gt;&lt;p&gt;Learn it, live it, love it. Once you start getting into the habit of doing things like this, there's no turning back and you can rest easy knowing that &lt;strong&gt;you've future proofed your application&lt;/strong&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpaceProgramBlog/~4/238435462" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.spaceprogram.com/feeds/5289322802582039460/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7774229&amp;postID=5289322802582039460" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/5289322802582039460?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/5289322802582039460?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/SpaceProgramBlog/~3/238435462/liveness-rule-2-asynchronize-everything.html" title="Liveness Rule #2: Asynchronize Everything for Writes" /><author><name>Travis Reeder</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.spaceprogram.com/2007/04/liveness-rule-2-asynchronize-everything.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7774229.post-8765018843024742630</id><published>2007-04-27T01:27:00.000-07:00</published><updated>2007-04-27T01:35:00.390-07:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2007-04-27T01:35:00.390-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="scaling" /><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="caching" /><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="web apps" /><title type="text">Liveness Rule #1: Cache Everything for Reads</title><content type="html">&lt;p&gt;Caching is really the holy grail of liveness. Consider the difference between hitting your database for every request vs pulling that data directly out of memory. Here is a small comparison of performance related properties with pros in green and cons in red.&lt;/p&gt;&lt;p&gt;Memory:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="color:#006600;"&gt;Near instantaneous access to data&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="color:#006600;"&gt;Concurrent contention is virtually nil&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="color:#990000;"&gt;Limited amount of memory&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;span style="color:#000000;"&gt;Database Hit:&lt;/span&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="color:#990000;"&gt;Disk seek speed&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="color:#990000;"&gt;Concurrent contention as threads wait for disk access&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="color:#990000;"&gt;IO speed&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="color:#990000;"&gt;The database query speed&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="color:#990000;"&gt;Connection setup/teardown&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="color:#990000;"&gt;Marshalling and unmarshalling&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="color:#006600;"&gt;Large amount of disk space available&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;These are all pretty obvious points, but it is just to highlight how much more stuff is done when you don't cache. These things are really taxing on the entire system, much more so than pulling stuff from memory which also means &lt;strong&gt;your application is far more scalable&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Our experience:&lt;br /&gt;&lt;/strong&gt;Traffic was increasing in large amounts and the response times were getting worse and worse. Not to the point where it was the end of the world, but bad enough that we had to do something about it before it got even worse (over a second is bad). Now that we cache almost everything, response times are &lt;strong&gt;down to a few milliseconds, &lt;/strong&gt;right up there with Google search responses. &lt;/p&gt;&lt;p&gt;Caching is actually pretty simple to implement. No matter what solution you use, the interface is always something like java.util.Map where you put, get, and remove elements.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpaceProgramBlog/~4/238435463" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.spaceprogram.com/feeds/8765018843024742630/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7774229&amp;postID=8765018843024742630" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/8765018843024742630?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/8765018843024742630?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/SpaceProgramBlog/~3/238435463/liveness-rule-1-cache-everything-for.html" title="Liveness Rule #1: Cache Everything for Reads" /><author><name>Travis Reeder</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.spaceprogram.com/2007/04/liveness-rule-1-cache-everything-for.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7774229.post-7024688046683852462</id><published>2007-04-26T23:53:00.000-07:00</published><updated>2007-04-29T12:10:37.950-07:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2007-04-29T12:10:37.950-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="scaling" /><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="web apps" /><title type="text">Liveness In Web Applications</title><content type="html">&lt;blockquote&gt;&lt;a href="http://java.sun.com/docs/books/tutorial/essential/concurrency/liveness.html"&gt;Liveness&lt;/a&gt;: A concurrent application's ability to execute in a timely manner is&lt;br /&gt;known as its liveness. &lt;/blockquote&gt;&lt;p&gt;In other words, liveness is making your application respond extremely fast to your users requests. Having had to deal with this over the past few months on &lt;a href="http://www.rel8r.com"&gt;rel8r&lt;/a&gt;, I thought I'd share my experiences.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="http://blog.spaceprogram.com/2007/04/liveness-rule-1-cache-everything-for.html"&gt;Caching&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blog.spaceprogram.com/2007/04/liveness-rule-2-asynchronize-everything.html"&gt;Asynchronizing&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;img src="http://feeds.feedburner.com/~r/SpaceProgramBlog/~4/238435464" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.spaceprogram.com/feeds/7024688046683852462/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7774229&amp;postID=7024688046683852462" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/7024688046683852462?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/7024688046683852462?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/SpaceProgramBlog/~3/238435464/liveness-in-web-applications.html" title="Liveness In Web Applications" /><author><name>Travis Reeder</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.spaceprogram.com/2007/04/liveness-in-web-applications.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7774229.post-7336741110107975203</id><published>2007-01-02T17:59:00.000-08:00</published><updated>2007-01-02T18:00:45.618-08:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2007-01-02T18:00:45.618-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="tomcat" /><category scheme="http://www.blogger.com/atom/ns#" term="ssl certificates" /><title type="text">Renewing SSL Certificates on Tomcat</title><content type="html">&lt;p&gt;So I had to renew a couple of SSL certificates that are used by sites running standalone Tomcat, here is what I had to do: &lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Generate a new CSR request. This is easier than when first starting out since you've already created your keypair from the last time you bought your certificate:&lt;br /&gt;&lt;span style="color:#6600cc;"&gt;keytool -certreq -keyalg RSA -alias tomcat -file certreq.csr -keystore .keystore&lt;/span&gt; &lt;li&gt;Now open certreq.csr in a text editor and copy and paste the contents into your SSL issuers website form to finish the process of getting your new certificate. &lt;li&gt;Now you should get an email to verify that you are the one who submitted the request and a link to Approve it. This email will go to the email address on your whois record for your domain name to verify that you own the domain. &lt;li&gt;After you Approve the SSL request, you can download your new certificate along with the issuers intermediary certificate. &lt;li&gt;You must first install the issuers Intermediate Certificate:&lt;br /&gt;&lt;span style="color:#6600cc;"&gt;keytool -import -alias intermed -keystore .keystore -trustcacerts -file sf_issuing.crt&lt;/span&gt; &lt;li&gt;&lt;span style="color:#000000;"&gt;Then import your fresh new certificate:&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#6600cc;"&gt;keytool -import -alias tomcat -keystore .keystore -trustcacerts -file ariel1.spaceprogram.com.crt&lt;/span&gt; &lt;li&gt;&lt;span style="color:#000000;"&gt;And finally, restart Tomcat and double check by surfing to your page and checking out your certificate by clicking on the padlock icon on your web browser. Make sure the expiry date is correct.&lt;/span&gt; &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;That's about it. Nice and easy. &lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpaceProgramBlog/~4/238435465" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.spaceprogram.com/feeds/7336741110107975203/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7774229&amp;postID=7336741110107975203" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/7336741110107975203?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/7336741110107975203?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/SpaceProgramBlog/~3/238435465/so-i-had-to-renew-couple-of-ssl.html" title="Renewing SSL Certificates on Tomcat" /><author><name>Travis Reeder</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.spaceprogram.com/2007/01/so-i-had-to-renew-couple-of-ssl.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7774229.post-115861557604535990</id><published>2006-09-18T14:39:00.000-07:00</published><updated>2006-09-18T14:40:54.166-07:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2006-09-18T14:40:54.166-07:00</app:edited><title type="text">Poor Man's Oracle Client</title><content type="html">&lt;p&gt;I generally despise having to install Oracle software because it's so big and bloated, it's scary. Most downloads won't fit on a typical CD, even their Oracle Express edition is bigger than Microsoft Windows!&amp;nbsp;I don't know what Express means to them, but "huge" isn't the description I would think of.&lt;/p&gt; &lt;p&gt;But there is light at the end of the tunnel, Oracle now has &lt;a href="http://www.oracle.com/technology/tech/oci/instantclient/index.html"&gt;Instant Client&lt;/a&gt; which is only 35MB! Wow! And all you have to do is unzip it. It includes OCI, OCCI, and JDBC drivers, but if you want to make it useful out of the box, you should get the SQL Plus package for Instant Client (722KB!) and unzip it into the same directory.&amp;nbsp; Put your tnsnames.ora into the directory as well if required.&amp;nbsp; Then run sqlplus.exe as you normally would and voila, you're done.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Download &lt;a href="http://www.oracle.com/technology/tech/oci/instantclient/index.html"&gt;Oracle Instant Client&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Download SQL*Plus for Instant Client (from same download page)&lt;/li&gt; &lt;li&gt;Unzip Instant Client into a directory&lt;/li&gt; &lt;ol&gt; &lt;li&gt;eg: c:\oracle_ic&lt;/li&gt;&lt;/ol&gt; &lt;li&gt;Unzip SQL*Plus into the same directory&lt;/li&gt; &lt;li&gt;Put tnsnames.ora into the same directory (OPTIONAL)&lt;/li&gt; &lt;li&gt;Run: sqlplus &lt;a href="mailto:username/password@SID"&gt;username/password@SID&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Get &lt;a href="http://eclipsesql.sourceforge.net/"&gt;SQL Explorer&lt;/a&gt;&amp;nbsp;for a free JDBC based client if you want to connect with a visual client.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SpaceProgramBlog/~4/238435466" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.spaceprogram.com/feeds/115861557604535990/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7774229&amp;postID=115861557604535990" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/115861557604535990?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/115861557604535990?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/SpaceProgramBlog/~3/238435466/poor-mans-oracle-client.html" title="Poor Man's Oracle Client" /><author><name>Travis Reeder</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.spaceprogram.com/2006/09/poor-mans-oracle-client.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7774229.post-115205253593739346</id><published>2006-07-04T15:35:00.000-07:00</published><updated>2006-07-06T09:42:19.183-07:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2006-07-06T09:42:19.183-07:00</app:edited><title type="text">Db4oUtil (aka. The Easiest Way to Get Started With Db4o)</title><content type="html">Want the quickest and easiest way to get started with &lt;a href="http://www.db4o.com"&gt;db4o&lt;/a&gt;?  Use the following Db4oUtil class.  This class is very similar to the HibernateUtil class that you may be familiar with if you're a Hibernate user. It uses a thread local object so &lt;span style="font-weight: bold;"&gt;it's thread safe, makes multi-tier usage a no brainer and it's just plain simple to use.&lt;br&gt;&lt;br&gt;&lt;span style="font-weight: bold;"&gt;The simple step-by-step for this tutorial:&lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;ol&gt;&lt;li&gt;Copy the Db4oUtil.java code below into a new class&lt;/li&gt;&lt;li&gt;Use the Db4oUtil methods in your code, samples below&lt;br&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br&gt;That is it... seriously.  You can optionally tweak the fields in Db4oUtil to your liking, like you'll want to change the YAPFILENAME field for each application you will use this with.&lt;br&gt;&lt;h2&gt;Db4oUtil.java&lt;br&gt; &lt;/h2&gt; &lt;pre class="code"&gt;public class Db4oUtil {&lt;br&gt;    // EDIT THESE SETTINGS&lt;br&gt;    private static final String YAPFILENAME = "test.db4o.yap";&lt;br&gt;    private static final int PORT = 0;&lt;br&gt;    /*&lt;br&gt;     If you want the server to be networked, change the port number above and uncomment the USER, PASSWORD lines below/&lt;br&gt;     Then in getObjectServer, uncomment the objectServer.grantAccess line&lt;br&gt;     */&lt;br&gt;    //private static final String USER = "username";&lt;br&gt;    //private static final String PASSWORD = "password";&lt;br&gt;    &lt;br&gt;    private static ObjectServer objectServer;&lt;br&gt;&lt;br&gt;    private static final ThreadLocal dbThreadLocal = new ThreadLocal();&lt;br&gt;&lt;br&gt;    public static ObjectContainer getObjectContainer() {&lt;br&gt;        ObjectContainer oc = (ObjectContainer) dbThreadLocal.get();&lt;br&gt;        if (oc == null || oc.ext().isClosed()) {&lt;br&gt;            oc = getObjectServer().openClient();&lt;br&gt;            dbThreadLocal.set(oc);&lt;br&gt;        }&lt;br&gt;        return oc;&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    public static void closeObjectContainer() {&lt;br&gt;        ObjectContainer oc = (ObjectContainer) dbThreadLocal.get();&lt;br&gt;        dbThreadLocal.set(null);&lt;br&gt;        if (oc != null) oc.close();&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    public synchronized static ObjectServer getObjectServer() {&lt;br&gt;        if (objectServer == null) {&lt;br&gt;            objectServer = getObjectServerForFilename(YAPFILENAME, PORT);&lt;br&gt;            // and give access&lt;br&gt;            //objectServer.grantAccess(USER, PASSWORD);&lt;br&gt;        }&lt;br&gt;        return objectServer;&lt;br&gt;    }&lt;br&gt;&lt;br&gt;&lt;br&gt;    public static void shutdown() {&lt;br&gt;        if (objectServer != null) {&lt;br&gt;            objectServer.close();&lt;br&gt;        }&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    public static ObjectServer getObjectServerForFilename(String yapfilename, int port) {&lt;br&gt;        File parentDir = getDbDirectory();&lt;br&gt;        File dbfile = new File(parentDir, yapfilename);&lt;br&gt;&lt;br&gt;        // for replication //////////////////////////&lt;br&gt;        Db4o.configure().generateUUIDs(Integer.MAX_VALUE);&lt;br&gt;        Db4o.configure().generateVersionNumbers(Integer.MAX_VALUE);&lt;br&gt;&lt;br&gt;        // other options&lt;br&gt;        Db4o.configure().exceptionsOnNotStorable(true);&lt;br&gt;        Db4o.configure().objectClass("java.math.BigDecimal").translate(new com.db4o.config.TSerializable());&lt;br&gt;&lt;br&gt;        // now open server&lt;br&gt;        ObjectServer objectServer = Db4o.openServer(dbfile.getPath(), port);&lt;br&gt;&lt;br&gt;        return objectServer;&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    private static File getDbDirectory() {&lt;br&gt;        // will store data files in {user.home}/db4o/data directory&lt;br&gt;        String dbfile = System.getProperty("user.home") + "/db4o/data";&lt;br&gt;        File f = new File(dbfile);&lt;br&gt;        if (!f.exists()) {&lt;br&gt;            f.mkdirs();&lt;br&gt;        }&lt;br&gt;        return f;&lt;br&gt;    }&lt;br&gt;}&lt;br&gt;&lt;/pre&gt; You can edit the fields at the top to modify your database filename, etc.&lt;br&gt; &lt;h2&gt;   Using Db4oUtil &lt;/h2&gt; This is a simple code sample of usage:&lt;br&gt; &lt;pre class="code"&gt;// Get ObjectContainer - you can repetitively call this function in different methods without the need to pass the ObjectContainer around&lt;br&gt;ObjectContainer oc = Db4oUtil.getObjectContainer();&lt;br&gt;&lt;br&gt;// YOUR CODE HERE - use the ObjectContainer and do all your stuff here&lt;br&gt;&lt;br&gt;// Close ObjectContainer when done &lt;br&gt;Db4oUtil.closeDb();&lt;br&gt;&lt;br&gt;// Close object server when completely exiting application&lt;br&gt;Db4oUtil.shutdown();&lt;br&gt;&lt;/pre&gt; That's all there is to it!&lt;br&gt;&lt;br&gt;&lt;img src="http://feeds.feedburner.com/~r/SpaceProgramBlog/~4/238435467" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.spaceprogram.com/feeds/115205253593739346/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7774229&amp;postID=115205253593739346" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/115205253593739346?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/115205253593739346?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/SpaceProgramBlog/~3/238435467/db4outil-aka-easiest-way-to-get.html" title="Db4oUtil (aka. The Easiest Way to Get Started With Db4o)" /><author><name>Travis Reeder</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total><feedburner:origLink>http://blog.spaceprogram.com/2006/07/db4outil-aka-easiest-way-to-get.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7774229.post-114798576846630432</id><published>2006-05-18T13:53:00.000-07:00</published><updated>2006-05-20T19:57:11.246-07:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2006-05-20T19:57:11.246-07:00</app:edited><title type="text">Say Goodbye to your Relational Database</title><content type="html">&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;h3 xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;a href="http://www.db4o.com" title="   db40"&gt;   db40&lt;/a&gt; Has Entered the Building&lt;br style="font-family: Verdana;"/&gt; &lt;/h3&gt; &lt;span style="font-family: Verdana;"&gt; I have been using db4o a LOT lately, and &lt;/span&gt;&lt;a href="http://www.imdb.com/title/tt0120737/quotes" style="font-family: Verdana;" title="I don't expect I shall return"&gt;I don't expect I shall return&lt;/a&gt;&lt;span style="font-family: Verdana;"&gt;.  I can say without question that it has increased my productivity by at least...  &lt;/span&gt;&lt;a href="http://www.austinpowers.com/drevil/" style="font-family: Verdana;" title="1 million times"&gt;1 million times&lt;/a&gt;&lt;span style="font-family: Verdana;"&gt;.  Well probably not that much, but a heck of a lot.  It definitely takes a bit of getting use to if you come from a relational database world, but consider &lt;/span&gt;&lt;span style="font-weight: bold; font-family: Verdana;"&gt;never having to map your objects to a relational database&lt;/span&gt;&lt;span style="font-family: Verdana;"&gt;.  And how about &lt;/span&gt;&lt;span style="font-weight: bold; font-family: Verdana;"&gt;never having to make the database at all!&lt;/span&gt;&lt;span style="font-family: Verdana;"&gt;  You just worry about your object model and db4o will take care of the &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Persistence" style="font-family: Verdana;" title="persistence"&gt;persistence&lt;/a&gt;&lt;span style="font-family: Verdana;"&gt; (long term storage).&lt;/span&gt;&lt;br style="font-family: Verdana;"/&gt; &lt;br style="font-family: Verdana;"/&gt; &lt;span style="font-family: Verdana;"&gt; Check out these examples to see just how easy it is.&lt;/span&gt;&lt;br style="font-family: Verdana;"/&gt; &lt;h3 style="font-family: Verdana;"&gt;   Starting the Database Server&lt;br/&gt; &lt;/h3&gt; &lt;blockquote style="font-family: Verdana;"&gt;&lt;code style="font-family: Courier New;"&gt;// openServer() takes the filename where you want your database stored and a port&lt;/code&gt;&lt;br style="font-family: Courier New;"/&gt;&lt;code&gt;&lt;span style="font-family: Courier New;"&gt;ObjectServer server = Db4o.openServer("somefilename.yap", 1234); &lt;/span&gt;&lt;br style="font-family: Courier New;"/&gt;&lt;span style="font-family: Courier New;"&gt;// Now you can give access to particular logins&lt;/span&gt;&lt;br style="font-family: Courier New;"/&gt;&lt;span style="font-family: Courier New;"&gt; server.grantAccess("username","password");&lt;/span&gt;&lt;br/&gt;&lt;/code&gt;&lt;/blockquote&gt;&lt;code style="font-family: Verdana;"&gt;There are other ways of doing this: you can run it in non-server mode, but I don't recommend that since you'll probably just end up changing it down the road if your application is multi-threaded (and what application isn't these days?); you can also use an embedded server by using port zero [&lt;/code&gt;&lt;code style="font-family: Verdana;"&gt;ObjectServer server = Db4o.openServer("somefilename.yap", 0);] and getting connections from the ObjectServer directly [&lt;/code&gt;&lt;code style="font-family: Verdana;"&gt;ObjectContainer db = server.openClient();] which isn't too bad because it'll be faster, but it can't be networked.&lt;/code&gt;&lt;br style="font-family: Verdana;"/&gt; &lt;code style="font-family: Verdana;"&gt;&lt;br/&gt;When your program is ready to shutdown, you'll want to call &lt;span style="font-weight: bold;"&gt;server.close() &lt;/span&gt;to shut it down.&lt;br/&gt;&lt;/code&gt; &lt;h3 style="font-family: Verdana;"&gt;   Getting a Connection &lt;/h3&gt; &lt;code style="font-family: Verdana;"/&gt;&lt;blockquote style="font-family: Verdana;"&gt;&lt;code&gt;&lt;span style="font-family: Courier New;"&gt;ObjectContainer db = Db4o.openClient("localhost",PORT,USER,PASSWORD);&lt;/span&gt;&lt;br style="font-family: Courier New;"/&gt;&lt;span style="font-family: Courier New;"&gt;try{&lt;/span&gt;&lt;br style="font-family: Courier New;"/&gt;&lt;span style="font-family: Courier New;"&gt;     // with the client, we can do all the fun stuff in the examples below &lt;/span&gt;&lt;br style="font-family: Courier New;"/&gt;&lt;span style="font-family: Courier New;"&gt;    // ALL EXAMPLES ARE ASSUMED TO BE PLUGGED IN HERE&lt;/span&gt;&lt;br style="font-family: Courier New;"/&gt;&lt;span style="font-family: Courier New;"&gt;} finally {&lt;/span&gt;&lt;br style="font-family: Courier New;"/&gt;&lt;span style="font-family: Courier New;"&gt;     db.close();&lt;/span&gt;&lt;br style="font-family: Courier New;"/&gt;&lt;span style="font-family: Courier New;"&gt;}&lt;/span&gt;&lt;br/&gt;&lt;/code&gt;&lt;/blockquote&gt;&lt;code style="font-family: Verdana;"/&gt;&lt;h3 style="font-family: Verdana;"&gt;Saving and Updating an Object&lt;br/&gt;&lt;/h3&gt;&lt;span style="font-family: Verdana;"&gt;Doesn't get much easier than this.&lt;/span&gt;&lt;br style="font-family: Verdana;"/&gt;&lt;blockquote style="font-family: Verdana;"&gt;&lt;span style="font-family: Courier New;"&gt;db.set(myObject);&lt;/span&gt;&lt;br/&gt;&lt;/blockquote&gt; &lt;h3 style="font-family: Verdana;"&gt;Query&lt;/h3&gt;&lt;span style="font-family: Verdana;"&gt;This is equivalent to your SQL Select.  For this example, lets say we saved a couple of objects that looked like this:&lt;/span&gt;&lt;br style="font-family: Verdana;"/&gt;&lt;blockquote style="font-family: Verdana;"&gt;&lt;span style="font-family: Courier New;"&gt;Contact contact = new Contact();&lt;/span&gt;&lt;br style="font-family: Courier New;"/&gt;&lt;span style="font-family: Courier New;"&gt;contact.setName("Travis");&lt;/span&gt;&lt;br style="font-family: Courier New;"/&gt;&lt;span style="font-family: Courier New;"&gt;db.set(contact);&lt;/span&gt;&lt;br style="font-family: Courier New;"/&gt;&lt;span style="font-family: Courier New;"&gt;contact = new Contact();&lt;/span&gt;&lt;br style="font-family: Courier New;"/&gt;&lt;span style="font-family: Courier New;"&gt;contact.setName("Jimbo");&lt;/span&gt;&lt;br style="font-family: Courier New;"/&gt;&lt;span style="font-family: Courier New;"&gt;db.set(contact);&lt;/span&gt;&lt;br/&gt;&lt;/blockquote&gt;&lt;span style="font-family: Verdana;"&gt;Now to query for the contact named Travis, you do this:&lt;/span&gt;&lt;br style="font-family: Verdana;"/&gt;&lt;blockquote style="font-family: Verdana;"&gt;&lt;span style="font-family: Courier New;"&gt;Query q = db.query();&lt;/span&gt;&lt;br style="font-family: Courier New;"/&gt;&lt;span style="font-family: Courier New;"&gt;q.constrain(Contact.class);&lt;/span&gt;&lt;br style="font-family: Courier New;"/&gt;&lt;span style="font-family: Courier New;"&gt;q.descend("name").constrain("Travis");&lt;/span&gt;&lt;br style="font-family: Courier New;"/&gt;&lt;code style="font-family: Courier New;"&gt;ObjectSet result = q.execute();&lt;br/&gt;while (result.hasNext()) {&lt;br/&gt;     Contact c = (Contact) result.next();&lt;br/&gt;     System.out.println("Contact: " + c.getName());&lt;br/&gt;}&lt;/code&gt;&lt;br/&gt;&lt;/blockquote&gt;&lt;p style="font-family: Verdana;"&gt;The example above is a &lt;a href="http://sodaquery.sourceforge.net/" title="SODA"&gt;SODA&lt;/a&gt;   query which as you can see, uses strings and can be built dynamically. db4o does have another method of querying called &lt;a href="http://www.ddj.com/184406432" title="Native Queries"&gt;Native Queries&lt;/a&gt;. db4objects recommends Native Queries and it's for good reason. Native queries don't reference fields by strings, they're compile time checked, are object oriented and, most importantly, they are refactorable. &lt;br/&gt;&lt;/p&gt;&lt;p style="font-family: Verdana;"&gt;&lt;br/&gt;&lt;/p&gt;&lt;blockquote style="font-family: Verdana;"&gt;&lt;p style="font-family: Courier New;"&gt;&lt;code&gt;List &amp;lt;Contact&amp;gt; contacts = db.query(new Predicate&amp;lt;Contact&amp;gt;() {&lt;br/&gt;     public boolean match(Contact contact) {&lt;br/&gt;         return contact.getName().equals("Travis");&lt;/code&gt;&lt;/p&gt;&lt;p style="font-family: Courier New;"&gt;&lt;code&gt;      }&lt;/code&gt;&lt;/p&gt;&lt;p style="font-family: Courier New;"&gt;&lt;code&gt;});&lt;/code&gt;&lt;/p&gt;&lt;p style="font-family: Courier New;"&gt;&lt;code/&gt;for (Contact contact: contacts) {&lt;/p&gt;&lt;span style="font-family: Courier New;"&gt;     &lt;/span&gt;&lt;code style="font-family: Courier New;"&gt;System.out.println("Contact: " + c.getName());&lt;/code&gt;&lt;p&gt;&lt;span style="font-family: Courier New;"&gt;}&lt;/span&gt;&lt;br/&gt;&lt;code/&gt; &lt;/p&gt;&lt;/blockquote&gt;&lt;h3 style="font-family: Verdana;"&gt;Deleting an Object&lt;/h3&gt;&lt;blockquote style="font-family: Verdana;"&gt;&lt;span style="font-family: Courier New;"&gt;db.delete(myObject);&lt;/span&gt;&lt;br/&gt;&lt;/blockquote&gt;&lt;h2 style="font-family: Verdana;"&gt;Gotchas&lt;/h2&gt;&lt;span style="font-family: Verdana;"&gt;Now not everything is greener on the other side, there are still many little gotchas that may bite you, for instance:&lt;/span&gt;&lt;br style="font-family: Verdana;"/&gt;&lt;ul style="font-family: Verdana;"&gt;&lt;li&gt;No ID support like Hibernate / EJB so you can't let db4o rebind objects based on an id field in your objects&lt;/li&gt;&lt;ul&gt;&lt;li&gt;This is extremely apparent in a web based application where you have to be sure to reload your objects in every request, so they can be in your new db4o session (assuming session per request pattern).  I have figured out ways to work around this though to make it automated and I'll try to share these with you in a later post.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Weak management GUI&lt;/li&gt;&lt;ul&gt;&lt;li&gt;If you're used to working with nice tools like the tools provided by major database vendors, the db4o Object Manager doesn't really compare. But hopefully with time and with more adopters, the Object Manager will get better and we'll see third party tools. &lt;br/&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;No joins&lt;/li&gt;&lt;ul&gt;&lt;li&gt;This isn't bad if your object model is not complex and you can have all your objects connected to each other in your object graph, but you have to be careful when your data set gets large and your object model is a complex graph with bidirectional relationships because you may end up loading your entire database! Or at least a good chunk of data that you may not always need. And this is a *huge* performance killer.&lt;br/&gt;&lt;/li&gt;&lt;li&gt;Now the obvious answer would be to break apart your object model which is easy to do in a relational database because you have id's and foreign keys. In db4o, if you break apart your model, there is no built in way to reference your disconnected objects. &lt;br/&gt;&lt;/li&gt;&lt;li&gt;It is possible to workaround this though, by using keys and ID's as fields in your objects and querying for the related objects when you need them.&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;br/&gt;&lt;h2 style="font-family: Verdana;"&gt;Conclusion&lt;/h2&gt;&lt;span style="font-family: Verdana;"/&gt;&lt;span style="font-family: Verdana;"&gt;In any case, &lt;/span&gt;&lt;a href="http://developer.db4o.com/user/Profile.aspx?UserID=2114" id="ctl00___ctl00___ctl00_ctl00_bcr_ctl00___Entry___AuthorLink"&gt;Carl Rosenberger&lt;/a&gt;&lt;span style="font-family: Verdana;"&gt; &lt;/span&gt;&lt;span style="font-family: Verdana;"&gt;and the &lt;/span&gt;&lt;a href="http://www.db4o.com/" title="db4objects"&gt;db4objects&lt;/a&gt;  &lt;span style="font-family: Verdana;"&gt; folks have done a great job with this open source object database and they are definitely the leaders in the space.  The simplicity, performance, and productivity gains outweight and disadvantages by a long shot. &lt;/span&gt;&lt;span style="font-family: Verdana;"&gt;I urge you to try it.  &lt;/span&gt;&lt;span style="font-family: Verdana;"&gt;&lt;br/&gt;&lt;br/&gt;Also, I plan on sharing more of my experiences with db4o in the near future, along with code such as how to easily use it in a web application, how to partition, and how to scale.&lt;/span&gt;&lt;br style="font-family: Verdana;"/&gt;&lt;br style="font-family: Verdana;"/&gt;&lt;br/&gt;&lt;br /&gt;Tags: &lt;a href="http://technorati.com/tag/rel8r" rel="tag"&gt;db4o&lt;/a&gt; | &lt;a href="http://technorati.com/tag/tagging" rel="tag"&gt;object databases&lt;/a&gt; | &lt;a href="http://technorati.com/tag/spam" rel="tag"&gt;tutorial&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SpaceProgramBlog/~4/238435468" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.spaceprogram.com/feeds/114798576846630432/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7774229&amp;postID=114798576846630432" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/114798576846630432?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/114798576846630432?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/SpaceProgramBlog/~3/238435468/say-goodbye-to-your-relational.html" title="Say Goodbye to your Relational Database" /><author><name>Travis Reeder</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.spaceprogram.com/2006/05/say-goodbye-to-your-relational.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7774229.post-114797659963226970</id><published>2006-05-18T09:31:00.000-07:00</published><updated>2006-05-18T11:36:06.573-07:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2006-05-18T11:36:06.573-07:00</app:edited><title type="text">Installing Java 5 JDK and Tomcat on Ubuntu (using VMWare)</title><content type="html">This document will walk you through installing &lt;a href="http://tomcat.apache.org/"&gt;Apache Tomcat&lt;/a&gt; on &lt;a href="http://www.ubuntu.com/"&gt;Ubuntu Linux&lt;/a&gt; using &lt;a href="http://www.vmware.com/"&gt;VMware&lt;/a&gt; for virtualization. Most of the steps apply even if you're not using VMware.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Download and install VMWare on your server&lt;/li&gt;&lt;li&gt;Download and install VMWare client on your workstation (if it is different than your server)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Option 1: Prepackaged Ubuntu VM (Please note, this will NOT work on a headless server)&lt;br /&gt;&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Download Ubuntu VM from &lt;a href="http://www.vmware.com"&gt;www.vmware.com&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Open Ubuntu VM (user/pass is ubuntu/ubuntu) in VMWare client&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Option 2: New fresh install of Ubuntu (you have to do this if you have a headless server)&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Download Ubuntu ISO from &lt;a href="http://www.ubuntu.com"&gt;www.ubuntu.com&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Create new virtual machine in vmware, choose Linux -&gt; Ubuntu&lt;/li&gt;&lt;li&gt;Mount the cd drive for the virtual machine to your downloaded iso in the virtual machine settings&lt;/li&gt;&lt;li&gt;Start virtual machine, this will ask if you want to install, so perform the full install (this is just a regular Ubuntu install)&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Now you should be in Ubuntu linux&lt;/li&gt;&lt;li&gt;modify /etc/apt/sources.list (ex: run: sudo nano -w /etc/apt/sources.list)&lt;br /&gt;- Change the first section lines deb http://archive.ubuntu.com/ubuntu breezy main restricted&lt;br /&gt;to deb http://archive.ubuntu.com/ubuntu breezy main restricted universe multiverse&lt;br /&gt;You can also add universe multiverse to deb-src and do the same to the breezy-update lines too.&lt;br /&gt;(breezy will be dapper in 6.X versions)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;run: sudo apt-get update&lt;/li&gt;&lt;li&gt;Install JDK&lt;/li&gt;&lt;ol&gt;&lt;li&gt;Option 1:&lt;/li&gt;&lt;ol&gt;&lt;li&gt;run: sudo apt-get install sun-java5-jdk&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Option 2: (if option 1 doesn't work)&lt;/li&gt;&lt;ol&gt;&lt;li&gt;download jdk 1.5 from sun, the Self extracting linux version, .bin extension (NOT rpm)&lt;/li&gt;&lt;li&gt;run: sudo apt-get java-package&lt;/li&gt;&lt;li&gt;run: fakeroot jdk***.bin&lt;/li&gt;&lt;li&gt;run: sudo update-alternatives --config java&lt;br /&gt;- select the j2sdk1.5-sun option&lt;/li&gt;&lt;li&gt;run: java -version&lt;br /&gt;- just to make sure it's the new version&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt;&lt;li&gt;add:&lt;br /&gt;export JAVA_HOME=/usr/lib/jvm/java-1.5.0-sun-1.5.0.06&lt;br /&gt;if you used Option 1 for installing JDK above or:&lt;br /&gt;export JAVA_HOME=/usr/lib/j2sdk1.5-sun&lt;br /&gt;if option 2 was used&lt;br /&gt;to /home/ubuntu/.bashrc&lt;/li&gt;&lt;li&gt;Open a new console window to continue with the rest of the steps&lt;/li&gt;&lt;li&gt;Download tomcat 5.5 from &lt;a href="http://tomcat.apache.org/"&gt;tomcat.apache.org&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;extract tomcat (to a directory under your HOME directory is a good idea - /home/ubuntu/java/apache-tomcatXXX)&lt;/li&gt;&lt;li&gt;go to tomcat directory/bin&lt;/li&gt;&lt;li&gt;run: ./startup.sh&lt;/li&gt;&lt;li&gt;surf to http://yournewserversip:8080/&lt;/li&gt;&lt;ol&gt;&lt;li&gt;You should see the Tomcat welcome page&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt;If you want to run Tomcat as a service: http://tomcat.apache.org/tomcat-5.5-doc/setup.html&lt;br /&gt;&lt;br /&gt;Other tips:&lt;br /&gt;- If you want to use 7-zip which is nice for all compression/decompression tasks, run: "sudo apt-get install p7zip", then to extract anything, you just run "7za x myfile" (.zip or .tar or .tar.gz or .7z, etc)&lt;br /&gt;- If you want an ssh server (sshd) on your new ubuntu box, run: "sudo apt-get install openssh-server". Apparently Ubuntu does not come with an ssh server installed out of the box.&lt;br /&gt;- if you use nano, while you're editing .bashrc above, it's a good idea to add an alias for nano with the -w option like: alias nano='nano -w'&lt;br /&gt;- VMware kicks a**, so be sure to try it (note: I have no affiliation with VMware, I just like good products)&lt;br /&gt;&lt;br /&gt;If you have any issues with the steps above or want to add anything, please post your comment below.&lt;br /&gt;&lt;br /&gt;Good night and good luck...&lt;img src="http://feeds.feedburner.com/~r/SpaceProgramBlog/~4/238435469" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.spaceprogram.com/feeds/114797659963226970/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7774229&amp;postID=114797659963226970" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/114797659963226970?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/114797659963226970?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/SpaceProgramBlog/~3/238435469/installing-java-5-jdk-and-tomcat-on.html" title="Installing Java 5 JDK and Tomcat on Ubuntu (using VMWare)" /><author><name>Travis Reeder</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://blog.spaceprogram.com/2006/05/installing-java-5-jdk-and-tomcat-on.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-7774229.post-114685769049092858</id><published>2006-05-05T12:32:00.000-07:00</published><updated>2006-05-17T11:32:44.186-07:00</updated><app:edited xmlns:app="http://purl.org/atom/app#">2006-05-17T11:32:44.186-07:00</app:edited><title type="text">Normalize Schnormalize (aka Real-Time Data Warehousing)</title><content type="html">&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;Some applications need real-time reporting, &lt;a href="http://www.ecommstats.com/" title="ecommStats Web Analytics" xmlns="http://www.w3.org/1999/xhtml"&gt;ecommStats Web Analytics&lt;/a&gt; is one such app.  ecommStats customers want to see what is happening on their website and they want to see it now.&lt;br /&gt;&lt;br /&gt;A little background might be in order: In general, with enterprise software, you move and transform data from your &lt;a href="http://en.wikipedia.org/wiki/Database_transaction" title="Transactional Database"&gt;Transactional Database&lt;/a&gt; (the one that is involved in the day to day work and storing every little piece of data) to your &lt;a href="http://en.wikipedia.org/wiki/Data_warehouse" title="Data Warehouse"&gt;Data Warehouse&lt;/a&gt; so that you can generate reports faster and easier, which basically boils down to &lt;a href="http://en.wikipedia.org/wiki/Business_Intelligence" title="Business Intelligence"&gt;Business Intelligence&lt;/a&gt;.  And this is generally a heavy process so it will run once per day, once per week, or whatever fits into the business needs and the gap must be longer than it takes to actually run the process (if the process takes 24 hours to run, it's probably not a good idea to run it every day).&lt;br /&gt;&lt;br /&gt;But why wait until the night time (&lt;a href="http://www.lyricsfreak.com/a/adam+sandler/joining+the+cult_20003930.html" title="the night time is the right time"&gt;the night time is the right time&lt;/a&gt;) or the weekend to move all that data into a separate database when you can do simple preemptive operations on your database to give your users real-time data?&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Database_normalization" title=" Normalization"&gt; Normalization&lt;/a&gt; is great and all, but a &lt;span style="font-weight: bold;font-size:100%;" &gt;hybrid approach can work wonders&lt;/span&gt;.  The data is still normalized, but we have extra tables and extra columns that act as our data warehouse.&lt;br /&gt;&lt;br /&gt;Lets take the Search Phrase report for instance, it is a time based report which shows you how many people have searched on a particular search phrase or keyword.  In a normalized system, you would have your search phrase in one table and the request that came in in another table (this is seriously simplified to make a point):&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;table style="color: rgb(51, 51, 255);" border="1" cellpadding="3" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="50%"&gt;&lt;span style="font-weight: bold;"&gt;SearchPhrase&lt;/span&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="50%"&gt;id&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="50%"&gt;phrase&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;table style="color: rgb(51, 51, 255);" border="1" cellpadding="3" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="100%"&gt;&lt;span style="font-weight: bold;"&gt;SearchRequest&lt;/span&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="100%"&gt;id&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="100%"&gt;phraseId&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="100%"&gt;date&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="" height="" width="100%"&gt;user&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Now you could sum up all the requests that used the phrase everytime someone wants the Search Phrase report, but do you want to make your users wait for this report?  There could be thousands of words and thousands of requests for each word which quickly puts you into the millions of rows!   The user might as well go have a coffee while they're waiting.  And do you want your poor server to have to work so hard for this little report?&lt;br /&gt;&lt;br /&gt;But by adding a single column, we can make the report almost instantaneous:&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;table style="color: rgb(51, 51, 255);" border="1" cellpadding="3" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="50%"&gt;&lt;span style="font-weight: bold;"&gt;SearchPhrase&lt;/span&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="50%"&gt;id&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td width="50%"&gt;phrase&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="" height="" width="50%"&gt;&lt;span style="font-weight: bold; color: rgb(204, 0, 0);"&gt;requestCount&lt;/span&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="vertical-align: top;"&gt;&lt;span style="font-weight: bold; color: rgb(204, 0, 0);"&gt;lastRequestDate&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Now when we're showing that report, we don't even have to look at the SearchRequest table, so what used have to go through potentially millions of rows, now is just a few thousands rows (or however many search phrases you are looking at).  Obviously this example won't give you the time based reporting, but using an extra time bucket table, with similar techniques can get the results you want.&lt;br /&gt;&lt;br /&gt;And lets say you also wanted to show when the last time some searched for a particular phrase. You could look in the SearchRequest table, sort by date descending and then grab the first one, but this is time, disk and processor intense if the request table is large. So try simply adding a date column to the SearchPhrase table like above and update it when the request is made. &lt;span style="font-weight: bold;"&gt;Don't be afraid to duplicate data when the performance benefits can be substantial&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Now how much harder is this to implement in your code?  It's actually very simple in most cases, usually just requiring an extra update.  In the example above, when saveSearchRequest(SearchPhrase phrase) is called in the code, it will save the SearchRequest, &lt;span style="font-style: italic;"&gt;and&lt;/span&gt; do a simple update on the requestCount column:&lt;br /&gt;&lt;blockquote&gt;UPDATE SearchPhrase SET requestCount = requestCount + 1, lastRequestDate = sysdate where id = PHRASE_ID;&lt;br /&gt;&lt;/blockquote&gt; &lt;br /&gt;&lt;br /&gt;This one time update is insignificant when compared to the many times that queries will be run against your tables.&lt;br /&gt;&lt;br /&gt;In conclusion, using these hybrid techniques for database design can reduce wait time significantly and you can report in near real-time, rather than making your users wait days for their data. The new columns and/or tables may take up more space, but space is cheap and peformance is not.  It truly is a small price to pay when compared to the huge price of doing this repeatedly in a purely normalized database or a non-real-time huge bulk process to move the data into a data warehouse.&lt;br /&gt;&lt;br /&gt;Tags: &lt;a href="http://technorati.com/tag/rel8r" rel="tag"&gt;normalizing&lt;/a&gt; | &lt;a href="http://technorati.com/tag/tagging" rel="tag"&gt;data warehouse&lt;/a&gt; | &lt;a href="http://technorati.com/tag/spam" rel="tag"&gt;analytics&lt;/a&gt; | &lt;a href="http://technorati.com/tag/ranking" rel="tag"&gt;real-time&lt;/a&gt; | &lt;a href="http://technorati.com/tag/blog" rel="tag"&gt;databases&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/SpaceProgramBlog/~4/238435470" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.spaceprogram.com/feeds/114685769049092858/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=7774229&amp;postID=114685769049092858" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/114685769049092858?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7774229/posts/default/114685769049092858?v=2" /><link rel="alternate" type="text/html" href="http://feeds.feedburner.com/~r/SpaceProgramBlog/~3/238435470/normalize-schnormalize-aka-real-time.html" title="Normalize Schnormalize (aka Real-Time Data Warehousing)" /><author><name>Travis Reeder</name><email>noreply@blogger.com</email></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.spaceprogram.com/2006/05/normalize-schnormalize-aka-real-time.html</feedburner:origLink></entry></feed>
