<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" gd:etag="W/&quot;CkcAR3o_fSp7ImA9WhRaFEg.&quot;"><id>tag:blogger.com,1999:blog-4109835711556836944</id><updated>2012-02-16T19:40:46.445-08:00</updated><title>Gabe's Groove</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://gabe97330.begeddov.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://gabe97330.begeddov.com/" /><author><name>Gabe Beged-Dov</name><uri>http://www.blogger.com/profile/09946138594619738523</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="26" src="http://2.bp.blogspot.com/-KWt_QUB8ZHs/TdBO6PQ_A1I/AAAAAAAAAqQ/lsJJriFzCp4/s220/fb_profile.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>2</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/GabesGroove" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="gabesgroove" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;C0MHQ3g4cCp7ImA9WxBTFUg.&quot;"><id>tag:blogger.com,1999:blog-4109835711556836944.post-6052996094918742414</id><published>2009-12-08T09:02:00.000-08:00</published><updated>2009-12-11T09:10:32.638-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-11T09:10:32.638-08:00</app:edited><title>Morning musings on Grails and Cloud Foundry deployment</title><content type="html">&lt;p&gt;
    One pain point I have with doing agile cloud development with Java is the overhead of re-deploying the app to the cloud.
    The
    default model is to re-deploy the entire WAR (or EAR) to the cloud after every change. This isn't that bad when the
    app server you are deploying to is nearby although even there you often end up doing a more efficient in-place
    update using an exploded WAR. It is pretty miserable though when you have a humongous lib directory making up the
    lion's share of your app footprint and it can take time and money (in bandwidth costs) to upload the entire app
    after a change which may involve only a few classes that are 10s of K in size rather than 10s of MB.
&lt;/p&gt;
&lt;p&gt;
    I am using &lt;a href="http://www.cloudfoundry.com/"&gt;Cloud Foundry&lt;/a&gt; as my default cloud deployment platform and while
    its currently free, the underlying platform, EC2 is not. The overhead of re-deploying a 40+ MB app usually runs to
    around a sec/MB for the upload and then 10-20 seconds for the app restart. This means at least 1 to 2 minutes per
    re-deploy. Cloud Foundry (and the underlying SpringSource tool chain) have some optimizations (existing or planned)
    that can cut this down such as:&lt;/p&gt;
    &lt;ul&gt;
    &lt;li&gt;
     &lt;b&gt;CloudFoundry shared Libs&lt;/b&gt;: You can upload a single archive file (tar, zip) as part of your application
        specification and this will be unpacked in the app server shared libs directory. I tried to use this initially
        but gave up after running into many classpath and shared state errors in the logging and GSP libraries. I may
        revisit this when I start using tc server rather than stock tomcat in my local environment. The reason being
        that the shared lib errors may be specific to tc server since I don't have a problem with them when using stock
        tomcat in my local environment.
    &lt;/li&gt;
    &lt;li&gt;
     &lt;a href="http://static.springsource.com/projects/dm-server/1.0.x/programmer-guide/html/ch04.html#architecture-shared-libraries-war"&gt;
        &lt;b&gt;shared-libraries-war&lt;/b&gt;:
    &lt;/a&gt; This feature is available for apps that are deployed to &lt;a href="http://www.springsource.com/products/dmserver"&gt;SpringSource's DM server&lt;/a&gt; (their packaging of an OSGi
        server). AFAIK, this is not yet available and its not clear how you would indicate what parts of your app should be
        included in the shared vs app-specific modules that make up the
        &lt;a href="http://static.springsource.com/projects/dm-server/1.0.x/programmer-guide/html/ch04.html#architecture-pars"&gt;PAR&lt;/a&gt;.
    &lt;/li&gt;
    &lt;li&gt;
        &lt;b&gt;Standard JAR stripping&lt;/b&gt;: There are multiple mentions of the ability of SpringSource tools
        (see &lt;a href="http://blog.springsource.com/2009/12/02/obtaining-spring-3-artifacts-with-maven/"&gt;spring-3-with-maven&lt;/a&gt;
         for an example) to strip standard JAR from the WAR on the client-side and then "re-constitute" them on the
        server-side. I haven't seen this work in practice as the entire WAR is uploaded AFAICT based on the fact that
        there is no noticeable reduction in the upload time. Even if it does work, the standard JAR make up only a
        subset (often less than a quarter) of the app footprint and the ideal solution would strip all the JAR leaving
        the equivalent of the "nojars" option of the &lt;a href="http://grails.org/doc/latest/ref/Command%20Line/war.html"&gt;Grails war&lt;/a&gt;
        command. I'm also not clear on whether standard JAR equate to libraries that are part of the
        &lt;a href="http://www.springsource.com/repository/app/"&gt;Enterprise Bundle Repository (EBR)&lt;/a&gt; or whether they
        equate the to broader &lt;a href="http://svn.grails.codehaus.org/browse/~raw,r=8877/grails/trunk/grails/dependencies.txt"&gt;set of libraries&lt;/a&gt;
        that are part of the Grails distribution.
    &lt;/li&gt;
    &lt;/ul&gt;
&lt;p&gt;I'm wondering what, if any issues there would be with extending Cloud Foundry to have the concept of a "nojars" redeploy.
    The idea would be that if the app signalled that it wanted to do a "nojars" redeploy, Cloud Foundry would run the
    Grails war command with the "nojars" option, upload the WAR to S3 and then to the instance(s) and update the app on the server
    in a way that keeps all of the JAR from the initial deploy. I don't see any obvious gotchas and this would avoid
    all of the sticky issues with shared libs. Ideally, you could even have the option of doing a lighter weight redploy
    which is currently really a restart of the app server.
    &lt;/p&gt;
&lt;p&gt;Another more general approach could be extending Cloud Foundry to fire Grails events at relevant points.
    To make this really work, there would have to be both client-side and server-side events and more work on defining
    the server side event model. In this model, you might have events like DeployOnClientStart, DeployOnServerStart, RedployOnClientStart,
    RedployOnServerStart and these would be defined similar to CreateWarStart and CreateWarEnd. On the server-side,
    Cloud Foundry would need to be extended to set up the execution environment and fire the events. There is likely an
    existing alternative way to do server-side deployment scripting that I am not aware of. If not or if a more Graily
    way makes sense, then maybe this could be considered?
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4109835711556836944-6052996094918742414?l=gabe97330.begeddov.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://gabe97330.begeddov.com/feeds/6052996094918742414/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4109835711556836944&amp;postID=6052996094918742414" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4109835711556836944/posts/default/6052996094918742414?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4109835711556836944/posts/default/6052996094918742414?v=2" /><link rel="alternate" type="text/html" href="http://gabe97330.begeddov.com/2009/12/morning-musings-on-grails-and-cloud.html" title="Morning musings on Grails and Cloud Foundry deployment" /><author><name>Gabe Beged-Dov</name><uri>http://www.blogger.com/profile/09946138594619738523</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="26" src="http://2.bp.blogspot.com/-KWt_QUB8ZHs/TdBO6PQ_A1I/AAAAAAAAAqQ/lsJJriFzCp4/s220/fb_profile.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CUYHQ3c4fip7ImA9WxBTEUo.&quot;"><id>tag:blogger.com,1999:blog-4109835711556836944.post-4322913517747238106</id><published>2009-12-06T21:49:00.000-08:00</published><updated>2009-12-07T00:05:32.936-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-07T00:05:32.936-08:00</app:edited><title>Types of Plugins based on level of integration in Grails</title><content type="html">Some quick notes on distinctions between Grails plugins. One useful cut is by how integrated the plugin is into Grails. There are the following levels of integration that I see from most to least integrated:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;b&gt;Internal Core plugin&lt;/b&gt;: this type is part of the Grails core build. Loaded statically at startup by &lt;a href="http://www.google.com/codesearch/p?hl=en#BExOlTNH8oU/grails/src/commons/org/codehaus/groovy/grails/plugins/CorePluginFinder.java&amp;q=loadcorepluginsstatically&amp;sa=N&amp;cd=1&amp;ct=rc"&gt;CorePluginFinder&lt;/a&gt; 
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;External Core plugin&lt;/b&gt;: maintained as part of the Grails distribution but installed using scripts and opt-in. See &lt;a href="http://svn.codehaus.org/grails/trunk/grails-plugins/"&gt;Grails plugins&lt;/a&gt; for list.
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Supported plugins&lt;/b&gt;: Superset of the external core plugins that is maintained by &lt;a href="http://www.grails.org/plugin/category/supported"&gt;SpringSource&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Central repository plugins&lt;/b&gt;: grab-bag of plugins that are maintained according to a loose set of conventions and accessed via a &lt;a href="http://svn.codehaus.org/grails-plugins/.plugin-meta/plugins-list.xml"&gt;list&lt;/a&gt; at Grails.org&lt;/li&gt;
&lt;li&gt;&lt;b&gt;User repository plugins&lt;/b&gt;: plugins that are accessed via a &lt;a href="http://www.grails.org/doc/1.2.0.RC1/guide/12.%20Plug-ins.html#12.2%20Plugin%20Repositories"&gt;user repository&lt;/a&gt; specified in BuildConfig.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Local plugins&lt;/b&gt;: plugins that are accessed using "grails.plugin.location"&lt;/li&gt;  
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4109835711556836944-4322913517747238106?l=gabe97330.begeddov.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://gabe97330.begeddov.com/feeds/4322913517747238106/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4109835711556836944&amp;postID=4322913517747238106" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4109835711556836944/posts/default/4322913517747238106?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4109835711556836944/posts/default/4322913517747238106?v=2" /><link rel="alternate" type="text/html" href="http://gabe97330.begeddov.com/2009/12/types-of-plugins-based-on-level-of.html" title="Types of Plugins based on level of integration in Grails" /><author><name>Gabe Beged-Dov</name><uri>http://www.blogger.com/profile/09946138594619738523</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="26" src="http://2.bp.blogspot.com/-KWt_QUB8ZHs/TdBO6PQ_A1I/AAAAAAAAAqQ/lsJJriFzCp4/s220/fb_profile.jpg" /></author><thr:total>0</thr:total></entry></feed>

