<?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:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Global Gateway</title>
	<atom:link href="http://globalgateway.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://globalgateway.wordpress.com</link>
	<description>Learning the American way...</description>
	<lastBuildDate>Fri, 09 Dec 2011 23:07:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='globalgateway.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Global Gateway</title>
		<link>http://globalgateway.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://globalgateway.wordpress.com/osd.xml" title="Global Gateway" />
	<atom:link rel='hub' href='http://globalgateway.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Simple CRUD with Gaelyk</title>
		<link>http://globalgateway.wordpress.com/2010/10/21/simple-crud-with-gaelyk/</link>
		<comments>http://globalgateway.wordpress.com/2010/10/21/simple-crud-with-gaelyk/#comments</comments>
		<pubDate>Fri, 22 Oct 2010 00:26:15 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[GAE]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Search]]></category>
		<category><![CDATA[App Engine]]></category>
		<category><![CDATA[Big Table]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[GAE/J]]></category>
		<category><![CDATA[Gaelyk]]></category>
		<category><![CDATA[Google]]></category>

		<guid isPermaLink="false">http://globalgateway.wordpress.com/?p=889</guid>
		<description><![CDATA[After having written a Grails application for Google App Engine I know exactly what the pain points are in production: Cold startup times make using the application an unenjoyable experience. App Engine calls for a lightweight application with far less JAR baggage and fast startup times. Yesterday I attended Guillaume LaForge&#8217;s session &#8220;Gaelyk, a lightweight [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=globalgateway.wordpress.com&amp;blog=961442&amp;post=889&amp;subd=globalgateway&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>After having written a Grails application for Google App Engine I know exactly what the pain points are in production: Cold startup times make using the application an unenjoyable experience. App Engine calls for a lightweight application with far less JAR baggage and fast startup times. Yesterday I attended Guillaume LaForge&#8217;s session <a href="http://www.springone2gx.com/conference/chicago/2010/10/session?id=18914">&#8220;Gaelyk, a lightweight Groovy toolkit for Google App Engine&#8221;</a> at <a href="http://www.springone2gx.com">SpringOne2GX</a> presenting the nuts and bolts of <a href="http://gaelyk.appspot.com">Gaelyk</a>. The session was reason enough to think about rewriting my application to Gaelyk. To get started I whipped up a simple CRUD example in Gaelyk. All you need to do is to download the <a href="http://gaelyk.appspot.com/download">Gaelyk template application</a> and you are ready to go. The test application will have four simple use cases: show all entities of a certain type (in my case a &#8220;Goal&#8221; entity), create new ones, update and delete them. </p>
<p>Gaelyk doesn&#8217;t support multiple closures in a controller class to automatically expose URLs by convention like Grails does. Instead you have to define your URL routing for each operation separately.</p>
<p><strong>war/WEB-INF/routes.groovy:</strong><br />
<pre class="brush: groovy; wrap-lines: false;">
get  &quot;/goals&quot;,                forward:  &quot;/showGoals.groovy&quot;
get  &quot;/goals/add&quot;,            forward:  &quot;/WEB-INF/pages/goal.gtpl&quot;
post &quot;/goals/insert&quot;,         forward:  &quot;/insertGoal.groovy&quot;
get  &quot;/goals/delete/@id&quot;,     forward:  &quot;/deleteGoal.groovy?id=@id&quot;
get  &quot;/goals/edit/@id&quot;,       forward:  &quot;/editGoal.groovy?id=@id&quot;
post &quot;/goals/update&quot;,         forward:  &quot;/updateGoal.groovy&quot;
</pre></p>
<p>To show all Goals I defined a Groovlet named <code>showGoals.groovy</code> that uses the App Engine datastore low-level API to retrieve them and forward to the view <code>goals.gtpl</code>. In the view you can add a new goal or edit/delete existing goals.</p>
<p><b>war/WEB-INF/groovy/showGoals.groovy:</b><br />
<pre class="brush: groovy; wrap-lines: false;">
import com.google.appengine.api.datastore.Query
import com.google.appengine.api.datastore.PreparedQuery
import static com.google.appengine.api.datastore.FetchOptions.Builder.*

log.info &quot;Getting all goals&quot;

def query = new Query(&quot;Goal&quot;)
PreparedQuery preparedQuery = datastore.prepare(query)
query.addSort(&quot;created&quot;, Query.SortDirection.DESCENDING)
def goals = preparedQuery.asList(withDefaults())

request.goals = goals

forward '/WEB-INF/pages/goals.gtpl'
</pre></p>
<p><b>war/WEB-INF/pages/goals.gtpl:</b><br />
<pre class="brush: xml; wrap-lines: false;">
&lt;% include '/WEB-INF/includes/header.gtpl' %&gt;

&lt;h2&gt;Goals&lt;/h2&gt;

&lt;a href=&quot;/goals/add&quot;&gt;Add Goal&lt;/a&gt;
&lt;br&gt;&lt;br&gt;
&lt;table border=&quot;1&quot;&gt;
  &lt;thead&gt;
     &lt;tr&gt;
        &lt;th&gt;Name&lt;/th&gt;
        &lt;th&gt;Description&lt;/th&gt;
        &lt;th&gt;Created&lt;/th&gt;
        &lt;th&gt;&amp;nbsp;&lt;/th&gt;
     &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
     &lt;% request.goals.each { goal -&gt; %&gt;
        &lt;tr&gt;
           &lt;td&gt;${goal.name}&lt;/td&gt;
           &lt;td&gt;${goal.description}&lt;/td&gt;
           &lt;td&gt;${goal.created}&lt;/td&gt;
           &lt;td&gt;&lt;a href=&quot;/goals/delete/${goal.key.id}&quot;&gt;Delete&lt;/a&gt; | &lt;a href=&quot;/goals/edit/${goal.key.id}&quot;&gt;Edit&lt;/a&gt;&lt;/td&gt;
        &lt;/tr&gt;
     &lt;% } %&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;% include '/WEB-INF/includes/footer.gtpl' %&gt;
</pre></p>
<p>The operations insert and edit share a common view named <code>goal.gtpl</code>. Based on whether the request contains the attribute <code>goal</code> the view will be in insert or edit mode. In case an existing Goal entity was provided the form gets populated with the entity data and is ready to be updated. The Goal to be edited will be retrieved by providing the entity&#8217;s ID in the <code>editGoal.groovy</code> Groovlet.</p>
<p><b>war/WEB-INF/groovy/editGoal.groovy:</b><br />
<pre class="brush: groovy; wrap-lines: false;">
import com.google.appengine.api.datastore.KeyFactory
import com.google.appengine.api.datastore.Key

log.info &quot;Editing goal&quot;

def id = Long.parseLong(params.id)
Key key = KeyFactory.createKey(&quot;Goal&quot;, id)
def goal = datastore.get(key)

request.goal = goal
forward '/WEB-INF/pages/goal.gtpl'
</pre></p>
<p><b>war/WEB-INF/pages/goal.gtpl:</b><br />
<pre class="brush: xml; wrap-lines: false;">
&lt;% include '/WEB-INF/includes/header.gtpl' %&gt;

&lt;%
  def goal = request.getAttribute(&quot;goal&quot;)
  boolean existingKey = goal?.key
  String action = !existingKey ? 'Add' : 'Update'
%&gt;

&lt;h2&gt;${action} Goal&lt;/h2&gt;

&lt;form action=&quot;/goals/${!existingKey ? 'insert' : 'update'}&quot; method=&quot;POST&quot;&gt;
   &lt;table border=&quot;0&quot;&gt;
      &lt;tbody&gt;
         &lt;tr&gt;
            &lt;td&gt;Name:&lt;/td&gt;
            &lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;name&quot; value=&quot;${goal?.name ? goal.name : ''}&quot;&gt;&lt;/td&gt;
         &lt;/tr&gt;
         &lt;tr&gt;
            &lt;td&gt;Description:&lt;/td&gt;
            &lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;description&quot; value=&quot;${goal?.description ? goal.description : ''}&quot;&gt;&lt;/td&gt;
         &lt;/tr&gt;
      &lt;/tbody&gt;
      &lt;% if(existingKey) { %&gt;
         &lt;input type=&quot;hidden&quot; name=&quot;id&quot; value=&quot;${goal.key.id}&quot;&gt;
      &lt;% } %&gt;
   &lt;/table&gt;
   &lt;br&gt;
   &lt;input type=&quot;submit&quot; value=&quot;${action}&quot;&gt;
   &lt;input type=&quot;button&quot; value=&quot;Cancel&quot; onclick=&quot;javascript:document.location.href = '/goals';&quot;&gt;
&lt;/form&gt;

&lt;% include '/WEB-INF/includes/footer.gtpl' %&gt;
</pre></p>
<p>At last we need to implement the Groovlets for persisting the changes to your entity. All of them are quite straight forward to implement. Gaelyk&#8217;s abstractions for the datastore work quite nicely.</p>
<p><b>war/WEB-INF/groovy/insertGoal.groovy:</b><br />
<pre class="brush: groovy; wrap-lines: false;">
import com.google.appengine.api.datastore.Entity

log.info &quot;Inserting goal&quot;

def goal = new Entity(&quot;Goal&quot;)
goal.name = params.name
goal.description = params.description
goal.created = new Date()
goal.save()

redirect '/goals'
</pre></p>
<p><b>war/WEB-INF/groovy/updateGoal.groovy:</b><br />
<pre class="brush: groovy; wrap-lines: false;">
import com.google.appengine.api.datastore.KeyFactory
import com.google.appengine.api.datastore.Key

log.info &quot;Updating goal&quot;

def id = Long.parseLong(params.id)
Key key = KeyFactory.createKey(&quot;Goal&quot;, id)
def goal = datastore.get(key)
goal.name = params.name
goal.description = params.description
goal.save()

redirect '/goals'
</pre></p>
<p><b>war/WEB-INF/groovy/deleteGoal.groovy:</b><br />
<pre class="brush: groovy; wrap-lines: false;">
import com.google.appengine.api.datastore.KeyFactory
import com.google.appengine.api.datastore.Key

log.info &quot;Deleting goal&quot;

def id = Long.parseLong(params.id)
Key key = KeyFactory.createKey(&quot;Goal&quot;, id)
key.delete()

redirect '/goals'
</pre></p>
<br /> Tagged: <a href='http://globalgateway.wordpress.com/tag/app-engine/'>App Engine</a>, <a href='http://globalgateway.wordpress.com/tag/big-table/'>Big Table</a>, <a href='http://globalgateway.wordpress.com/tag/cloud/'>cloud</a>, <a href='http://globalgateway.wordpress.com/tag/gae/'>GAE</a>, <a href='http://globalgateway.wordpress.com/tag/gaej/'>GAE/J</a>, <a href='http://globalgateway.wordpress.com/tag/gaelyk/'>Gaelyk</a>, <a href='http://globalgateway.wordpress.com/tag/google/'>Google</a>, <a href='http://globalgateway.wordpress.com/tag/groovy/'>Groovy</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/globalgateway.wordpress.com/889/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/globalgateway.wordpress.com/889/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/globalgateway.wordpress.com/889/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/globalgateway.wordpress.com/889/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/globalgateway.wordpress.com/889/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/globalgateway.wordpress.com/889/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/globalgateway.wordpress.com/889/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/globalgateway.wordpress.com/889/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/globalgateway.wordpress.com/889/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/globalgateway.wordpress.com/889/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/globalgateway.wordpress.com/889/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/globalgateway.wordpress.com/889/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/globalgateway.wordpress.com/889/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/globalgateway.wordpress.com/889/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=globalgateway.wordpress.com&amp;blog=961442&amp;post=889&amp;subd=globalgateway&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://globalgateway.wordpress.com/2010/10/21/simple-crud-with-gaelyk/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8f2248c6bfcc6df39a2cd8edf4267cb5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Ben</media:title>
		</media:content>
	</item>
		<item>
		<title>Grails on Google App Engine – Part 5: Conclusion</title>
		<link>http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-%e2%80%93-part-5-conclusion/</link>
		<comments>http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-%e2%80%93-part-5-conclusion/#comments</comments>
		<pubDate>Sun, 17 Oct 2010 22:12:00 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[GAE]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Big Table]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[Engine]]></category>
		<category><![CDATA[GAE/J]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[JDO]]></category>

		<guid isPermaLink="false">http://globalgateway.wordpress.com/?p=849</guid>
		<description><![CDATA[Thanks to the App Engine plugin you can get Grails running on App Engine. Yeah, you got your favorite web application framework deployed on the cloud. But wait&#8230;there&#8217;s a problem. Grails comes with a lot of libraries that are bundled with the framework. You got Spring, Hibernate, Sitemesh and all the other libraries you added [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=globalgateway.wordpress.com&amp;blog=961442&amp;post=849&amp;subd=globalgateway&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Thanks to the App Engine plugin you can get Grails running on App Engine. Yeah, you got your favorite web application framework deployed on the cloud. But wait&#8230;there&#8217;s a problem. Grails comes with a lot of libraries that are bundled with the framework. You got Spring, Hibernate, Sitemesh and all the other libraries you added to your application. This is how we&#8217;re used to build applications. However, building applications for Google App Engine is different. The platform puts your application into sleep mode when you don&#8217;t get enough traffic. This is understandable from Google&#8217;s view on scalability but not from a software developer standpoint. Calling the application after a period of no usage will reinitialize your classes, Spring application contexts and libraries. If the application cannot serve the request within 30 seconds the user will get a <code>com.google.apphosting.api.DeadlineExceededException</code>. The cold startup time will even be longer the bigger your WAR file is and the more libraries you use. This gets extremely painful with Grails. Sometimes you have to call your application three times in a row, run into an initialization error and try again until Grails can serve your request. Google was talking about &#8220;reserved instances&#8221; that would not put your application into sleep mode for paying customers. However, this has not been realized yet. The <a href="http://groups.google.com/group/google-appengine">GAE/J forum</a> is full of frustrated users complaining about this issue. You can work around the cold startup time by setting up a cron job in <code>cron.xml</code> that pings your application every minute. From an architectural view this not only is unnecessary and useless traffic for your application it also will not fully solve the problem. I still ran into issues with requests that couldn&#8217;t finish with the deadline time period.</p>
<p><pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;cronentries&gt;
   &lt;cron&gt;
      &lt;url&gt;/user/ping&lt;/url&gt;
      &lt;description&gt;Keep the app alive by ping every 1 minutes&lt;/description&gt;
      &lt;schedule&gt;every 1 minutes&lt;/schedule&gt;
   &lt;/cron&gt;
&lt;/cronentries&gt;
</pre></p>
<p>Clearly, App Engine calls for a lightweight application framework until the cold startup issues have been resolved by Google in some sort of form. This puts Grails out of the running as a production-ready framework on App Engine. No company can afford exceptions being thrown on paying customers. This is not an issue solely to Grails. I am sure the startup times for full-fledged Spring applications on App Engine are not extremely better. An alternative for a Groovy-based web framework can be seen in <a href="http://gaelyk.appspot.com/">Gaelyk</a>. Gaelyk is not as feature-rich as Grails but will give you the benefit of faster startup times. Implementing non-trivial web applications with Gaeylk can be painful to develop because it&#8217;s not as feature-rich as Grails is. I guess in the end there&#8217;s always a tradeoff.</p>
<p><b>More on this topic:</b></p>
<ul>
<li><a href="http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-part-1-a-case-study/">Grails on Google App Engine &#8211; Part 1: A Case Study</a>
<li><a href="http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-part-2-project-setup/">Grails on Google App Engine – Part 2: Project Setup</a>
<li><a href="http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-part-3-persistence/">Grails on Google App Engine – Part 3: Persistence</a>
<li><a href="http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-%E2%80%93-part-4-third-party-libraries/">Grails on Google App Engine – Part 4: Third-Party Libraries</a>
</ul>
<br /> Tagged: <a href='http://globalgateway.wordpress.com/tag/big-table/'>Big Table</a>, <a href='http://globalgateway.wordpress.com/tag/cloud/'>cloud</a>, <a href='http://globalgateway.wordpress.com/tag/engine/'>Engine</a>, <a href='http://globalgateway.wordpress.com/tag/gae/'>GAE</a>, <a href='http://globalgateway.wordpress.com/tag/gaej/'>GAE/J</a>, <a href='http://globalgateway.wordpress.com/tag/google/'>Google</a>, <a href='http://globalgateway.wordpress.com/tag/grails/'>Grails</a>, <a href='http://globalgateway.wordpress.com/tag/groovy/'>Groovy</a>, <a href='http://globalgateway.wordpress.com/tag/jdo/'>JDO</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/globalgateway.wordpress.com/849/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/globalgateway.wordpress.com/849/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/globalgateway.wordpress.com/849/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/globalgateway.wordpress.com/849/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/globalgateway.wordpress.com/849/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/globalgateway.wordpress.com/849/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/globalgateway.wordpress.com/849/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/globalgateway.wordpress.com/849/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/globalgateway.wordpress.com/849/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/globalgateway.wordpress.com/849/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/globalgateway.wordpress.com/849/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/globalgateway.wordpress.com/849/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/globalgateway.wordpress.com/849/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/globalgateway.wordpress.com/849/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=globalgateway.wordpress.com&amp;blog=961442&amp;post=849&amp;subd=globalgateway&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-%e2%80%93-part-5-conclusion/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8f2248c6bfcc6df39a2cd8edf4267cb5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Ben</media:title>
		</media:content>
	</item>
		<item>
		<title>Grails on Google App Engine – Part 4: Third-Party Libraries</title>
		<link>http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-%e2%80%93-part-4-third-party-libraries/</link>
		<comments>http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-%e2%80%93-part-4-third-party-libraries/#comments</comments>
		<pubDate>Sun, 17 Oct 2010 22:11:11 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[GAE]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Big Table]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[Engine]]></category>
		<category><![CDATA[GAE/J]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[JDO]]></category>
		<category><![CDATA[Spring Security]]></category>

		<guid isPermaLink="false">http://globalgateway.wordpress.com/?p=829</guid>
		<description><![CDATA[Certain aspects of web application development have already been solved by third-party libraries. Why implement a solution yourself when it&#8217;s already out there?! Not every existing library will work with App Engine though. Google published a page listing compatible libraries and frameworks for their platform. I will describe two very common use cases that I [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=globalgateway.wordpress.com&amp;blog=961442&amp;post=829&amp;subd=globalgateway&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Certain aspects of web application development have already been solved by third-party libraries. Why implement a solution yourself when it&#8217;s already out there?! Not every existing library will work with App Engine though. Google published a <a href="http://groups.google.com/group/google-appengine-java/web/will-it-play-in-app-engine">page listing compatible libraries and frameworks</a> for their platform. I will describe two very common use cases that I chose to use in my application: Security with <a href="http://static.springsource.org/spring-security/site/">Spring Security</a> and making HTTP calls using <a href="http://hc.apache.org/httpcomponents-client-ga/index.html">HttpClient</a>.</p>
<h3>Security</h3>
<p>Spring Security fits right into the Grails technology stack and it a proven solution for authenticating/authorizing users. This section will only describe the steps necessary to specifically integrate Spring Security with Grails on App Engine. For a detailed configuration description please refer to the Spring Security documentation. I set up my application with version 3.0.3 by dropping in the JAR files into the <code>lib</code> directory. Spring Security in it&#8217;s default configuration requires your container to support sessions. This is no problem for App Engine. You have to make sure though that you enable them. The configuration file <code>appengine-web.xml</code> has to have this entry to make it work:  </p>
<p><pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;appengine-web-app xmlns=&quot;http://appengine.google.com/ns/1.0&quot;&gt;
   ...
   &lt;sessions-enabled&gt;true&lt;/sessions-enabled&gt; 
   ...
&lt;/appengine-web-app&gt;
</pre></p>
<p>First of all I declared my domain objects <code>User</code> and <code>Role</code>. Please see the <a href="http://static.springsource.org/spring-security/site/docs/3.1.x/reference/appendix-schema.html#d0e7262">Spring Security database schema</a> for more information.</p>
<p><pre class="brush: groovy;">
package com.favalike

import com.google.appengine.api.datastore.Key
import javax.jdo.annotations.*

@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable=&quot;true&quot;)
class User {
   @PrimaryKey
   @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
   Key key

   @Persistent
   String username

   @Persistent
   String password

   @Persistent
   boolean enabled

   @Persistent(defaultFetchGroup = &quot;true&quot;)
   List&lt;Role&gt; authorities = new ArrayList&lt;Role&gt;()
}
</pre></p>
<p><pre class="brush: groovy;">
package com.favalike

import com.google.appengine.api.datastore.Key
import javax.jdo.annotations.*

@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable=&quot;true&quot;)
class Role {
   @PrimaryKey
   @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
   Key key

   @Persistent
   String authority

   @Persistent
   User user
}
</pre></p>
<p>Because Spring Security doesn&#8217;t define a JDO <a href="http://static.springsource.org/spring-security/site/docs/3.1.x/reference/technical-overview.html#d0e1722">UserDetailsService</a> implementation that would be compatible with App Engine you have to write it yourself.</p>
<p><pre class="brush: groovy; wrap-lines: false;">
package com.favalike.security

import org.apache.commons.lang.StringUtils
import org.apache.commons.logging.Log
import org.apache.commons.logging.LogFactory
import org.springframework.context.support.MessageSourceAccessor
import org.springframework.dao.DataAccessException
import org.springframework.dao.DataRetrievalFailureException
import org.springframework.security.core.SpringSecurityMessageSource
import org.springframework.security.core.authority.GrantedAuthorityImpl
import org.springframework.security.core.userdetails.User
import org.springframework.security.core.userdetails.UserDetails
import org.springframework.security.core.userdetails.UserDetailsService
import org.springframework.security.core.userdetails.UsernameNotFoundException
import org.springframework.security.authentication.BadCredentialsException

class JdoUserDetailsService implements UserDetailsService {
   static final Log log = LogFactory.getLog(JdoUserDetailsService)
   def userService
   MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor()

   public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
      if(StringUtils.isBlank(username)) {
         log.error &quot;Username was empty. Authentication failed.&quot;
         throw new BadCredentialsException(messages.getMessage(&quot;login.username.blank&quot;, [] as Object[], &quot;Username may not be empty&quot;), username)
      }

      def user = null

      try {
         user = userService.findUserByUsername(username)
      }
      catch(Exception e) {
         log.error &quot;Problem retrieving user from database&quot;, e
         throw new DataRetrievalFailureException(messages.getMessage(&quot;login.database.error&quot;, [] as Object[], &quot;User could not be retrieved from database. Please try later&quot;))
      }

      if(user == null) {
         log.error &quot;User for username '${username}' not found in database. Authentication failed.&quot;
         throw new UsernameNotFoundException(messages.getMessage(&quot;JdbcDaoImpl.notFound&quot;, [username] as Object[], &quot;Username {0} not found&quot;), username)
      }

      if(log.infoEnabled) {
         log.info &quot;Found user for username '${username}': ${user}&quot;
      }

      def grantedAuthorities = []

      user.authorities.each { role -&gt;
         grantedAuthorities &lt;&lt; new GrantedAuthorityImpl(role.authority)
      }

      if(grantedAuthorities.size() == 0) {
         log.error &quot;User needs to have at least one granted authority!&quot;
         throw new UsernameNotFoundException(messages.getMessage(&quot;JdbcDaoImpl.noAuthority&quot;, [username] as Object[], &quot;User {0} has no GrantedAuthority&quot;), username)
      }

      if(log.infoEnabled) {
         log.info &quot;User found for username '${username}'.&quot;
      }

      return new User(user.username, user.password, user.enabled, true, true, true, grantedAuthorities)
   }
}
</pre></p>
<p>I was able to put all the Spring wiring for Spring Security in <code>grails-app/conf/spring/resources.groovy</code>. My configuration is pretty much the ordinary security setup you would have to define for every application using Spring Security except that I defined it in Groovy.</p>
<p><pre class="brush: groovy; wrap-lines: false;">
beans = {
   // Security
   xmlns security: 'http://www.springframework.org/schema/security'

   jdoUserDetailsService(com.favalike.security.JdoUserDetailsService) {
      userService = ref('userService')
   }

   passwordEncoder(org.springframework.security.authentication.encoding.Md5PasswordEncoder)

   security.'http'('auto-config': true, 'access-denied-page': '/user/index') {
      security.'intercept-url'('pattern': '/user/index*', 'filters': 'none')
      security.'intercept-url'('pattern': '/user/signup', 'filters': 'none')
      security.'intercept-url'('pattern': '/favicon.ico', 'filters': 'none')
      security.'intercept-url'('pattern': '/**/*.html', 'access': 'ROLE_USER')
      security.'intercept-url'('pattern': '/**/*.js', 'access': 'ROLE_USER')
      security.'intercept-url'('pattern': '/**/*.gsp', 'access': 'ROLE_USER')
      security.'intercept-url'('pattern': '/**', 'access': 'ROLE_USER')
      security.'form-login'('authentication-failure-url': '/user/index?login_error=1', 'default-target-url': '/', 'login-page': '/user/index')
      security.'remember-me'('key': '99sdfll74soq')
      security.'logout'('logout-success-url': '/user/index')
   }

   security.'authentication-manager'('alias': 'authenticationManager') {
      security.'authentication-provider'('user-service-ref': 'jdoUserDetailsService') {
         security.'password-encoder'('hash': 'md5')
      }
   }
}
</pre></p>
<h3>HTTP Calls</h3>
<p>App Engine provides you with the <a href="http://code.google.com/appengine/docs/java/javadoc/index.html?com/google/appengine/api/urlfetch/package-summary.html">URL Fetch API</a> right out of the box. Even though the API does its job it is relatively feature-less. If you need more advanced feature sets like support for cookies you can turn to <code>HttpClient</code>. All you need to do is to download version 4 of the HttpComponents and drop the libraries into your <code>lib</code> directory. HttpClient needs some additional work to make it run on App Engine. It usually works with <code>java.net</code> package which is not allowed on App Engine. <a href="http://esxx.blogspot.com/2009/06/using-apaches-httpclient-on-google-app.html">This posting</a> shows you a way to work around it.</p>
<p><pre class="brush: groovy;">
package com.favalike.http

import org.apache.commons.logging.Log
import org.apache.commons.logging.LogFactory
import org.apache.http.Header
import org.apache.http.HttpEntity
import org.apache.http.client.HttpClient
import org.apache.http.client.methods.HttpGet
import org.apache.http.client.methods.HttpUriRequest
import org.apache.http.conn.ClientConnectionManager
import org.apache.http.impl.client.DefaultHttpClient
import org.apache.http.params.BasicHttpParams
import org.apache.http.params.CoreConnectionPNames
import org.apache.http.params.CoreProtocolPNames
import org.apache.http.params.HttpParams
import org.apache.http.util.EntityUtils

class CommonsHttpRequestExecutor implements HttpRequestExecutor {
   static final Log log = LogFactory.getLog(CommonsHttpRequestExecutor)
   final Integer timeout

   CommonsHttpRequestExecutor(timeout) {
      this.timeout = timeout
   }

   def HttpResponse sendGetRequest(String url) {
      HttpGet httpGet = new HttpGet(url);

      if(log.debugEnabled) {
         log.debug(&quot;Sending GET request to URL '${httpget.getURI()}'&quot;)
      }

      executeHttpRequest(httpGet);
   }

   def executeHttpRequest(HttpUriRequest httpUriRequest) {
      HttpResponse httpResponse = new HttpResponse()
      HttpClient httpclient = getDefaultHttpClient()

      try {
         def response = httpclient.execute(httpUriRequest)
         populateResponseData(response, httpResponse)
      }
      catch(Exception e) {
         log.error(&quot;Error accessing site for url '${httpUriRequest.getURI()}'&quot;, e)
         httpResponse.errorMessage = e.message
         httpUriRequest.abort()
      }
      finally {
         httpclient.getConnectionManager().shutdown();
      }

      httpResponse
   }

   def getDefaultHttpClient() {
      ClientConnectionManager clientConnectionManager = new GAEConnectionManager();
      HttpParams params = new BasicHttpParams();
      params.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, timeout);
      params.setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, &quot;UTF-8&quot;);    
      new DefaultHttpClient(clientConnectionManager, params)
   }

   def populateResponseData(actualResponse, httpResponse) {
      httpResponse.statusCode = actualResponse.statusLine.statusCode
      httpResponse.reasonPhrase = actualResponse.statusLine.reasonPhrase
      httpResponse.statusLine = actualResponse.statusLine.toString()
      HttpEntity entity = actualResponse.getEntity();
      
      if(entity != null) {
         byte[] content = EntityUtils.toByteArray(entity)
         Header header = entity.getContentType() 
         httpResponse.responseBody = new String(content)
      }
   }
}
</pre></p>
<p><b>More on this topic:</b></p>
<ul>
<li><a href="http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-part-1-a-case-study/">Grails on Google App Engine &#8211; Part 1: A Case Study</a>
<li><a href="http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-part-2-project-setup/">Grails on Google App Engine – Part 2: Project Setup</a>
<li><a href="http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-part-3-persistence/">Grails on Google App Engine – Part 3: Persistence</a>
<li><a href="http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-%E2%80%93-part-5-conclusion/">Grails on Google App Engine – Part 5: Conclusion</a>
</ul>
<br /> Tagged: <a href='http://globalgateway.wordpress.com/tag/big-table/'>Big Table</a>, <a href='http://globalgateway.wordpress.com/tag/cloud/'>cloud</a>, <a href='http://globalgateway.wordpress.com/tag/engine/'>Engine</a>, <a href='http://globalgateway.wordpress.com/tag/gae/'>GAE</a>, <a href='http://globalgateway.wordpress.com/tag/gaej/'>GAE/J</a>, <a href='http://globalgateway.wordpress.com/tag/google/'>Google</a>, <a href='http://globalgateway.wordpress.com/tag/grails/'>Grails</a>, <a href='http://globalgateway.wordpress.com/tag/groovy/'>Groovy</a>, <a href='http://globalgateway.wordpress.com/tag/jdo/'>JDO</a>, <a href='http://globalgateway.wordpress.com/tag/spring-security/'>Spring Security</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/globalgateway.wordpress.com/829/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/globalgateway.wordpress.com/829/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/globalgateway.wordpress.com/829/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/globalgateway.wordpress.com/829/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/globalgateway.wordpress.com/829/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/globalgateway.wordpress.com/829/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/globalgateway.wordpress.com/829/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/globalgateway.wordpress.com/829/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/globalgateway.wordpress.com/829/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/globalgateway.wordpress.com/829/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/globalgateway.wordpress.com/829/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/globalgateway.wordpress.com/829/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/globalgateway.wordpress.com/829/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/globalgateway.wordpress.com/829/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=globalgateway.wordpress.com&amp;blog=961442&amp;post=829&amp;subd=globalgateway&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-%e2%80%93-part-4-third-party-libraries/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8f2248c6bfcc6df39a2cd8edf4267cb5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Ben</media:title>
		</media:content>
	</item>
		<item>
		<title>Grails on Google App Engine &#8211; Part 3: Persistence</title>
		<link>http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-part-3-persistence/</link>
		<comments>http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-part-3-persistence/#comments</comments>
		<pubDate>Sun, 17 Oct 2010 22:10:21 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[GAE]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[JDO]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[Big Table]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[App Engine]]></category>
		<category><![CDATA[GAE/J]]></category>

		<guid isPermaLink="false">http://globalgateway.wordpress.com/?p=772</guid>
		<description><![CDATA[The App Engine plugin installation script will prompt you for the persistence option you want to choose in your project. Google lets you select only one of its persistence implementations for BigTable: JDO or JPA. Using plain GORM is not an option. I decided to go with JDO for the simple fact that there&#8217;s more [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=globalgateway.wordpress.com&amp;blog=961442&amp;post=772&amp;subd=globalgateway&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The App Engine plugin installation script will prompt you for the persistence option you want to choose in your project. Google lets you select only one of its persistence implementations for BigTable: JDO or JPA. Using plain GORM is not an option. I decided to go with JDO for the simple fact that there&#8217;s more documentation for JDO than for JPA. Despite the fact that there&#8217;s documentation it certainly doesn&#8217;t cover all the questions I had. I found myself digging for answers to undescriptive exception messages for hours and hours in forums. Implementing persistence for my relatively easy domain model by far took the most of my development time making it a very frustrating experience. There are some good blogs about JDO persistence in App Engine that might be helpful to you: <a href="http://gae-java-persistence.blogspot.com/">Google App Engine Java Persistence</a>, <a href="http://gaejexperiments.wordpress.com/">Google App Engine Java Experiments</a>. Often times I could only make things work by trail and error especially when it comes to modeling relationships.</p>
<h3>Domain Classes</h3>
<p>Grails domain classes have to reside in <code>grails-app/domain</code> and must be placed in a package. Only then the DataNucleus tool will enhance your classes. App Engine introduces its own <a href="http://code.google.com/appengine/docs/java/datastore/dataclasses.html#Core_Value_Types">data types</a>. You definitely want to have a look at the list before you define the data types to your fields. It&#8217;s really a hassle to change the data type after you deployed your application to production and want to change the data type. Usually that means that you have to run a data migration script because App Engine might throw an exception on you for existing data. In my application I used the data type <code>com.google.appengine.api.datastore.Key</code> as primary key. The class <code>Key</code> has a String representation that you can use if you want to send it to your client code. This String representation can be converted back to a <code>Key</code>. The class you use for that is <code>com.google.appengine.api.datastore.KeyFactory</code>.</p>
<p><pre class="brush: groovy;">
String bookmarkId = KeyFactory.keyToString(bookmark.key)
Key key = KeyFactory.stringToKey(bookmarkId)
</pre></p>
<p>You can try to exclude the default domain object fields <code>id</code> and <code>version</code>. However, that doesn&#8217;t quite propagate down to App Engine. The DataStore Viewer still shows both fields. I am not sure if there&#8217;s a different way around it.</p>
<p><pre class="brush: groovy;">
static mapping = {
   id visible: false
   version visible: false
}
</pre></p>
<p>Defining relationships between domain objects can be tedious. More than often you run into funny error messages trying to store or retrieve data. You got to read the <a href="http://code.google.com/appengine/docs/java/datastore/relationships.html">App Engine manual</a> very closely to make them work. Especially when it comes down to defining many to many and self-referential owned relationship it can get hairy. Often times I had to fall back to just reference the <code>Key</code> of a different domain class to create a relationship.</p>
<h3>Service Classes</h3>
<p>The App Engine plugin automatically configures and provides you with Spring&#8217;s <code>JdoTemplate</code> that can be injected into your Grails services. Transaction boundaries can be set by wrapping your database interactions into a <code>transactionTemplate</code>. The <code>JdoTemplate</code> is easy to use and shouldn&#8217;t be new to you if you used one of Spring&#8217;s template implementations before like the <code>JdbcTemplate</code>. In some cases I had to fall back to the JDO low-level API because the <code>JdoTemplate</code> doesn&#8217;t provide the functionality. For my needs I created a super class that injects the <code>JdoTemplate</code> and the <code>transactionTemplate</code>.</p>
<p><pre class="brush: groovy;">
class JdoService {
   def jdoTemplate
   def transactionTemplate
}
</pre></p>
<p>By default the JDO persistence configuration (<code>jdoconfig.xml</code>) created by the App Engine plugin auto-creates transactions. If you want to have full control over your transactions use the <code>transactionTemplate</code>. When you want to<a href="http://code.google.com/appengine/docs/java/datastore/transactions.html#Disabling_Transactions_and_Porting_Existing_JDO_Apps"> operate on more than one domain object within a transaction</a> you have to set the property <code>datanucleus.appengine.autoCreateDatastoreTxns</code> to <code>false</code>.</p>
<p><pre class="brush: xml; highlight: [8]; wrap-lines: false;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;jdoconfig xmlns=&quot;http://java.sun.com/xml/ns/jdo/jdoconfig&quot;
    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
    xsi:noNamespaceSchemaLocation=&quot;http://java.sun.com/xml/ns/jdo/jdoconfig&quot;&gt;

    &lt;persistence-manager-factory name=&quot;transactions-optional&quot;&gt;
        ...
        &lt;property name=&quot;datanucleus.appengine.autoCreateDatastoreTxns&quot; value=&quot;false&quot;/&gt;
    &lt;/persistence-manager-factory&gt;
&lt;/jdoconfig&gt;
</pre></p>
<p>Using the <code>JdoTemplate</code> doesn&#8217;t require you to close your connection. This is being handled by Spring. This is an example on how I used it:</p>
<p><pre class="brush: groovy; wrap-lines: false;">
def findAllByUser() {
   def bookmarks = []

   transactionTemplate.execute( { status -&gt;
      def user = getLoggedInUser()
      bookmarks = jdoTemplate.find(Bookmark, &quot;userKey == userKeyParam&quot;, &quot;com.google.appengine.api.datastore.Key userKeyParam&quot;, [user.key] as Object[], &quot;created asc&quot;)
   } as TransactionCallback)

   bookmarks
}
</pre></p>
<p>Despite the benefits of <code>JdoTemplate</code> you sometimes have to leverage the low-level API. However, you don&#8217;t have to create a <a href="http://code.google.com/appengine/docs/java/datastore/usingjdo.html#Getting_a_PersistenceManager_Instance">class to retrieve the <code>PersistenceManagerFactory</code></a>. You can easily get it from the <code>JdoTemplate</code>. Make sure you close your resources after you used them. I wrote a little helper class to does that. One of the reasons I had to use the low-level API was to implement pagination. I chose to go down the naive, classic path of counting all records of a specific domain object and then retrieve the a list of these objects for the page we want to display. Using the range operator has implications for performance: the datastore must retrieve and then discard all results prior to the starting offset. For example, a query with a range of 5, 10 fetches 10 results from the datastore, then discards the first 5 and returns the remaining 5 to the application. I don&#8217;t expect users to have thousands and thousands of bookmarks in one folder so this would be a minor issue. Furthermore, I wanted to get up and running as soon as possible. Alternatively, this <a href="http://code.google.com/appengine/articles/paging.html">posting</a> describes a performant but harder to implement solution.</p>
<p><pre class="brush: groovy; wrap-lines: false;">
def findAllByUserInRange(offset, max) {
   def bookmarks = []
   def total

   transactionTemplate.execute( { status -&gt;
      def user = getLoggedInUser()
      Query query

      try {
         final filter = &quot;userKey == userKeyParam&quot;
         final parameters = &quot;com.google.appengine.api.datastore.Key userKeyParam&quot; 
         query = jdoTemplate.getPersistenceManagerFactory().getPersistenceManager().newQuery(Bookmark)
         query.setFilter(filter)
         query.declareParameters(parameters);
         query.setResult(&quot;count(this)&quot;)
         total = query.execute(user.key)
         query = jdoTemplate.getPersistenceManagerFactory().getPersistenceManager().newQuery(Bookmark)
         query.setFilter(filter)
         query.declareParameters(parameters);
         query.setOrdering(&quot;created asc&quot;)
         query.setRange(offset, offset + max)
         bookmarks = query.execute(user.key)
      }
      finally {
         JdoUtil.closeAll(query)
      }
   } as TransactionCallback)

   new Page(offset, max, total, bookmarks)
}
</pre></p>
<h3>Indexes</h3>
<p>The App Engine datastore maintains an index for every query an application intends to make. As the application makes changes to datastore entities, the datastore updates the indexes with the correct results. When the application executes a query, the datastore fetches the results directly from the corresponding index. As this might hold true for your development machine this isn&#8217;t necessarily true when you deploy your application to App Engine. Often times App Engine didn&#8217;t indicate that I have a missing index. You either have to analyze your queries very closely and add the indexes manually in <code>grails-app/conf/datastore-indexes.xml</code> or you&#8217;ll find yourself seeing exceptions. These exception can be fixed easily. However, you have to redeploy your application. It might take App Engine a while (sometimes 30 minutes or longer) to build the indexes once you have them defined. Indexes that are in the process of being built cannot serve the query causing an exception. This makes it impossible to deploy a new index without problems for your users. At the moment there&#8217;s no way to delete indexes over the administration console. </p>
<p><b>More on this topic:</b></p>
<ul>
<li><a href="http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-part-1-a-case-study/">Grails on Google App Engine &#8211; Part 1: A Case Study</a>
<li><a href="http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-part-2-project-setup/">Grails on Google App Engine – Part 2: Project Setup</a>
<li><a href="http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-%E2%80%93-part-4-third-party-libraries/">Grails on Google App Engine – Part 4: Third-Party Libraries</a>
<li><a href="http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-%E2%80%93-part-5-conclusion/">Grails on Google App Engine – Part 5: Conclusion</a>
</ul>
<br /> Tagged: <a href='http://globalgateway.wordpress.com/tag/app-engine/'>App Engine</a>, <a href='http://globalgateway.wordpress.com/tag/big-table/'>Big Table</a>, <a href='http://globalgateway.wordpress.com/tag/cloud/'>cloud</a>, <a href='http://globalgateway.wordpress.com/tag/gae/'>GAE</a>, <a href='http://globalgateway.wordpress.com/tag/gaej/'>GAE/J</a>, <a href='http://globalgateway.wordpress.com/tag/google/'>Google</a>, <a href='http://globalgateway.wordpress.com/tag/grails/'>Grails</a>, <a href='http://globalgateway.wordpress.com/tag/groovy/'>Groovy</a>, <a href='http://globalgateway.wordpress.com/tag/jdo/'>JDO</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/globalgateway.wordpress.com/772/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/globalgateway.wordpress.com/772/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/globalgateway.wordpress.com/772/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/globalgateway.wordpress.com/772/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/globalgateway.wordpress.com/772/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/globalgateway.wordpress.com/772/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/globalgateway.wordpress.com/772/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/globalgateway.wordpress.com/772/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/globalgateway.wordpress.com/772/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/globalgateway.wordpress.com/772/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/globalgateway.wordpress.com/772/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/globalgateway.wordpress.com/772/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/globalgateway.wordpress.com/772/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/globalgateway.wordpress.com/772/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=globalgateway.wordpress.com&amp;blog=961442&amp;post=772&amp;subd=globalgateway&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-part-3-persistence/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8f2248c6bfcc6df39a2cd8edf4267cb5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Ben</media:title>
		</media:content>
	</item>
		<item>
		<title>Grails on Google App Engine &#8211; Part 2: Project Setup</title>
		<link>http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-part-2-project-setup/</link>
		<comments>http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-part-2-project-setup/#comments</comments>
		<pubDate>Sun, 17 Oct 2010 22:09:41 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[GAE]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[JDO]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[Big Table]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[App Engine]]></category>
		<category><![CDATA[GAE/J]]></category>

		<guid isPermaLink="false">http://globalgateway.wordpress.com/?p=679</guid>
		<description><![CDATA[Setting up Grails for App Engine on my favorite IDE IntelliJ was as easy as installing the App Engine plugin. At the time of writing the latest plugin version is 0.8.10. It is by far not free of bugs but gets you where you want. It provides you with the basic setup to build, run [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=globalgateway.wordpress.com&amp;blog=961442&amp;post=679&amp;subd=globalgateway&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Setting up Grails for App Engine on my favorite IDE IntelliJ was as easy as installing the <a href="http://www.grails.org/plugin/app-engine">App Engine plugin</a>. At the time of writing the latest plugin version is 0.8.10. It is by far not free of bugs but gets you where you want. It provides you with the basic setup to build, run and deploy your project in your development environment. The plugin was fully compatible with Grails 1.3.1. I didn&#8217;t try out to upgrade my project to the latest version of Grails yet. Stick to the plugin documentation to get the basic setup going. To be able to reference the GAE/J classes I dropped in the JAR files <code>appengine-api-1.0-sdk-1.3.7.jar</code> and <code>jdo2-api-2.3-eb.jar</code> into my project&#8217;s <code>lib</code> directory. It was extremely helpful to set up Log4J correctly right away. Earlier versions of the plugin had some Log4J-related bugs but they seem to be fixed now. Here&#8217;s an excerpt of my <code>Config.groovy</code>: </p>
<p><pre class="brush: groovy; wrap-lines: false;">
log4j = {
   appenders {
      console name:'stdout', layout:pattern(conversionPattern: '%d{dd MMM yyyy HH:mm:ss,SSS} [%t] %-5p %c{2} - %m%n')
   }

   debug  'grails.app', 'com.favalike'
   ...
}
</pre></p>
<p>The plugin still has a bug related to i18n. In case you&#8217;re using one of the messages.properties files to store internalized texts that would leave these files empty after building the WAR file. I could still make it work by applying the workaround described in the <a href="http://jira.codehaus.org/browse/GRAILSPLUGINS-1905">JIRA ticket</a>. You got to change your <code>Bootstrap.groovy</code> as follows and build your WAR file for production environment: <code>grails -Dgrails.env=production app-engine package</code>.</p>
<p><pre class="brush: groovy;">
import grails.util.Environment

class BootStrap {
   def messageSource

   def init = { servletContext -&gt;
      if(Environment.getCurrent() == Environment.PRODUCTION) {
         messageSource.basenames = ['WEB-INF/grails-app/i18n/messages']
         messageSource.clearCache()
      }
   }

   def destroy = {
   }
} 
</pre></p>
<p>To improve performance from the get go I made sure I had precompilation enabled. Furthermore, <a href="http://code.google.com/appengine/docs/java/config/appconfig.html#Static_Files_and_Resource_Files">static files</a> can get served by dedicated servers and caches. Both settings are made in <code>appengine-web.xml</code>. </p>
<p><pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;appengine-web-app xmlns=&quot;http://appengine.google.com/ns/1.0&quot;&gt;
   ...
   &lt;precompilation-enabled&gt;true&lt;/precompilation-enabled&gt;
   &lt;static-files&gt;
      &lt;include path=&quot;/favicon.ico&quot; /&gt;
      &lt;include path=&quot;/css/**.css&quot; /&gt;
      &lt;include path=&quot;/images/**.*&quot; /&gt;
      &lt;include path=&quot;/js/**.js&quot; expiration=&quot;1d&quot; /&gt;    
   &lt;/static-files&gt;
&lt;/appengine-web-app&gt;
</pre></p>
<p><b>More on this topic:</b></p>
<ul>
<li><a href="http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-part-1-a-case-study/">Grails on Google App Engine &#8211; Part 1: A Case Study</a>
<li><a href="http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-part-3-persistence/">Grails on Google App Engine &#8211; Part 3: Persistence</a>
<li><a href="http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-%E2%80%93-part-4-third-party-libraries/">Grails on Google App Engine – Part 4: Third-Party Libraries</a>
<li><a href="http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-%E2%80%93-part-5-conclusion/">Grails on Google App Engine – Part 5: Conclusion</a>
</ul>
<br /> Tagged: <a href='http://globalgateway.wordpress.com/tag/app-engine/'>App Engine</a>, <a href='http://globalgateway.wordpress.com/tag/big-table/'>Big Table</a>, <a href='http://globalgateway.wordpress.com/tag/cloud/'>cloud</a>, <a href='http://globalgateway.wordpress.com/tag/gae/'>GAE</a>, <a href='http://globalgateway.wordpress.com/tag/gaej/'>GAE/J</a>, <a href='http://globalgateway.wordpress.com/tag/google/'>Google</a>, <a href='http://globalgateway.wordpress.com/tag/grails/'>Grails</a>, <a href='http://globalgateway.wordpress.com/tag/groovy/'>Groovy</a>, <a href='http://globalgateway.wordpress.com/tag/jdo/'>JDO</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/globalgateway.wordpress.com/679/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/globalgateway.wordpress.com/679/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/globalgateway.wordpress.com/679/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/globalgateway.wordpress.com/679/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/globalgateway.wordpress.com/679/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/globalgateway.wordpress.com/679/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/globalgateway.wordpress.com/679/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/globalgateway.wordpress.com/679/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/globalgateway.wordpress.com/679/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/globalgateway.wordpress.com/679/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/globalgateway.wordpress.com/679/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/globalgateway.wordpress.com/679/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/globalgateway.wordpress.com/679/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/globalgateway.wordpress.com/679/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=globalgateway.wordpress.com&amp;blog=961442&amp;post=679&amp;subd=globalgateway&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-part-2-project-setup/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8f2248c6bfcc6df39a2cd8edf4267cb5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Ben</media:title>
		</media:content>
	</item>
		<item>
		<title>Grails on Google App Engine &#8211; Part 1: A Case Study</title>
		<link>http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-part-1-a-case-study/</link>
		<comments>http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-part-1-a-case-study/#comments</comments>
		<pubDate>Sun, 17 Oct 2010 22:08:57 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[GAE]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[App Engine]]></category>
		<category><![CDATA[Big Table]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[GAE/J]]></category>
		<category><![CDATA[Gaelyk]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[JDO]]></category>

		<guid isPermaLink="false">http://globalgateway.wordpress.com/?p=663</guid>
		<description><![CDATA[Soon after Google had announced App Engine for Java I started to play around with the platform. Despite the limitations that App Engine imposes on developers I really wanted to know what all the buzz is about. Not only did I want to deploy a useful, non-trivial application I also wanted to get a feel [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=globalgateway.wordpress.com&amp;blog=961442&amp;post=663&amp;subd=globalgateway&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Soon after Google had announced App Engine for Java I started to play around with the platform. Despite the limitations that App Engine imposes on developers I really wanted to know what all the buzz is about. Not only did I want to deploy a useful, non-trivial application I also wanted to get a feel for App Engine&#8217;s production readiness. Most of today&#8217;s developers are embracing (web) frameworks that help them to focus on implementing business logic. This might become an issue with App Engine for multiple reasons. Adding Megabytes of JAR files to your application increases the cold start up time. Furthermore, App Engine <a href="http://groups.google.com/group/google-appengine-java/web/will-it-play-in-app-engine">restricts the usage of certain specifications, technologies and frameworks</a>. Over the past two years I became a big fan of Groovy and Grails. Therefore, I wanted to leverage the ease of use of Grails to implement a solution on App Engine. All I needed to get started was the <a href="http://www.grails.org/plugin/app-engine">Grails App Engine plugin</a>. Even though I read about <a href="http://gaelyk.appspot.com/">Gaelyk</a> I wasn&#8217;t fully convinced that it would be able to provide me with all the functionality I needed to implement my application e.g. no support for taglibs or Sitemesh.</p>
<p><a href="http://www.favalike.com"><img src='http://www.favalike.com/images/logo.png' alt='Favalike' style="float:left;margin:0 10px 0 0;" /></a>To limit the amount of work I&#8217;d have to put into this experiment I chose to implement a online bookmark manager with limited functionality. The features I wanted to cover should also take advantage of some of the services provided by App Engine. My plan was to use the Mail service and the URL Fetch API to get a feel on how easy it is to use them.</p>
<ul>
<li>User registration and confirmation via email</li>
<li>User authenication</li>
<li>Management of bookmarks in folders per user</li>
<li>Tagging of bookmarks</li>
<li>Marking bookmarks as favorites</li>
<li>Automatic retrieval of URL meta data</li>
<li>Export of bookmarks as XML and HTML</li>
</ul>
<p>The final result became <a href="http://www.favalike.com/">Favalike</a> which uses Grails 1.3.1 and the App Engine plugin 0.8.10. The following postings will describe my experience and the challenges I had to face in detail.</p>
<p><b>More on this topic:</b></p>
<ul>
<li><a href="http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-part-2-project-setup/">Grails on Google App Engine &#8211; Part 2: Project Setup</a>
<li><a href="http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-part-3-persistence/">Grails on Google App Engine &#8211; Part 3: Persistence</a>
<li><a href="http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-%E2%80%93-part-4-third-party-libraries/">Grails on Google App Engine – Part 4: Third-Party Libraries</a>
<li><a href="http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-%E2%80%93-part-5-conclusion/">Grails on Google App Engine – Part 5: Conclusion</a>
</ul>
<br /> Tagged: <a href='http://globalgateway.wordpress.com/tag/app-engine/'>App Engine</a>, <a href='http://globalgateway.wordpress.com/tag/big-table/'>Big Table</a>, <a href='http://globalgateway.wordpress.com/tag/cloud/'>cloud</a>, <a href='http://globalgateway.wordpress.com/tag/gae/'>GAE</a>, <a href='http://globalgateway.wordpress.com/tag/gaej/'>GAE/J</a>, <a href='http://globalgateway.wordpress.com/tag/gaelyk/'>Gaelyk</a>, <a href='http://globalgateway.wordpress.com/tag/google/'>Google</a>, <a href='http://globalgateway.wordpress.com/tag/grails/'>Grails</a>, <a href='http://globalgateway.wordpress.com/tag/groovy/'>Groovy</a>, <a href='http://globalgateway.wordpress.com/tag/jdo/'>JDO</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/globalgateway.wordpress.com/663/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/globalgateway.wordpress.com/663/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/globalgateway.wordpress.com/663/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/globalgateway.wordpress.com/663/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/globalgateway.wordpress.com/663/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/globalgateway.wordpress.com/663/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/globalgateway.wordpress.com/663/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/globalgateway.wordpress.com/663/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/globalgateway.wordpress.com/663/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/globalgateway.wordpress.com/663/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/globalgateway.wordpress.com/663/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/globalgateway.wordpress.com/663/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/globalgateway.wordpress.com/663/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/globalgateway.wordpress.com/663/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=globalgateway.wordpress.com&amp;blog=961442&amp;post=663&amp;subd=globalgateway&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://globalgateway.wordpress.com/2010/10/17/grails-on-google-app-engine-part-1-a-case-study/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8f2248c6bfcc6df39a2cd8edf4267cb5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Ben</media:title>
		</media:content>

		<media:content url="http://www.favalike.com/images/logo.png" medium="image">
			<media:title type="html">Favalike</media:title>
		</media:content>
	</item>
		<item>
		<title>Configuring Solr 1.4 logging with Log4J in Tomcat</title>
		<link>http://globalgateway.wordpress.com/2010/01/06/configuring-solr-1-4-logging-with-log4j-in-tomcat/</link>
		<comments>http://globalgateway.wordpress.com/2010/01/06/configuring-solr-1-4-logging-with-log4j-in-tomcat/#comments</comments>
		<pubDate>Thu, 07 Jan 2010 02:15:26 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Search]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Log4J]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[Solr]]></category>
		<category><![CDATA[Tomcat]]></category>

		<guid isPermaLink="false">http://globalgateway.wordpress.com/?p=633</guid>
		<description><![CDATA[Solr 1.4 logging is based on the &#8220;SLF4J&#8221; API. To configure Solr to use Log4J as standard logging implementation deploy the Solr web application to your Tomcat. Once the Solr web application got started add the libraries &#8220;slf4j-log4j12-1.5.5.jar&#8221; and &#8220;log4j-1.2.15.jar&#8221; to $CATALINA_HOME/webapps/solr/WEB-INF/lib. Delete the library &#8220;slf4j-jdk14-1.5.5.jar&#8221; from $CATALINA_HOME/webapps/solr/WEB-INF/lib. Create the directory $CATALINA_HOME/webapps/solr/WEB-INF/classes and add the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=globalgateway.wordpress.com&amp;blog=961442&amp;post=633&amp;subd=globalgateway&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://wiki.apache.org/solr/SolrLogging">Solr 1.4 logging</a> is based on the <a href="http://www.slf4j.org/">&#8220;SLF4J&#8221; API</a>. To configure Solr to use Log4J as standard logging implementation deploy the Solr web application to your Tomcat. Once the Solr web application got started add the libraries &#8220;slf4j-log4j12-1.5.5.jar&#8221; and &#8220;log4j-1.2.15.jar&#8221; to <code>$CATALINA_HOME/webapps/solr/WEB-INF/lib</code>. Delete the library &#8220;slf4j-jdk14-1.5.5.jar&#8221; from <code>$CATALINA_HOME/webapps/solr/WEB-INF/lib</code>.</p>
<p>Create the directory <code>$CATALINA_HOME/webapps/solr/WEB-INF/classes</code> and add the file <code>log4j.properties</code>. The file should hold your Log4J configuration. Here&#8217;s an example using a rolling log file:</p>
<p><pre class="brush: plain;">
log4j.rootLogger=ERROR, logfile

log4j.appender.logfile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.logfile.File=${catalina.home}/logs/solr.log

log4j.appender.logfile.DatePattern='.'yyyy-MM-dd
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c{3}] - [%t] - %X{ip}: %m%n
</pre></p>
<p>Alternatively, you can prepare your Solr web application WAR file to reflect the steps mentioned above. The Solr logging page (<code>http://&lt;host&gt;:&lt;port&gt;/solr/admin/logging</code>) that comes with the web app will not reflect these changes. It only works for JDK logging that we just configured not to be used anymore. The Tomcat instance has to be restarted to reflect the changes.</p>
<br /> Tagged: Log4J, logging, Solr, Tomcat <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/globalgateway.wordpress.com/633/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/globalgateway.wordpress.com/633/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/globalgateway.wordpress.com/633/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/globalgateway.wordpress.com/633/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/globalgateway.wordpress.com/633/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/globalgateway.wordpress.com/633/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/globalgateway.wordpress.com/633/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/globalgateway.wordpress.com/633/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/globalgateway.wordpress.com/633/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/globalgateway.wordpress.com/633/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/globalgateway.wordpress.com/633/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/globalgateway.wordpress.com/633/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/globalgateway.wordpress.com/633/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/globalgateway.wordpress.com/633/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=globalgateway.wordpress.com&amp;blog=961442&amp;post=633&amp;subd=globalgateway&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://globalgateway.wordpress.com/2010/01/06/configuring-solr-1-4-logging-with-log4j-in-tomcat/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8f2248c6bfcc6df39a2cd8edf4267cb5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Ben</media:title>
		</media:content>
	</item>
		<item>
		<title>Reusable, centralized AJAX component based on jQuery</title>
		<link>http://globalgateway.wordpress.com/2010/01/05/reusable-centralized-ajax-component-based-on-jquery/</link>
		<comments>http://globalgateway.wordpress.com/2010/01/05/reusable-centralized-ajax-component-based-on-jquery/#comments</comments>
		<pubDate>Wed, 06 Jan 2010 01:05:13 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[callback]]></category>
		<category><![CDATA[design pattern]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[JS]]></category>
		<category><![CDATA[reusability]]></category>

		<guid isPermaLink="false">http://globalgateway.wordpress.com/?p=601</guid>
		<description><![CDATA[When working on applications that use JavaScript you want to apply good practices like design patterns also on the client-side. Often times you&#8217;ll find yourself using the same piece of code over and over again but slightly changing parts of it. Sometimes you even want to have a centralized functionality you want to reuse across [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=globalgateway.wordpress.com&amp;blog=961442&amp;post=601&amp;subd=globalgateway&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>When working on applications that use JavaScript you want to apply good practices like design patterns also on the client-side. Often times you&#8217;ll find yourself using the same piece of code over and over again but slightly changing parts of it. Sometimes you even want to have a centralized functionality you want to reuse across your application.</p>
<p>If your application makes AJAX calls to your server-side components <a href="http://docs.jquery.com/Ajax">jQuery&#8217;s AJAX implementation</a> comes in handy. Usually you want to handle at least the successful and erroneous response of that call. Today&#8217;s web applications (like <a href="http://www.gmail.com">Gmail</a>) based on a lot of AJAX calls display a &#8220;busy/loading&#8221; indicator like a <a href="http://www.ajaxload.info/">spinner</a> or some text.</p>
<p>JavaScript supports the Factory pattern (see the book <a href="http://www.apress.com/book/view/159059908x">&#8220;Pro JavaScript Design Patterns&#8221;</a>) which lets you create an implementation with the <code>new</code> keyword. The nice thing about it is that you can even create multiple implementations that handle your HTTP calls differently. The methods are being added over the the class&#8217;s <a href="http://mckoss.com/jscript/object.htm">prototype object</a>. Below you&#8217;ll find an implementation for making AJAX calls using jQuery. For each GET or POST call you pass in a callback variable. The callback variable defines how to handle the response.</p>
<p><strong>ajax.js:</strong></p>
<p><pre class="brush: jscript;">
var AjaxHttpSender = function() {};

AjaxHttpSender.prototype.sendGet = function(url, callback) {
   $.ajax({
      url: url,
      type: 'GET',
      beforeSend: function() {
         onStartAjaxRequest();
      },
      error: function(XMLHttpRequest, textStatus, errorThrown) {
         callback.failure(XMLHttpRequest, textStatus, errorThrown);
      },
      success: function(data, textStatus) {
         callback.success(data, textStatus);
      },
      complete: function (XMLHttpRequest, textStatus) {
         onEndAjaxRequest();
      }
   });
}

AjaxHttpSender.prototype.sendPost = function(url, data, callback) {
   $.ajax({
      url: url,
      type: 'POST',
      data: data,
      beforeSend: function() {
         onStartAjaxRequest();
      },
      error: function(XMLHttpRequest, textStatus, errorThrown) { 
         callback.failure(XMLHttpRequest, textStatus, errorThrown);
      },
      success: function(data, textStatus) {
         callback.success(data, textStatus);
      },
      complete: function (XMLHttpRequest, textStatus) {
         onEndAjaxRequest();
      }
   });
}

function onStartAjaxRequest() {
    // e.g. show spinner
}

function onEndAjaxRequest() {
    // e.g. hide spinner
}
</pre></p>
<p><strong>Usage Example:</strong></p>
<p><pre class="brush: jscript;">
&lt;script type=&quot;text/javascript&quot; src=&quot;js/jquery-1.3.2.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;js/ajax.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
   var callback = {
      success: function(data, textStatus) {
         $('#content').html(data);
      },
      failure: function(XMLHttpRequest, textStatus, errorThrown) {
         alert('Error making AJAX call: ' + XMLHttpRequest.statusText + ' (' + XMLHttpRequest.status + ')');
      }
   }

   function makeAjaxCall() {
      var ajaxHttpSender = new AjaxHttpSender();
      ajaxHttpSender.sendGet(url, callback);
   }
&lt;/script&gt;
</pre></p>
<br /> Tagged: AJAX, callback, design pattern, HTTP, JavaScript, jQuery, JS, reusability <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/globalgateway.wordpress.com/601/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/globalgateway.wordpress.com/601/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/globalgateway.wordpress.com/601/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/globalgateway.wordpress.com/601/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/globalgateway.wordpress.com/601/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/globalgateway.wordpress.com/601/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/globalgateway.wordpress.com/601/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/globalgateway.wordpress.com/601/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/globalgateway.wordpress.com/601/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/globalgateway.wordpress.com/601/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/globalgateway.wordpress.com/601/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/globalgateway.wordpress.com/601/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/globalgateway.wordpress.com/601/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/globalgateway.wordpress.com/601/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=globalgateway.wordpress.com&amp;blog=961442&amp;post=601&amp;subd=globalgateway&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://globalgateway.wordpress.com/2010/01/05/reusable-centralized-ajax-component-based-on-jquery/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8f2248c6bfcc6df39a2cd8edf4267cb5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Ben</media:title>
		</media:content>
	</item>
		<item>
		<title>Country Roads</title>
		<link>http://globalgateway.wordpress.com/2009/09/29/country-roads/</link>
		<comments>http://globalgateway.wordpress.com/2009/09/29/country-roads/#comments</comments>
		<pubDate>Tue, 29 Sep 2009 23:22:14 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Over There]]></category>
		<category><![CDATA[Sightseeing]]></category>
		<category><![CDATA[Blue Ridge Mountains]]></category>
		<category><![CDATA[Country]]></category>
		<category><![CDATA[Shenandoah]]></category>
		<category><![CDATA[Skyline Drive]]></category>
		<category><![CDATA[Virginia]]></category>

		<guid isPermaLink="false">http://globalgateway.wordpress.com/?p=553</guid>
		<description><![CDATA[I wanted to do this for a long time: explore Shenandoah National Park. One way to do it is to take a ride on Skyline Drive. For a full experience you actually would have to camp there but some friends and I decided to make a day trip. We definitely planned to go camping but [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=globalgateway.wordpress.com&amp;blog=961442&amp;post=553&amp;subd=globalgateway&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href='http://globalgateway.files.wordpress.com/2009/09/mountain_view.jpg'><img src="http://globalgateway.files.wordpress.com/2009/09/mountain_view.jpg?w=112&#038;h=150" alt="Mountain View" title="Mountain View" width="112" height="150" style="float:left;margin:0 10px 0 0;" /></a>I wanted to do this for a long time: explore <a href="http://www.nps.gov/shen/index.htm">Shenandoah National Park</a>. One way to do it is to take a ride on <a href="http://www.nps.gov/shen/planyourvisit/driving-skyline-drive.htm">Skyline Drive</a>. For a full experience you actually would have to camp there but some friends and I decided to make a day trip. We definitely planned to go camping but August still was to humid to do this. Beware of the mosquitos. They can drive you crazy. We could only get rid of them after turning on a smoky fire.</p>
<p>The park is perfect for hiking up the mountains to catch breathtaking views of the area. There are multiple paths you can follow. From beginner to expert you should find a trail that suits you well. The park has much more to offer than you can cover in one day. Someday I&#8217;ll drive the whole 105 miles of the Skyline Drive. A camping trip is already in planning.</p>
<p><a href="http://globalgateway.files.wordpress.com/2009/09/valley_view.jpg"><img src="http://globalgateway.files.wordpress.com/2009/09/valley_view.jpg?w=150&#038;h=112" alt="" width="150" height="112" class="alignnone size-thumbnail wp-image-558" /></a>&nbsp;&nbsp;&nbsp;<a href="http://globalgateway.files.wordpress.com/2009/09/shenandoah_valley.jpg"><img src="http://globalgateway.files.wordpress.com/2009/09/shenandoah_valley.jpg?w=150&#038;h=112" alt="Shenandoah Valley" title="Shenandoah Valley" width="150" height="112" class="alignnone size-thumbnail wp-image-558" /></a>&nbsp;&nbsp;&nbsp;<a href="http://globalgateway.files.wordpress.com/2009/09/relaxation_with_a_view.jpg"><img src="http://globalgateway.files.wordpress.com/2009/09/relaxation_with_a_view.jpg?w=150&#038;h=112" alt="Relaxation with a View" title="Relaxation with a View" width="150" height="112" class="alignnone size-thumbnail wp-image-558" /></a></p>
<br /> Tagged: Blue Ridge Mountains, Country, Shenandoah, Skyline Drive, Virginia <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/globalgateway.wordpress.com/553/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/globalgateway.wordpress.com/553/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/globalgateway.wordpress.com/553/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/globalgateway.wordpress.com/553/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/globalgateway.wordpress.com/553/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/globalgateway.wordpress.com/553/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/globalgateway.wordpress.com/553/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/globalgateway.wordpress.com/553/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/globalgateway.wordpress.com/553/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/globalgateway.wordpress.com/553/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/globalgateway.wordpress.com/553/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/globalgateway.wordpress.com/553/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/globalgateway.wordpress.com/553/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/globalgateway.wordpress.com/553/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=globalgateway.wordpress.com&amp;blog=961442&amp;post=553&amp;subd=globalgateway&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://globalgateway.wordpress.com/2009/09/29/country-roads/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8f2248c6bfcc6df39a2cd8edf4267cb5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Ben</media:title>
		</media:content>

		<media:content url="http://globalgateway.files.wordpress.com/2009/09/mountain_view.jpg?w=112" medium="image">
			<media:title type="html">Mountain View</media:title>
		</media:content>

		<media:content url="http://globalgateway.files.wordpress.com/2009/09/valley_view.jpg?w=128" medium="image" />

		<media:content url="http://globalgateway.files.wordpress.com/2009/09/shenandoah_valley.jpg?w=128" medium="image">
			<media:title type="html">Shenandoah Valley</media:title>
		</media:content>

		<media:content url="http://globalgateway.files.wordpress.com/2009/09/relaxation_with_a_view.jpg?w=128" medium="image">
			<media:title type="html">Relaxation with a View</media:title>
		</media:content>
	</item>
		<item>
		<title>Left my Heart in San Francisco</title>
		<link>http://globalgateway.wordpress.com/2009/09/26/left-my-heart-in-san-francisco/</link>
		<comments>http://globalgateway.wordpress.com/2009/09/26/left-my-heart-in-san-francisco/#comments</comments>
		<pubDate>Sat, 26 Sep 2009 15:12:12 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Over There]]></category>
		<category><![CDATA[Sightseeing]]></category>
		<category><![CDATA[Alcatraz]]></category>
		<category><![CDATA[Cable Car]]></category>
		<category><![CDATA[Giradelli]]></category>
		<category><![CDATA[Golden Gate Bridge]]></category>
		<category><![CDATA[Nob Hill]]></category>
		<category><![CDATA[Pier 39]]></category>
		<category><![CDATA[San Francisco]]></category>

		<guid isPermaLink="false">http://globalgateway.wordpress.com/?p=524</guid>
		<description><![CDATA[It all started out good when our taxi driver asked us if we knew that we&#8217;re staying in a fancy hotel. We actually didn&#8217;t know that hotels on Nob Hill are supposed to be swanky. When we decided to go on a trip to San Francisco for a long weekend we found a good deal [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=globalgateway.wordpress.com&amp;blog=961442&amp;post=524&amp;subd=globalgateway&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>It all started out good when our taxi driver asked us if we knew that we&#8217;re staying in a fancy hotel. We actually didn&#8217;t know that hotels on <a href="http://en.wikipedia.org/wiki/Nob_Hill,_San_Francisco">Nob Hill</a> are supposed to be swanky. When we decided to go on a trip to San Francisco for a long weekend we found a good deal for a hotel that even had a spa. Well, we didn&#8217;t get disappointed. The hotel we stayed in, <a href="http://www.huntingtonhotel.com/">the Huntington</a>, feels like staying with your rich uncle with a great taste for interior design. Should you plan to stay there don&#8217;t miss out on the Espresso Martini in the hotel bar.</p>
<p>Knowing that we just have three days to explore the city we tried to pack as much sightseeing into our day as we could. A must is seeing the <a href="http://en.wikipedia.org/wiki/Golden_Gate_Bridge">Golden Gate Bridge</a>. Don&#8217;t forget to bring a sweater. It&#8217;s always kind of chilly. In this city weather can change fast. We decided to take the boat tour in the bay which also let us see <a href="http://en.wikipedia.org/wiki/Alcatraz_Island">Alcatraz</a>. We tried to avoid setting a foot on the island. There are masses of tourists and I don&#8217;t think you actually miss something. While being in the bay area we checked with <a href="http://www.ghirardellisq.com/ghirardellisq/index.htm">Giradelli</a>. They give out free samples in their store. Even though the samples are good I still think European chocolate tastes better. Don&#8217;t miss out on <a href="http://en.wikipedia.org/wiki/Lombard_Street_%28San_Francisco%29">Lombard Street</a>. Probably the funniest street I&#8217;ve ever seen.</p>
<p>Did I already tell you that I love San Francisco? This city really has flair. From great panorama views from up the hill to laid back people. This city is adorable. Personality is everywhere. People keep their architecture and culture intact and maintain it well. Apart from the hiking to get from point a to b it takes time to get around. After a while we actually decided to always take the taxi. <a href="http://en.wikipedia.org/wiki/San_Francisco_cable_car_system">Cable Cars</a> are definitely made to entertain tourists but are a rip off. You pay the same price for a ride with a taxi. Because we got so many recommendations from friends for good restaurants and bars we wanted to visit taxis are the way to go.</p>
<p>We got a good impression of San Francisco within three days. If prices for living wouldn&#8217;t be that high we would totally consider living there. Sarah and I will go there again. Next up: Making a tour to the wineries and exploring the surrounding area.</p>

<a href='http://globalgateway.wordpress.com/2009/09/26/left-my-heart-in-san-francisco/alcatraz/' title='Alcatraz'><img data-attachment-id='533' data-orig-size='600,450' data-liked='0'width="150" height="112" src="http://globalgateway.files.wordpress.com/2009/09/alcatraz.jpg?w=150&#038;h=112" class="attachment-thumbnail" alt="Alcatraz" title="Alcatraz" /></a>
<a href='http://globalgateway.wordpress.com/2009/09/26/left-my-heart-in-san-francisco/alcatraz_from_hill/' title='Alcatraz From Hill'><img data-attachment-id='534' data-orig-size='600,450' data-liked='0'width="150" height="112" src="http://globalgateway.files.wordpress.com/2009/09/alcatraz_from_hill.jpg?w=150&#038;h=112" class="attachment-thumbnail" alt="Alcatraz From Hill" title="Alcatraz From Hill" /></a>
<a href='http://globalgateway.wordpress.com/2009/09/26/left-my-heart-in-san-francisco/bay_area/' title='Bay Area'><img data-attachment-id='535' data-orig-size='600,450' data-liked='0'width="150" height="112" src="http://globalgateway.files.wordpress.com/2009/09/bay_area.jpg?w=150&#038;h=112" class="attachment-thumbnail" alt="Bay Area" title="Bay Area" /></a>
<a href='http://globalgateway.wordpress.com/2009/09/26/left-my-heart-in-san-francisco/giradelli_square/' title='Giradelli Square'><img data-attachment-id='536' data-orig-size='600,450' data-liked='0'width="150" height="112" src="http://globalgateway.files.wordpress.com/2009/09/giradelli_square.jpg?w=150&#038;h=112" class="attachment-thumbnail" alt="Giradelli Square" title="Giradelli Square" /></a>
<a href='http://globalgateway.wordpress.com/2009/09/26/left-my-heart-in-san-francisco/golden_gate_bridge/' title='Golden Gate Bridge'><img data-attachment-id='537' data-orig-size='600,450' data-liked='0'width="150" height="112" src="http://globalgateway.files.wordpress.com/2009/09/golden_gate_bridge.jpg?w=150&#038;h=112" class="attachment-thumbnail" alt="Golden Gate Bridge" title="Golden Gate Bridge" /></a>
<a href='http://globalgateway.wordpress.com/2009/09/26/left-my-heart-in-san-francisco/hill_view/' title='Hill View'><img data-attachment-id='538' data-orig-size='600,450' data-liked='0'width="150" height="112" src="http://globalgateway.files.wordpress.com/2009/09/hill_view.jpg?w=150&#038;h=112" class="attachment-thumbnail" alt="Hill View" title="Hill View" /></a>
<a href='http://globalgateway.wordpress.com/2009/09/26/left-my-heart-in-san-francisco/lombard_street/' title='Lombard Street'><img data-attachment-id='539' data-orig-size='450,600' data-liked='0'width="112" height="150" src="http://globalgateway.files.wordpress.com/2009/09/lombard_street.jpg?w=112&#038;h=150" class="attachment-thumbnail" alt="Lombard Street" title="Lombard Street" /></a>
<a href='http://globalgateway.wordpress.com/2009/09/26/left-my-heart-in-san-francisco/pier_39/' title='Pier 39'><img data-attachment-id='540' data-orig-size='600,450' data-liked='0'width="150" height="112" src="http://globalgateway.files.wordpress.com/2009/09/pier_39.jpg?w=150&#038;h=112" class="attachment-thumbnail" alt="Pier 39" title="Pier 39" /></a>
<a href='http://globalgateway.wordpress.com/2009/09/26/left-my-heart-in-san-francisco/san_francisco_street/' title='San Francisco Street View'><img data-attachment-id='541' data-orig-size='600,450' data-liked='0'width="150" height="112" src="http://globalgateway.files.wordpress.com/2009/09/san_francisco_street.jpg?w=150&#038;h=112" class="attachment-thumbnail" alt="San Francisco Street View" title="San Francisco Street View" /></a>

<br /> Tagged: Alcatraz, Cable Car, Giradelli, Golden Gate Bridge, Nob Hill, Pier 39, San Francisco <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/globalgateway.wordpress.com/524/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/globalgateway.wordpress.com/524/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/globalgateway.wordpress.com/524/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/globalgateway.wordpress.com/524/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/globalgateway.wordpress.com/524/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/globalgateway.wordpress.com/524/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/globalgateway.wordpress.com/524/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/globalgateway.wordpress.com/524/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/globalgateway.wordpress.com/524/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/globalgateway.wordpress.com/524/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/globalgateway.wordpress.com/524/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/globalgateway.wordpress.com/524/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/globalgateway.wordpress.com/524/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/globalgateway.wordpress.com/524/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=globalgateway.wordpress.com&amp;blog=961442&amp;post=524&amp;subd=globalgateway&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://globalgateway.wordpress.com/2009/09/26/left-my-heart-in-san-francisco/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/8f2248c6bfcc6df39a2cd8edf4267cb5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Ben</media:title>
		</media:content>

		<media:content url="http://globalgateway.files.wordpress.com/2009/09/alcatraz.jpg?w=150" medium="image">
			<media:title type="html">Alcatraz</media:title>
		</media:content>

		<media:content url="http://globalgateway.files.wordpress.com/2009/09/alcatraz_from_hill.jpg?w=150" medium="image">
			<media:title type="html">Alcatraz From Hill</media:title>
		</media:content>

		<media:content url="http://globalgateway.files.wordpress.com/2009/09/bay_area.jpg?w=150" medium="image">
			<media:title type="html">Bay Area</media:title>
		</media:content>

		<media:content url="http://globalgateway.files.wordpress.com/2009/09/giradelli_square.jpg?w=150" medium="image">
			<media:title type="html">Giradelli Square</media:title>
		</media:content>

		<media:content url="http://globalgateway.files.wordpress.com/2009/09/golden_gate_bridge.jpg?w=150" medium="image">
			<media:title type="html">Golden Gate Bridge</media:title>
		</media:content>

		<media:content url="http://globalgateway.files.wordpress.com/2009/09/hill_view.jpg?w=150" medium="image">
			<media:title type="html">Hill View</media:title>
		</media:content>

		<media:content url="http://globalgateway.files.wordpress.com/2009/09/lombard_street.jpg?w=112" medium="image">
			<media:title type="html">Lombard Street</media:title>
		</media:content>

		<media:content url="http://globalgateway.files.wordpress.com/2009/09/pier_39.jpg?w=150" medium="image">
			<media:title type="html">Pier 39</media:title>
		</media:content>

		<media:content url="http://globalgateway.files.wordpress.com/2009/09/san_francisco_street.jpg?w=150" medium="image">
			<media:title type="html">San Francisco Street View</media:title>
		</media:content>
	</item>
	</channel>
</rss>
