<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule"
>

<channel>
	<title>Craig Andrews</title>
	<atom:link href="http://candrews.integralblue.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://candrews.integralblue.com</link>
	<description>Please excuse the ugliness of this site. Just remember, as McCoy said to Kirk so many times, &#34;D*&#38;@!$ Jim! I&#039;m an engineer, not a web designer!&#34;</description>
	<lastBuildDate>Wed, 28 Oct 2009 16:25:33 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<creativeCommons:license>http://creativecommons.org/licenses/by-sa/3.0/us/</creativeCommons:license>
<cloud domain='candrews.integralblue.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com" />
	<atom:link rel="hub" href="http://superfeedr.com/hubbub" />
			<item>
		<title>Running Ubuntu in VMWare</title>
		<link>http://candrews.integralblue.com/2009/10/running-ubuntu-in-vmware/</link>
		<comments>http://candrews.integralblue.com/2009/10/running-ubuntu-in-vmware/#comments</comments>
		<pubDate>Wed, 28 Oct 2009 15:06:45 +0000</pubDate>
		<dc:creator>Craig Andrews</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://candrews.integralblue.com/?p=106</guid>
		<description><![CDATA[VMWare is a leading (if not the leading) virtualization solution. Unfortunately, it is also proprietary software, which means that distributions tend not to care too much about it (and in my opinion, rightfully so!).
My employer is one such company that uses VMWare, and it recently instituted a policy that all VMs must have VMWare Tools [...]]]></description>
			<content:encoded><![CDATA[<div class='microid-mailto+http:sha1:0237128cf7f96b6cd4d3fe1c70947957bf258280'><p><a href="http://www.vmware.com/">VMWare</a> is a leading (if not the leading) virtualization solution. Unfortunately, it is also proprietary software, which means that distributions tend not to care too much about it (and in my opinion, rightfully so!).</p>
<p><a href="http://www.molecular.com">My employer</a> is one such company that uses VMWare, and it recently instituted a policy that all VMs must have <a href="http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&amp;cmd=displayKC&amp;externalId=340">VMWare Tools</a> installed on them, which causes a number of problems for Linux sysadmins, such as myself.</p>
<ol>
<li>VMWare Tools is not Free software</li>
<li>VMWare Tools is a pain to acquire: it&#8217;s not packaged in any distribution (due to the non-Free nature), finding it on VMWare&#8217;s site is a serious pain, and the version that VMWare server includes seems to be perpetually out of date.</li>
<li><a href="http://kb.vmware.com/kb/1014294">Installing VMWare Tools</a> is not a fun experience. The installer requires you to figure out how to get the kernel sources, then compiles and installs some kernel modules, and throws a bunch of proprietary binaries all over your file system. Also, depending on what kernel you&#8217;re using, the modules may not compile at all, in which case you have to hunt down patches.</li>
<li>Installing VMWare Tools on a bunch of servers is an even bigger annoyance, because there&#8217;s no real automated way to do it.</li>
</ol>
<p>The solution to all of these problems is the <a href="http://open-vm-tools.sourceforge.net/">open-vm-tools</a> project. It&#8217;s packaged in <a href="http://packages.debian.org/search?keywords=open-vm-tools">Debian</a> and <a href="http://packages.ubuntu.com/search?keywords=open-vm-tools">Ubuntu</a>, and by all means, should Just Work.</p>
<p>Here&#8217;s when things get really interesting. Open-vm-tools really does Just Work &#8211; if the packaging is done correctly. As it stands right now, the packaging just copies the kernel module sources, and you are expected to figure out how to compile and install them, and do so each time you change kernels. Thanks to <a href="http://en.wikipedia.org/wiki/Dynamic_Kernel_Module_Support">DKMS</a>, this could be done automatically.</p>
<p>In <a href="https://bugs.launchpad.net/ubuntu/+source/open-vm-tools/+bug/277556">Ubuntu bug #277556</a>, that&#8217;s exactly how it&#8217;s done. I&#8217;ve been using the <a href="https://launchpad.net/~grexk/+archive/ubuntu-dev">PPA referenced in that bug</a> on 5 servers for about 4 months now, and it works great. Installation? As simple as apt-get install open-vm-tools! Upgrade your kernel? Open-vm-tools recompiles automatically.</p>
<p>So for you all you Debian/Ubuntu users who run VMs on VMWare, take a look at this bug, and you should save yourself some serious time and effort.</p>
</div>]]></content:encoded>
			<wfw:commentRss>http://candrews.integralblue.com/2009/10/running-ubuntu-in-vmware/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-sa/3.0/us/</creativeCommons:license>
	</item>
		<item>
		<title>oEmbed</title>
		<link>http://candrews.integralblue.com/2009/08/oembed/</link>
		<comments>http://candrews.integralblue.com/2009/08/oembed/#comments</comments>
		<pubDate>Fri, 07 Aug 2009 18:15:45 +0000</pubDate>
		<dc:creator>Craig Andrews</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://candrews.integralblue.com/?p=100</guid>
		<description><![CDATA[oEmbed is a relatively simple concept, which can be basically thought of as hyperlinking to the next level. According to oembed.com: &#8220;oEmbed is a format for allowing an embedded representation of a URL on third party sites. The simple API allows a website to display embedded content (such as photos or videos) when a user [...]]]></description>
			<content:encoded><![CDATA[<div class='microid-mailto+http:sha1:309cf8925cf7ecf432dfe9ca75354174d4fcd107'><p>oEmbed is a relatively simple concept, which can be basically thought of as hyperlinking to the next level. According to <a href="http://www.oembed.com">oembed.com</a>: &#8220;oEmbed is a format for allowing an embedded representation of a URL on third party sites. The simple API allows a website to display embedded content (such as photos or videos) when a user posts a link to that resource, without having to parse the resource directly.&#8221;</p>
<p>Today, if I want to embed this <a href="http://www.youtube.com/watch?v=Pube5Aynsls">Youtube video</a> into a Wordpress blog (such as this one), I need to complete these steps:</p>
<ol>
<li>Start typing my new blog post</li>
<li>Switch browser windows, and go the Youtube video&#8217;s page</li>
<li>Copy the &#8220;embed&#8221; code, which is kind of crazy looking:

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;object width=&quot;425&quot; height=&quot;344&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://www.youtube.com/v/Pube5Aynsls&amp;hl=en&amp;fs=1&amp;&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot;&gt;&lt;/param&gt;&lt;embed src=&quot;http://www.youtube.com/v/Pube5Aynsls&amp;hl=en&amp;fs=1&amp;&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; width=&quot;425&quot; height=&quot;344&quot;&gt;&lt;/embed&gt;&lt;/object&gt;</pre></div></div>

</li>
<li>Switch back to the Wordpress window, and paste the embed code (as HTML) into my Wordpress post</li>
</ol>
<p>Clearly, that&#8217;s not ideal. Figuring out where the embed code is, and how to copy and paste it as HTML into Wordpress is not very easy, or intuitive. Now consider a future where Wordpress is an oEmbed consumer, and Youtube is an oEmbed provider. To do the same thing, these are the steps:</p>
<ol>
<li>Start typing my new blog post</li>
<li>Click the &#8220;embed&#8221; button in Wordpress</li>
<li>Enter the regular web browser link to the Youtube video in the box</li>
<li>Click &#8220;OK.&#8221; Wordpress will automagically figure out how to embed the video, and do it for you.</li>
</ol>
<p>No copy and paste, no tabbing between pages, and best of all, no code. The user doesn&#8217;t need to know what oEmbed is, or how it works.</p>
<p>oEmbed can be used in more creative ways, too. For example, if you link to a Youtube video on the microblogging site <a href="http://identi.ca">identi.ca</a>, the link will get a little paper clip next to it, and when clicked on, the video player will open in a lightbox. For example, take a look at <a href="http://identi.ca/notice/7736240">this notice</a>.</p>
<p>At this early stage of oEmbed&#8217;s lifetime, there are not many providers or consumers. To jumpstart the process, <a href="http://antrix.net/">Deepak Sarda </a>created <a href="http://www.oohembed.com/">oohembed</a>, a service that acts as a provider for many sites that don&#8217;t yet support oEmbed themselves (since Youtube isn&#8217;t an oEmbed provider, identi.ca uses oohembed, and that&#8217;s how the video embedding notice example works). oohembed supports a number of popular sites, such as Youtube, Vimeo, Hulu, Wikipedia, and Wordpress.com.</p>
<p>Hopefully, we&#8217;ll see more and more sites and pieces of software support oEmbed as both providers and consumers to improve their user experience. Wordpress 2.9 will likely be an oEmbed consumer (so the theoretical process I gave above may soon become a reality), and I&#8217;ve created a <a href="http://wordpress.org/extend/plugins/oembed-provider/">plugin that makes Wordpress an oEmbed provider</a>. Here&#8217;s to an easier (to embed, at least) future!</p>
</div>]]></content:encoded>
			<wfw:commentRss>http://candrews.integralblue.com/2009/08/oembed/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-sa/3.0/us/</creativeCommons:license>
	</item>
		<item>
		<title>Install JBoss 4.2 on Centos/RHEL 5</title>
		<link>http://candrews.integralblue.com/2009/07/install-jboss-4-2-on-centosrhel-5/</link>
		<comments>http://candrews.integralblue.com/2009/07/install-jboss-4-2-on-centosrhel-5/#comments</comments>
		<pubDate>Wed, 01 Jul 2009 21:01:21 +0000</pubDate>
		<dc:creator>Craig Andrews</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://candrews.integralblue.com/?p=88</guid>
		<description><![CDATA[I was recently tasked with installing JBoss 4.2 on Centos/RHEL 5. I found the experience remarkably difficult, so I figured I should share it for my own future reference, and hopefully to also save the sanity of whatever other poor souls are tasked with the same project.

Start off with RHEL 5 or Centos 5
Install jpackage50.repo [...]]]></description>
			<content:encoded><![CDATA[<div class='microid-mailto+http:sha1:520567311b493398703d38c0bf9c25f25b96338e'><p>I was recently tasked with installing JBoss 4.2 on Centos/RHEL 5. I found the experience remarkably difficult, so I figured I should share it for my own future reference, and hopefully to also save the sanity of whatever other poor souls are tasked with the same project.</p>
<ol>
<li>Start off with RHEL 5 or Centos 5</li>
<li>Install <a href="http://candrews.integralblue.com/wp-content/uploads/2009/07/jpackage50.repo">jpackage50.repo</a> into /etc/yum.repos.d/ (instructions for how to make this file can be found at <a href="http://jpackage.org/yum.php">jpackage.org</a>)</li>
<li>run &#8220;yum update&#8221;</li>
<li>run &#8220;yum install jbossas&#8221;</li>
<li>If you see this message: &#8221; &#8211;&gt; Missing Dependency: /usr/bin/rebuild-security-providers&#8221; then download <a href="http://candrews.integralblue.com/wp-content/uploads/2009/07/jpackage-utils-compat-el5-0.0.1-1.noarch.rpm">jpackage-utils-compat-el5-0.0.1-1.noarch</a> and install it by using  rpm -i jpackage-utils-compat-el5-0.0.1-1.noarch.rpm , then run &#8220;yum install jbossas&#8221; again. See <a href="https://bugzilla.redhat.com/show_bug.cgi?id=497213">this bug at Red Hat</a> for details, and <a href="http://www.zarb.org/pipermail/jpackage-discuss/2008-July/012751.html">http://www.zarb.org/pipermail/jpackage-discuss/2008-July/012751.html</a> for how the rpm was built.</li>
<li>run &#8220;/sbin/chkconfig jbossas on&#8221; to start JBoss automatically at startup</li>
<li>Until <a href="https://www.jpackage.org/bugzilla/show_bug.cgi?id=324">this bug</a> is resolved , run this command: &#8220;ln -s /usr/share/java/eclipse-ecj.jar /usr/share/java/ecj.jar&#8221;</li>
<li>If you want JBoss to listen to requests from systems other than localhost, edit /etc/jbossas/jbossas.conf. Create a new line that reads &#8220;JBOSS_IP=0.0.0.0&#8243;.</li>
<li>put your .ear&#8217;s, .war&#8217;s, ejb .jar&#8217;s, *-ds.xml&#8217;s into /var/lib/jbossas/server/default/deploy</li>
<li>Start JBoss by running &#8220;/etc/init.d/jbossas start&#8221;</li>
</ol>
<p>JVM args can be found in /etc/jbossas/run.conf.</p>
<p>Note that if your web application (war, ear, whatever) depends on JNDI, you need to edit /var/lib/jbossas/server/default/deploy/jboss-web.deployer/META-INF/jboss-service.xml and a line for each JNDI data source like this: &#8220;&lt;depends&gt;jboss.jca:service=DataSourceBinding,name=jdbc/whatever&lt;/depends&gt;&#8221;. This little detail cost me quite a few hours to figure out&#8230; an explanation as to why this is necessary can be found at <a href="http://confluence.atlassian.com/display/DOC/Known+Issues+for+JBoss">http://confluence.atlassian.com/display/DOC/Known+Issues+for+JBoss</a>. Basically, JBoss will start applications before JNDI data sources unless told otherwise, so your application will error out on startup with an exception like this: &#8220;Caused by: javax.naming.NamingException: Could not dereference object [Root exception is javax.naming.NameNotFoundException: jdbc not bound]&#8220;.</p>
<p>Some may argue that I should have simply downloaded the tar from jboss.org and manually installed JBoss without a package manager. However, the package manager offers a lot of advantages, such as dependency resolution/management, automatic updates for security and/or new features, clean and easy uninstall, and a lot more. When given the choice, I always choose to use a package manager, and will even create packages if ones are not available, and I report package bugs so others, and my future self,will have a better experience.</p>
<p>A lot of the pain in installing JBoss is due to bugs in the packaging. I hope that jpackage.org / Red Hat solves these problems soon &#8211; I wouldn&#8217;t really want anyone to have to live through the trouble I went through to figure all this out again.</p>
</div>]]></content:encoded>
			<wfw:commentRss>http://candrews.integralblue.com/2009/07/install-jboss-4-2-on-centosrhel-5/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-sa/3.0/us/</creativeCommons:license>
	</item>
		<item>
		<title>Compression (deflate) and HTML, CSS, JS Minification in ASP.NET</title>
		<link>http://candrews.integralblue.com/2009/05/compression-deflate-and-html-css-js-minification-in-asp-net/</link>
		<comments>http://candrews.integralblue.com/2009/05/compression-deflate-and-html-css-js-minification-in-asp-net/#comments</comments>
		<pubDate>Fri, 22 May 2009 22:02:01 +0000</pubDate>
		<dc:creator>Craig Andrews</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://candrews.integralblue.com/?p=76</guid>
		<description><![CDATA[As I&#8217;ve already demonstrated, I like performance. So I cache and compress a lot. When I was put onto an ASP.NET project at work, I obviously wanted to optimize the site, so here&#8217;s what I did.
Taking some hints from Y! Slow, I decided I wanted to:

Get rid of all the MS AJAX/toolkit javascript, as we [...]]]></description>
			<content:encoded><![CDATA[<div class='microid-mailto+http:sha1:ba4b67f02e8e42084769ae735ef86352cdf69d71'><p>As I&#8217;ve <a href="/2009/03/ehcache-implementation-of-openjpa-caching/">already</a> <a href="/2009/02/http-caching-header-aware-servlet-filter/">demonstrated</a>, I like performance. So I cache and compress a lot. When I was put onto an ASP.NET project at work, I obviously wanted to optimize the site, so here&#8217;s what I did.</p>
<p>Taking some hints from <a href="http://developer.yahoo.com/yslow/">Y! Slow</a>, I decided I wanted to:</p>
<ul>
<li>Get rid of all the MS AJAX/toolkit javascript, as we used jQuery instead</li>
<li>Combine all the javascript into one request</li>
<li>Combine all the CSS into one request</li>
<li>Minify the CSS</li>
<li>Minify the javascript</li>
<li>Minify the HTML</li>
<li>Deflate everything (gzip is slightly larger, and all modern browsers support deflate, so I just ignored gzip)</li>
</ul>
<p>I followed the <a href="http://weblogs.asp.net/bleroy/archive/2008/07/07/using-scriptmanager-with-other-frameworks.aspx">directions outlined at this site</a> to override the <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.scriptmanager.aspx">ScriptManager</a> and prevent it from including the Microsoft AJAX javascript. Removing uunsed code is always a good thing.</p>
<p>Combining the javascript was easy. Starting in ASP.NET 3.5 SP1, <a href="http://www.asp.net/learn/3.5-SP1/video-296.aspx">ASP.NET&#8217;s ScriptManager supports the CombineScript tag</a> inside of it. That was easy.</p>
<p>Combining the CSS was not so easy, as there&#8217;s no such thing in ASP.NET as a &#8220;ScriptManager.&#8221; I had two options: make a CSS manager (and use it everywhere), or figure out another way. Never taking the easy route when there&#8217;s a more interesting (and more front end developer transparent) way, I decided to make a filter (implementer of <a href="http://msdn.microsoft.com/en-us/library/system.web.ihttpmodule.aspx">IHttpModule</a>) to find all the &#8220;&lt;link&gt;&#8221; tags in the page header and replace them with one &#8220;&lt;link&gt;&#8221; to a combined CSS handler (which I called &#8220;CssResource.axd&#8221; to parallel ScriptManager&#8217;s &#8220;ScriptResource.axd&#8221;). Then, in my <a href="http://msdn.microsoft.com/en-us/library/system.web.ihttphandler.aspx">IHttpHandler</a> implementation which handles CssResource.axd, I read the querystring, grab the requested CSS files from the file system, combine them into one string, and return them. CSS combining done.</p>
<p>For minifying the CSS and Javascript, I used the <a href="http://www.codeplex.com/YUICompressor">C# version of YUI Compressor</a>. I used the original (Java) <a href="http://developer.yahoo.com/yui/compressor/">YUI Compressor</a> before, and had a great experience, so picking this version was a no-brainer. In my aforementioned filter, I intercept requests for &#8220;ScriptResource.axd&#8221; and &#8220;CssResource.axd,&#8221; apply YUI Compressor to the response content, cache the result (so I don&#8217;t need to minify every single request), then return.</p>
<p>I also minify inline (as in, mixed with HTML) CSS and Javascript. Also in my filter, if the return type is HTML, I scan for &#8220;&lt;script src&#8221; and &#8220;&lt;link rel=&#8217;stylesheet&#8217; src=&#8221; and minify their contents. This minification does have to happen for every request to that page, unless that whole page is cached.</p>
<p>Finally, the last thing the filter does is check if the browser accepts deflate compression. If it does, the filter compresses the stream. In the case of &#8220;ScriptResource.axd&#8221; and &#8220;CssResource.axd&#8221; requests, the deflating is done before the response is cached, so requests for those resources don&#8217;t need to be re-deflated for every request (their content is static, unlike regular html requests, so caching the whole response is okay).</p>
<p>The initial (cache empty) page load was 780k before I started. When I had finished, the page load was only 234k &#8211; a 70% decrease.</p>
<p>You can <a href="http://candrews.integralblue.com/wp-content/uploads/2009/05/Compression.zip">download the code from this site</a>. To use it, you need to modify your web.config.</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;system.web<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;httpModules<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;add</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;CompressionModule&quot;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;CompressionModule&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><span style="color: #808080; font-style: italic;">&lt;!--This must be the last entry in the httpHandlers list--&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/httpModules<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;httpHandlers<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;add</span> <span style="color: #000066;">verb</span>=<span style="color: #ff0000;">&quot;GET,HEAD&quot;</span> <span style="color: #000066;">path</span>=<span style="color: #ff0000;">&quot;CssResource.axd&quot;</span> <span style="color: #000066;">validate</span>=<span style="color: #ff0000;">&quot;false&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;CssResourceHandler&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/httpHandlers<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/system.web<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>I cannot claim 100% credit for all of this work. I got many ideas from just browsing web search results, trying things out, and combining ideas from various sources. If I have not credited you, and I should have &#8211; I apologize, and will be happy to do. But I can say, that I did not just &#8220;copy and paste&#8221; this from anywhere &#8211; I&#8217;m confident that this work cannot be classified as a derived work of anything else. With that in mind, I release it into the public domain.</p>
</div>]]></content:encoded>
			<wfw:commentRss>http://candrews.integralblue.com/2009/05/compression-deflate-and-html-css-js-minification-in-asp-net/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-sa/3.0/us/</creativeCommons:license>
	</item>
		<item>
		<title>Hibernate Deep Deproxy</title>
		<link>http://candrews.integralblue.com/2009/03/hibernate-deep-deproxy/</link>
		<comments>http://candrews.integralblue.com/2009/03/hibernate-deep-deproxy/#comments</comments>
		<pubDate>Mon, 16 Mar 2009 17:48:54 +0000</pubDate>
		<dc:creator>Craig Andrews</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://candrews.integralblue.com/?p=58</guid>
		<description><![CDATA[A common problem faced with using ORMs that use lazy loading is that the objects returned by the ORM contain (obviously) lazy loading references, so that you need an ORM session to access those objects. For example, if you have a &#8220;Person&#8221; class, that contains a &#8220;mother&#8221; property, when you do &#8220;person.getMother()&#8221;, the ORM will [...]]]></description>
			<content:encoded><![CDATA[<div class='microid-mailto+http:sha1:a593ed13f617fa55664cf44bb81065a9844dc24f'><p>A common problem faced with using ORMs that use lazy loading is that the objects returned by the ORM contain (obviously) lazy loading references, so that you need an ORM session to access those objects. For example, if you have a &#8220;Person&#8221; class, that contains a &#8220;mother&#8221; property, when you do &#8220;person.getMother()&#8221;, the ORM will get the mother from the database when it&#8217;s requested &#8211; not when the person is initialized.</p>
<p>Lazy loading is great, because it means you don&#8217;t load a huge amount of data when you really just want one object (say you just want the person&#8217;s name, with lazy loading, the person&#8217;s mother is never retrieved). However, when you want to do caching, lazy loading can be a serious problem.</p>
<p>For example, let&#8217;s say I have a method I call a lot &#8211; &#8220;personDao.findAll()&#8221;. I&#8217;d like to cache this entire method, so I don&#8217;t need to hit the database or the ORM at all, so I use something like an aspect to do declarative caching on that method. On the second and subsequent calls, the returned list of persons won&#8217;t have sessions attached (as they&#8217;re still attached to the first caller, which is long gone), so they can&#8217;t load their lazy references, and you end up with the famous <a href="http://www.hibernate.org/hib_docs/v3/api/org/hibernate/LazyInitializationException.html">LazyInitializationException</a>. If you know the list of people isn&#8217;t too big, and that it doesn&#8217;t refer to too many other objects, you can removed the lazy proxies and load everything at once &#8211; then cache that result. But be careful &#8211; by doing deep deproxying, all objects that are refered to will be loaded, so if you&#8217;re not careful, you can load the entire database, which results is either a loss of performance (due to using all the memory) or an immediate error.</p>
<p>Here&#8217;s how I do deep deproxying with Hibernate. I&#8217;ve read about many techniques to do this, but this approach works for better than anything I&#8217;ve been able to find so far.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">    <span style="color: #000000; font-weight: bold;">public</span> T deepDeproxy<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Object</span> maybeProxy<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">ClassCastException</span> <span style="color: #009900;">&#123;</span>
    	<span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>maybeProxy<span style="color: #339933;">==</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
		T ret <span style="color: #339933;">=</span> deepDeproxy<span style="color: #009900;">&#40;</span>maybeProxy,<span style="color: #000000; font-weight: bold;">new</span> HashSet<span style="color: #339933;">&lt;</span>Object<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    	<span style="color: #000000; font-weight: bold;">return</span> ret<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> T deepDeproxy<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Object</span> maybeProxy,<span style="color: #000000; font-weight: bold;">final</span> HashSet<span style="color: #339933;">&lt;</span>Object<span style="color: #339933;">&gt;</span> visited<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">ClassCastException</span> <span style="color: #009900;">&#123;</span>
    	<span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>maybeProxy<span style="color: #339933;">==</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">Class</span> clazz<span style="color: #339933;">;</span>
        Hibernate.<span style="color: #006633;">initialize</span><span style="color: #009900;">&#40;</span>maybeProxy<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>maybeProxy <span style="color: #000000; font-weight: bold;">instanceof</span> HibernateProxy<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                HibernateProxy proxy <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>HibernateProxy<span style="color: #009900;">&#41;</span> maybeProxy<span style="color: #339933;">;</span>
                LazyInitializer li <span style="color: #339933;">=</span> proxy.<span style="color: #006633;">getHibernateLazyInitializer</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                clazz <span style="color: #339933;">=</span> li.<span style="color: #006633;">getImplementation</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getClass</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
                clazz <span style="color: #339933;">=</span> maybeProxy.<span style="color: #006633;">getClass</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        T ret <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>T<span style="color: #009900;">&#41;</span> deepDeproxy<span style="color: #009900;">&#40;</span>maybeProxy,clazz<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>visited.<span style="color: #006633;">contains</span><span style="color: #009900;">&#40;</span>ret<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">return</span> ret<span style="color: #339933;">;</span>
        visited.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>ret<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">PropertyDescriptor</span> property <span style="color: #339933;">:</span> PropertyUtils.<span style="color: #006633;">getPropertyDescriptors</span><span style="color: #009900;">&#40;</span>ret<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        	<span style="color: #000000; font-weight: bold;">try</span><span style="color: #009900;">&#123;</span>
	        	<span style="color: #003399;">String</span> name <span style="color: #339933;">=</span> property.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        		<span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #0000ff;">&quot;owner&quot;</span>.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>name<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span>  property.<span style="color: #006633;">getWriteMethod</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">!=</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        			<span style="color: #003399;">Object</span> value <span style="color: #339933;">=</span> PropertyUtils.<span style="color: #006633;">getProperty</span><span style="color: #009900;">&#40;</span>ret, name<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    				<span style="color: #000066; font-weight: bold;">boolean</span> needToSetProperty<span style="color: #339933;">=</span><span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span>
        			<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>value <span style="color: #000000; font-weight: bold;">instanceof</span> HibernateProxy<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    					value <span style="color: #339933;">=</span> deepDeproxy<span style="color: #009900;">&#40;</span>value,visited<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    					needToSetProperty<span style="color: #339933;">=</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
        			<span style="color: #009900;">&#125;</span>
        			<span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>value <span style="color: #000000; font-weight: bold;">instanceof</span> <span style="color: #003399;">Object</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        				<span style="color: #003399;">Object</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> valueArray <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> value<span style="color: #339933;">;</span>
        				<span style="color: #003399;">Object</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> result <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #003399;">Array</span>.<span style="color: #006633;">newInstance</span><span style="color: #009900;">&#40;</span>value.<span style="color: #006633;">getClass</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, valueArray.<span style="color: #006633;">length</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        				<span style="color: #000000; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> i<span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>i<span style="color: #339933;">&lt;</span>valueArray.<span style="color: #006633;">length</span><span style="color: #339933;">;</span>i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        					result<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>deepDeproxy<span style="color: #009900;">&#40;</span>valueArray<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>,visited<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        				<span style="color: #009900;">&#125;</span>
        				value<span style="color: #339933;">=</span>result<span style="color: #339933;">;</span>
        				needToSetProperty<span style="color: #339933;">=</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
        			<span style="color: #009900;">&#125;</span>
        			<span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>value <span style="color: #000000; font-weight: bold;">instanceof</span> <span style="color: #003399;">Set</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        				<span style="color: #003399;">Set</span> valueSet <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Set</span><span style="color: #009900;">&#41;</span> value<span style="color: #339933;">;</span>
        				<span style="color: #003399;">Set</span> result <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">HashSet</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        				<span style="color: #000000; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> o <span style="color: #339933;">:</span> valueSet<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        					result.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>deepDeproxy<span style="color: #009900;">&#40;</span>o,visited<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        				<span style="color: #009900;">&#125;</span>
        				value<span style="color: #339933;">=</span>result<span style="color: #339933;">;</span>
    					needToSetProperty<span style="color: #339933;">=</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
        			<span style="color: #009900;">&#125;</span>
        			<span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>value <span style="color: #000000; font-weight: bold;">instanceof</span> <span style="color: #003399;">Map</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        				<span style="color: #003399;">Map</span> valueMap <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Map</span><span style="color: #009900;">&#41;</span> value<span style="color: #339933;">;</span>
        				<span style="color: #003399;">Map</span> result <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">HashMap</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        				<span style="color: #000000; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> o <span style="color: #339933;">:</span> valueMap.<span style="color: #006633;">keySet</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        					result.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span>deepDeproxy<span style="color: #009900;">&#40;</span>o, visited<span style="color: #009900;">&#41;</span>,deepDeproxy<span style="color: #009900;">&#40;</span>valueMap.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>o<span style="color: #009900;">&#41;</span>,visited<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        				<span style="color: #009900;">&#125;</span>
        				value<span style="color: #339933;">=</span>result<span style="color: #339933;">;</span>
    					needToSetProperty<span style="color: #339933;">=</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
        			<span style="color: #009900;">&#125;</span>
        			<span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>value <span style="color: #000000; font-weight: bold;">instanceof</span> <span style="color: #003399;">List</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        				<span style="color: #003399;">List</span> valueList <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">List</span><span style="color: #009900;">&#41;</span> value<span style="color: #339933;">;</span>
        				<span style="color: #003399;">List</span> result <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">ArrayList</span><span style="color: #009900;">&#40;</span>valueList.<span style="color: #006633;">size</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        				<span style="color: #000000; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> o <span style="color: #339933;">:</span> valueList<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        					result.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>deepDeproxy<span style="color: #009900;">&#40;</span>o,visited<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        				<span style="color: #009900;">&#125;</span>
        				value<span style="color: #339933;">=</span>result<span style="color: #339933;">;</span>
    					needToSetProperty<span style="color: #339933;">=</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
        			<span style="color: #009900;">&#125;</span>
					<span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>needToSetProperty<span style="color: #009900;">&#41;</span> PropertyUtils.<span style="color: #006633;">setProperty</span><span style="color: #009900;">&#40;</span>ret, name, value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        		<span style="color: #009900;">&#125;</span>
        	<span style="color: #009900;">&#125;</span><span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span>java.<span style="color: #006633;">lang</span>.<span style="color: #003399;">IllegalAccessException</span> e<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
				e.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        	<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">InvocationTargetException</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				e.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">NoSuchMethodException</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				e.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">return</span> ret<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #339933;">&lt;</span>T<span style="color: #339933;">&gt;</span> T deepDeproxy<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> maybeProxy, Class<span style="color: #339933;">&lt;</span>T<span style="color: #339933;">&gt;</span> baseClass<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">ClassCastException</span> <span style="color: #009900;">&#123;</span>
    	<span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>maybeProxy<span style="color: #339933;">==</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>maybeProxy <span style="color: #000000; font-weight: bold;">instanceof</span> HibernateProxy<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        	<span style="color: #000000; font-weight: bold;">return</span> baseClass.<span style="color: #006633;">cast</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>HibernateProxy<span style="color: #009900;">&#41;</span> maybeProxy<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getHibernateLazyInitializer</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getImplementation</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #000000; font-weight: bold;">else</span><span style="color: #009900;">&#123;</span>
           <span style="color: #000000; font-weight: bold;">return</span> baseClass.<span style="color: #006633;">cast</span><span style="color: #009900;">&#40;</span>maybeProxy<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
     <span style="color: #009900;">&#125;</span></pre></div></div>

</div>]]></content:encoded>
			<wfw:commentRss>http://candrews.integralblue.com/2009/03/hibernate-deep-deproxy/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-sa/3.0/us/</creativeCommons:license>
	</item>
		<item>
		<title>EhCache implementation of OpenJPA caching</title>
		<link>http://candrews.integralblue.com/2009/03/ehcache-implementation-of-openjpa-caching/</link>
		<comments>http://candrews.integralblue.com/2009/03/ehcache-implementation-of-openjpa-caching/#comments</comments>
		<pubDate>Thu, 12 Mar 2009 19:46:55 +0000</pubDate>
		<dc:creator>Craig Andrews</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://candrews.integralblue.com/?p=52</guid>
		<description><![CDATA[I usually use Hibernate, which supports a number of caching implementations (such as EhCache, oscache, JBoss, etc). My most recent project had a dependency on a product which has a dependency on OpenJPA, and OpenJPA only has it&#8217;s own built in implementations of a query cache and a data cache. I like to have one [...]]]></description>
			<content:encoded><![CDATA[<div class='microid-mailto+http:sha1:13297a0c2f8058a49def0cd2ebba5bd1ba244286'><p>I usually use <a href="http://www.hibernate.org/">Hibernate</a>, which supports a <a href="http://www.hibernate.org/hib_docs/reference/en/html/performance-cache.html">number of caching implementations</a> (such as EhCache, oscache, JBoss, etc). My most recent project had a dependency on <a href="http://www.elasticpath.com/">a product</a> which has a dependency on <a href="http://http://openjpa.apache.org/">OpenJPA</a>, and OpenJPA only has it&#8217;s own built in implementations of a <a href="http://openjpa.apache.org/builds/1.2.0/apache-openjpa-1.2.0/docs/manual/ref_guide_caching.html#ref_guide_cache_query">query cache</a> and a <a href="http://openjpa.apache.org/builds/1.2.0/apache-openjpa-1.2.0/docs/manual/ref_guide_caching.html#ref_guide_cache_conf">data cache</a>. I like to have one caching implementation in my project, so having two (OpenJPA&#8217;s for itself, and EhCache for everything else) annoyed me. So I had to fix it.</p>
<p>I started with <a href="http://mail-archives.apache.org/mod_mbox/openjpa-users/200803.mbox/%3C16378911.post@talk.nabble.com%3E">Pinaki Poddar&#8217;s implementation of a Coherence provided OpenJPA data cache</a>. I changed it to use EhCache, adjusted the unit tests, and then added a query cache implementation. To use it, add a dependency on the openjpa-ehcache, then set OpenJPA&#8217;s &#8220;openjpa.QueryCache&#8221; to &#8220;ehcache&#8221; and &#8220;openjpa.DataCacheManager&#8221; to ehcache. That&#8217;s it!</p>
<p>The code can be compiled with Maven. Simply run &#8220;mvn install&#8221;.</p>
<p>My code, like EhCache and OpenJPA, is licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0.html">Apache Public License 2.0</a>. <a href="http://candrews.integralblue.com/wp-content/uploads/2009/03/openjpa-ehcachetar.gz">Get it here</a>.</p>
</div>]]></content:encoded>
			<wfw:commentRss>http://candrews.integralblue.com/2009/03/ehcache-implementation-of-openjpa-caching/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-sa/3.0/us/</creativeCommons:license>
	</item>
		<item>
		<title>One HTTPS site per IP address&#8230; or may be not?</title>
		<link>http://candrews.integralblue.com/2009/02/one-https-site-per-ip-address-or-may-be-not/</link>
		<comments>http://candrews.integralblue.com/2009/02/one-https-site-per-ip-address-or-may-be-not/#comments</comments>
		<pubDate>Thu, 26 Feb 2009 05:07:25 +0000</pubDate>
		<dc:creator>Craig Andrews</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://candrews.integralblue.com/?p=47</guid>
		<description><![CDATA[I randomly ran across SNI (aka RFC 4366) tonight. It&#8217;s a technology that has been under development since before 2000 that allows the client to tell the server what domain it&#8217;s visiting before the server sends the certificate. The history is fascinating!
The situation today is that SNI is not here yet. OpenSSL will support it [...]]]></description>
			<content:encoded><![CDATA[<div class='microid-mailto+http:sha1:7f0c71eef52767699fcdba550989be22f45b4a8b'><p>I randomly ran across SNI (aka <a href="http://www.ietf.org/rfc/rfc4366.txt">RFC 4366</a>) tonight. It&#8217;s a technology that has been under development since before 2000 that allows the client to tell the server what domain it&#8217;s visiting before the server sends the certificate. <a href="http://en.wikipedia.org/wiki/Server_Name_Indication">The history is fascinating!</a></p>
<p>The situation today is that SNI is not here yet. OpenSSL will support it starting in 0.9.9, but has it as a compile time option (default disabled) as of 0.9.8f. Apache may support in it&#8217;s next minor release (2.2.12), or maybe not&#8230; at least it&#8217;s in their trunk, so it will be released someday. I just installed the <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=34607">SNI patch</a> on my Apache 2.2.11 server, and I&#8217;m going to try it out. IIS has no stated plan to support it or not. The other popular servers, like Cherokee, lighthttps, and nginx, support it today.</p>
<p>But, as usual, browser support is the limiting factor:</p>
<ul>
<li>Mozilla Firefox 2.0 or later</li>
<li>Opera 8.0 or later (the TLS 1.1 protocol must be enabled)</li>
<li><a href="http://blogs.msdn.com/ie/archive/2005/10/22/483795.aspx">Internet Explorer 7 (Vista, not XP) or later</a></li>
<li>Google Chrome</li>
<li>Safari 3.2.1 on Mac OS X 10.5.6</li>
</ul>
<p>As usual, Internet Explorer is the limiting factor. You need *Vista* to use SNI, so given that <a href="http://en.wikipedia.org/wiki/IE6">IE6</a> still has a <a href="http://www.w3schools.com/browsers/browsers_stats.asp">decent market share</a>, and it&#8217;s 8 years old&#8230; it&#8217;s going to be at least 2017 before we can reliably host multiple HTTPS sites on the same IP address &#8211; and who knows about embedded browsers (like those in cell phones and PDAs). Perhaps using one IPv6 address per HTTPS site will be more practical before SNI is widely available&#8230; who knows.</p>
</div>]]></content:encoded>
			<wfw:commentRss>http://candrews.integralblue.com/2009/02/one-https-site-per-ip-address-or-may-be-not/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-sa/3.0/us/</creativeCommons:license>
	</item>
		<item>
		<title>Why would a cache include cookies?</title>
		<link>http://candrews.integralblue.com/2009/02/why-would-a-cache-include-cookies/</link>
		<comments>http://candrews.integralblue.com/2009/02/why-would-a-cache-include-cookies/#comments</comments>
		<pubDate>Thu, 26 Feb 2009 03:20:23 +0000</pubDate>
		<dc:creator>Craig Andrews</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://candrews.integralblue.com/?p=43</guid>
		<description><![CDATA[Ehcache&#8217;s SimplePageCachingFilter caches cookies. And that baffles me&#8230; why would a cache include cookies in it?
I ran into the interesting situation where servlets, interceptors, and all those other Java goodies were writing cookies for purposes like the current browsing user&#8217;s identifier so it could track that user on the site and keep track of his [...]]]></description>
			<content:encoded><![CDATA[<div class='microid-mailto+http:sha1:53a7ea59b7708e6589007f2bf6942b48b42c3b5c'><p>Ehcache&#8217;s <a href="http://ehcache.sourceforge.net/EhcacheUserGuide.html#id.s19.3">SimplePageCachingFilter</a> caches cookies. And that baffles me&#8230; why would a cache include cookies in it?</p>
<p>I ran into the interesting situation where servlets, interceptors, and all those other Java goodies were writing cookies for purposes like the current browsing user&#8217;s identifier so it could track that user on the site and keep track of his shopping cart. The problem, which is obvious in retrospect but was incredibly puzzling at first, was that the cookies that included the user id were being cached, so when a subsequent user hit that page, he got the original requester&#8217;s user id, and got all that implied (like his cart).</p>
<p>Since each page is cached separately and at separate times, and there is more than one user on the site, visitors would see their carts changing, items seemingly appearing and disappearing randomly, and other such fun. For example, if Alice happened to hit the home page when its cache was expired, her user id cookie ended up in the home page cache. Then Bob comes along and hits the accessories page when its cache has expired, so his user id cookies ends up in that page&#8217;s cache. Finally, Charles visits the home page, and sees Alice&#8217;s cart. Then, he goes to the accessories page, and sees Bob&#8217;s cart. It&#8217;s just an incredibly weird and confusing situation!</p>
<p>I&#8217;ve been wracking my brain on the topic of caching cookies &#8211; when would it be useful? Cookies, as far as I can imagine (and have experienced), contain only user unique information &#8211; so why would you cache them?</p>
<p>To solve this problem, I extended SimplePageCachingFilter and overrode the setCookies method, having it be a no-op. <a href="https://sourceforge.net/tracker2/?func=detail&amp;aid=2630970&amp;group_id=93232&amp;atid=603559">And I filed a bug report with Ehcache</a>.</p>
<p>Apache&#8217;s <a href="http://httpd.apache.org/docs/2.2/mod/mod_cache.html">mod_cache</a> will include cookies in its cache too. But, in their documentation, <a href="http://httpd.apache.org/docs/2.2/mod/mod_cache.html#cacheignoreheaders">they specifically point out the case of cookies in their example of how to exclude items from the cache</a>. It seems Apache knows including cookies is a bad idea&#8230; perhaps they should default to excluded?</p>
</div>]]></content:encoded>
			<wfw:commentRss>http://candrews.integralblue.com/2009/02/why-would-a-cache-include-cookies/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-sa/3.0/us/</creativeCommons:license>
	</item>
		<item>
		<title>One instance at a time with PID file in Bash</title>
		<link>http://candrews.integralblue.com/2009/02/one-instance-at-a-time-with-pid-file-in-bash/</link>
		<comments>http://candrews.integralblue.com/2009/02/one-instance-at-a-time-with-pid-file-in-bash/#comments</comments>
		<pubDate>Mon, 16 Feb 2009 21:18:55 +0000</pubDate>
		<dc:creator>Craig Andrews</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://candrews.integralblue.com/?p=37</guid>
		<description><![CDATA[Often times, I only want a script to run one instance at a time. For example, if the the script is copying files, or rsync&#8217;ing between systems, it can be disastrous to have two instances running concurrently, and this situation is definitely possible if you run the script from cron.
I figured out a simple way [...]]]></description>
			<content:encoded><![CDATA[<div class='microid-mailto+http:sha1:1f948f7c315f3f8e7401b922104a6cf662b85ffc'><p>Often times, I only want a script to run one instance at a time. For example, if the the script is copying files, or rsync&#8217;ing between systems, it can be disastrous to have two instances running concurrently, and this situation is definitely possible if you run the script from cron.</p>
<p>I figured out a simple way to make sure only one instance runs at a time, and it has the added benefit that if the script dies midway through, another instance will start &#8211; a drawback of just using lock files without a pid.</p>
<p>Without further ado, here&#8217;s my script:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #007800;">pidfile</span>=<span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>run<span style="color: #000000; font-weight: bold;">/</span>sync.pid
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-e</span> <span style="color: #007800;">$pidfile</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #007800;">pid</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #007800;">$pidfile</span><span style="color: #000000; font-weight: bold;">`</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #c20cb9; font-weight: bold;">kill</span> <span style="color: #660033;">-0</span> <span style="color: #000000; font-weight: bold;">&amp;&gt;</span><span style="color: #000000;">1</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null <span style="color: #007800;">$pid</span>; <span style="color: #000000; font-weight: bold;">then</span>
        <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Already running&quot;</span>
        <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">1</span>
    <span style="color: #000000; font-weight: bold;">else</span>
        <span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #007800;">$pidfile</span>
    <span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$$</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #007800;">$pidfile</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#do your thing here</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #007800;">$pidfile</span></pre></div></div>

</div>]]></content:encoded>
			<wfw:commentRss>http://candrews.integralblue.com/2009/02/one-instance-at-a-time-with-pid-file-in-bash/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-sa/3.0/us/</creativeCommons:license>
	</item>
		<item>
		<title>HTTP Caching Header Aware Servlet Filter</title>
		<link>http://candrews.integralblue.com/2009/02/http-caching-header-aware-servlet-filter/</link>
		<comments>http://candrews.integralblue.com/2009/02/http-caching-header-aware-servlet-filter/#comments</comments>
		<pubDate>Sat, 14 Feb 2009 06:34:26 +0000</pubDate>
		<dc:creator>Craig Andrews</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://candrews.integralblue.com/?p=32</guid>
		<description><![CDATA[On the project I&#8217;m working on, we&#8217;re desperately trying to improve performance. One of the approaches taken by my coworkers was to add the SimplePageCachingFilter from Ehcache, so that Ehcache can serve frequently hit pages that aren&#8217;t completely dynamic. However, it occurred to me that the SimplePageCachingFilter can be improved by adding support for the [...]]]></description>
			<content:encoded><![CDATA[<div class='microid-mailto+http:sha1:ee9bf3f057ac65821d67b32f4ab66d6ea3851849'><p>On the project I&#8217;m working on, we&#8217;re desperately trying to improve performance. One of the approaches taken by my coworkers was to add the <a href="http://ehcache.sourceforge.net/EhcacheUserGuide.html#id.s19.3">SimplePageCachingFilter</a> from <a href="http://ehcache.sourceforge.net">Ehcache</a>, so that Ehcache can serve frequently hit pages that aren&#8217;t completely dynamic. However, it occurred to me that the SimplePageCachingFilter can be improved by adding support for the HTTP caching headers (namely, <a href="http://en.wikipedia.org/wiki/HTTP_ETag">ETags</a>, Expires, Last-Modified, and If-Modified-Since). Adding these headers will do two important things:</p>
<ol>
<li>Allow Apache&#8217;s mod_cache to cache Tomcat served pages, so that requests to these pages never even hit Tomcat, which should massively improve performance</li>
<li>Allow browsers to accurately cache, so visitors don&#8217;t need to re-request pages after the first visit</li>
</ol>
<p>Implementing these headers wasn&#8217;t terribly difficult &#8211; just tedious in that I had to read the relevant HTTP specification.</p>
<p>I sincerely hope that Ehcache picks up this class and adds it to the next version &#8211; I imagine that many applications could benefit from this class!</p>
<p>Here&#8217;s my class:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #008000; font-style: italic; font-weight: bold;">/**
 *  Copyright 2009 Craig Andrews
 *
 *  Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.io.IOException</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.text.ParseException</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.text.SimpleDateFormat</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.Collection</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.Date</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.Iterator</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.List</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.Locale</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.TimeZone</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.zip.DataFormatException</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.servlet.FilterChain</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.servlet.http.HttpServletRequest</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.servlet.http.HttpServletResponse</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.commons.lang.StringUtils</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">net.sf.ehcache.constructs.web.AlreadyGzippedException</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">net.sf.ehcache.constructs.web.PageInfo</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">net.sf.ehcache.constructs.web.ResponseHeadersNotModifiableException</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">net.sf.ehcache.constructs.web.filter.SimplePageCachingFilter</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/*
 * Filter than extends {@link SimplePageCachingFilter}, adding support for
 * the HTTP cache headers (ETag, Last-Modified, Expires, and If-None-Match.
 */</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> HttpCachingHeadersPageCachingFilter <span style="color: #000000; font-weight: bold;">extends</span>
		SimplePageCachingFilter <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">SimpleDateFormat</span> httpDateFormat <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">SimpleDateFormat</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;EEE, dd MMM yyyy HH:mm:ss z&quot;</span>, <span style="color: #003399;">Locale</span>.<span style="color: #006633;">US</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">static</span><span style="color: #009900;">&#123;</span>
		httpDateFormat.<span style="color: #006633;">setTimeZone</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">TimeZone</span>.<span style="color: #006633;">getTimeZone</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;GMT&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">synchronized</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399;">String</span> getHttpDate<span style="color: #009900;">&#40;</span><span style="color: #003399;">Date</span> date<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">return</span> httpDateFormat.<span style="color: #006633;">format</span><span style="color: #009900;">&#40;</span>date<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">synchronized</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399;">Date</span> getDateFromHttpDate<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> date<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">ParseException</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">return</span> httpDateFormat.<span style="color: #006633;">parse</span><span style="color: #009900;">&#40;</span>date<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	@SuppressWarnings<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;unchecked&quot;</span><span style="color: #009900;">&#41;</span>
	@Override
	<span style="color: #000000; font-weight: bold;">protected</span> PageInfo buildPage<span style="color: #009900;">&#40;</span>HttpServletRequest request, HttpServletResponse response, FilterChain chain<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> AlreadyGzippedException, <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
		PageInfo pageInfo <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">buildPage</span><span style="color: #009900;">&#40;</span>request, response, chain<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>pageInfo.<span style="color: #006633;">isOk</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
			<span style="color: #666666; font-style: italic;">//add expires and last-modified headers</span>
			<span style="color: #003399;">Date</span> now <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Date</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
			List<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>String<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> headers <span style="color: #339933;">=</span> pageInfo.<span style="color: #006633;">getHeaders</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #000066; font-weight: bold;">long</span> ttlSeconds <span style="color: #339933;">=</span> getTimeToLive<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
			headers.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">&quot;Last-Modified&quot;</span>, getHttpDate<span style="color: #009900;">&#40;</span>now<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			headers.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">&quot;Expires&quot;</span>, getHttpDate<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Date</span><span style="color: #009900;">&#40;</span>now.<span style="color: #006633;">getTime</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> ttlSeconds<span style="color: #339933;">*</span><span style="color: #cc66cc;">1000</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			headers.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">&quot;Cache-Control&quot;</span>,<span style="color: #0000ff;">&quot;max-age=&quot;</span> <span style="color: #339933;">+</span> ttlSeconds<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			headers.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">&quot;ETag&quot;</span>, <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\&quot;</span>&quot;</span> <span style="color: #339933;">+</span> <span style="color: #003399;">Integer</span>.<span style="color: #006633;">toHexString</span><span style="color: #009900;">&#40;</span>java.<span style="color: #006633;">util</span>.<span style="color: #003399;">Arrays</span>.<span style="color: #006633;">hashCode</span><span style="color: #009900;">&#40;</span>pageInfo.<span style="color: #006633;">getUngzippedBody</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\&quot;</span>&quot;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #000000; font-weight: bold;">return</span> pageInfo<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	@Override
	<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> writeResponse<span style="color: #009900;">&#40;</span>HttpServletRequest request, HttpServletResponse response, PageInfo pageInfo<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">IOException</span>, <span style="color: #003399;">DataFormatException</span>, ResponseHeadersNotModifiableException <span style="color: #009900;">&#123;</span>
&nbsp;
		<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Collection</span> headers <span style="color: #339933;">=</span> pageInfo.<span style="color: #006633;">getHeaders</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> header <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> value <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Iterator</span> iterator <span style="color: #339933;">=</span> headers.<span style="color: #006633;">iterator</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> iterator.<span style="color: #006633;">hasNext</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> headerPair <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> iterator.<span style="color: #006633;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>StringUtils.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>headerPair<span style="color: #009900;">&#91;</span>header<span style="color: #009900;">&#93;</span>,<span style="color: #0000ff;">&quot;ETag&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
            	<span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>StringUtils.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>headerPair<span style="color: #009900;">&#91;</span>value<span style="color: #009900;">&#93;</span>,request.<span style="color: #006633;">getHeader</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;If-None-Match&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
            		response.<span style="color: #006633;">sendError</span><span style="color: #009900;">&#40;</span>HttpServletResponse.<span style="color: #006633;">SC_NOT_MODIFIED</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            		<span style="color: #666666; font-style: italic;">// use the same date we sent when we created the ETag the first time through</span>
            		response.<span style="color: #006633;">setHeader</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Last-Modified&quot;</span>, request.<span style="color: #006633;">getHeader</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;If-Modified-Since&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            		<span style="color: #000000; font-weight: bold;">return</span><span style="color: #339933;">;</span>
            	<span style="color: #009900;">&#125;</span>
            	<span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
            <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>StringUtils.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>headerPair<span style="color: #009900;">&#91;</span>header<span style="color: #009900;">&#93;</span>,<span style="color: #0000ff;">&quot;Last-Modified&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
				<span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
					<span style="color: #003399;">String</span> requestIfModifiedSince <span style="color: #339933;">=</span> request.<span style="color: #006633;">getHeader</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;If-Modified-Since&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
					<span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>requestIfModifiedSince<span style="color: #339933;">!=</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
						<span style="color: #003399;">Date</span> requestDate <span style="color: #339933;">=</span> getDateFromHttpDate<span style="color: #009900;">&#40;</span>requestIfModifiedSince<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		            	<span style="color: #003399;">Date</span> pageInfoDate <span style="color: #339933;">=</span> getDateFromHttpDate<span style="color: #009900;">&#40;</span>headerPair<span style="color: #009900;">&#91;</span>value<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		            	<span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>requestDate.<span style="color: #006633;">getTime</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;=</span>pageInfoDate.<span style="color: #006633;">getTime</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		            	    response.<span style="color: #006633;">sendError</span><span style="color: #009900;">&#40;</span>HttpServletResponse.<span style="color: #006633;">SC_NOT_MODIFIED</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		            		response.<span style="color: #006633;">setHeader</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Last-Modified&quot;</span>, request.<span style="color: #006633;">getHeader</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;If-Modified-Since&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		            		<span style="color: #000000; font-weight: bold;">return</span><span style="color: #339933;">;</span>
		            	<span style="color: #009900;">&#125;</span>
					<span style="color: #009900;">&#125;</span>
				<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">ParseException</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
					<span style="color: #666666; font-style: italic;">//just ignore this error</span>
				<span style="color: #009900;">&#125;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">writeResponse</span><span style="color: #009900;">&#40;</span>request, response, pageInfo<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #008000; font-style: italic; font-weight: bold;">/** Get the time to live for a page, in seconds
	 * @return time to live in seconds
	 */</span>
	<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">long</span> getTimeToLive<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>blockingCache.<span style="color: #006633;">isDisabled</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
			<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span><span style="color: #000000; font-weight: bold;">else</span><span style="color: #009900;">&#123;</span>
			<span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>blockingCache.<span style="color: #006633;">isEternal</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
				<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #cc66cc;">60</span><span style="color: #339933;">*</span><span style="color: #cc66cc;">60</span><span style="color: #339933;">*</span><span style="color: #cc66cc;">24</span><span style="color: #339933;">*</span><span style="color: #cc66cc;">365</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//one year, in seconds</span>
			<span style="color: #009900;">&#125;</span><span style="color: #000000; font-weight: bold;">else</span><span style="color: #009900;">&#123;</span>
				<span style="color: #000000; font-weight: bold;">return</span> blockingCache.<span style="color: #006633;">getTimeToLiveSeconds</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

</div>]]></content:encoded>
			<wfw:commentRss>http://candrews.integralblue.com/2009/02/http-caching-header-aware-servlet-filter/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-sa/3.0/us/</creativeCommons:license>
	</item>
	</channel>
</rss>
