<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-224320715137455380</id><updated>2024-10-25T00:05:58.158+03:00</updated><category term="Example"/><category term="Front End"/><category term="java"/><category term="Free"/><category term="GWT"/><category term="Source Code"/><category term="Github"/><category term="Javascript"/><category term="Chrome"/><category term="Extension"/><category term="Performance"/><category term="Android"/><category term="Build"/><category term="Game"/><category term="HTML5"/><category term="React"/><category term="Rich Client"/><category term="Spring"/><category term="Book"/><category term="C/C++"/><category term="Debug"/><category term="Flux"/><category term="Fun"/><category term="MVC"/><category term="NDK"/><category term="Node"/><category term="Profiling"/><category term="ReactJS"/><category term="Ant"/><category term="App"/><category term="CPU"/><category term="Carbon Dioxide"/><category term="Closure"/><category term="Comparison"/><category term="DI"/><category term="DOM"/><category term="Dependency Injection"/><category term="Design"/><category term="ES6"/><category term="Emission"/><category term="Energy"/><category term="FlowPanel"/><category term="Gradle"/><category term="Groovy"/><category term="Grunt"/><category term="Guice"/><category term="HorizontalPanel"/><category term="Hubot"/><category term="JPA Hibernate H2 HSQLDB Junit"/><category term="JSONP"/><category term="Kilowatt"/><category term="Linux"/><category term="MVP"/><category term="Memory Model"/><category term="MobX"/><category term="NPM"/><category term="Plugin"/><category term="RAD"/><category term="REST"/><category term="RPM"/><category term="React Templates"/><category term="SHA"/><category term="Sass"/><category term="Script"/><category term="Server"/><category term="Slack"/><category term="Space"/><category term="Spaceship"/><category term="Spaceship X"/><category term="Spring ROO"/><category term="Swing"/><category term="Test"/><category term="Testing"/><category term="Typescript"/><category term="Ubuntu"/><category term="Users"/><category term="VCS"/><category term="VerticalPanel"/><category term="Watt"/><category term="Webpack"/><category term="encryption"/><category term="environment"/><category term="functions"/><category term="jQuery"/><category term="password"/><category term="review"/><title type='text'>Tech Drum - Nir&#39;s Tech blog</title><subtitle type='html'>Code code code</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://tech-drum.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://tech-drum.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Nir Moav</name><uri>http://www.blogger.com/profile/05879703892878058262</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>26</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-224320715137455380.post-7980437036000056867</id><published>2017-05-19T18:29:00.001+03:00</published><updated>2017-05-19T18:29:04.440+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ES6"/><category scheme="http://www.blogger.com/atom/ns#" term="Example"/><category scheme="http://www.blogger.com/atom/ns#" term="Flux"/><category scheme="http://www.blogger.com/atom/ns#" term="Front End"/><category scheme="http://www.blogger.com/atom/ns#" term="Javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="MobX"/><category scheme="http://www.blogger.com/atom/ns#" term="React"/><category scheme="http://www.blogger.com/atom/ns#" term="Source Code"/><title type='text'>React + MobX - 101 Todo App for beginners - Part 1</title><content type='html'>&lt;div class=&quot;p1&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif;&quot;&gt;This walk-through-tutorial (yet another) is to guide you through the usage of the &lt;a href=&quot;https://mobx.js.org/&quot; target=&quot;_blank&quot;&gt;MobX&lt;/a&gt; library, while building a React application.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif;&quot;&gt;The application we&#39;ll build is a simple Todo App.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEih5-a6tP-f6MsYqC3xxvV0Ns-SD_FVH4hnD1MySwZUdsBUUJ6CoxRB1XiZeRWgUmF2qis272rzrmzpBQSMK_9uJIbp5QA_mj8111V9gg_a3sDX9ATYHNiTgH5yhGyluwkiSpWg8wvQvpdS/s1600/Screen+Shot+2017-05-06+at+10.26.52+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEih5-a6tP-f6MsYqC3xxvV0Ns-SD_FVH4hnD1MySwZUdsBUUJ6CoxRB1XiZeRWgUmF2qis272rzrmzpBQSMK_9uJIbp5QA_mj8111V9gg_a3sDX9ATYHNiTgH5yhGyluwkiSpWg8wvQvpdS/s320/Screen+Shot+2017-05-06+at+10.26.52+PM.png&quot; width=&quot;312&quot; /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;b&gt;&lt;u&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif; font-size: large;&quot;&gt;The post discusses the following topics:&lt;/span&gt;&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;
&lt;style type=&quot;text/css&quot;&gt;
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px &#39;Helvetica Neue&#39;; -webkit-text-stroke: #000000}
li.li1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px &#39;Helvetica Neue&#39;; -webkit-text-stroke: #000000}
span.s1 {text-decoration: underline ; font-kerning: none}
span.s2 {font-kerning: none}
ol.ol1 {list-style-type: decimal}
ol.ol2 {list-style-type: lower-alpha}

.code-block {
background: #eeeeee;
color: #000000;
padding: 5px;
border: 1px solid #000000;
font-weight: bold;
}
&lt;/style&gt;



&lt;br /&gt;
&lt;ol class=&quot;ol1&quot;&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif;&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;span class=&quot;s2&quot;&gt;&lt;b&gt;What is MobX&lt;/b&gt; - A very short explanation about what MobX is.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif;&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;span class=&quot;s2&quot;&gt;&lt;b&gt;Why do you need it? &lt;/b&gt;-&lt;b&gt; &lt;/b&gt;Reasons to consider using MobX.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif;&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;span class=&quot;s2&quot;&gt;&lt;b&gt;Why not Redux (another state management library)?&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class=&quot;li1&quot;&gt;&lt;span class=&quot;s2&quot; style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif;&quot;&gt;&lt;b&gt;Code tutorial - Part 1 (out of 2)&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
&lt;h2&gt;
&lt;b style=&quot;font-family: Times, &amp;quot;Times New Roman&amp;quot;, serif; font-size: x-large;&quot;&gt;&lt;u&gt;What is MobX -&amp;nbsp;&lt;/u&gt;&lt;/b&gt;&lt;u style=&quot;font-family: Times, &amp;quot;Times New Roman&amp;quot;, serif; font-size: x-large;&quot;&gt;&lt;a href=&quot;https://mobx.js.org/&quot; target=&quot;_blank&quot;&gt;https://mobx.js.org/&lt;/a&gt;&lt;/u&gt;&lt;/h2&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;u&gt;In short&lt;/u&gt;&lt;/b&gt; - MobX is a state management library.&lt;/div&gt;
&lt;br /&gt;&lt;b&gt;&lt;u&gt;In &quot;long&quot;&lt;/u&gt;&lt;/b&gt; - MobX is a JS library that allows you to define &quot;observable&quot; state (/model/your JS Objects) containing your App information.&lt;br /&gt;&lt;br /&gt;The library gives you the power to derive any computed model that depends on observables automatically!&lt;br /&gt;&lt;u&gt;&lt;i&gt;As MobX puts it&lt;/i&gt;&lt;/u&gt;: &lt;br /&gt;&lt;blockquote class=&quot;tr_bq&quot;&gt;
Anything that can be derived from the application state, should be derived. Automatically&lt;/blockquote&gt;
&lt;b&gt;&lt;u&gt;In aspect to React:&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;This gives you the power to mutate the state directly by reference from your components without calling React&#39;s setState, and triggering render only on the components that need to be re-rendered.&lt;br /&gt;&lt;br /&gt;Pretty nifty.&lt;br /&gt;&lt;br /&gt;For more about MobX: &lt;a href=&quot;https://mobx.js.org/&quot;&gt;https://mobx.js.org/&lt;/a&gt;&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;helvetica neue&amp;quot;;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;h2&gt;
&lt;span style=&quot;font-family: &amp;quot;helvetica neue&amp;quot;;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif; font-size: large;&quot;&gt;&lt;b&gt;&lt;u&gt;Why do you need it?&lt;/u&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;/div&gt;
&lt;div&gt;
First of all, no one said you should use it. &lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif;&quot;&gt;There are plenty React based applications that work just fine without MobX.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif;&quot;&gt;However, you should consider MobX for the following reasons, that may give you some advantage.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif;&quot;&gt;&lt;u&gt;For instance:&lt;/u&gt;&lt;/span&gt;&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif;&quot;&gt;&lt;b&gt;Simpler Components&lt;/b&gt; - Having a shared state in your App between several components can be cumbersome to share, especially if one component is deeply nested in another component that uses same data.&lt;br /&gt;It would mean, that you&#39;d need to pass to all the children of the top-most component that state, resulting many components that are on the way passing on that same state, but never using it.&lt;br /&gt;Components that change state to other components, the state of your application distributed among many components, and other complications.&lt;br /&gt;With MobX, you can specify for each component the exact &lt;i&gt;props&lt;/i&gt;&amp;nbsp;it should use.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif;&quot;&gt;&lt;b&gt;Organized state model&lt;/b&gt; - Your application state with MobX is mostly organized in one or few objects that hold only the state of your application. That makes it easy to reason about the application&#39;s model.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif;&quot;&gt;&lt;b&gt;Optimized App&lt;/b&gt; - render only components that need to render instead of&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
That sounds like I&#39;m trying to &quot;sell&quot; you MobX.&lt;br /&gt;I find it to be a good library for state management (not saying it&#39;s the only, check &lt;a href=&quot;http://redux.js.org/&quot;&gt;Redux&lt;/a&gt; too), despite the &quot;magic&quot; which I dislike in principal in software, and the awkward feeling I get when this reminds me of &quot;two-way-data-binding&quot; stuff (which the industry has a love-hate relationship since the ages of JavaFX, Flex, and probably even earlier libraries and frameworks).&lt;br /&gt;&lt;br /&gt; It comes with a small cost of adding a library to your App, and learning how to use it.&lt;br /&gt;If you have a small application, with a very simple model, you might not even need it.&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;helvetica neue&amp;quot;;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif; font-size: 12px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;

&lt;br /&gt;
&lt;h2&gt;
&lt;span style=&quot;font-family: &amp;quot;helvetica neue&amp;quot;;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif; font-size: large;&quot;&gt;&lt;b&gt;&lt;u&gt;Why not Redux?&lt;/u&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
In case you don&#39;t know &lt;a href=&quot;http://redux.js.org/&quot;&gt;Redux&lt;/a&gt;, as mentioned on their site is: &lt;br /&gt;&lt;b&gt;&lt;i&gt;&quot;A predictable state container for JavaScript apps.&quot;&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;In other words - it&#39;s a state managing library, like MobX is. But different.&lt;br /&gt;The &quot;&lt;u&gt;what&lt;/u&gt;&quot; is similar, the &quot;&lt;u&gt;how&lt;/u&gt;&quot;, a bit different.&lt;br /&gt;&lt;br /&gt;&lt;u style=&quot;font-family: times, &amp;quot;times new roman&amp;quot;, serif;&quot;&gt;So first of all - why not use it instead?&amp;nbsp;&lt;/u&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;helvetica neue&amp;quot;;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif; font-size: 12px;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;There&#39;s really no good answer for that, and IMO it&#39;s a matter of personal style and what you&#39;re comfortable with. It does seem to have less &quot;&lt;i&gt;magic&lt;/i&gt;&quot; though.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;helvetica neue&amp;quot;;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif; font-size: 12px;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;(The &quot;&lt;i&gt;magic&lt;/i&gt;&quot;&lt;i&gt;&amp;nbsp;&lt;/i&gt;i refer to are the &lt;i&gt;observables&lt;/i&gt;&amp;nbsp;in MobX - this is where the MobX fun happens).&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;helvetica neue&amp;quot;;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif; font-size: 12px;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;helvetica neue&amp;quot;;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif; font-size: 12px;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;Some say that MobX is easier to get started with as there&#39;s less code to write.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;helvetica neue&amp;quot;;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif; font-size: 12px;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;It supports several (optional) “stores” vs one store in Redux which can be annoying if you already have an existing App and you need to start consolidating all your state to a single place.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;helvetica neue&amp;quot;;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif; font-size: 12px;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;It conforms to a non-FP paradigm, where your state can be mutable (the &lt;i&gt;observable &lt;/i&gt;objects in your state).&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;helvetica neue&amp;quot;;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif; font-size: 12px;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;br /&gt;In any case, I would advise to try &lt;a href=&quot;http://redux.js.org/&quot; target=&quot;_blank&quot;&gt;Redux&lt;/a&gt; before you make your decision.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;helvetica neue&amp;quot;;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif; font-size: 12px;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;helvetica neue&amp;quot;;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif; font-size: 12px;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;h2&gt;
&lt;span style=&quot;font-family: &amp;quot;helvetica neue&amp;quot;;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif; font-size: 12px;&quot;&gt;&lt;b style=&quot;font-size: x-large;&quot;&gt;&lt;u&gt;Code walk-through&lt;/u&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;span style=&quot;font-family: &amp;quot;helvetica neue&amp;quot;;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif; font-size: 12px;&quot;&gt;&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;
Lets get our hands dirty.&lt;br /&gt;
We&#39;re going to build the Todo App using MobX &amp;amp; React at last.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;Step 0: Fork or clone the Git Repo&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
Go here and fork/clone it:&amp;nbsp;&lt;a href=&quot;https://github.com/nirgit/todoMobxTutorial&quot; target=&quot;_blank&quot;&gt;https://github.com/nirgit/todoMobxTutorial&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
You will now have a skeleton application which is ready and set up, using ES6 with JSX &amp;amp; Webpack.&lt;br /&gt;
&lt;b&gt;MobX&lt;/b&gt; is also included in the &lt;i&gt;package.json&lt;/i&gt;, so &lt;u&gt;you won&#39;t need to add it as a dependency&lt;/u&gt;.&lt;br /&gt;
&lt;br /&gt;
Go to the project&#39;s directory and run from the console / shell:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;code-block&quot;&gt;
&lt;i&gt;&amp;gt; npm run start&lt;/i&gt;&lt;/div&gt;
&lt;br /&gt;
Now go to &lt;i&gt;http://localhost:8080&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Your web page should look like this:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjDWXZnkDfzLYQ4ErzMHjp0RQw0u-2sgNPtW1Stn1D-Cry34lYiri9mwqr9dV3B97i8URgaAAL0yWHLYSA2xzqVXNOSVD8DJOieNgtkRe5ohCG7q0azidrnru6acVlgOAes5_bvo5h_4h1/s1600/Screen+Shot+2017-05-09+at+23.45.10.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;152&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjDWXZnkDfzLYQ4ErzMHjp0RQw0u-2sgNPtW1Stn1D-Cry34lYiri9mwqr9dV3B97i8URgaAAL0yWHLYSA2xzqVXNOSVD8DJOieNgtkRe5ohCG7q0azidrnru6acVlgOAes5_bvo5h_4h1/s320/Screen+Shot+2017-05-09+at+23.45.10.png&quot; style=&quot;border: 1px solid rgb(0, 0, 0); padding: 2px;&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;helvetica neue&amp;quot;;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif; font-size: 12px;&quot;&gt;&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;h3&gt;
&lt;u&gt;&lt;span style=&quot;font-size: small;&quot;&gt;Step 1: Creating a plain React Todo App&lt;/span&gt;&lt;/u&gt;&lt;/h3&gt;
Lets create our plain Todo application based on React only.&lt;br /&gt;&lt;ol&gt;
&lt;li&gt;Stop Webpack watching your changes&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Go to the project&#39;s directory and run from the console / shell:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;code-block&quot;&gt;
&lt;i&gt;&amp;gt; git checkout step1&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&amp;gt; npm install&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&amp;gt; npm run start&lt;/i&gt;&lt;br /&gt;
&lt;div&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
Re-open http://localhost:8080, you should now see this:&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimGDniImjCn9Uo5JGVUxMQO3zvNTY9RVJgD6hG8ioJtijB4NwXT243BOVMQjSgw3-RlGQmw3HP6-R7qAE7X0ePdSS2Ks1gj5BIiCUgC6adeEHcDk9fHlfCbocbxdKa1BYBHVmCQPuVw_Pp/s1600/Screen+Shot+2017-05-12+at+13.22.19.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;315&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimGDniImjCn9Uo5JGVUxMQO3zvNTY9RVJgD6hG8ioJtijB4NwXT243BOVMQjSgw3-RlGQmw3HP6-R7qAE7X0ePdSS2Ks1gj5BIiCUgC6adeEHcDk9fHlfCbocbxdKa1BYBHVmCQPuVw_Pp/s320/Screen+Shot+2017-05-12+at+13.22.19.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Great!&lt;/div&gt;
You now have a functional React Todo app.&lt;br /&gt;
You can open the &lt;b&gt;&lt;i&gt;app.js&lt;/i&gt;&lt;/b&gt; file and see all the code pretty much.&lt;br /&gt;
You won&#39;t find anything unusual.&lt;br /&gt;
Note how the entire state though is stored on the &lt;i&gt;App&lt;/i&gt;&amp;nbsp;component, so once we will refactor the code a little bit, we will have to pass in the todos as a prop to the child components, and probably stuff like a callback to toggle the todos &quot;isDone&quot; field, so we can use setState in order to make it work.&lt;br /&gt;
&lt;br /&gt;
Go back to your shell and now, checkout the &lt;i style=&quot;font-weight: bold;&quot;&gt;step1_2&lt;/i&gt;&amp;nbsp;branch.&lt;br /&gt;
&lt;div class=&quot;code-block&quot;&gt;
&lt;i&gt;&amp;gt; git checkout step1_2&lt;/i&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Open the &lt;i&gt;App.js&lt;/i&gt;&amp;nbsp;file and take a look at the &lt;i&gt;render&lt;/i&gt;&amp;nbsp;method.&lt;br /&gt;
See the line?&lt;br /&gt;
...&lt;br /&gt;
&lt;span style=&quot;color: #5fb3b3; font-family: &amp;quot;menlo&amp;quot;; font-size: 9pt;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #ec5f67; font-family: &amp;quot;menlo&amp;quot;; font-size: 9pt;&quot;&gt;TodoList &lt;/span&gt;&lt;span style=&quot;color: #bb80b3; font-family: &amp;quot;menlo&amp;quot;; font-size: 9pt;&quot;&gt;todos&lt;/span&gt;&lt;span style=&quot;color: #99c794; font-family: &amp;quot;menlo&amp;quot;; font-size: 9pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #5fb3b3; font-family: &amp;quot;menlo&amp;quot;; font-size: 9pt;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #bb80b3; font-family: &amp;quot;menlo&amp;quot;; font-size: 9pt; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #5fb3b3; font-family: &amp;quot;menlo&amp;quot;; font-size: 9pt;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #ec5f67; font-family: &amp;quot;menlo&amp;quot;; font-size: 9pt; font-weight: bold;&quot;&gt;state&lt;/span&gt;&lt;span style=&quot;color: #5fb3b3; font-family: &amp;quot;menlo&amp;quot;; font-size: 9pt;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #ec5f67; font-family: &amp;quot;menlo&amp;quot;; font-size: 9pt; font-weight: bold;&quot;&gt;todos&lt;/span&gt;&lt;span style=&quot;color: #5fb3b3; font-family: &amp;quot;menlo&amp;quot;; font-size: 9pt;&quot;&gt;} &lt;/span&gt;&lt;span style=&quot;color: #bb80b3; font-family: &amp;quot;menlo&amp;quot;; font-size: 9pt;&quot;&gt;toggleDone&lt;/span&gt;&lt;span style=&quot;color: #99c794; font-family: &amp;quot;menlo&amp;quot;; font-size: 9pt;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #5fb3b3; font-family: &amp;quot;menlo&amp;quot;; font-size: 9pt;&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color: #bb80b3; font-family: &amp;quot;menlo&amp;quot;; font-size: 9pt; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #5fb3b3; font-family: &amp;quot;menlo&amp;quot;; font-size: 9pt;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #6699cc; font-family: &amp;quot;menlo&amp;quot;; font-size: 9pt;&quot;&gt;toggleDone&lt;/span&gt;&lt;span style=&quot;color: #5fb3b3; font-family: &amp;quot;menlo&amp;quot;; font-size: 9pt;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #6699cc; font-family: &amp;quot;menlo&amp;quot;; font-size: 9pt;&quot;&gt;bind&lt;/span&gt;&lt;span style=&quot;color: #5fb3b3; font-family: &amp;quot;menlo&amp;quot;; font-size: 9pt;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #bb80b3; font-family: &amp;quot;menlo&amp;quot;; font-size: 9pt; font-weight: bold;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color: #5fb3b3; font-family: &amp;quot;menlo&amp;quot;; font-size: 9pt;&quot;&gt;)} /&amp;gt;&lt;/span&gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Notice how we pass in to the &lt;i&gt;TodoList&lt;/i&gt; component the &lt;i&gt;toggleDone&lt;/i&gt; callback, which is still defined on the &lt;i&gt;App&lt;/i&gt; component. &amp;nbsp;If you would decide to create &lt;i&gt;Todo&lt;/i&gt;&amp;nbsp;components, you&#39;d probably pass on that callback into each of those components.&lt;br /&gt;
And so you will have a component which passes a function to a child (TodoList) which does nothing with that function but pass it on to its children, which affect a state that&#39;s found on its grand parent.&lt;br /&gt;
&lt;i&gt;A bit Messy.&lt;/i&gt;&lt;br /&gt;
If you&#39;d have this situation in a large scale application, not only it may be confusing, but it could be practically impossible to reason about the full state of your application at any given point in time.&lt;br /&gt;
&lt;br /&gt;
Lets add &lt;b&gt;MobX&lt;/b&gt; and see what happens.&lt;br /&gt;


&lt;h3&gt;
&lt;u&gt;&lt;span style=&quot;font-size: small;&quot;&gt;Step 2: Adding MobX to our React App&lt;/span&gt;&lt;/u&gt;&lt;/h3&gt;
MobX uses a very small set of core API.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;u&gt;&lt;b&gt;@observable&lt;/b&gt;&lt;/u&gt;&lt;/i&gt;&lt;br /&gt;
The API&#39;s most significant and basis to all the MobX &quot;magic&quot; is the &lt;i style=&quot;font-weight: bold;&quot;&gt;observable&lt;/i&gt;&amp;nbsp;function / decoration (function if you decide not to use the decoration syntax from ES Next).&lt;br /&gt;
On this post we&#39;ll stick with the decoration as it &lt;i&gt;feels &lt;/i&gt;(subjective) a cleaner way to &lt;u&gt;declaratively&lt;/u&gt;&amp;nbsp;state the fact a piece of data/object is being observed.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;u&gt;&lt;i&gt;@observer&lt;/i&gt;&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
We have an &quot;&lt;b&gt;&lt;i&gt;observable&lt;/i&gt;&lt;/b&gt;&quot; data, now what?&lt;br /&gt;
We need someone to &quot;observe&quot; it, and react to the changes.&lt;br /&gt;
MobX being a library in its own right, does not provide an&amp;nbsp;&lt;i style=&quot;font-weight: bold;&quot;&gt;@observer&lt;/i&gt;&amp;nbsp;for React Components &quot;OOTB&quot; (&quot;out of the box&quot;).&lt;br /&gt;
In order to use such&amp;nbsp;@&lt;i style=&quot;font-weight: bold;&quot;&gt;observer&lt;/i&gt;&amp;nbsp;we need to use the &lt;i style=&quot;font-weight: bold;&quot;&gt;&lt;a href=&quot;https://github.com/mobxjs/mobx-react&quot; target=&quot;_blank&quot;&gt;MobX-React&lt;/a&gt;&lt;/i&gt;&amp;nbsp;NPM package.&lt;br /&gt;
Then we can &quot;decorate&quot; our React Components with an&amp;nbsp;&lt;b&gt;&lt;i&gt;@observer&lt;/i&gt;&lt;/b&gt;&amp;nbsp;decoration.&lt;br /&gt;
&lt;br /&gt;
The reaction to the changes made to the &lt;i style=&quot;font-weight: bold;&quot;&gt;observable&lt;/i&gt;&amp;nbsp;object will result in calling the &lt;i style=&quot;font-weight: bold;&quot;&gt;render&lt;/i&gt;&amp;nbsp;method of the React component observing that object. Pretty cool.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;Code example:&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;iframe allowfullscreen=&quot;allowfullscreen&quot; frameborder=&quot;0&quot; height=&quot;300&quot; src=&quot;//jsfiddle.net/getnirm/xnkLgcqp/embedded/js,html,result/&quot; testim_frame_id=&quot;8394227&quot; width=&quot;100%&quot;&gt;&lt;/iframe&gt;

&lt;br /&gt;
So every time you will change the &lt;b style=&quot;font-style: italic;&quot;&gt;bestMovies&lt;/b&gt;&amp;nbsp;collection, the &lt;i style=&quot;font-weight: bold;&quot;&gt;render&lt;/i&gt;&amp;nbsp;of &lt;i style=&quot;font-weight: bold;&quot;&gt;MovieList&lt;/i&gt;&amp;nbsp;component will be triggered.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Stop your app from running if it is, go back to your shell and now, checkout the&amp;nbsp;&lt;i style=&quot;font-weight: bold;&quot;&gt;step2&lt;/i&gt;&amp;nbsp;branch.&lt;br /&gt;
&lt;div class=&quot;code-block&quot;&gt;
&lt;i&gt;&amp;gt; git checkout step2&lt;/i&gt;&lt;br /&gt;
&lt;div&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;
&lt;/div&gt;
and run the following to install missing missing NPM pacakges and re-run the app:
&lt;br /&gt;
&lt;div class=&quot;code-block&quot;&gt;
&lt;i&gt;&amp;gt; npm install &amp;amp;&amp;amp; npm run start&lt;/i&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
You shouldn&#39;t see any &lt;b&gt;&lt;u&gt;visual&lt;/u&gt;&lt;/b&gt;&amp;nbsp;difference, but open the browser&#39;s Console and see what you got:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKi0A9Y3dxTd_1p7LELleznIYB_QCUmGYnMjMWxRic5DFn75zFZx9Tw_frheDDMlTgf0fs0x7AUudV_x-QqV01GhAvVhuTeQzBBMc-sVQKOsPR1Hm7Gjzki-4Ubj-YX6YknN7hlbaSGn-j/s1600/Screen+Shot+2017-05-19+at+17.37.55.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;286&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKi0A9Y3dxTd_1p7LELleznIYB_QCUmGYnMjMWxRic5DFn75zFZx9Tw_frheDDMlTgf0fs0x7AUudV_x-QqV01GhAvVhuTeQzBBMc-sVQKOsPR1Hm7Gjzki-4Ubj-YX6YknN7hlbaSGn-j/s400/Screen+Shot+2017-05-19+at+17.37.55.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
See how now you get a &lt;i&gt;log&lt;/i&gt; print in the console when a component renders.&lt;/div&gt;
&lt;div&gt;
Try clicking a checkbox, you should get the following prints:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTkcyAxwcaxDByPX0JNy2SBb-5L0p7BoFiXNcAqtSzVYqo-FIZ7Tgs5FfU55tNbSb6dCNhkaTmIzPeSyR3bufZBxDkmQ-o-xkbdEUKQ05UxUHgJ3WCfEz8Bl0IiYBgfOEhom9F7beuUmAP/s1600/Screen+Shot+2017-05-19+at+17.41.07.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;288&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTkcyAxwcaxDByPX0JNy2SBb-5L0p7BoFiXNcAqtSzVYqo-FIZ7Tgs5FfU55tNbSb6dCNhkaTmIzPeSyR3bufZBxDkmQ-o-xkbdEUKQ05UxUHgJ3WCfEz8Bl0IiYBgfOEhom9F7beuUmAP/s400/Screen+Shot+2017-05-19+at+17.41.07.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
See how now you get only part of the prints?&lt;/div&gt;
&lt;b&gt;&lt;u&gt;Lets do a quick analysis:&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;b&gt;&lt;u&gt;&lt;i&gt;App &lt;/i&gt;Component&lt;/u&gt;&lt;/b&gt; - renders because its &lt;i&gt;render&lt;/i&gt;&amp;nbsp;function is using the &lt;i&gt;isDone&lt;/i&gt;&amp;nbsp;flags of the Todos in order to render the Progress Bar.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;u&gt;&lt;i&gt;ProgressBar&lt;/i&gt; Component&lt;/u&gt;&lt;/b&gt; - renders for obvious reasons.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;u&gt;&lt;i&gt;TodoList&lt;/i&gt;&amp;nbsp;Component&lt;/u&gt;&lt;/b&gt; - renders because it passes all of the properties of the &lt;i&gt;Todo&lt;/i&gt; objects, including the &lt;i&gt;isDone&lt;/i&gt;&amp;nbsp;property when rendering. &lt;br /&gt;It does that by using the ES6 spread operator (see in the code &quot;{...t}&quot;)&lt;/li&gt;
&lt;li&gt;&lt;u&gt;The &lt;/u&gt;&lt;i style=&quot;font-weight: bold; text-decoration-line: underline;&quot;&gt;TodoLine&lt;/i&gt;&lt;u style=&quot;font-weight: bold;&quot;&gt; Component&lt;/u&gt;&lt;i style=&quot;font-weight: bold;&quot;&gt;&amp;nbsp;- &lt;/i&gt;A new component created representing the Todo lines, as it makes it clearer to see MobX&#39;s benefit.&lt;br /&gt;Notice how only the &lt;i&gt;TodoLine&lt;/i&gt; Component whose line we changed rendered.&lt;br /&gt;&lt;u&gt;All the rest - stayed the same without getting re-rendered.&lt;/u&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
&lt;u&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/u&gt;&lt;/div&gt;
&lt;br /&gt;
You can run the quick following check.&lt;br /&gt;
&lt;u&gt;Go to the &lt;b&gt;&lt;i&gt;todoLine.js&lt;/i&gt;&lt;/b&gt; file and change the following line:&lt;/u&gt;&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&lt;span style=&quot;color: #0b5394;&quot;&gt;export default&lt;/span&gt; observer(TodoLine);&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;to this line:&lt;/u&gt;&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&lt;span style=&quot;color: #0b5394;&quot;&gt;export default&lt;/span&gt; TodoLine;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
See how we omitted the MobX observer?&lt;br /&gt;
Now go back to the browser, and try to check the same checkbox as earlier. &lt;br /&gt;Keep your console opened. You should get the following prints:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5pv0hcuemIjLf2S4PnFFnMN4fGfNUhyWBPY2i_jZWr-vp9Wa6gWTA6Vpf367vCM44oQ4-lR5FEj1irO78-GxHY7XDO5EkJ0h-B2HIbOjlSVodYDnTLFaQzCregJHdtVuzm68umbljqRoL/s1600/Screen+Shot+2017-05-19+at+17.54.22.png&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5pv0hcuemIjLf2S4PnFFnMN4fGfNUhyWBPY2i_jZWr-vp9Wa6gWTA6Vpf367vCM44oQ4-lR5FEj1irO78-GxHY7XDO5EkJ0h-B2HIbOjlSVodYDnTLFaQzCregJHdtVuzm68umbljqRoL/s320/Screen+Shot+2017-05-19+at+17.54.22.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;br /&gt;
Hopefully you got something out of this post, as it should give you an idea of what MobX is by now. Stay tuned for Part 2 blog post that will discuss topics like:&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Adding Actions and Action Handler&lt;/li&gt;
&lt;li&gt;Adding a Provider component&lt;/li&gt;
&lt;li&gt;Adding Containers&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
Or go explore more yourself on &lt;a href=&quot;https://mobx.js.org/&quot; target=&quot;_blank&quot;&gt;https://mobx.js.org/&lt;/a&gt;.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Enjoy,&lt;/div&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;helvetica neue&amp;quot;;&quot;&gt;&lt;span style=&quot;font-size: 12px;&quot;&gt;&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;helvetica neue&amp;quot;;&quot;&gt;&lt;span style=&quot;font-size: 12px;&quot;&gt;&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;helvetica neue&amp;quot;;&quot;&gt;&lt;span style=&quot;font-size: 12px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;helvetica neue&amp;quot;;&quot;&gt;&lt;span style=&quot;font-size: 12px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://mobx.js.org/index.html&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif;&quot;&gt;&lt;img alt=&quot;MobX library image&quot; border=&quot;0&quot; height=&quot;200&quot; src=&quot;https://mobx.js.org/docs/mobx.png&quot; title=&quot;&quot; width=&quot;200&quot; /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;a href=&quot;https://facebook.github.io/react/&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif;&quot;&gt;&lt;img alt=&quot; ReactJS library image&quot; border=&quot;0&quot; height=&quot;200&quot; src=&quot;https://raw.githubusercontent.com/wiki/facebook/react/react-logo-1000-transparent.png&quot; title=&quot;&quot; width=&quot;200&quot; /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;times&amp;quot; , &amp;quot;times new roman&amp;quot; , serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;helvetica neue&amp;quot;;&quot;&gt;&lt;span style=&quot;font-size: 12px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://tech-drum.blogspot.com/feeds/7980437036000056867/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-drum.blogspot.com/2017/05/react-mobx-101-todo-app-for-beginners.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/7980437036000056867'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/7980437036000056867'/><link rel='alternate' type='text/html' href='http://tech-drum.blogspot.com/2017/05/react-mobx-101-todo-app-for-beginners.html' title='React + MobX - 101 Todo App for beginners - Part 1'/><author><name>Nir Moav</name><uri>http://www.blogger.com/profile/05879703892878058262</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEih5-a6tP-f6MsYqC3xxvV0Ns-SD_FVH4hnD1MySwZUdsBUUJ6CoxRB1XiZeRWgUmF2qis272rzrmzpBQSMK_9uJIbp5QA_mj8111V9gg_a3sDX9ATYHNiTgH5yhGyluwkiSpWg8wvQvpdS/s72-c/Screen+Shot+2017-05-06+at+10.26.52+PM.png" height="72" width="72"/><thr:total>0</thr:total><georss:featurename>Israel</georss:featurename><georss:point>31.046051 34.851611999999932</georss:point><georss:box>27.5779785 29.688037999999931 34.5141235 40.015185999999929</georss:box></entry><entry><id>tag:blogger.com,1999:blog-224320715137455380.post-4415270056122808622</id><published>2016-11-14T22:35:00.000+02:00</published><updated>2016-11-14T22:36:25.355+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Chrome"/><category scheme="http://www.blogger.com/atom/ns#" term="Extension"/><category scheme="http://www.blogger.com/atom/ns#" term="Free"/><category scheme="http://www.blogger.com/atom/ns#" term="Front End"/><category scheme="http://www.blogger.com/atom/ns#" term="Github"/><category scheme="http://www.blogger.com/atom/ns#" term="HTML5"/><category scheme="http://www.blogger.com/atom/ns#" term="Javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="Source Code"/><title type='text'>Bit.ly Resolver - Chrome extension</title><content type='html'>It&#39;s been a while since I last blogged about anything...&lt;br /&gt;
&lt;br /&gt;
Something that&#39;s been bothering me for a long time since I&#39;ve been on Twitter, are &lt;a href=&quot;https://bitly.com/&quot;&gt;bit.ly&lt;/a&gt; links.&lt;br /&gt;
&lt;br /&gt;
Naturally Bit.ly links got a serious boost in usage with Twitter&#39;s launch, and they serve a great tool of compacting links and embedding them beautifully inside Tweets.&lt;br /&gt;
&lt;br /&gt;
However, many times, looking at those links, you can&#39;t help but wonder - &quot;where will it take me if I click it? Am I going to get a worm or a virus on my laptop?&quot;&lt;br /&gt;
Sometimes, people are just lazy to put any context telling you what this link is about, and so, they tweet or post a bit.ly link with their cat&#39;s photo.&lt;br /&gt;
(Usually it is not their cat&#39;s paw-n-shop ya&#39; know...).&lt;br /&gt;
&lt;br /&gt;
So being very lazy that I am, yet curious as a cat.. I decided to pick up the glove, and create my very own Chrome extension (sorry y&#39;all other folks using other browsers), that shows you the &lt;b&gt;REAL URL&lt;/b&gt; behind that bit.ly link you&#39;re gazing it right at this second, &lt;b&gt;simply by hovering on it&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
Welcome -&amp;nbsp;&lt;b&gt;&lt;a href=&quot;https://chrome.google.com/webstore/detail/bitly-resolver-chrome-ext/jeeajejfdlklcbedakfaokpjnkkpfclh&quot; target=&quot;_blank&quot;&gt;Bit.ly Resolver Chrome Extension&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;You can simply click it, in order to install that extension on your browser.&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://nirgit.github.io/bitlyResolverCE/&quot; target=&quot;_blank&quot;&gt;&lt;img alt=&quot;Bit.ly Resolver - Chrome Extension&quot; border=&quot;0&quot; height=&quot;360&quot; src=&quot;https://static.wixstatic.com/media/32d4ec_1104e84ef06b418e9238342494cb9e2b~mv2.png&quot; width=&quot;576&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;GitHub link for those of you who are interested:&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
As a bit.ly :) :&amp;nbsp;&lt;a href=&quot;http://bit.ly/2fzMal8&quot;&gt;http://bit.ly/2fzMal8&lt;/a&gt;&lt;br /&gt;
Or simply as:&amp;nbsp;&lt;a href=&quot;https://nirgit.github.io/bitlyResolverCE/&quot;&gt;https://nirgit.github.io/bitlyResolverCE/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See you in a bit.ly!&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://tech-drum.blogspot.com/feeds/4415270056122808622/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-drum.blogspot.com/2016/11/bitly-resolver-chrome-extension.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/4415270056122808622'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/4415270056122808622'/><link rel='alternate' type='text/html' href='http://tech-drum.blogspot.com/2016/11/bitly-resolver-chrome-extension.html' title='Bit.ly Resolver - Chrome extension'/><author><name>Nir Moav</name><uri>http://www.blogger.com/profile/05879703892878058262</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total><georss:featurename>Israel</georss:featurename><georss:point>31.046051 34.851611999999932</georss:point><georss:box>27.5779785 29.688037999999931 34.5141235 40.015185999999929</georss:box></entry><entry><id>tag:blogger.com,1999:blog-224320715137455380.post-6957824937792643312</id><published>2016-05-21T23:53:00.000+03:00</published><updated>2016-05-22T10:40:00.370+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Front End"/><category scheme="http://www.blogger.com/atom/ns#" term="Javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="React"/><category scheme="http://www.blogger.com/atom/ns#" term="ReactJS"/><category scheme="http://www.blogger.com/atom/ns#" term="Sass"/><category scheme="http://www.blogger.com/atom/ns#" term="Typescript"/><category scheme="http://www.blogger.com/atom/ns#" term="Webpack"/><title type='text'>Typescript, React and Sass - All in one - Skeleton Project built with Webpack</title><content type='html'>&lt;span style=&quot;font-size: large;&quot;&gt;Just recently&amp;nbsp;I had the need to set up a project that included&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #073763;&quot;&gt;Typescript&lt;/span&gt;, &lt;span style=&quot;color: #6fa8dc;&quot;&gt;React&lt;/span&gt;, &lt;span style=&quot;color: magenta;&quot;&gt;Sass&lt;/span&gt;&amp;nbsp;&lt;/b&gt;and building it with &lt;a href=&quot;https://webpack.github.io/&quot; target=&quot;_blank&quot;&gt;Webpack&lt;/a&gt;,&amp;nbsp;and couldn&#39;t find any good up-to-date source on the web for a&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;skeleton project to base it on.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;div&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;So I decided to create my own.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;You can check it out (free of course) on my GitHub account:&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;a href=&quot;https://github.com/nirgit/react-typescript-skel&quot;&gt;&lt;span style=&quot;font-size: large;&quot;&gt;https://github.com/nirgit/react-typescript-skel&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;img border=&quot;0&quot; height=&quot;125&quot; src=&quot;https://s3.amazonaws.com/ionic-marketplace/typescript-starter/icon.png&quot; style=&quot;float: left;&quot; width=&quot;125&quot; /&gt;
&lt;img border=&quot;0&quot; height=&quot;125&quot; src=&quot;https://pbs.twimg.com/profile_images/636592875418046464/392UXhOt.png&quot; style=&quot;float: left;&quot; width=&quot;125&quot; /&gt;
&lt;img border=&quot;0&quot; height=&quot;125&quot; src=&quot;https://raw.githubusercontent.com/indievox-inc/iNDIEVOX-Web-Profile/master/image/sass-logo.png&quot; style=&quot;float: left;&quot; width=&quot;125&quot; /&gt;
&lt;img border=&quot;0&quot; height=&quot;125&quot; src=&quot;https://avatars0.githubusercontent.com/webpack?&amp;s=256&quot; style=&quot;float: left;&quot; width=&quot;125&quot; /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tech-drum.blogspot.com/feeds/6957824937792643312/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-drum.blogspot.com/2016/05/typescript-react-and-sass-all-in-one.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/6957824937792643312'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/6957824937792643312'/><link rel='alternate' type='text/html' href='http://tech-drum.blogspot.com/2016/05/typescript-react-and-sass-all-in-one.html' title='Typescript, React and Sass - All in one - Skeleton Project built with Webpack'/><author><name>Nir Moav</name><uri>http://www.blogger.com/profile/05879703892878058262</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total><georss:featurename>Israel</georss:featurename><georss:point>31.046051 34.851611999999932</georss:point><georss:box>27.5781805 29.688037999999931 34.513921499999995 40.015185999999929</georss:box></entry><entry><id>tag:blogger.com,1999:blog-224320715137455380.post-6215062341426049317</id><published>2016-05-09T22:40:00.002+03:00</published><updated>2016-05-11T10:58:52.549+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Example"/><category scheme="http://www.blogger.com/atom/ns#" term="Free"/><category scheme="http://www.blogger.com/atom/ns#" term="Fun"/><category scheme="http://www.blogger.com/atom/ns#" term="Hubot"/><category scheme="http://www.blogger.com/atom/ns#" term="Javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="Node"/><category scheme="http://www.blogger.com/atom/ns#" term="Script"/><category scheme="http://www.blogger.com/atom/ns#" term="Slack"/><category scheme="http://www.blogger.com/atom/ns#" term="Source Code"/><title type='text'>Hubot Script for Image Search on Bing</title><content type='html'>&lt;h1&gt;
How to write a Hubot script that integrates with Bing in Javascript
&lt;/h1&gt;
In case you haven&#39;t heard of &lt;a href=&quot;https://slack.com/&quot; target=&quot;_blank&quot;&gt;Slack&lt;/a&gt;, I recommend you check it out.&lt;br /&gt;
Slack is a Messaging App with an extremely cool edge of customization abilities.&lt;br /&gt;
&lt;br /&gt;
One of those abilities allows you to install an App that plugs-in to Slack, called &lt;a href=&quot;https://slack.com/apps/A0F7XDU93-hubot&quot; target=&quot;_blank&quot;&gt;Hubot&lt;/a&gt;.&lt;br /&gt;
A Hubot is a Bot app, that can listen to your commands on Slack, and perform a task.&lt;br /&gt;
&lt;br /&gt;
After installing your Hubot on your machine, you will notice it has a &quot;scripts&quot; directory.&lt;br /&gt;
You can use this directory to write your own custom scripts which the Hubot will execute!&lt;br /&gt;
Very cool!&lt;br /&gt;
&lt;br /&gt;
The scripts can be written in CoffeeScript and in Javascript.&lt;br /&gt;
You can simply copy-paste the code below, but notice that it will &lt;b&gt;not&lt;/b&gt; work, unless you get
your own Bing API key.&lt;br /&gt;
You can easily get it for free &lt;a href=&quot;https://www.microsoft.com/cognitive-services/en-US/subscriptions&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
This is how the screen looks like at Bing after you will (create an account as needed and) login.




&lt;br /&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;pre&gt;Be sure to copy the API Key that (highlighted in red) shows in the box, &lt;/pre&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;pre style=&quot;-webkit-text-stroke-width: 0px; color: black; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; margin: 0px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; widows: 1; word-spacing: 0px;&quot;&gt;and replace it with the &#39;key&#39;,&amp;nbsp;&lt;/pre&gt;
&lt;pre style=&quot;-webkit-text-stroke-width: 0px; color: black; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; margin: 0px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; widows: 1; word-spacing: 0px;&quot;&gt;which equals to &#39;XXXX-....-XXXX&#39; in the code below.&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTlhKTnpkmDZuxDeg8vDhRI78TQ3CL6ITHaCHwx8yLyQQVCuGJIAuWWals-Z1Clg_nZEEdM6B65Uns-kQy-M1Cz0MRqDs9Htvypp9iwak_3DNIqQiM_-64oVGzKJdzJUIJqbuqZonjSdAB/s1600/screenshot-bing-api.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;242&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTlhKTnpkmDZuxDeg8vDhRI78TQ3CL6ITHaCHwx8yLyQQVCuGJIAuWWals-Z1Clg_nZEEdM6B65Uns-kQy-M1Cz0MRqDs9Htvypp9iwak_3DNIqQiM_-64oVGzKJdzJUIJqbuqZonjSdAB/s400/screenshot-bing-api.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;h2&gt;
The expected result&lt;/h2&gt;
&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgx99Edwtkj72L9n_JrCEZcMzN_Yoz4bVZAMLstrlVXWJ6zNIfY-x-kMqE06sXXH6h6yRSRG7j646TdkWaBJcsw8LosryW2JN8n8SuSgzAlCEYfCWj1zrmbDb7Y3rVPHvzAbd6ugoA_nCyM/s1600/hubot-bing-example-screenshot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;290&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgx99Edwtkj72L9n_JrCEZcMzN_Yoz4bVZAMLstrlVXWJ6zNIfY-x-kMqE06sXXH6h6yRSRG7j646TdkWaBJcsw8LosryW2JN8n8SuSgzAlCEYfCWj1zrmbDb7Y3rVPHvzAbd6ugoA_nCyM/s400/hubot-bing-example-screenshot.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
Enjoy hacking &amp;amp; slacking!&lt;br /&gt;
Nir&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3&gt;
The code&lt;/h3&gt;
&lt;div&gt;
// bing.js&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre&gt;&#39;use strict&#39;

var querystring = require(&#39;querystring&#39;);
var http = require(&#39;https&#39;);

&lt;/pre&gt;
&lt;pre&gt;&lt;pre&gt;&lt;b&gt;// replace the &#39;XXXXX...&#39; string here with your own Bing API KEY&lt;/b&gt;&lt;/pre&gt;
&lt;b&gt;var key = &#39;XXXXX-XXXXX-XXXXX-XXXXX&#39;;&amp;nbsp;&lt;/b&gt;&lt;/pre&gt;
&lt;pre&gt;var HOST_NAME = &#39;bingapis.azure-api.net&#39;;
var DEFAULT_NUMBER_OF_IMGS = 20;
var SAFE = {
  low: &#39;Off&#39;,
  medium: &#39;Moderate&#39;,
  high: &#39;Strict&#39;
};

var HTTP_REQUEST_HEADERS = {
  &quot;Accept&quot;: &quot;*/*&quot;,
  &quot;Content-Type&quot;: &quot;application/json&quot;,
  &quot;Ocp-Apim-Subscription-Key&quot;: key
};

function getParams(query, count, offset, safe) {
  count = count || DEFAULT_NUMBER_OF_IMGS;
  count = Math.max(5, Math.min(50, count));
  offset = offset || Math.floor(Math.random() * 4);
  return {
    &#39;hostname&#39;: HOST_NAME,
    &#39;method&#39;: &#39;GET&#39;,
    &#39;path&#39;: buildQueryParameters(query, count, offset, safe || SAFE.medium),
    &#39;headers&#39;: HTTP_REQUEST_HEADERS
  };
}

function buildQueryParameters(query, count, offset, safey) {
  return &#39;/api/v5/images/search?q=&#39; + query +&amp;nbsp;
&#39;&amp;amp;count=&#39; + count + &#39;&amp;amp;offset=&#39; + offset +&amp;nbsp;
&#39;&amp;amp;mkt=en-us&amp;amp;safeSearch=&#39; + safey;
}

function getImagesFromBing(query, hubotCallback) {
  var body = [];
  var params = getParams(query);
  var req = http.request(params, function(res) {
    res.setEncoding(&#39;utf8&#39;);
    res.on(&#39;data&#39;, function (chunk) {
      body.push(chunk);
    });
    res.on(&#39;end&#39;, function () {
       var data = body.join(&#39;&#39;);
       var dataAsJson = JSON.parse(data);
       var values = dataAsJson.value;
       var imgs = values.map(function(val) {
         return val.contentUrl;
       });
       hubotCallback(imgs);
    });
  });
  req.end();
}

module.exports = function(robot) {
    robot.hear(/bingme (.*)/i, function(res) {
        var photoname = res.match[1];
        res.reply(&quot;Looking for a photo of \&quot;&quot; + photoname + &quot;\&quot; on Bing!&quot;);

        var escapedQuery = querystring.escape(photoname);
        getImagesFromBing(escapedQuery, function(imgs) {
          var randomPhotoIndex = Math.floor(Math.random() * imgs.length);
          res.send(imgs[randomPhotoIndex]);
        });
    });
}&lt;/pre&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;text-align: center;&quot;&gt;

&lt;img src=&quot;https://a.slack-edge.com/ae7f/plugins/hubot/assets/service_512.png&quot; height=&quot;179&quot; width=&quot;179&quot; style=&quot;float: left; border: none; -webkit-box-shadow: none; box-shadow: none&quot;/&gt;
&lt;img src=&quot;http://cdn1.tnwcdn.com/wp-content/blogs.dir/1/files/2014/10/Slack.png&quot; height=&quot;179&quot; width=&quot;320&quot; style=&quot;float: left; border: none; -webkit-box-shadow: none; box-shadow: none&quot;/&gt;

&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tech-drum.blogspot.com/feeds/6215062341426049317/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-drum.blogspot.com/2016/05/hubot-script-for-image-search-on-bing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/6215062341426049317'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/6215062341426049317'/><link rel='alternate' type='text/html' href='http://tech-drum.blogspot.com/2016/05/hubot-script-for-image-search-on-bing.html' title='Hubot Script for Image Search on Bing'/><author><name>Nir Moav</name><uri>http://www.blogger.com/profile/05879703892878058262</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTlhKTnpkmDZuxDeg8vDhRI78TQ3CL6ITHaCHwx8yLyQQVCuGJIAuWWals-Z1Clg_nZEEdM6B65Uns-kQy-M1Cz0MRqDs9Htvypp9iwak_3DNIqQiM_-64oVGzKJdzJUIJqbuqZonjSdAB/s72-c/screenshot-bing-api.png" height="72" width="72"/><thr:total>0</thr:total><georss:featurename>Israel</georss:featurename><georss:point>31.046051 34.851611999999932</georss:point><georss:box>27.5781805 29.688037999999931 34.513921499999995 40.015185999999929</georss:box></entry><entry><id>tag:blogger.com,1999:blog-224320715137455380.post-2849259594966010420</id><published>2016-01-17T13:34:00.000+02:00</published><updated>2016-02-19T10:05:06.919+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Android"/><category scheme="http://www.blogger.com/atom/ns#" term="App"/><category scheme="http://www.blogger.com/atom/ns#" term="Free"/><category scheme="http://www.blogger.com/atom/ns#" term="Front End"/><category scheme="http://www.blogger.com/atom/ns#" term="Fun"/><category scheme="http://www.blogger.com/atom/ns#" term="Game"/><category scheme="http://www.blogger.com/atom/ns#" term="Javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="Space"/><category scheme="http://www.blogger.com/atom/ns#" term="Spaceship"/><category scheme="http://www.blogger.com/atom/ns#" term="Spaceship X"/><title type='text'>Spaceship X - Game Launch on Android Play</title><content type='html'>&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em; text-align: center;&quot;&gt;
&lt;img border=&quot;0&quot; height=&quot;400&quot; src=&quot;https://2.bp.blogspot.com/VeyR5u2JfNBUjovUjPOkki0LbOMbg7XrPJ-NDiQPsy_v4-v-TxcuYmb-iKSAaL5ilNg=h900-rw&quot; width=&quot;225&quot; /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h2&gt;
Spaceship X - Timeless Hero&lt;/h2&gt;
&lt;h3&gt;
A retro flavoured Spaceship shooter saving the Galaxy!&lt;/h3&gt;
&lt;br /&gt;
Exciting!&lt;br /&gt;
I have released my first Game App to Google Play!&lt;br /&gt;
&lt;br /&gt;
It is free to download:&lt;br /&gt;
&lt;a href=&quot;https://play.google.com/store/apps/details?id=nm.ibex.spaceshipx&quot;&gt;https://play.google.com/store/apps/details?id=nm.ibex.spaceshipx&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
The game&#39;s website:&lt;br /&gt;
&lt;a href=&quot;http://leapingibex.wix.com/spaceshipx&quot;&gt;http://leapingibex.wix.com/spaceshipx&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Have fun!&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://tech-drum.blogspot.com/feeds/2849259594966010420/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-drum.blogspot.com/2016/01/spaceship-x-game-launch-on-android-play.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/2849259594966010420'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/2849259594966010420'/><link rel='alternate' type='text/html' href='http://tech-drum.blogspot.com/2016/01/spaceship-x-game-launch-on-android-play.html' title='Spaceship X - Game Launch on Android Play'/><author><name>Nir Moav</name><uri>http://www.blogger.com/profile/05879703892878058262</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://2.bp.blogspot.com/VeyR5u2JfNBUjovUjPOkki0LbOMbg7XrPJ-NDiQPsy_v4-v-TxcuYmb-iKSAaL5ilNg=s72-h900-c-rw" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-224320715137455380.post-3930155348516001941</id><published>2015-04-18T23:34:00.000+03:00</published><updated>2015-05-15T15:22:34.801+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Example"/><category scheme="http://www.blogger.com/atom/ns#" term="Flux"/><category scheme="http://www.blogger.com/atom/ns#" term="Free"/><category scheme="http://www.blogger.com/atom/ns#" term="Front End"/><category scheme="http://www.blogger.com/atom/ns#" term="Github"/><category scheme="http://www.blogger.com/atom/ns#" term="Javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="React"/><category scheme="http://www.blogger.com/atom/ns#" term="React Templates"/><category scheme="http://www.blogger.com/atom/ns#" term="ReactJS"/><title type='text'>Simple Webapp example using Flux with React</title><content type='html'>If you&#39;ve been following the latest Front-End news for Web for the past year,&lt;br /&gt;
you have probably seen the huge buzz around ReactJS.&lt;br /&gt;
&lt;br /&gt;
Just in case you haven&#39;t, you can visit ReactJS on the Facebook Github&#39;s page at:&amp;nbsp;&lt;a href=&quot;https://facebook.github.io/react/&quot;&gt;https://facebook.github.io/react/&lt;/a&gt;&amp;nbsp;or just Google it and read about it.&lt;br /&gt;
&lt;br /&gt;
So for those of you that do know what React is all about, you may have also heard about Flux.&lt;br /&gt;
If you haven&#39;t :) I recommend you to read about it a bit&lt;br /&gt;
here as well&amp;nbsp;&lt;a href=&quot;http://facebook.github.io/flux/docs/overview.html&quot;&gt;http://facebook.github.io/flux/docs/overview.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
If I have to try and sum it up on one leg, I&#39;d say that Flux is an application architecture for building&lt;br /&gt;
big web-apps on the front-end that scale. &amp;nbsp;- Well, that&#39;s pretty vague :)&lt;br /&gt;
&lt;br /&gt;
A main concept regarding this architecture is about a Uni-directional flow where an &quot;&lt;i&gt;Action&lt;/i&gt;&quot;&lt;br /&gt;
(a Application Event)&amp;nbsp;is triggered by the View part (Your components, which are shown the users),&lt;br /&gt;
using a &quot;&lt;i&gt;Dispatcher&quot;&lt;/i&gt;&amp;nbsp;(Some kind of an Event Hub) which propagates the Actions&lt;br /&gt;
on to the &quot;&lt;i&gt;Stores&quot; (&lt;/i&gt;Your application&#39;s model), which hold the state (data) of your application,&lt;br /&gt;
perform the necessary update and logic, and updates the View back using listeners.&lt;br /&gt;
&lt;br /&gt;
This illustration might help understanding the Flux flow a little better:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_YhL-QgTBnJEisOv9K2sPZAczuNBDmFdpgkw1qTciBtIL1avD1lhpVtiUSEEKQP9abLlp0nFY00ZwEnnug_MooVpBfoSf0hST2TD878F3oDU45H5lO12KyBHPdZT1ucRuHMqgyNwc8eTx/s1600/Screen+Shot+2015-03-29+at+10.54.00+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;122&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_YhL-QgTBnJEisOv9K2sPZAczuNBDmFdpgkw1qTciBtIL1avD1lhpVtiUSEEKQP9abLlp0nFY00ZwEnnug_MooVpBfoSf0hST2TD878F3oDU45H5lO12KyBHPdZT1ucRuHMqgyNwc8eTx/s1600/Screen+Shot+2015-03-29+at+10.54.00+PM.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Why is Flux a good idea? - There are several reasons, but I will mention only 2 which I think&lt;br /&gt;
are the most important.&lt;br /&gt;
&lt;br /&gt;
1. Simple Application Architecture - You can show this diagram to someone who never&lt;br /&gt;
heard of Flux before, and explain it in 2 minutes.&lt;br /&gt;
&lt;br /&gt;
2. Scalable - Flux lets you scale. Meaning, it&#39;s relatively easy to add new features to&lt;br /&gt;
your application, debug it, and keeping it performant.&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i&gt;Why?&lt;/i&gt;&lt;br /&gt;
There&#39;s a really good talk about it by Facebook which is worth watching:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;iframe allowfullscreen=&quot;&quot; class=&quot;YOUTUBE-iframe-video&quot; data-thumbnail-src=&quot;https://i.ytimg.com/vi/nYkdrAPrdcw/0.jpg&quot; frameborder=&quot;0&quot; height=&quot;266&quot; src=&quot;http://www.youtube.com/embed/nYkdrAPrdcw?feature=player_embedded&quot; width=&quot;320&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
After all that being said, I really wanted to do some basic implementation of Flux myself,&lt;br /&gt;
to &quot;feel&quot; how it works. And so I created a very small Repository on Github that implements&lt;br /&gt;
Flux which you are welcome to look at and use.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
The example code&lt;/h3&gt;
The application built on top of that is a classic Todo App:&amp;nbsp;&lt;a href=&quot;https://github.com/nirgit/Flux1&quot;&gt;https://github.com/nirgit/Flux1&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
The code uses several 3rd party libraries such as&amp;nbsp;&lt;a href=&quot;http://requirejs.org/&quot; target=&quot;_blank&quot;&gt;RequireJS&lt;/a&gt;&amp;nbsp;and &lt;a href=&quot;https://github.com/wix/react-templates&quot; target=&quot;_blank&quot;&gt;React Templates&lt;/a&gt;&amp;nbsp;but even if you are not familiar with RequireJS, or with &lt;a href=&quot;https://github.com/amdjs/amdjs-api/wiki/AMD&quot; target=&quot;_blank&quot;&gt;AMD&lt;/a&gt;, my guess is you will still be able to understand how&lt;br /&gt;
it works.&lt;br /&gt;
&lt;a href=&quot;https://github.com/wix/react-templates&quot; target=&quot;_blank&quot;&gt;React Templates&lt;/a&gt;&amp;nbsp;is an amazing 3rd party library that helps you implement the &quot;render&quot; method&lt;br /&gt;
of React Components in an HTML like syntax. Totally cool.&lt;br /&gt;
&lt;br /&gt;
Good luck!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://tech-drum.blogspot.com/feeds/3930155348516001941/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-drum.blogspot.com/2015/04/simple-implementation-of-flux-with-react.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/3930155348516001941'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/3930155348516001941'/><link rel='alternate' type='text/html' href='http://tech-drum.blogspot.com/2015/04/simple-implementation-of-flux-with-react.html' title='Simple Webapp example using Flux with React'/><author><name>Nir Moav</name><uri>http://www.blogger.com/profile/05879703892878058262</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_YhL-QgTBnJEisOv9K2sPZAczuNBDmFdpgkw1qTciBtIL1avD1lhpVtiUSEEKQP9abLlp0nFY00ZwEnnug_MooVpBfoSf0hST2TD878F3oDU45H5lO12KyBHPdZT1ucRuHMqgyNwc8eTx/s72-c/Screen+Shot+2015-03-29+at+10.54.00+PM.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-224320715137455380.post-5676977418430024275</id><published>2014-01-25T23:42:00.001+02:00</published><updated>2014-01-31T09:46:07.962+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Build"/><category scheme="http://www.blogger.com/atom/ns#" term="Grunt"/><category scheme="http://www.blogger.com/atom/ns#" term="Javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="Node"/><category scheme="http://www.blogger.com/atom/ns#" term="NPM"/><category scheme="http://www.blogger.com/atom/ns#" term="Plugin"/><title type='text'>Grunt - Create your custom local Grunt plugin</title><content type='html'>This post describes how you can write your own Grunt Plugin in Javascript and install it locally,&lt;br /&gt;
in order to use it on your own (Grunt) project build file.&lt;br /&gt;
&lt;br /&gt;
If you don&#39;t know what Grunt is then to explain it on one leg -&lt;br /&gt;
&quot;Grunt is a pluggable (JavaScript) task runner&quot;, which can be used to build JavaScript projects.&lt;br /&gt;
&lt;br /&gt;
Such typical build of a Javascript project may contain a Linting task, minification task, and so on...&lt;br /&gt;
&lt;br /&gt;
So, you can &lt;a href=&quot;http://gruntjs.com/&quot; target=&quot;_blank&quot;&gt;read more about Grunt&lt;/a&gt; if you want to get a better understanding.&lt;br /&gt;
&lt;br /&gt;
And now, to the recipe!&lt;br /&gt;
&lt;u&gt;&lt;b&gt;Ingredients:&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
1 &lt;a href=&quot;http://nodejs.org/&quot; target=&quot;_blank&quot;&gt;NPM&lt;/a&gt; installed on your machine&lt;br /&gt;
1 &lt;a href=&quot;http://git-scm.com/book/en/Getting-Started-Installing-Git&quot; target=&quot;_blank&quot;&gt;GIT&lt;/a&gt; installed on your machine&lt;br /&gt;
1 Skill writing a tiny bit of Javascript&lt;br /&gt;
A zest of patience&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;u&gt;Instructions:&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
1. First thing would be to install a Grunt plugin that is used for templates scaffolding.&lt;br /&gt;
In order to do that, you need to run the following in your shell:&lt;br /&gt;
&lt;pre style=&quot;background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; color: #333333; font-family: Consolas, &#39;Liberation Mono&#39;, Courier, monospace; font-size: 13px; line-height: 19px; margin-bottom: 15px; margin-top: 15px; overflow: auto; padding: 6px 10px; word-wrap: normal;&quot;&gt;&lt;code style=&quot;background-color: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: none; box-sizing: border-box; font-family: Consolas, &#39;Liberation Mono&#39;, Courier, monospace; font-size: 12px; margin: 0px; padding: 0px; word-wrap: normal;&quot;&gt;$ npm install -g grunt-init&lt;/code&gt;&lt;/pre&gt;
2. Clone a GIT repository which is going to be used as your template for creating your glorious &lt;br /&gt;
Grunt Plugin. (&lt;a href=&quot;https://github.com/gruntjs/grunt-init-gruntplugin&quot;&gt;https://github.com/gruntjs/grunt-init-gruntplugin&lt;/a&gt;)&lt;br /&gt;
So, run the following in your shell:&lt;br /&gt;
&lt;pre style=&quot;background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; color: #333333; font-family: Consolas, &#39;Liberation Mono&#39;, Courier, monospace; font-size: 13px; line-height: 19px; margin-bottom: 15px; margin-top: 15px; overflow: auto; padding: 6px 10px; word-wrap: normal;&quot;&gt;&lt;code style=&quot;background-color: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: none; box-sizing: border-box; font-family: Consolas, &#39;Liberation Mono&#39;, Courier, monospace; font-size: 12px; margin: 0px; padding: 0px; word-wrap: normal;&quot;&gt;$ git clone https://github.com/gruntjs/grunt-init-gruntplugin.git ~/.grunt-init/gruntplugin&lt;/code&gt;&lt;/pre&gt;
3. Create an empty directory where you want to place your Plugin like &quot;&lt;i&gt;my-custom-plugin&lt;/i&gt;&quot;, and &lt;i&gt;cd&lt;/i&gt;&amp;nbsp;into it.&lt;br /&gt;
&lt;pre style=&quot;background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; color: #333333; font-family: Consolas, &#39;Liberation Mono&#39;, Courier, monospace; line-height: 19px; margin-bottom: 15px; margin-top: 15px; overflow: auto; padding: 6px 10px; word-wrap: normal;&quot;&gt;&lt;span style=&quot;font-size: 12px;&quot;&gt;$ mkdir my-custom-plugin
$ cd my-custom-plugin&lt;/span&gt;&lt;/pre&gt;
Then run the following in your shell:&lt;br /&gt;
&lt;pre style=&quot;background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; color: #333333; font-family: Consolas, &#39;Liberation Mono&#39;, Courier, monospace; font-size: 13px; line-height: 19px; margin-bottom: 15px; margin-top: 15px; overflow: auto; padding: 6px 10px; word-wrap: normal;&quot;&gt;&lt;code style=&quot;background-color: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: none; box-sizing: border-box; font-family: Consolas, &#39;Liberation Mono&#39;, Courier, monospace; font-size: 12px; margin: 0px; padding: 0px; word-wrap: normal;&quot;&gt;$ grunt-init gruntplugin&lt;/code&gt;&lt;/pre&gt;
4. You should now be prompted with a serie of questions in the shell, in order to create your plugin.&lt;br /&gt;
You should be seeing something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; color: #333333; font-family: Consolas, &#39;Liberation Mono&#39;, Courier, monospace; font-size: 13px; line-height: 19px; margin-bottom: 15px; margin-top: 15px; overflow: auto; padding: 6px 10px; word-wrap: normal;&quot;&gt;&lt;code style=&quot;background-color: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: none; box-sizing: border-box; font-family: Consolas, &#39;Liberation Mono&#39;, Courier, monospace; font-size: 12px; margin: 0px; padding: 0px; word-wrap: normal;&quot;&gt;Please answer the following:

[?] Project name (grunt-my-custom-plugin)

[?] Description (The best Grunt plugin ever.) the best custom plugin ever!

[?] Version (0.1.0)

[?] Project git repository (ssh://&lt;b&gt;&lt;i&gt;&amp;lt;Your GIT remote Repository URL&amp;gt;&lt;/i&gt;&lt;/b&gt;)

[?] Project homepage (none)

[?] Project issues tracker (none)

[?] Licenses (MIT)

[?] Author name (nirgit) Nir M

[?] Author email (getnirm@gmail.com)

[?] Author url (none) tech-drum.blogspot.com

[?] What versions of grunt does it require? (~0.4.2)

[?] What versions of node does it run on? (&amp;gt;= 0.8.0)

[?] Do you need to make any changes to the above before continuing? (y/N) N



Writing .gitignore...OK

Writing .jshintrc...OK

Writing Gruntfile.js...OK

Writing README.md...OK

Writing tasks/my_custom_plugin.js...OK

Writing test/expected/custom_options...OK

Writing test/expected/default_options...OK

Writing test/fixtures/123...OK

Writing test/fixtures/testing...OK

Writing test/my_custom_plugin_test.js...OK

Writing LICENSE-MIT...OK

Writing package.json...OK



Initialized from template &quot;gruntplugin&quot;.

You should now install project dependencies with npm install. After that, you

may execute project tasks with grunt. For more information about installing

and configuring Grunt, please see the Getting Started guide:



http://gruntjs.com/getting-started



Done, without errors.
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
5. Now you should have your directory containing a Grunt Plugin template.&lt;br /&gt;
Open the file you have inside the &quot;&lt;i&gt;tasks&lt;/i&gt;&quot; directory in order to edit it.&lt;br /&gt;
&lt;br /&gt;
6. The file should look as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5Z2Btt5_AnRETXVmtI9rYm_xk26Ig2nOtsBFRm0o3l-Z-KcZpDeSWjnrel9FDfKmbqbVh2meHDRJIpgF8tYr1RY3nHXip04tUHcc6AI4C57hNcVWUb754CxduXdPGAoVOb-IFonlKdfV2/s1600/grunt-plugin-template.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5Z2Btt5_AnRETXVmtI9rYm_xk26Ig2nOtsBFRm0o3l-Z-KcZpDeSWjnrel9FDfKmbqbVh2meHDRJIpgF8tYr1RY3nHXip04tUHcc6AI4C57hNcVWUb754CxduXdPGAoVOb-IFonlKdfV2/s1600/grunt-plugin-template.png&quot; height=&quot;337&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
7. Just in order to get started, lets strip the file and change it to contain the following:&lt;br /&gt;
&lt;pre style=&quot;background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; margin-bottom: 15px; margin-top: 15px; overflow: auto; padding: 6px 10px; word-wrap: normal;&quot;&gt;&lt;pre&gt;/*
 * grunt-my-custom-plugin
 * 
 *
 * Copyright (c) 2014 Nir M
 * Licensed under the MIT license.
 */

&#39;use strict&#39;;

module.exports = function(grunt) {

 grunt.file.defaultEncoding = &#39;utf8&#39;;

 // Please see the Grunt documentation for more information regarding task
 // creation: http://gruntjs.com/creating-tasks

 grunt.registerTask(&#39;&lt;b&gt;my_custom_plugin&lt;/b&gt;&#39;, function() {
  grunt.log.writeln(&#39;Hello my great Grunt Plugin!&#39;) ;
 });
};&lt;/pre&gt;
&lt;/pre&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Times New Roman;&quot;&gt;&lt;span style=&quot;white-space: normal;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
The &lt;b&gt;my_custom_plugin&lt;/b&gt;&amp;nbsp;shown in bold above, is the name of your task in the Grunt build, that&lt;br /&gt;
you&#39;ll execute at the end.&lt;br /&gt;
&lt;br /&gt;
Lets change the &lt;i&gt;Gruntfile.js&lt;/i&gt; in the root directory of the Plugin so &lt;i&gt;tests&lt;/i&gt; won&#39;t execute when&lt;br /&gt;
we will run &quot;&lt;i&gt;grunt&lt;/i&gt;&quot; on the plugin&#39;s source. Otherwise the build would fail.&lt;br /&gt;
So now the &lt;i&gt;Gruntfile.js &lt;/i&gt;last line should look like:&lt;br /&gt;
&lt;pre style=&quot;background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; margin-bottom: 15px; margin-top: 15px; overflow: auto; padding: 6px 10px; word-wrap: normal;&quot;&gt;&lt;span style=&quot;font-family: Times New Roman;&quot;&gt;&lt;span style=&quot;white-space: normal;&quot;&gt;grunt.registerTask(&#39;default&#39;, [&#39;jshint&#39;]);&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
8. Go back to the root directory of your Grunt Plugin and run the following:&lt;br /&gt;
&lt;pre style=&quot;background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; color: #333333; font-family: Consolas, &#39;Liberation Mono&#39;, Courier, monospace; font-size: 13px; line-height: 19px; margin-bottom: 15px; margin-top: 15px; overflow: auto; padding: 6px 10px; word-wrap: normal;&quot;&gt;&lt;div style=&quot;color: black; font-family: &#39;Times New Roman&#39;; font-size: medium; line-height: normal; white-space: normal;&quot;&gt;
$ npm install&lt;/div&gt;
&lt;/pre&gt;
&lt;pre style=&quot;background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; margin-bottom: 15px; margin-top: 15px; overflow: auto; padding: 6px 10px; word-wrap: normal;&quot;&gt;&lt;div style=&quot;color: black; font-family: &#39;Times New Roman&#39;; font-size: medium; line-height: normal; white-space: normal;&quot;&gt;
$ grunt&lt;/div&gt;
&lt;div style=&quot;color: black; font-family: &#39;Times New Roman&#39;; font-size: medium; line-height: normal; white-space: normal;&quot;&gt;
&lt;/div&gt;
&lt;span style=&quot;font-family: Times New Roman;&quot;&gt;&lt;span style=&quot;white-space: normal;&quot;&gt;Running &quot;jshint:all&quot; (jshint) task&lt;/span&gt;&lt;/span&gt;

&lt;span style=&quot;font-family: Times New Roman;&quot;&gt;&lt;span style=&quot;white-space: normal;&quot;&gt;&amp;gt;&amp;gt; 3 files lint free.&lt;/span&gt;&lt;/span&gt;

&lt;span style=&quot;font-family: Times New Roman;&quot;&gt;&lt;span style=&quot;white-space: normal;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Times New Roman;&quot;&gt;&lt;span style=&quot;white-space: normal;&quot;&gt;Done, without errors.&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
9. Almost done.&lt;br /&gt;
Now go to your own project where you want to use your plugin and add the following line to the&lt;br /&gt;
&lt;i&gt;Gruntfile.js&lt;/i&gt;&amp;nbsp;of your project:&lt;br /&gt;
&lt;pre style=&quot;background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; margin-bottom: 15px; margin-top: 15px; overflow: auto; padding: 6px 10px; word-wrap: normal;&quot;&gt;&lt;span style=&quot;font-family: &#39;Times New Roman&#39;; white-space: normal;&quot;&gt;grunt.loadNpmTasks(&#39;grunt-my-custom-plugin&#39;);&lt;/span&gt;&lt;/pre&gt;
This will load your Grunt plugin task to your Grunt&#39;s project.&lt;br /&gt;
&lt;br /&gt;
10. Next step would be to install the plugin locally in the node modules of your Proect.&lt;br /&gt;
You should now run in the root directory of your Project (where you want to use your plugin) the following:&lt;br /&gt;
&lt;pre style=&quot;background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; margin-bottom: 15px; margin-top: 15px; overflow: auto; padding: 6px 10px; word-wrap: normal;&quot;&gt;&lt;span style=&quot;font-family: Times New Roman;&quot;&gt;&lt;span style=&quot;white-space: normal;&quot;&gt;$ npm install /&lt;b&gt;&lt;i&gt;&amp;lt;PATH_TO_YOUR_PLUGIN&amp;gt;&lt;/i&gt;&lt;/b&gt;/my-custom-plugin&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
11. You should now be able to execute:&lt;br /&gt;
&lt;pre style=&quot;background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; margin-bottom: 15px; margin-top: 15px; overflow: auto; padding: 6px 10px; word-wrap: normal;&quot;&gt;&lt;span style=&quot;font-family: Times New Roman;&quot;&gt;&lt;span style=&quot;white-space: normal;&quot;&gt;$&amp;nbsp;grunt &lt;b&gt;my_custom_plugin&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
And see:&lt;br /&gt;
&lt;pre style=&quot;background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; margin-bottom: 15px; margin-top: 15px; overflow: auto; padding: 6px 10px; word-wrap: normal;&quot;&gt;&lt;span style=&quot;font-family: Times New Roman;&quot;&gt;&lt;span style=&quot;white-space: normal;&quot;&gt;Running &quot;my_custom_plugin&quot; task&lt;/span&gt;&lt;/span&gt;

&lt;span style=&quot;font-family: Times New Roman;&quot;&gt;&lt;span style=&quot;white-space: normal;&quot;&gt;Hello my great Grunt Plugin!&lt;/span&gt;&lt;/span&gt;

&lt;span style=&quot;font-family: Times New Roman;&quot;&gt;&lt;span style=&quot;white-space: normal;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Times New Roman;&quot;&gt;&lt;span style=&quot;white-space: normal;&quot;&gt;Done, without errors.&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
That&#39;s all folks.&lt;br /&gt;
Hope this was helpful to get you started with Grunt Plugins.&lt;br /&gt;
Don&#39;t forget to publish it (&lt;span style=&quot;background-color: #f7f7f9; color: #dd1144; font-family: Monaco, Consolas, &#39;Lucida Console&#39;, monospace; font-size: 12.800000190734863px; line-height: 30px; white-space: nowrap;&quot;&gt;npm publish&lt;/span&gt;) afterwards to the rest of the Node community if you think it may be helpful to others as well.&lt;br /&gt;
&lt;br /&gt;
Check out the official guide for creating Grunt plugins at:&lt;br /&gt;
&lt;a href=&quot;http://gruntjs.com/creating-plugins&quot;&gt;http://gruntjs.com/creating-plugins&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Good luck!&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;http://gruntjs.com/img/grunt-logo.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://gruntjs.com/img/grunt-logo.png&quot; height=&quot;320&quot; width=&quot;271&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://tech-drum.blogspot.com/feeds/5676977418430024275/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-drum.blogspot.com/2014/01/grunt-create-your-custom-local-grunt.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/5676977418430024275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/5676977418430024275'/><link rel='alternate' type='text/html' href='http://tech-drum.blogspot.com/2014/01/grunt-create-your-custom-local-grunt.html' title='Grunt - Create your custom local Grunt plugin'/><author><name>Nir Moav</name><uri>http://www.blogger.com/profile/05879703892878058262</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5Z2Btt5_AnRETXVmtI9rYm_xk26Ig2nOtsBFRm0o3l-Z-KcZpDeSWjnrel9FDfKmbqbVh2meHDRJIpgF8tYr1RY3nHXip04tUHcc6AI4C57hNcVWUb754CxduXdPGAoVOb-IFonlKdfV2/s72-c/grunt-plugin-template.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-224320715137455380.post-6363969290498799375</id><published>2013-06-16T07:16:00.000+03:00</published><updated>2013-06-16T07:16:27.363+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Android"/><category scheme="http://www.blogger.com/atom/ns#" term="Book"/><category scheme="http://www.blogger.com/atom/ns#" term="C/C++"/><category scheme="http://www.blogger.com/atom/ns#" term="Debug"/><category scheme="http://www.blogger.com/atom/ns#" term="Free"/><category scheme="http://www.blogger.com/atom/ns#" term="Front End"/><category scheme="http://www.blogger.com/atom/ns#" term="java"/><category scheme="http://www.blogger.com/atom/ns#" term="NDK"/><category scheme="http://www.blogger.com/atom/ns#" term="Performance"/><category scheme="http://www.blogger.com/atom/ns#" term="Profiling"/><title type='text'>Lottery for winning a copy of the &quot;Android NDK Cookbook&quot; is now opened</title><content type='html'>In continuation to last week&#39;s post for winning a free copy of the eBook &quot;Android NDK Cookbook&quot;,&lt;br /&gt;
the lottery starts today!&lt;br /&gt;
&lt;br /&gt;
3 Lucky people will be given a free copy of the &quot;Android NDK Cookbook&quot; sponsored by &lt;a href=&quot;http://www.packtpub.com/android-native-development-kit-cookbook/book&quot; target=&quot;_blank&quot;&gt;&quot;&lt;i&gt;Packt Publishing&lt;/i&gt;&quot;&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;http://www.packtpub.com/android-native-development-kit-cookbook/book&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeYor7b9Yi_6TR0FRIyfA0-loxamnUcRMPmhq-ajzCnOqnaVDNj1arbl8CigcQExeFlzqaYwE7NNtHOnNpk5UFo25zxXuehJ0rAnJmzKSygw5HWdDfIv1Q9dWVj1nmWKFB9i0j56-6oO_d/s320/Android-NDK-Cookbook.jpg&quot; width=&quot;259&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h2&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;Description of the book&lt;/span&gt;&lt;/h2&gt;
&lt;div&gt;
&amp;nbsp;Android Native Development Kit Cookbook will help you understand the development, building, and debugging of your native Android applications. You will discover and learn JNI programming and essential NDK APIs such as OpenGL ES, and the native application API. You will then explore the process of porting existing libraries and software to NDK. By the end of this book you will be able to build your own apps in NDK apps.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h2&gt;
&lt;span style=&quot;font-size: small;&quot;&gt;Check it out on Packt Publishing:&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;http://www.packtpub.com/android-native-development-kit-cookbook/book&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;http://www.packtpub.com/android-native-development-kit-cookbook/book&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;div&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h2&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;How to participate?&lt;/span&gt;&lt;/h2&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;Simply send an email by &lt;a href=&quot;mailto:getnirm@gmail.com?subject=Android%20NDK%20Cookbook%20lottery&quot; target=&quot;_blank&quot;&gt;clicking here&lt;/a&gt; or by sending it to&lt;/span&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6c-6KUyA6TVN2S1YN9LLm6qVnVga-IR-GCCtdcnCs4wd7uGn9WkXuE4cHJdDPfduaDhgprLSma4-Hrmfa4w6Nx6HTlCTu4YdL2DJ46a9B-elVqzvyLReOdq_h-zvGq7rShXfeta6F-qxi/s1600/email.png&quot; imageanchor=&quot;1&quot; style=&quot;font-family: inherit; margin-left: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6c-6KUyA6TVN2S1YN9LLm6qVnVga-IR-GCCtdcnCs4wd7uGn9WkXuE4cHJdDPfduaDhgprLSma4-Hrmfa4w6Nx6HTlCTu4YdL2DJ46a9B-elVqzvyLReOdq_h-zvGq7rShXfeta6F-qxi/s1600/email.png&quot; /&gt;&lt;/a&gt;&amp;nbsp;&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;c&lt;span style=&quot;background-color: white; color: #222222; white-space: nowrap;&quot;&gt;ontaining a subject line &quot;&lt;b&gt;Android NDK Cookbook lottery&lt;/b&gt;&quot;.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;span style=&quot;background-color: white; color: #222222; white-space: nowrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;span style=&quot;background-color: white; color: #222222; white-space: nowrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;h2&gt;
&lt;span style=&quot;font-family: inherit; font-size: x-large;&quot;&gt;&lt;span style=&quot;background-color: white; color: #222222; white-space: nowrap;&quot;&gt;Deadline&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;div&gt;
&lt;span style=&quot;background-color: white; color: #222222; white-space: nowrap;&quot;&gt;The contest will close on 30th June 2013. Winners will be contacted by email, so be sure to use&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;background-color: white; color: #222222; white-space: nowrap;&quot;&gt;your real email address!&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;background-color: white; color: #222222; white-space: nowrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;background-color: white; color: #222222; white-space: nowrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;background-color: white; color: #222222; white-space: nowrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;background-color: white; color: #222222; white-space: nowrap;&quot;&gt;&lt;span style=&quot;font-size: large;&quot;&gt;Good luck !&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;background-color: white; color: #222222; white-space: nowrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;background-color: white; color: #222222; white-space: nowrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://tech-drum.blogspot.com/feeds/6363969290498799375/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-drum.blogspot.com/2013/06/lottery-for-winning-copy-of-android-ndk.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/6363969290498799375'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/6363969290498799375'/><link rel='alternate' type='text/html' href='http://tech-drum.blogspot.com/2013/06/lottery-for-winning-copy-of-android-ndk.html' title='Lottery for winning a copy of the &quot;Android NDK Cookbook&quot; is now opened'/><author><name>Nir Moav</name><uri>http://www.blogger.com/profile/05879703892878058262</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeYor7b9Yi_6TR0FRIyfA0-loxamnUcRMPmhq-ajzCnOqnaVDNj1arbl8CigcQExeFlzqaYwE7NNtHOnNpk5UFo25zxXuehJ0rAnJmzKSygw5HWdDfIv1Q9dWVj1nmWKFB9i0j56-6oO_d/s72-c/Android-NDK-Cookbook.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-224320715137455380.post-5126769165027274427</id><published>2013-06-08T23:12:00.000+03:00</published><updated>2013-06-08T23:12:14.776+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Android"/><category scheme="http://www.blogger.com/atom/ns#" term="Book"/><category scheme="http://www.blogger.com/atom/ns#" term="C/C++"/><category scheme="http://www.blogger.com/atom/ns#" term="Debug"/><category scheme="http://www.blogger.com/atom/ns#" term="Free"/><category scheme="http://www.blogger.com/atom/ns#" term="Front End"/><category scheme="http://www.blogger.com/atom/ns#" term="java"/><category scheme="http://www.blogger.com/atom/ns#" term="NDK"/><category scheme="http://www.blogger.com/atom/ns#" term="Performance"/><category scheme="http://www.blogger.com/atom/ns#" term="Profiling"/><title type='text'>Win a free eBook copy of &quot;Android NDK Cookbook&quot;</title><content type='html'>Are you an Android developer or interested in Android development?&lt;br /&gt;
This might interest you!&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
On the 16th of June 2013 I will conduct a lottery on the blog, to win a free eBook copy of &quot;Android NDK Cookbook&quot;.&lt;/h3&gt;
The lottery will last for 2 weeks (until June 30th) where you will be able to participate to win a free copy of the book.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
&lt;b&gt;&lt;u&gt;Description of the book:&lt;/u&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;h3&gt;
&lt;span style=&quot;font-weight: normal;&quot;&gt;&quot;Android Native Development Kit Cookbook&quot; will help you understand the development, building, and debugging of your native Android applications. You will discover and learn JNI programming and essential NDK APIs such as OpenGL ES, and the native application API. You will then explore the process of porting existing libraries and software to NDK. By the end of this book you will be able to build your own apps in NDK apps.&amp;nbsp;&lt;/span&gt;&lt;/h3&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOL6IX60Q6zCu6JoMCMMouXmoeQY6D1U-tbYowJVE4VxCZjR6w-le2BYa3T-o8lsGGmLs5gLTa4z9a9D3uTgA2arnfsGTm0Utf_-bnILo50Zs1Y4trThdVh8o5XJ_mVFy72G0Qm-hkav4R/s1600/Android-NDK-Cookbook.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOL6IX60Q6zCu6JoMCMMouXmoeQY6D1U-tbYowJVE4VxCZjR6w-le2BYa3T-o8lsGGmLs5gLTa4z9a9D3uTgA2arnfsGTm0Utf_-bnILo50Zs1Y4trThdVh8o5XJ_mVFy72G0Qm-hkav4R/s320/Android-NDK-Cookbook.jpg&quot; width=&quot;259&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-weight: normal;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-weight: normal;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
Further details of the book can be found here:&amp;nbsp;&lt;a href=&quot;http://www.packtpub.com/android-native-development-kit-cookbook/book&quot;&gt;http://www.packtpub.com/android-native-development-kit-cookbook/book&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Stay tuned for the 16th of June!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;* The copy of the book is sponsored thanks to&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&quot;&lt;a href=&quot;http://www.packtpub.com/&quot; target=&quot;_blank&quot;&gt;Packt Publishing&lt;/a&gt;&quot;.&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://tech-drum.blogspot.com/feeds/5126769165027274427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-drum.blogspot.com/2013/06/win-free-ebook-copy-of-android-ndk.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/5126769165027274427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/5126769165027274427'/><link rel='alternate' type='text/html' href='http://tech-drum.blogspot.com/2013/06/win-free-ebook-copy-of-android-ndk.html' title='Win a free eBook copy of &quot;Android NDK Cookbook&quot;'/><author><name>Nir Moav</name><uri>http://www.blogger.com/profile/05879703892878058262</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOL6IX60Q6zCu6JoMCMMouXmoeQY6D1U-tbYowJVE4VxCZjR6w-le2BYa3T-o8lsGGmLs5gLTa4z9a9D3uTgA2arnfsGTm0Utf_-bnILo50Zs1Y4trThdVh8o5XJ_mVFy72G0Qm-hkav4R/s72-c/Android-NDK-Cookbook.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-224320715137455380.post-3941213469940670493</id><published>2013-05-26T01:04:00.001+03:00</published><updated>2013-05-29T17:12:03.357+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Closure"/><category scheme="http://www.blogger.com/atom/ns#" term="Example"/><category scheme="http://www.blogger.com/atom/ns#" term="Front End"/><category scheme="http://www.blogger.com/atom/ns#" term="functions"/><category scheme="http://www.blogger.com/atom/ns#" term="Javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="Memory Model"/><title type='text'>Javascript Closure Functions Memory Model - How does it work?</title><content type='html'>Hey everyone,&lt;br /&gt;
For those of you who are writing code in &lt;b&gt;&lt;i&gt;Javascript &lt;/i&gt;&lt;/b&gt;or wish to do so, it is essential to understand&lt;br /&gt;
the concept of closures, and how they work.&lt;br /&gt;
&lt;br /&gt;
I must say that when I started looking into it, it was somewhat difficult to find proper material&lt;br /&gt;
on the web, to get a good grasp of how things work. So this post&#39;s idea is to try and shed some&lt;br /&gt;
light on this matter. I don&#39;t guarantee that this will make you understand everything, but do hope&lt;br /&gt;
it will help in some way.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;i style=&quot;font-weight: bold;&quot;&gt;*Note:&lt;/i&gt;&amp;nbsp;I could have some mistakes in this post of course, and would be very happy if you send me&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;any corrections or comment as this is suppose to help people, and show the power of Javascript closures.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;Everything that&#39;s written in this post is according to my understanding of how things work.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;So regard this writing with care. I tried to do the best I could when I wrote this post.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;u&gt;The post topics will contain 2 parts:&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
1. What is a Closure?&lt;br /&gt;
2. How does the memory model look like.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
&lt;b&gt;&lt;i&gt;1. What is a Closure?&lt;/i&gt;&lt;/b&gt;&lt;/h3&gt;
&quot;...&amp;nbsp;is a function or reference to a function together with a referencing environment—a table storing a reference to each of the non-local variables (also called free variables) of that function. A closure— unlike a plain function pointer—allows a function to access those non-local variables even when invoked outside of its immediate lexical scope.&lt;span style=&quot;background-color: white; font-family: sans-serif; font-size: 12.571428298950195px; line-height: 19.196428298950195px;&quot;&gt;&quot; - &lt;i&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Closure_(computer_science)&quot; target=&quot;_blank&quot;&gt;From Wikipedia.&lt;/a&gt;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/b&gt;
A simple example to such Closure is a counter.&lt;br /&gt;
Consider the following script for example:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot; style=&quot;background-color: #cccccc;&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;function createCounter() {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;var counter = 0 ;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return function() {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; counter++ ;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return counter ;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt;}&lt;/span&gt;&lt;span style=&quot;background-color: transparent;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/blockquote&gt;
&lt;blockquote class=&quot;tr_bq&quot; style=&quot;background-color: #cccccc;&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;var counter = createCounter() ;&lt;br /&gt;counter() ; &lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;// returns 1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;counter() ; &lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;// returns 2&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;var counter2 = createCounter() ;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;counter2() ; &lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;// returns 1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;counter() ; &lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;// returns 3&lt;/span&gt;&lt;/blockquote&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;b&gt;How does this work?&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
The &lt;i&gt;createCounter&lt;/i&gt;&amp;nbsp;function being executed creates a new &lt;i&gt;Execution Scope&lt;/i&gt;, which contains references to a variable named &lt;i&gt;counter &lt;/i&gt;and returns an anonymous function.&lt;br /&gt;
&lt;br /&gt;
So how does that function know about &lt;i&gt;counter&lt;/i&gt;&amp;nbsp;when it&#39;s executed?&lt;br /&gt;
In Javascript any function, has some kind of property called a &quot;Scope Chain&quot;, which defines the scopes the function is bounded to. When we define a function in Javascript, the &quot;&lt;i&gt;definition scope&lt;/i&gt;&quot; is such scope that is stored in the function&#39;s &quot;Scope chain&quot;. So when we define and return the anonymous function in &lt;i&gt;createCounter&lt;/i&gt;&amp;nbsp;that anonymous function is binded to a scope where it was defined.&lt;br /&gt;
Thus, when the function is being executed by calling &quot;&lt;i&gt;counter()&quot;&lt;/i&gt;&amp;nbsp;a new &quot;&lt;i&gt;execution scope&lt;/i&gt;&quot; is being created and added to the function&#39;s scope chain. So when the function needs to look up &lt;i&gt;counter&lt;/i&gt;&amp;nbsp;it looks up it&#39;s &quot;scope-chain&quot;, and finds it eventually on the &quot;&lt;i&gt;definition scope&lt;/i&gt;&quot; of the function.&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/b&gt;
Another thing to remember is that every time you run a function you run it inside a &quot;&lt;i&gt;context&lt;/i&gt;&quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;What is a &lt;i&gt;context&lt;/i&gt;?&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
A context is the object the function is executed on. It is recognized with the &lt;i&gt;this&lt;/i&gt;&amp;nbsp;keyword.&lt;br /&gt;
It is defined when we write the following code in Javascript for example:&lt;br /&gt;
&lt;br /&gt;
// context here equals to&amp;nbsp;&lt;i&gt;obj1 (this === obj1)&lt;/i&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; font-family: Courier New, Courier, monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;obj1.sayHello() ;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
// context here equals to the&amp;nbsp;&lt;i&gt;global object&lt;/i&gt;&amp;nbsp;which in case of a browser, is *&lt;i&gt;window&amp;nbsp;&lt;/i&gt;&lt;i&gt;(this === window)&lt;/i&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;background-color: white; font-family: Courier New, Courier, monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;sayHello() ; &lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; color: #0080ff; font-family: Consolas, &#39;Lucida Console&#39;, monospace; font-size: 12px; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
* It might be equal to undefined (this === undefined) in case we&#39;re running in &#39;&lt;i&gt;strict mode&lt;/i&gt;&#39;.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
You can check more about it at &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/this#Function_context&quot; target=&quot;_blank&quot;&gt;MDN - Function Context&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
&lt;b&gt;&lt;i&gt;2. How does the memory model look like?&lt;/i&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;div&gt;
I think it&#39;s important to understand how the memory model looks like, graphically, to get a better&lt;/div&gt;
&lt;div&gt;
notion of how things work. Even though you could handle without it, I find illustrations very&lt;/div&gt;
&lt;div&gt;
helpful understanding how something works.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
Simple example&lt;/h4&gt;
&lt;/div&gt;
&lt;div&gt;
When you define a regular function, like:&lt;/div&gt;
&lt;div&gt;
&lt;blockquote class=&quot;tr_bq&quot; style=&quot;background-color: #cccccc;&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;function foo(number) {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;[&amp;nbsp;&lt;i&gt;function_body &lt;/i&gt;]&lt;br /&gt;}&lt;/span&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
We get something of the following in memory:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwlLBayACSqtn-2w72B13H2jO_TKRTsjiMwi7A6fWO8KqhrakWlz6vRRT0lkImGhhWaxq1oYEU-Tk8g2wNNO1my6oyqgfVWr-CyrGGW2I0DSCp2Jb0LAmQgvlmf88EhhkrwcJWpnV4-3C8/s1600/foo.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;97&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwlLBayACSqtn-2w72B13H2jO_TKRTsjiMwi7A6fWO8KqhrakWlz6vRRT0lkImGhhWaxq1oYEU-Tk8g2wNNO1my6oyqgfVWr-CyrGGW2I0DSCp2Jb0LAmQgvlmf88EhhkrwcJWpnV4-3C8/s400/foo.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
If we execute &lt;i&gt;&lt;b style=&quot;background-color: #cccccc;&quot;&gt;foo(3)&lt;/b&gt;&lt;/i&gt;, we will get something of the following in memory:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmIlZMA3Wv3AVc5-fxItjPpmi4YUgjQQpbsSWjWE4dWPu47l97A5czZ2LfH8fnmaAa9pC1hnyby5-zCMQl43vLVej6URakIQjY1ju1-MiImQzI5POVVyoNZ0hwuhaTn6YIHvSC3EzYTw1J/s1600/foo-exec.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;195&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmIlZMA3Wv3AVc5-fxItjPpmi4YUgjQQpbsSWjWE4dWPu47l97A5czZ2LfH8fnmaAa9pC1hnyby5-zCMQl43vLVej6URakIQjY1ju1-MiImQzI5POVVyoNZ0hwuhaTn6YIHvSC3EzYTw1J/s400/foo-exec.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
So when &lt;i style=&quot;font-weight: bold;&quot;&gt;foo(3)&lt;/i&gt;&amp;nbsp;is executed, a new &lt;i&gt;&quot;Activation object&quot;&lt;/i&gt;&amp;nbsp;is created.&lt;br /&gt;
Passing to it the function&#39;s parameters and arguments array, and adding it to the scope chain of &lt;b style=&quot;font-style: italic;&quot;&gt;foo(3)&lt;/b&gt;.&lt;br /&gt;
So the next time &lt;b style=&quot;font-style: italic;&quot;&gt;foo&lt;/b&gt;&amp;nbsp;will be looking up for the &quot;&lt;i&gt;&lt;b&gt;num&lt;/b&gt;&quot; &lt;/i&gt;parameter, it will be looking it up the&lt;br /&gt;
&lt;i&gt;scope chain&lt;/i&gt;&amp;nbsp;starting from the closest(last) scope that is relevant to the execution, which in this&lt;br /&gt;
case is of course the &quot;Activation&quot;. If it won&#39;t find &lt;i style=&quot;font-weight: bold;&quot;&gt;num&lt;/i&gt;&amp;nbsp;there, it will continue to the next scope in the&lt;br /&gt;
chain, until it finds it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
Closure example&lt;/h4&gt;
&lt;div&gt;
Lets take the &lt;i style=&quot;font-weight: bold;&quot;&gt;Closure&lt;/i&gt;&amp;nbsp;example we referred to earlier - the counter function and see how it&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
would look like in memory.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Quick reminder, our&amp;nbsp;&lt;i style=&quot;font-weight: bold;&quot;&gt;counter&lt;/i&gt;&amp;nbsp;function looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot; style=&quot;background-color: #cccccc;&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;function createCounter() {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;var counter = 0 ;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return function() {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; counter++ ;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return counter ;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;}&lt;/span&gt;&lt;/blockquote&gt;
&lt;br /&gt;
This maps to a memory model which looks (somewhat) like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5kcErdxON1lFgfIJqsenLo_fGPQztV0hKw5PGoLLj9LsOKwq629z1o2dLpeypTkCU_J-WBh6gW_NT0roNKhtLJ8w_bOls4xubczCkuG0zahAOF7R7_4_CaRQWpzlZP7yobTIfqYSvTxU6/s1600/counter.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;counter javascript closure&quot; border=&quot;0&quot; height=&quot;275&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5kcErdxON1lFgfIJqsenLo_fGPQztV0hKw5PGoLLj9LsOKwq629z1o2dLpeypTkCU_J-WBh6gW_NT0roNKhtLJ8w_bOls4xubczCkuG0zahAOF7R7_4_CaRQWpzlZP7yobTIfqYSvTxU6/s400/counter.png&quot; title=&quot;&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
You might wonder why the &lt;i&gt;Closure&lt;/i&gt;&#39;s scope chain also refers to the Global Object.&lt;br /&gt;
The reason is that when we create a closure, it copies the scope chain of the execution context scope chain which in this case belongs to &lt;i&gt;createCounter()&lt;/i&gt;.&lt;br /&gt;
What makes the &lt;i&gt;Closure &lt;/i&gt;a &lt;i style=&quot;font-weight: bold;&quot;&gt;closure&lt;/i&gt;&amp;nbsp;is the interesting side affect in Javascript, that instead of the &lt;i&gt;Activation&lt;/i&gt;&amp;nbsp;&lt;i&gt;Object&lt;/i&gt;&amp;nbsp;being destroyed after &lt;i&gt;createCounter&lt;/i&gt;&amp;nbsp;execution, it remains alive, because there is a reference to it, from another function - the closure.&lt;br /&gt;
&lt;br /&gt;
Now, lets create such counter by executing the following:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot; style=&quot;background-color: #cccccc;&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;var myCounter = createCounter(); &amp;nbsp;[1]&lt;br /&gt;&lt;b&gt;myCounter() ;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/b&gt;[2]&lt;/span&gt;&lt;/blockquote&gt;
&lt;br /&gt;
So on line [1] we create &lt;i&gt;myCounter&lt;/i&gt;&amp;nbsp;which is a reference to the &lt;i&gt;closure&lt;/i&gt;&amp;nbsp;on the above illustration.&lt;br /&gt;
When we execute line [2], we get &lt;i style=&quot;font-weight: bold;&quot;&gt;1&lt;/i&gt;&amp;nbsp;as an answer, and the second time we will get &lt;i style=&quot;font-weight: bold;&quot;&gt;2.&lt;/i&gt;&lt;br /&gt;
How it looks in the memory is shown in the next illustration:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEip6w8oquGEa6FU3Sde1EZcTUZbwS0fZ6HyoGmYv6liFcxV4TxzflY1xtvALPCzEi3IsjQmscRqXMPcRGUr_uqEa47TI9ASSa3r2DbvjbO7aOpLXh789jNf_eMbDDvsVY_eFVxLJSG0vieq/s1600/counter-exec.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;292&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEip6w8oquGEa6FU3Sde1EZcTUZbwS0fZ6HyoGmYv6liFcxV4TxzflY1xtvALPCzEi3IsjQmscRqXMPcRGUr_uqEa47TI9ASSa3r2DbvjbO7aOpLXh789jNf_eMbDDvsVY_eFVxLJSG0vieq/s400/counter-exec.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
When we execute &lt;i&gt;&lt;b&gt;myCounter&lt;/b&gt;&lt;/i&gt;&amp;nbsp;which is our closure in this case, we are incrementing the &lt;span style=&quot;font-family: Courier New, Courier, monospace; font-style: italic;&quot;&gt;counter &lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;variable, but in order to do so, the variable needs to be reached somehow.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;This is where the &quot;&lt;i&gt;scope chain&lt;/i&gt;&quot; takes its place. The first &quot;environment&quot; where the variable is going to be looked up is at the top of the scope chain, in our case - the &lt;i&gt;&quot;Activation Object&quot;&lt;/i&gt;&amp;nbsp;of &lt;i&gt;myCounter&lt;/i&gt;.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;Since the variable is not an inner variable, nor a parameter, the &lt;i&gt;look-up&lt;/i&gt;&amp;nbsp;for the variable continues, and moves on to the next scope in the chain which is the &lt;i&gt;&quot;Activation Object&quot;&lt;/i&gt;&amp;nbsp;of &lt;i style=&quot;font-weight: bold;&quot;&gt;createCounter&lt;/i&gt;&amp;nbsp;! There it is found, read and assigned. (As counter++ is actually counter = counter + 1 ).&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;Note that every time you call &lt;i style=&quot;font-weight: bold;&quot;&gt;createCounter&lt;/i&gt;&amp;nbsp;a &lt;u&gt;new&lt;/u&gt;&amp;nbsp;&lt;i&gt;Activation Object&lt;/i&gt;&amp;nbsp;is created with a new &lt;/span&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;counter &lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;variable which equals to 0. This is how you can create as many separate counters as you like, without them affecting each other.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;I hope this helped you in some way to understand the memory model of functions and closures a little better. Any comments / suggestions and complaints are most welcome.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;Enjoy &quot;&lt;i&gt;closuring&lt;/i&gt;&quot;.&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://tech-drum.blogspot.com/feeds/3941213469940670493/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-drum.blogspot.com/2013/05/javascript-closure-memory-model-how.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/3941213469940670493'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/3941213469940670493'/><link rel='alternate' type='text/html' href='http://tech-drum.blogspot.com/2013/05/javascript-closure-memory-model-how.html' title='Javascript Closure Functions Memory Model - How does it work?'/><author><name>Nir Moav</name><uri>http://www.blogger.com/profile/05879703892878058262</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwlLBayACSqtn-2w72B13H2jO_TKRTsjiMwi7A6fWO8KqhrakWlz6vRRT0lkImGhhWaxq1oYEU-Tk8g2wNNO1my6oyqgfVWr-CyrGGW2I0DSCp2Jb0LAmQgvlmf88EhhkrwcJWpnV4-3C8/s72-c/foo.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-224320715137455380.post-7326335580718974824</id><published>2013-03-08T15:37:00.002+02:00</published><updated>2013-03-19T12:50:39.084+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Chrome"/><category scheme="http://www.blogger.com/atom/ns#" term="Example"/><category scheme="http://www.blogger.com/atom/ns#" term="Extension"/><category scheme="http://www.blogger.com/atom/ns#" term="Free"/><category scheme="http://www.blogger.com/atom/ns#" term="Front End"/><category scheme="http://www.blogger.com/atom/ns#" term="Github"/><category scheme="http://www.blogger.com/atom/ns#" term="GWT"/><category scheme="http://www.blogger.com/atom/ns#" term="jQuery"/><category scheme="http://www.blogger.com/atom/ns#" term="JSONP"/><category scheme="http://www.blogger.com/atom/ns#" term="REST"/><category scheme="http://www.blogger.com/atom/ns#" term="Rich Client"/><category scheme="http://www.blogger.com/atom/ns#" term="Server"/><category scheme="http://www.blogger.com/atom/ns#" term="Source Code"/><title type='text'>GWT Chrome extension with JSONP Server communication</title><content type='html'>I thought this post would be a good idea for people who want to know how to make an &#39;end-to-end&#39;&lt;br /&gt;
GWT Chrome extensions, with a connection to a server of their own.&lt;br /&gt;
&lt;br /&gt;
While this demonstrates specifically how to enable to communication from a Chrome extension, there is&lt;br /&gt;
no difference in code if you wish to deploy your client code else where (not on Chrome).&lt;br /&gt;
Many web applications choose to deploy their Server code &amp;amp; Client code on the same application server, like JBoss or Tomcat.&lt;br /&gt;
&lt;br /&gt;
As you know in GWT there are several ways to communicate with a server.&lt;br /&gt;
One of them is RPC for instance, which gives you the ability to invoke methods on a Java interface,&lt;br /&gt;
not having to deal with anything but Java code. Which is cool, as it makes a very smooth transition from&lt;br /&gt;
the client side code to the server side code.&lt;br /&gt;
&lt;br /&gt;
However, when we want to implement this in a Chrome extension things get a bit trickier.&lt;br /&gt;
The reason is that you&#39;d have to separate your server module from your Chrome extension module&lt;br /&gt;
(as we can&#39;t deploy Server side classes to Chrome - it runs only JavaScript),&lt;br /&gt;
and would need a shared model between the two in order to communicate.&lt;br /&gt;
It&#39;s not hard to do at all, it&#39;s only a longer example to make.&lt;br /&gt;
(In Eclipse, if you create a new &quot;Web Application Project&quot; using Google&#39;s plugin, you will have the client &amp;amp; server code in the same project, with a &quot;shared&quot; directory which serves a model bridge between the two).&lt;br /&gt;
&lt;br /&gt;
Another option that exists, is using &lt;b&gt;JSONP&lt;/b&gt; communication to the server.&lt;br /&gt;
In our case - this makes it a lot simpler.&lt;br /&gt;
We will expose some REST API on a Server we&#39;ll implement, for getting images, and send a JSONP request from the QuickPik extension to retrieve those images. Obviously, it can be anything else you want it to be in your application.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&lt;u&gt;TO THE CODE!!!&lt;/u&gt;&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/i&gt;&lt;/b&gt;
&lt;b&gt;&lt;u&gt;The Server&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
In order to create a REST service and expose it, we will use the &lt;a href=&quot;http://jersey.java.net/&quot; target=&quot;_blank&quot;&gt;Jersey &lt;/a&gt;library which is an implementation for&lt;br /&gt;
building RESTful web services. It&#39;s very simple.&lt;br /&gt;
&lt;br /&gt;
The following &lt;i&gt;QuickpikService&lt;/i&gt;&amp;nbsp;class, is our REST service:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #EEE;&quot;&gt;
&lt;br /&gt;
package quickpik.server.web;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import java.io.InputStream;&lt;br /&gt;
import java.net.MalformedURLException;&lt;br /&gt;
import java.net.URL;&lt;br /&gt;
import java.util.Date;&lt;br /&gt;
&lt;br /&gt;
import javax.ws.rs.GET;&lt;br /&gt;
import javax.ws.rs.Path;&lt;br /&gt;
import javax.ws.rs.Produces;&lt;br /&gt;
import javax.ws.rs.QueryParam;&lt;br /&gt;
import javax.ws.rs.core.MediaType;&lt;br /&gt;
&lt;br /&gt;
import org.codehaus.jettison.json.JSONException;&lt;br /&gt;
import org.codehaus.jettison.json.JSONObject;&lt;br /&gt;
&lt;br /&gt;
import com.sun.jersey.api.json.JSONWithPadding;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;@Path(&quot;/quickpik&quot;)&lt;/b&gt;&lt;br /&gt;
public class QuickPikService {&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;private final static int BUFFER_SIZE_IN_BYTES = 1024;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;private final static String FLICKR_API = &quot;http://api.flickr.com/services/feeds/photos_public.gne?format=json&amp;amp;tagmode=all&amp;amp;tags=&quot; ;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&lt;b&gt;@GET&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;@Path(&quot;searchPhotos&quot;)&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;@Produces({ &quot;application/x-javascript&quot;, MediaType.APPLICATION_JSON})&lt;/b&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;public JSONWithPadding getPhotos(@QueryParam(&quot;searchExp&quot;) String searchExp,&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;           &lt;/span&gt;@QueryParam(&quot;callback&quot;) String callback) {&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;// &quot;log&quot; the call&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;System.out.println(&quot;[&quot; + new Date() + &quot;] searching for: &quot; + searchExp) ;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;URL flickrUrl = getSearchURL(searchExp) ;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;JSONObject data = tryToGetSearchResult(flickrUrl);&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;return new JSONWithPadding(data, callback);&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;}&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;private URL getSearchURL(String searchExp) {&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;String composedURL = FLICKR_API + searchExp;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;try {&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;   &lt;/span&gt;return new URL(composedURL);&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;} catch (MalformedURLException e) {&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;   &lt;/span&gt;e.printStackTrace();&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;   &lt;/span&gt;throw new RuntimeException(&quot;URL composition failed. Please check your URL: &quot; + composedURL, e) ;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;}&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;}&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;private JSONObject tryToGetSearchResult(URL flickrUrl) {&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;try {&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;   &lt;/span&gt;return getSearchResult(flickrUrl) ;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;} catch (IOException | JSONException e) {&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;   &lt;/span&gt;e.printStackTrace();&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;   &lt;/span&gt;throw new RuntimeException(&quot;Failed searching.&quot;, e) ;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;}&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;}&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;private JSONObject getSearchResult(URL flickrUrl) throws IOException, JSONException {&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;InputStream is = flickrUrl.openStream() ;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;String result = readDataFromStream(is);&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;// Flickr specific string prefix for the JSON feed.&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;if(result.indexOf(&quot;jsonFlickrFeed(&quot;) &amp;gt;= 0) {&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;   &lt;/span&gt;result = result.substring(&quot;jsonFlickrFeed(&quot;.length(), result.length()-1) ;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;   &lt;/span&gt;return new JSONObject(result) ;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;} else {&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;   &lt;/span&gt;return new JSONObject(&quot;{}&quot;) ;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;}&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;}&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;private String readDataFromStream(InputStream is) throws IOException {&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;StringBuilder data = new StringBuilder() ;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;byte[] buffer = new byte[BUFFER_SIZE_IN_BYTES] ;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;int bytesRead = is.read(buffer) ;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;while(bytesRead != -1) {&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;   &lt;/span&gt;data.append(new String(buffer, 0, bytesRead)) ;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;   &lt;/span&gt;bytesRead = is.read(buffer) ;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;}&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;is.close() ;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;return data.toString() ;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;}&lt;br /&gt;
}&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
That&#39;s it. This our REST service, and we are exposing our API by using the &lt;b&gt;@Path&lt;/b&gt;&amp;nbsp;annotations&lt;br /&gt;
on the class and on the public method &lt;i&gt;getPhotos&lt;/i&gt;. There are also other annotations such as the&lt;br /&gt;
&lt;b&gt;@GET&lt;/b&gt;&amp;nbsp;annotation and the &lt;b&gt;@Produces&lt;/b&gt;&amp;nbsp;annotation which state that the method is invoked on&lt;br /&gt;
an HTTP GET, and returns (&lt;i&gt;@Produces&lt;/i&gt;&amp;nbsp;annotation) a JSON (with Padding eventually = JSONP) object.&lt;br /&gt;
&lt;br /&gt;
As you can see, in the class, we are using a Flickr API to get our images data from.&lt;br /&gt;
&lt;br /&gt;
Now all that&#39;s left in order to make this service work, is to define the Jersey servlet in the &lt;i style=&quot;font-weight: bold;&quot;&gt;web.xml&lt;/i&gt;&amp;nbsp;file,&lt;br /&gt;
which is done this way:&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #EEE;&quot;&gt;
&lt;br /&gt;
&amp;lt;web-app&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;servlet&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;lt;servlet-name&amp;gt;Jersey REST Service&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;lt;servlet-class&amp;gt;com.sun.jersey.spi.container.servlet.ServletContainer&amp;lt;/servlet-class&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;lt;init-param&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;&amp;lt;param-name&amp;gt;com.sun.jersey.config.property.packages&amp;lt;/param-name&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;&amp;lt;param-value&amp;gt;&lt;b&gt;quickpik.server.web&lt;/b&gt;&amp;lt;/param-value&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;lt;/init-param&amp;gt;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;lt;/servlet&amp;gt;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;lt;servlet-name&amp;gt;Jersey REST Service&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;lt;url-pattern&amp;gt;&lt;b&gt;/rest/*&lt;/b&gt;&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/web-app&amp;gt;&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
After doing that, we&#39;re able to refer to our REST service by using a URL in the browser:&lt;br /&gt;
&lt;b&gt;http://localhost:8080/&lt;i&gt;&amp;lt;web-app-name&amp;gt;&lt;/i&gt;/rest/quickpik/searchPhotos?searchExp=&lt;i&gt;&amp;lt;our-search-term&amp;gt;&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
In order to verify this worked indeed and to get a better understanding of how the strucutre of our JSON result looks like, before even writing code to the GWT Chrome extension client,&lt;br /&gt;
i did a small test using jQuery, to see whether this worked. - You can find it in the GitHub repository.&lt;br /&gt;
What I did in a nutshell, was to call the REST API:&lt;br /&gt;
&lt;b&gt;$.getJSON(&#39;http://localhost:8080/qpserver/rest/quickpik/searchPhotos?searchExp=hello&amp;amp;callback=?&#39;,&amp;nbsp;&lt;/b&gt;jsonCB&lt;b&gt;);&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
So I executed an AJAX call to search for &quot;hello&quot;, and passed a callback - &lt;i style=&quot;font-weight: bold;&quot;&gt;jsonCB&lt;/i&gt;&amp;nbsp;to process the result.&lt;br /&gt;
&lt;i style=&quot;font-weight: bold;&quot;&gt;jsonCB&lt;/i&gt;&amp;nbsp;looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #EEE;&quot;&gt;
&lt;br /&gt;
function jsonCB(result) {&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;console.log(result);&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;if (result !== null &amp;amp;&amp;amp; result) {&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;   &lt;/span&gt;if (result.items.length === 0) {&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;    &lt;/span&gt;$($(&quot;#serverResponses&quot;)[0]).append(&quot;No results.&quot;)&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;   &lt;/span&gt;} else {&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;    &lt;/span&gt;for (item in result.items) {&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;     &lt;/span&gt;&lt;span style=&quot;background-color: yellow;&quot;&gt;var url = &lt;b&gt;result.items[item].media.m&lt;/b&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;     &lt;/span&gt;var imgItem = document.createElement(&#39;img&#39;);&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;     &lt;/span&gt;imgItem.src = url;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;     &lt;/span&gt;$($(&quot;#serverResponses&quot;)[0]).append(&quot;Server response: &quot;)&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;       &lt;/span&gt;.append(url).append(&quot;&amp;lt;br&amp;gt;&quot;);&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;     &lt;/span&gt;$($(&quot;#serverResponses&quot;)[0]).append(imgItem).append(&quot;&amp;lt;br&amp;gt;&quot;);&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;   &lt;/span&gt;}&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;}&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;Note the highlighted text!&lt;/b&gt; - This is how we get the URL information of the photo items being sent back to us from the server.&lt;br /&gt;
So now we know that inside &quot;&lt;i&gt;result&quot;&lt;/i&gt;&amp;nbsp;which is a JSON object, resides an array of objects, that contain each&lt;br /&gt;
an object called &lt;i&gt;media&lt;/i&gt;&amp;nbsp;with a field called &lt;i&gt;m&lt;/i&gt;.&lt;br /&gt;
You can discover this by simply debugging the returned values from the Server in the browser.&lt;br /&gt;
&lt;br /&gt;
So now, we can finally add some code to our GWT Client.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;u&gt;&lt;i&gt;Client side - GWT Chrome extension&lt;/i&gt;&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;u&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/u&gt;&lt;/b&gt;
In the previous posts of QuickPik, you might have noticed, that in order to add an additional &lt;i&gt;ImageDataSource&lt;/i&gt;, all you need is to implement an Interface &lt;b&gt;IImagesDataSource&lt;/b&gt; and add that &lt;i&gt;ImageDataSource&lt;/i&gt;&amp;nbsp;to the &lt;b&gt;DataSource&lt;/b&gt;&amp;nbsp;enum.&lt;br /&gt;
It&#39;s much easier than it sounds.&lt;br /&gt;
So we need to do the following:&lt;br /&gt;
1. Write an &lt;i&gt;ImageDataSource&lt;/i&gt;&amp;nbsp;that &quot;talks&quot; to our Server.&lt;br /&gt;
2. Edit the &lt;i&gt;manifest.json&lt;/i&gt;&amp;nbsp;file to allow communication to our server in order to comply with the&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &quot;&lt;b&gt;&lt;i&gt;Content Security Policy&lt;/i&gt;&lt;/b&gt;&quot; of Chrome&#39;s extensions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&lt;u&gt;IImageDataSource implementation - ServerDS&lt;/u&gt;&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/i&gt;&lt;/b&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #EEE;&quot;&gt;
&lt;b&gt;&lt;i&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/i&gt;&lt;/b&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;public class ServerDS implements IImagesDataSource {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;private final static String QUICKPIK_SERVER_URL =&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;                                                  &lt;/span&gt;&quot;http://localhost:8080/qpserver/rest/quickpik/searchPhotos?searchExp=&quot; ;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;@Override&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;public void getImages(final String searchExpression, final FilterLevel filter,&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;final Callback&amp;lt;PhotosSearchResult, Void&amp;gt; callback) {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;String url = QUICKPIK_SERVER_URL + searchExpression ;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;&lt;b&gt;JsonpRequestBuilder jsonp = new JsonpRequestBuilder();&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;&lt;b&gt;jsonp.requestObject&lt;/b&gt;(url, new AsyncCallback&amp;lt;ServerResult&amp;gt;() {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;   &lt;/span&gt;public void onFailure(Throwable throwable) {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;    &lt;/span&gt;// do some error handling..&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;   &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;   &lt;/span&gt;public void onSuccess(ServerResult result) {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;    &lt;/span&gt;handleLoadedImagesResult(searchExpression, filter, result, callback) ;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;   &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;});&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;private void handleLoadedImagesResult(String searchExpression, FilterLevel filter, ServerResult result,&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;           &lt;/span&gt;Callback&amp;lt;PhotosSearchResult, Void&amp;gt; callback) {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;JsArray&amp;lt;ServerImageItem&amp;gt; imageItems = result.getItems();&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;LinkedList&amp;lt;Photo&amp;gt; photos = collectImages(imageItems);&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;callback.onSuccess(new PhotosSearchResult(searchExpression, filter, photos, 0, false)) ;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;private LinkedList&amp;lt;Photo&amp;gt; collectImages(JsArray&amp;lt;ServerImageItem&amp;gt; imageItems) {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;LinkedList&amp;lt;Photo&amp;gt; photos = new LinkedList&amp;lt;Photo&amp;gt;();&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;for (int i = 0; i &amp;lt; imageItems.length(); i++) {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;   &lt;/span&gt;ServerImageItem imageItem = imageItems.get(i);&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;   &lt;/span&gt;Photo p = new Photo(i+&quot;&quot;, imageItem.getImageURL(), imageItem.getImageURL()) ;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;   &lt;/span&gt;photos.add(p) ;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;return photos;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
I&#39;ll try to explain the code very shortly:&lt;br /&gt;
1. At the top of the class you can locate the URL to the server we will be using to get the images from.&lt;br /&gt;
2. &lt;i style=&quot;font-weight: bold;&quot;&gt;getImages&lt;/i&gt;&amp;nbsp;method which must be implemented is passed a &lt;i&gt;searchExpression&lt;/i&gt;&amp;nbsp;a &lt;i&gt;filter&lt;/i&gt;&amp;nbsp;and&lt;br /&gt;
&amp;nbsp; &amp;nbsp;a &lt;i&gt;callback.&amp;nbsp;&lt;/i&gt;We will ignore the &lt;i&gt;filter&lt;/i&gt;&amp;nbsp;to make things simpler.&lt;br /&gt;
&amp;nbsp; &amp;nbsp;GWT offers a class called &lt;i style=&quot;font-weight: bold;&quot;&gt;JsonpRequestBuilder&lt;/i&gt;&amp;nbsp;which allows us to invoke an asynchrounous&lt;br /&gt;
&amp;nbsp; &amp;nbsp;call to the server, and passing a callback to deal with the result of the invocation.&lt;br /&gt;
3. If the call was successful, we have to handle the result somehow. We do that by calling a&lt;i&gt;&amp;nbsp;handle&lt;/i&gt;&amp;nbsp;method.&lt;br /&gt;
4. In the &lt;i&gt;handleLoadedImagesResult&lt;/i&gt;&amp;nbsp;method, we got an object called &lt;i style=&quot;font-weight: bold;&quot;&gt;ServerResult.&amp;nbsp;&lt;/i&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &lt;i style=&quot;font-weight: bold;&quot;&gt;ServerResult&lt;/i&gt;&amp;nbsp;is a custom object created especially for this operation. It is a wrapper to&lt;br /&gt;
&amp;nbsp; &amp;nbsp; a JavaScriptObject, that gives access to the &lt;i style=&quot;font-weight: bold;&quot;&gt;result.items&lt;/i&gt;&amp;nbsp;object array. (Remember from the jQuery test?)&lt;br /&gt;
&lt;br /&gt;
This is how &lt;b&gt;ServerResult&lt;/b&gt;&amp;nbsp;looks like:&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #EEE;&quot;&gt;
&lt;br /&gt;
public class ServerResult extends &lt;b&gt;JavaScriptObject &lt;/b&gt;{&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp;protected ServerResult() {&lt;br /&gt;
&amp;nbsp; &amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&lt;b&gt; &amp;nbsp;public final native JsArray&amp;lt;ServerImageItem&amp;gt; getItems() /*-{&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;return this.items ;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp;}-*/;&lt;/b&gt;&lt;br /&gt;
}&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
The native&amp;nbsp;&lt;i&gt;getItems&lt;/i&gt;&amp;nbsp;method, is a convention of GWT to write JavaScript code to the underlying JavaScriptObject that the Java object wraps. So when you invoke &lt;i&gt;getItems,&amp;nbsp;&lt;/i&gt;behind the scenes the&lt;br /&gt;
JavaScript code &quot;&lt;i&gt;return this.items&quot; &lt;/i&gt;is executed, returning the JavaScript items Array.&lt;br /&gt;
&lt;br /&gt;
I also mapped the objects in this array to a Java object in the same way I did with &lt;b&gt;ServerResult&lt;/b&gt;.&lt;br /&gt;
Following the same idea, &lt;b&gt;ServerImageItem&lt;/b&gt;&amp;nbsp;looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #EEE;&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;br /&gt;
public class ServerImageItem extends JavaScriptObject {&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;protected ServerImageItem() {&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;}&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&lt;b&gt;public final native String getImageURL() /*-{&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &amp;nbsp; &lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;return this.media.m ;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp; &lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;}-*/;&lt;/b&gt;&lt;br /&gt;
}&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Here we use &lt;i&gt;getImageURL &lt;/i&gt;method to return the (JavaScript) object&#39;s &lt;i style=&quot;font-weight: bold;&quot;&gt;media.m&lt;/i&gt;&amp;nbsp;property.&lt;/div&gt;
&lt;div&gt;
(This is exactly the same structure that was referred to when testing with jQuery above).&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
So after this long explanation, all we do in the &quot;handle&quot; method, is basically gathering all of our&lt;br /&gt;
images URLs, creating a Photo list, like expected in the callback passed to us in the &lt;i style=&quot;font-weight: bold;&quot;&gt;getImages&lt;/i&gt;&amp;nbsp;method&lt;br /&gt;
invocation and invoking the callback, passing it an expected &lt;b&gt;&lt;i&gt;PhotoSearchResult&lt;/i&gt;&lt;/b&gt; object containing&lt;br /&gt;
our Photos.&lt;br /&gt;
&lt;br /&gt;
5. Now we must add our &lt;b&gt;ServerDS&lt;/b&gt;&amp;nbsp;to the &lt;b&gt;DataSource&lt;/b&gt;&amp;nbsp;enum, so it will be included as a data source&lt;br /&gt;
&amp;nbsp; &amp;nbsp; when we run a search.&lt;br /&gt;
&amp;nbsp; &amp;nbsp; We do that simply by adding the (&lt;b&gt;bolded&lt;/b&gt;) line below:&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #EEE;&quot;&gt;
public enum DataSource {&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;// add here your data sources&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;FLICKR(false, new FlickrDS()),&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&lt;b&gt;QUICKPIK_SERVER(true, new ServerDS())&lt;/b&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;....&lt;br /&gt;
}&lt;/div&gt;
&lt;br /&gt;
Notice how I intentionally turned off FLICKR Data Source, setting its &lt;i&gt;isEnabled&lt;/i&gt;&amp;nbsp;flag to &lt;i&gt;false.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
6. Last thing that needs to be done, is to enable our Chrome extension to make calls to our server by&lt;br /&gt;
&amp;nbsp; &amp;nbsp; editing the &lt;i&gt;manifest.json&lt;/i&gt;&amp;nbsp;file, adding the following line to it:&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #EEE;&quot;&gt;
{&lt;br /&gt;
&amp;nbsp; &amp;nbsp;....&lt;br /&gt;
&amp;nbsp; &amp;nbsp;// A relaxed policy definition which allows script resources to be loaded from localhost:8080 over HTTP&lt;br /&gt;
&amp;nbsp; &lt;b&gt;&quot;content_security_policy&quot;: &quot;script-src &#39;self&#39; http://localhost:8080; object-src &#39;self&#39;&quot;&lt;/b&gt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
That&#39;s all folks, all you need to do now, is build the Server (I did it with Gradle in this project), compile&lt;br /&gt;
your GWT client, deploy it on Chrome and watch it work.&lt;br /&gt;
&lt;br /&gt;
You can access all the code on GitHub, and download it.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;u&gt;&lt;span style=&quot;font-size: large;&quot;&gt;Code on GitHub&lt;/span&gt;&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;All of the project&#39;s code can be found on GitHub at:&amp;nbsp;&lt;a href=&quot;https://github.com/nirgit/Quickpik-with-server&quot;&gt;https://github.com/nirgit/Quickpik-with-server&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://tech-drum.blogspot.com/feeds/7326335580718974824/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-drum.blogspot.com/2013/03/gwt-chrome-extension-with-server.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/7326335580718974824'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/7326335580718974824'/><link rel='alternate' type='text/html' href='http://tech-drum.blogspot.com/2013/03/gwt-chrome-extension-with-server.html' title='GWT Chrome extension with JSONP Server communication'/><author><name>Nir Moav</name><uri>http://www.blogger.com/profile/05879703892878058262</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-224320715137455380.post-8746139511614283553</id><published>2013-01-30T15:41:00.003+02:00</published><updated>2013-02-01T15:41:30.365+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Ant"/><category scheme="http://www.blogger.com/atom/ns#" term="Build"/><category scheme="http://www.blogger.com/atom/ns#" term="Example"/><category scheme="http://www.blogger.com/atom/ns#" term="Github"/><category scheme="http://www.blogger.com/atom/ns#" term="Linux"/><category scheme="http://www.blogger.com/atom/ns#" term="RPM"/><category scheme="http://www.blogger.com/atom/ns#" term="Source Code"/><category scheme="http://www.blogger.com/atom/ns#" term="Ubuntu"/><title type='text'>RPM example - Application packaging</title><content type='html'>This post is about something quite different than the others.&lt;br /&gt;
It concerns packaging your software as an RPM file making it ready for delivery.&lt;br /&gt;
If you have never used RPM before and/or you&#39;re not an experienced Linux user, this post is intended for you.&lt;br /&gt;
&lt;br /&gt;
I&#39;m far from being an expert in this area, and I would guess there is probably a better way of achieving the goal I want to show here. Please share your thoughts and experience if you have any.&lt;br /&gt;
&lt;br /&gt;
I assume you already heard of RPM, and understand it&#39;s benefits and so on.&lt;br /&gt;
This post is not to convince you to use RPM, only how to create such RPM file which you could use.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;u&gt;What&#39;s in this example?&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
I created a &quot;Hello World&quot; Java application, and using Ant, I compile it, and Jar it.&lt;br /&gt;
This application could be anything you want - this is just a &quot;place-holder&quot; for you, to replace with&lt;br /&gt;
your real stuff.&lt;br /&gt;
&lt;br /&gt;
So, after having an RPM file, we&#39;ll be able to install it to the system and remove it afterwards.&lt;br /&gt;
The path which the program will be installed into will contain the &quot;Hello World&quot; application Jar.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;u&gt;RPM Structure quick overview&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
As you probably know by now, RPM files are created using a &quot;&lt;i&gt;.spec&lt;/i&gt;&quot; file.&lt;br /&gt;
This file tells the &lt;i style=&quot;font-weight: bold;&quot;&gt;rpmbuild&lt;/i&gt;&amp;nbsp;tool which we will use how to create the RPM package.&lt;br /&gt;
The &lt;i&gt;.spec&lt;/i&gt;&amp;nbsp;file contains several sections:&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;b&gt;&lt;u&gt;Headers&lt;/u&gt;&lt;/b&gt; - Headers of the spec file contain stuff like a &lt;i&gt;Summary&lt;/i&gt;&amp;nbsp;of what the package is,&lt;br /&gt;&lt;i&gt;Name&lt;/i&gt;&amp;nbsp;of the package,&lt;i&gt;&amp;nbsp;Version &lt;/i&gt;&amp;amp; &lt;i&gt;Release&lt;/i&gt;&amp;nbsp;information, &lt;i&gt;License &lt;/i&gt;&amp;amp;&lt;i&gt;&amp;nbsp;Package&lt;/i&gt;&amp;nbsp;and an&lt;br /&gt;attribute named &lt;i style=&quot;font-weight: bold;&quot;&gt;BuildRoot&lt;/i&gt;. &lt;i style=&quot;font-weight: bold;&quot;&gt;BuildRoot&lt;/i&gt;&amp;nbsp;is important - it specifies the location&lt;br /&gt;of where your package will be &lt;u&gt;temporarily&lt;/u&gt; installed.&lt;br /&gt;What I mean by temporarily, we&#39;ll get to later.&lt;/li&gt;
&lt;li&gt;&lt;u style=&quot;font-weight: bold;&quot;&gt;%description step&lt;/u&gt;&amp;nbsp;- This is where you can type just about anything you want describing&lt;br /&gt;your awesome application.&lt;/li&gt;
&lt;li&gt;&lt;u style=&quot;font-weight: bold;&quot;&gt;%prep step&lt;/u&gt;&amp;nbsp;- In the step, preparing your Source files to be built (using Ant in our example).&lt;br /&gt;&lt;i&gt;&quot;What&#39;s to prepare?&quot; - &lt;/i&gt;you ask? - Well, in order to build an RPM package, you must provide&lt;br /&gt;RPM a &lt;i&gt;.tar&lt;/i&gt;&amp;nbsp;file or a zipped file of some kind to it&#39;s SOURCES directory,&amp;nbsp;(I&#39;ll explain the &lt;br /&gt;structure of RPM further down), so what you need to do in this step is to extract your&lt;br /&gt;archived sources.&lt;/li&gt;
&lt;li&gt;&lt;u style=&quot;font-weight: bold;&quot;&gt;%build step&lt;/u&gt;&amp;nbsp;- This is where the actual build of your application happens. In our case, we&#39;ll&lt;br /&gt;execute &lt;i style=&quot;font-weight: bold;&quot;&gt;ant&lt;/i&gt;&amp;nbsp;on our build.xml file, that &lt;i&gt;compiles&lt;/i&gt; and &lt;i&gt;Jars&lt;/i&gt; the application - real simple.&lt;/li&gt;
&lt;li&gt;&lt;b style=&quot;text-decoration: underline;&quot;&gt;%install step&lt;/b&gt;&amp;nbsp;- This is the step that happens after the &lt;i&gt;%build&lt;/i&gt;&amp;nbsp;step, and will determine how&lt;br /&gt;your installed package will look like. We will &lt;b&gt;copy&lt;/b&gt;&amp;nbsp;the necessary binaries (Jar in our case) to&amp;nbsp;a relevant directory.&lt;/li&gt;
&lt;li&gt;&lt;u style=&quot;font-weight: bold;&quot;&gt;%files section&lt;/u&gt;&amp;nbsp;- This section determines which files from the &lt;i&gt;%install&lt;/i&gt;&amp;nbsp;step to pack, and with&amp;nbsp;what access rights.&lt;/li&gt;
&lt;li&gt;&lt;u style=&quot;font-weight: bold;&quot;&gt;%clean section&lt;/u&gt;&amp;nbsp;- This section runs after packaging was done, and cleans up all the leftovers&amp;nbsp;from your &lt;i&gt;build&lt;/i&gt; and your &lt;i&gt;install&lt;/i&gt; steps. It&#39;s important to delete all the old files, especially if you&amp;nbsp;build several RPM packages, you don&#39;t want to have files of another RPM build process in&amp;nbsp;your way.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Okay. I know this still doesn&#39;t tell you how to do stuff, but this introduction is quite important in my opinion.&lt;/div&gt;
&lt;div&gt;
So take a deep breathe one last time, and we&#39;ll go over the &lt;b&gt;&lt;i&gt;rpmbuild&lt;/i&gt;&lt;/b&gt; directory structure and understand the steps we need to take in order to accomplish our mission.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;u&gt;&lt;i&gt;&quot;rpmbuild&quot;&lt;/i&gt;&amp;nbsp;Directory structure&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
An important part of the way RPM works, is its directory structure where work is being done.&lt;/div&gt;
&lt;div&gt;
You should be able to locate your &lt;i style=&quot;font-weight: bold;&quot;&gt;rpmbuild&lt;/i&gt;&amp;nbsp;directory on your machine, which usually should&lt;/div&gt;
&lt;div&gt;
show under your home directory.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The &lt;b&gt;&lt;i&gt;rpmbuild&amp;nbsp;&lt;/i&gt;&lt;/b&gt;directory contains the following sub-directories:&lt;/div&gt;
&lt;div&gt;
&lt;ol&gt;
&lt;li&gt;&lt;b&gt;&lt;i&gt;BUILD&lt;/i&gt;&lt;/b&gt; - This is the directory where your sources will be built, and where the artifacts of your&amp;nbsp;build will be located. The &lt;b&gt;%build&lt;/b&gt;&amp;nbsp;step, &lt;b&gt;reads&lt;/b&gt; from the directory and &lt;b&gt;writes&lt;/b&gt; to it.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;i style=&quot;font-weight: bold;&quot;&gt;BUILDROOT&lt;/i&gt;&amp;nbsp;- This is the directory where you will &quot;&lt;i&gt;temporarily&lt;/i&gt;&quot; install your binaries to.&lt;br /&gt;You can think of it as the &quot;INSTALL&quot; directory. After the build step, the BUILDROOT&lt;br /&gt;serves as a directory to contain the files in a given directory structure. Those files in this&lt;br /&gt;specified directory structure will be installed afterwards using RPM.&lt;br /&gt;To clarify: If you place under BUILDROOT a directory called &lt;i style=&quot;font-weight: bold;&quot;&gt;my-app-123&lt;/i&gt;&amp;nbsp;then on the&lt;br /&gt;&lt;u&gt;real&lt;/u&gt;&amp;nbsp;install of the RPM package, your package will be installed under &lt;b&gt;/my-app-123&lt;/b&gt;.&lt;br /&gt;This step &lt;b&gt;reads&lt;/b&gt;&amp;nbsp;from the &lt;i&gt;BUILD&lt;/i&gt;&amp;nbsp;directory and &lt;b&gt;writes&lt;/b&gt;&amp;nbsp;to the &lt;i&gt;BUILDROOT&lt;/i&gt;&amp;nbsp;directory.&lt;/li&gt;
&lt;li&gt;&lt;i style=&quot;font-weight: bold;&quot;&gt;RPMS&lt;/i&gt;&amp;nbsp;- This is the directory that will contain your RPM package in the end.&lt;/li&gt;
&lt;li&gt;&lt;i style=&quot;font-weight: bold;&quot;&gt;SOURCES&lt;/i&gt;&amp;nbsp;- This is the directory where you should place your archived sources.&lt;/li&gt;
&lt;li&gt;&lt;i style=&quot;font-weight: bold;&quot;&gt;SPECS&lt;/i&gt;&amp;nbsp;- This is the directory where you should place your &lt;i&gt;.spec&lt;/i&gt;&amp;nbsp;file which will create&lt;br /&gt;the RPM package.&lt;/li&gt;
&lt;li&gt;&lt;i style=&quot;font-weight: bold;&quot;&gt;SRPMS&lt;/i&gt;&amp;nbsp;- This is a directory where source RPMs are created and stored.&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Each of those directories, can be referenced in the &lt;i&gt;.spec&lt;/i&gt;&amp;nbsp;file using RPM variables.&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;u&gt;Variables&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;%_specdir&lt;/td&gt;&lt;td&gt;~/rpmbuild/SPECS&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;%_sourcedir&lt;/td&gt;&lt;td&gt;~/rpmbuild/SOURCES&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;%_builddir&lt;/td&gt;&lt;td&gt;~/rpmbuild/BUILD&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;%_buildrootdir&lt;/td&gt;&lt;td&gt;~/rpmbuild/BUILDROOT&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;%_rpmdir&lt;/td&gt;&lt;td&gt;~/rpmbuild/RPMS&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;%_srcrpmdir&lt;/td&gt;&lt;td&gt;~/rpmbuild/SRPMS&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Now that we finished our overview. Let&#39;s go over our 8 steps to create a packaged application with RPM.&lt;/div&gt;
&lt;div&gt;
&lt;ol&gt;
&lt;li&gt;Create an application (write source code) - in our case, a simple &quot;Hello World&quot; application.&lt;/li&gt;
&lt;li&gt;Create the build file for the application - Ant&#39;s build.xml file in our case.&lt;/li&gt;
&lt;li&gt;Create an archive from our application&#39;s sources.&lt;/li&gt;
&lt;li&gt;Place the archive (tar) at &lt;i style=&quot;font-weight: bold;&quot;&gt;~/rpmbuild/SOURCES&lt;/i&gt;&amp;nbsp;directory.&lt;/li&gt;
&lt;li&gt;Copy the &lt;i style=&quot;font-weight: bold;&quot;&gt;.spec&lt;/i&gt;&amp;nbsp;file into the &lt;i style=&quot;font-weight: bold;&quot;&gt;~/rpmbuild/SPECS&lt;/i&gt;&amp;nbsp;directory.&lt;/li&gt;
&lt;li&gt;Create the RPM package using: &lt;b&gt;&lt;i&gt;rpmbuild -ba &amp;lt;spec_file&amp;gt;&lt;/i&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;Install the package.&lt;/li&gt;
&lt;li&gt;Uninstall the package.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
Now, lets go a bit into details:&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;ol&gt;
&lt;li&gt;You can download the pre-made application entirely from GitHub: &lt;a href=&quot;https://github.com/nirgit/RPM-Project-Example/raw/master/rpm-example-project.zip&quot; target=&quot;_blank&quot;&gt;rpm-example-project.zip&lt;/a&gt;&lt;br /&gt;in order to skip steps 1,2 and 3.&lt;br /&gt;(You can also access the repository -&amp;nbsp;&lt;a href=&quot;http://github.com/nirgit/RPM-Project-Example&quot; target=&quot;_blank&quot;&gt;http://github.com/nirgit/RPM-Project-Example&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;After downloading the zipped application, and extracting it somewhere on your machine,&lt;br /&gt;you can take a closer look into its hierarchy. You will find under the &lt;i&gt;Application&lt;/i&gt;&amp;nbsp;directory,&lt;br /&gt;a directory called &lt;i&gt;src&lt;/i&gt;&amp;nbsp;which contains the sources of our application, and you will find&lt;br /&gt;the &lt;i&gt;build.xml&lt;/i&gt;&amp;nbsp;file which builds the application.&lt;br /&gt;You will also find 2 other files - the &lt;i&gt;application.tar&lt;/i&gt;&amp;nbsp;containing the application sources,&lt;br /&gt;and the &lt;i&gt;project.spec&lt;/i&gt;&amp;nbsp;file.&lt;/li&gt;
&lt;li&gt;You need now to copy the &lt;i&gt;.spec&lt;/i&gt;&amp;nbsp;file into the &lt;b&gt;&lt;i&gt;~/rpmbuild/SPECS&lt;/i&gt;&amp;nbsp;&lt;/b&gt;directory, and the&lt;br /&gt;&lt;i&gt;application.tar&lt;/i&gt;&amp;nbsp;file into the &lt;i style=&quot;font-weight: bold;&quot;&gt;~/rpmbuild/SOURCES&lt;/i&gt;&amp;nbsp;directory.&lt;/li&gt;
&lt;li&gt;In order to create the package now, you&#39;re required to run the &lt;b&gt;&lt;i&gt;rpmbuild&lt;/i&gt;&amp;nbsp;&lt;/b&gt;tool, by&lt;br /&gt;executing: &amp;gt; &lt;b&gt;&lt;i style=&quot;background-color: #eeeeee;&quot;&gt;rpmbuild -ba ~/rpmbuild/SPECS/project.spec&lt;/i&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;Since I use Ubuntu, I also use &lt;i&gt;alien&lt;/i&gt;&amp;nbsp;to install the package. In case you&#39;re running on&lt;br /&gt;a Linux flavor such as CentOS, I think you can simply run the regular RPM install.&lt;br /&gt;With &lt;i&gt;alien&lt;/i&gt;: &amp;gt;&lt;span style=&quot;background-color: #eeeeee;&quot;&gt; &lt;b&gt;&lt;i&gt;sudo alien -i ~/rpmbuild/RPMS/i386/Example-RPM-Project-1.0-1.i386.rpm&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;Without: &amp;gt; &lt;b&gt;&lt;i style=&quot;background-color: #eeeeee;&quot;&gt;rpm -i&amp;nbsp;~/rpmbuild/RPMS/i386/Example-RPM-Project-1.0-1.i386.rpm&lt;/i&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;After the install you should be able to find the package installed under the root: &lt;br /&gt;&lt;b&gt;/Example-RPM-Project-1.0-1&lt;/b&gt;&lt;br /&gt;Under it, you can find the &lt;i style=&quot;font-weight: bold;&quot;&gt;app.jar.&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;You can uninstall the package using RPM&#39;s command: &lt;i style=&quot;background-color: #eeeeee; font-weight: bold;&quot;&gt;rpm -e &amp;lt;package_name&amp;gt;&lt;/i&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;br /&gt;or (in my case using Ubuntu): &lt;b&gt;&lt;i style=&quot;background-color: #eeeeee;&quot;&gt;sudo dpkg --remove example-rpm-project&lt;/i&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
&lt;b&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;u&gt;The SPEC file&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
This is the SPEC file associated with the RPM package.&lt;br /&gt;
I hope it will serve you as a good starting point for your own SPEC file.&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;background: #eeefff;&quot;&gt;
&lt;b&gt;&lt;/b&gt;&lt;br /&gt;
&lt;div&gt;
################################################################&lt;/div&gt;
&lt;div&gt;
#&lt;/div&gt;
&lt;div&gt;
# This is an example of a simple RPM spec file.&lt;/div&gt;
&lt;div&gt;
#&lt;/div&gt;
&lt;div&gt;
################################################################&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Summary: &lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;An RPM Spec example&lt;/div&gt;
&lt;div&gt;
Name: &lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;Example-RPM-Project&lt;/div&gt;
&lt;div&gt;
Version: &lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;1.0&lt;/div&gt;
&lt;div&gt;
Release:&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;1&lt;/div&gt;
&lt;div&gt;
License:&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;Apache 2.0&lt;/div&gt;
&lt;div&gt;
Group:&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;Applications/Sample&lt;/div&gt;
&lt;div&gt;
URL:&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;http://www.mycompany.com&lt;/div&gt;
&lt;div&gt;
Packager:&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;Nir Moav &amp;lt;getnirm@gmail.com&amp;gt;&lt;/div&gt;
&lt;div&gt;
BuildRoot:&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;%{_buildrootdir}/%{name}-%{version}-%{release}&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
%description&lt;/div&gt;
&lt;div&gt;
This is a sample SPEC file for the RPM project&lt;/div&gt;
&lt;div&gt;
demonstrating how to build, package, install(deploy)&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
%prep&lt;/div&gt;
&lt;div&gt;
# extract the tar file containing all the sources, to the build directory.&lt;/div&gt;
&lt;div&gt;
tar -xvf %{_sourcedir}/*.tar -C %{_builddir}&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
%build&lt;/div&gt;
&lt;div&gt;
echo &quot;Building the project...&quot;&lt;/div&gt;
&lt;div&gt;
cd Application&lt;/div&gt;
&lt;div&gt;
# running ant to build the java project (could be make/maven/gradle or anything else).&lt;/div&gt;
&lt;div&gt;
ant&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
%install&lt;/div&gt;
&lt;div&gt;
# This is the hierarchy which is going to be inside the package (RPM/Deb) eventually.&lt;/div&gt;
&lt;div&gt;
echo &quot;Install phase...&quot;&lt;/div&gt;
&lt;div&gt;
mkdir -p %{buildroot}/%{name}-%{version}-%{release}&lt;/div&gt;
&lt;div&gt;
cp -R %{_builddir}/Application/output/jars/* %{buildroot}/%{name}-%{version}-%{release}&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
%post&lt;/div&gt;
&lt;div&gt;
#This runs post the install - maybe you want to execute the application already then&lt;/div&gt;
&lt;div&gt;
echo &quot;Post install..&quot;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
%postun&lt;/div&gt;
&lt;div&gt;
#this runs after the uninstall&lt;/div&gt;
&lt;div&gt;
echo &quot;Post Uninstall...&quot;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
%files&lt;/div&gt;
&lt;div&gt;
# tells which files to contain in the package and with what access rights&lt;/div&gt;
&lt;div&gt;
# the triplet contains of (&amp;lt;file mode&amp;gt;, &amp;lt;user&amp;gt;, &amp;lt;group&amp;gt;). Make the necessary changes.&lt;/div&gt;
&lt;div&gt;
%defattr(-,nir,nir)&lt;/div&gt;
&lt;div&gt;
/*&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
%clean&lt;/div&gt;
&lt;div&gt;
# Clean up! Must run this! after build and install steps execute, this will make&lt;/div&gt;
&lt;div&gt;
# sure that the directories are remained clean, so in case you&#39;re building another&lt;/div&gt;
&lt;div&gt;
# package, you don&#39;t want to pack the previous build&#39;s artifacts.&lt;/div&gt;
&lt;div&gt;
rm -rf %{_builddir}/*&lt;/div&gt;
&lt;div&gt;
rm -rf %{_buildrootdir}/*&lt;/div&gt;
&lt;div style=&quot;font-weight: bold;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;i&gt;That&#39;s all folks!&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
I hope you managed to read through this long post, and found it useful.&lt;br /&gt;
&lt;br /&gt;
Enjoy,&lt;br /&gt;
Nir&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://tech-drum.blogspot.com/feeds/8746139511614283553/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-drum.blogspot.com/2013/01/application-packaging-example-with-rpm.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/8746139511614283553'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/8746139511614283553'/><link rel='alternate' type='text/html' href='http://tech-drum.blogspot.com/2013/01/application-packaging-example-with-rpm.html' title='RPM example - Application packaging'/><author><name>Nir Moav</name><uri>http://www.blogger.com/profile/05879703892878058262</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total><georss:featurename>Israel</georss:featurename><georss:point>31.046051 34.851611999999932</georss:point><georss:box>27.578269 29.688037999999931 34.513833 40.015185999999929</georss:box></entry><entry><id>tag:blogger.com,1999:blog-224320715137455380.post-6321565820190502349</id><published>2012-12-05T23:23:00.002+02:00</published><updated>2012-12-05T23:23:34.502+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Example"/><category scheme="http://www.blogger.com/atom/ns#" term="Game"/><category scheme="http://www.blogger.com/atom/ns#" term="Github"/><category scheme="http://www.blogger.com/atom/ns#" term="GWT"/><category scheme="http://www.blogger.com/atom/ns#" term="HTML5"/><category scheme="http://www.blogger.com/atom/ns#" term="Source Code"/><title type='text'>SpacePong - version 2 - HTML5 Game with GWT</title><content type='html'>Hey,&lt;br /&gt;
This is just a small update of the game, to make it a bit more fun to play actually.&lt;br /&gt;
So now you can pick different levels to play and have something a bit more challenging.&lt;br /&gt;
&lt;br /&gt;
The source code has changed of course, and you can find it like before on GitHub:&lt;br /&gt;
&lt;a href=&quot;https://github.com/nirgit/GwtPong/tree/space_pong_ver_2_0_0&quot;&gt;https://github.com/nirgit/GwtPong/tree/space_pong_ver_2_0_0&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;http://space-pong.appspot.com/&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;218&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaIQUf0nAmPPlziN7kObVasR3eCP8S3AIs1oaX7aTctYHqhyFQtFbnKprmJj8s9kkVCLJXhm6WJ3Or3Bz7Vl94Uv6jg0z-gvmpdsJ_zSI3745XaNccKQUO8JHuEsnTgQwvUN29DNh6jQLl/s400/spacepong-screenshot-ver2.png&quot; width=&quot;400&quot; /&gt; Space Pong&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Enjoy!</content><link rel='replies' type='application/atom+xml' href='http://tech-drum.blogspot.com/feeds/6321565820190502349/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-drum.blogspot.com/2012/12/spacepong-version-2-html5-game-with-gwt.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/6321565820190502349'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/6321565820190502349'/><link rel='alternate' type='text/html' href='http://tech-drum.blogspot.com/2012/12/spacepong-version-2-html5-game-with-gwt.html' title='SpacePong - version 2 - HTML5 Game with GWT'/><author><name>Nir Moav</name><uri>http://www.blogger.com/profile/05879703892878058262</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaIQUf0nAmPPlziN7kObVasR3eCP8S3AIs1oaX7aTctYHqhyFQtFbnKprmJj8s9kkVCLJXhm6WJ3Or3Bz7Vl94Uv6jg0z-gvmpdsJ_zSI3745XaNccKQUO8JHuEsnTgQwvUN29DNh6jQLl/s72-c/spacepong-screenshot-ver2.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-224320715137455380.post-4965319693301360293</id><published>2012-11-28T01:32:00.000+02:00</published><updated>2013-03-23T20:08:00.812+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Example"/><category scheme="http://www.blogger.com/atom/ns#" term="Free"/><category scheme="http://www.blogger.com/atom/ns#" term="Front End"/><category scheme="http://www.blogger.com/atom/ns#" term="Game"/><category scheme="http://www.blogger.com/atom/ns#" term="Github"/><category scheme="http://www.blogger.com/atom/ns#" term="GWT"/><category scheme="http://www.blogger.com/atom/ns#" term="HTML5"/><category scheme="http://www.blogger.com/atom/ns#" term="Source Code"/><title type='text'>GWT HTML5 Game Example - Pong </title><content type='html'>Hi everyone,&lt;br /&gt;
&lt;br /&gt;
This post is intended to present a very simple example of a game, made with the HTML5 support of GWT.&lt;br /&gt;
The game uses only GWT, without any other 3rd party libraries such as PlayN which works with GWT and is rather famous and meant for creating games based on HTML5.&lt;br /&gt;
Take a look at PlayN&#39;s website:&amp;nbsp;&lt;a href=&quot;http://code.google.com/p/playn/&quot;&gt;http://code.google.com/p/playn/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
GWT provides an API to the underlying HTML5 Canvas, and lets you use it to create&lt;br /&gt;
custom graphics.&lt;br /&gt;
&lt;br /&gt;
This example shows the game of Pong. Though the game might be a little buggy, it nevertheless makes use of the fundamental HTML5 Canvas features, such as drawing simple geometric shapes, such as rectangles,&amp;nbsp;circles,&amp;nbsp;gradients and with those elements creating a very simple and compact code&amp;nbsp;for a game.&lt;br /&gt;
&lt;br /&gt;
You can find all the code on GitHub for you to clone:&amp;nbsp;&lt;a href=&quot;https://github.com/nirgit/GwtPong&quot;&gt;https://github.com/nirgit/GwtPong&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Click the screenshot to play:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;http://space-pong.appspot.com/&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;249&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVNVfA5nmCDNYuZhiBKyEemqI4lMF6aV-Cti0IWpMzX_h-yEIhkYkAZod66rm9kH-4BxYw2XkOZgupd1aypvxufYGEV-eUMIo2i5n3jKhQFT7C3uMW_jb0o4VGcBCWkPTLaQQ57doz3vKu/s400/spacepong-screenshot.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Have fun playing!&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://tech-drum.blogspot.com/feeds/4965319693301360293/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-drum.blogspot.com/2012/11/pong-html5-game-example-with-gwt.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/4965319693301360293'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/4965319693301360293'/><link rel='alternate' type='text/html' href='http://tech-drum.blogspot.com/2012/11/pong-html5-game-example-with-gwt.html' title='GWT HTML5 Game Example - Pong '/><author><name>Nir Moav</name><uri>http://www.blogger.com/profile/05879703892878058262</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVNVfA5nmCDNYuZhiBKyEemqI4lMF6aV-Cti0IWpMzX_h-yEIhkYkAZod66rm9kH-4BxYw2XkOZgupd1aypvxufYGEV-eUMIo2i5n3jKhQFT7C3uMW_jb0o4VGcBCWkPTLaQQ57doz3vKu/s72-c/spacepong-screenshot.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-224320715137455380.post-5011818827119637522</id><published>2012-11-11T17:41:00.000+02:00</published><updated>2012-11-13T11:27:57.637+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Build"/><category scheme="http://www.blogger.com/atom/ns#" term="Example"/><category scheme="http://www.blogger.com/atom/ns#" term="Gradle"/><category scheme="http://www.blogger.com/atom/ns#" term="Groovy"/><category scheme="http://www.blogger.com/atom/ns#" term="java"/><title type='text'>Gradle - Opinion, experience and examples</title><content type='html'>&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;&lt;i&gt;Opinion and Experience&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
I had quite a short experience with Gradle, but the impression it left is of an incredible tool.&lt;br /&gt;
&lt;br /&gt;
I don&#39;t want to diss&amp;nbsp;any&amp;nbsp;other build tools out there like Ant or Maven, they&#39;re great,&lt;br /&gt;
and if you&#39;re a real savvy,&amp;nbsp;you&#39;ll get the job done probably pretty fast.&lt;br /&gt;
I generally believe that one needs to use the right tool for the right task, but I&#39;d dare say&lt;br /&gt;
that whatever you&#39;re doing with Maven or Ant you could probably do better with Gradle -&lt;br /&gt;
it is simpler, faster, shorter to write any build file, much more concise yet very powerful.&lt;br /&gt;
&lt;br /&gt;
I have also my experience with Ant for years and with Maven, and I can tell you that I appreciate&lt;br /&gt;
Ant very much as a build tool. It does exactly what you expect it to do.&lt;br /&gt;
When you read a &lt;i&gt;build.xml&lt;/i&gt; file, you&#39;d hardly find something you don&#39;t understand.&lt;br /&gt;
It&#39;s just clear how things work, and what is expected at the end.&lt;br /&gt;
The problem is, you need to write so much &quot;build code&quot; in order to get your job done, especially&lt;br /&gt;
in a complex system, when you have includes of other &lt;i&gt;extension.xml&lt;/i&gt; files you rely on and so on.&lt;br /&gt;
What about dependency resolution? - OK, so you could use Ivy, but that&#39;s just for dependency resolution.&lt;br /&gt;
It&#39;s not a &quot;full&quot; build tool in the sense of Maven that comes with creating your packages out of the box,&amp;nbsp;deploying it to your tomcat and distributing it to your Repository.&lt;br /&gt;
&lt;br /&gt;
Yes, Maven can be great but I must say that my &#39;like&#39; metric towards it is not so stable.&lt;br /&gt;
It is too complicated to get simple stuff done... compiling GWT? - Get a plugin!&lt;br /&gt;
In Ant, it&#39;s really simple to compile a GWT project + you get the example from the GWT website.&lt;br /&gt;
In Gradle you can simply execute Ant Tasks, so no plugin extra work needed.&lt;br /&gt;
Want to include / exclude resources from your WAR file... why does it have to be complicated?&lt;br /&gt;
Dependency management and resolution is awesome, distributing your artifacts into a repository&lt;br /&gt;
is great, and fairly easy to do.&lt;br /&gt;
&lt;br /&gt;
However, despite the good stuff of these build tools, I must say that from my personal experience &amp;nbsp;Gradle tops them.&lt;br /&gt;
Gradle like many other posts on the internet would say - brings all the good stuff from the worlds&lt;br /&gt;
of Ant and Maven while keeping the ugly stuff out.&lt;br /&gt;
&lt;br /&gt;
What do I mean by that?&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;It is the easiest build tool I&#39;ve seen to get started with - simply download, extract and set the GRADLE_HOME&amp;nbsp;environment variable on your path.&lt;br /&gt;Like Ant - no other configuration is needed! Sweet.&lt;/li&gt;
&lt;li&gt;Very well documented!&lt;/li&gt;
&lt;li&gt;You can execute any Ant task from the Gradle build files. Any.&lt;/li&gt;
&lt;li&gt;Dependency resolution - from Maven repositories, it leverages the existing repositories you may&amp;nbsp;already have in your corporation without needing to change anything, while decreasing the&amp;nbsp;verbosity of dependency declarations in the build file itself.&lt;/li&gt;
&lt;li&gt;Gradle is based on Groovy, so you can just program your build.&lt;br /&gt;And you can use all the libraries of Groovy. And it runs on the JVM, so you could theoretically use any Java&amp;nbsp;library you like when running the build.&lt;br /&gt;Did I already say &lt;i&gt;powerful&lt;/i&gt;?&lt;/li&gt;
&lt;li&gt;It is dynamic - You can tell Gradle in run-time for example, which sub-projects you&#39;d like to include in your Project&#39;s&amp;nbsp;build. I did that, using naming conventions for instance when I had a process that was auto-generating&amp;nbsp;entire projects ready to be built in a pre-compilation phase. Incredible!&lt;/li&gt;
&lt;li&gt;No need to sit and rewrite ant targets to do jobs like &lt;i&gt;clean, compile, jar, war&lt;/i&gt; etc... it is all there already!&lt;/li&gt;
&lt;li&gt;The integration with Eclipse is excellent. All you need is there.&lt;/li&gt;
&lt;li&gt;It just works!&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Let me give you an example of how a simple Gradle build (&lt;i&gt;build.gradle&lt;/i&gt;) file looks like:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot; style=&quot;background: rgb(230, 230, 230);&quot;&gt;
apply plugin: &#39;java&#39;&lt;br /&gt;
apply plugin: &#39;eclipse&#39;&lt;br /&gt;
sourceCompatibility = 1.6&lt;br /&gt;
version = &#39;1.0&#39;&lt;br /&gt;
jar {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; manifest {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; attributes &#39;Implementation-Title&#39;: &#39;My project&#39;, &#39;Implementation-Version&#39;: version&lt;br /&gt;
&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
}&lt;br /&gt;
repositories {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; mavenCentral()&lt;br /&gt;
}&lt;br /&gt;
dependencies {&lt;br /&gt;
&amp;nbsp; &amp;nbsp; compile group: &#39;commons-collections&#39;, name: &#39;commons-collections&#39;, version: &#39;3.2&#39;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; testCompile group: &#39;junit&#39;, name: &#39;junit&#39;, version: &#39;4.+&#39;&lt;br /&gt;
}&lt;/blockquote&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
I think that what is so nice about this build file, is that you can understand it right away.&lt;br /&gt;
Lets go over the lines to try and understand this file:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;The first two lines declaring the &quot;&lt;i&gt;apply plugin....&lt;/i&gt;&quot; means that you are telling Gradle to use plugins&amp;nbsp;such as &#39;&lt;i&gt;java&lt;/i&gt;&#39; for example to it would know how to compile Java source to classes.&lt;br /&gt;Gradle is based on plugins, which facilitate all the needed &#39;know-how&#39; and logic of performing&lt;br /&gt;various tasks. - You could write your own custom plugins as well.&lt;/li&gt;
&lt;li&gt;The &#39;&lt;i&gt;eclipse&#39;&lt;/i&gt;&amp;nbsp;plugin for example generates the needed files for importing your Gradle project into Eclipse.&lt;br /&gt;You can read more on that on - &lt;a href=&quot;http://gradle.org/docs/current/userguide/eclipse_plugin.html&quot; target=&quot;_blank&quot;&gt;The Eclipse Plugin&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;sourceCompatibility&lt;/i&gt;&amp;nbsp;- tells Gradle what version of Java your source files are written in.&lt;br /&gt;You can also specify the &#39;&lt;span style=&quot;color: #333333; font-size: 14px; line-height: 21px; white-space: nowrap;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;i&gt;targetCompatibility&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; font-family: &#39;Ubuntu Mono&#39;, courier, monospace; font-size: 14px; line-height: 21px; white-space: nowrap;&quot;&gt;&#39;&lt;/span&gt;&amp;nbsp;attribute in order to compile your sources into a lower&amp;nbsp;version of Java.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;version -&lt;/i&gt;&amp;nbsp;Declares a variable called &#39;&lt;i&gt;version&lt;/i&gt;&#39; with the version number of your package&lt;br /&gt;(Be it a JAR or WAR file).&amp;nbsp;The Jar files that are generated with the Gradle &#39;&lt;i&gt;build&lt;/i&gt;&#39; task, have a Maven convention. So the version&amp;nbsp;number is appended to the name of the package at the end. (for example: &quot;&lt;i&gt;MyPackage-&lt;b&gt;1.2&lt;/b&gt;.jar&lt;/i&gt;&quot;, in case &lt;i&gt;version&lt;/i&gt; was given the value &quot;1.2&quot;).&lt;/li&gt;
&lt;li&gt;&lt;i&gt;jar { ... }&lt;/i&gt;&amp;nbsp;- This is a Gradle Task is a &quot;task&quot; (can be thought of an Ant task) which is part of the&amp;nbsp;&#39;&lt;i&gt;java&#39;&lt;/i&gt;&amp;nbsp;plugin that assembles a Jar file from your compiled code.&lt;br /&gt;You can add to the manifest file your own attributes, such as a version number.&lt;br /&gt;Note that&amp;nbsp;&amp;nbsp;&lt;i&gt;&#39;Implementation-Version&#39;: &lt;/i&gt;&lt;b style=&quot;font-style: italic;&quot;&gt;version &lt;/b&gt;is using the version number declared earlier in paragraph 3,&amp;nbsp;but you could have used any other variable to place your value in there.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;repositories {&amp;nbsp;mavenCentral() }&lt;/i&gt; - determines the repositories from which you want to perform&amp;nbsp;dependency resolution. &lt;br /&gt;In this case - using the Maven Central repository.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;dependencies { ... } - &lt;/i&gt;determines the needed dependencies for your build.&lt;br /&gt;Like Maven&#39;s dependency scope, in Gradle there are also so called &#39;scopes&#39; which you declare for&amp;nbsp;your dependencies: &lt;i&gt;compile, runtime, testCompile &amp;amp; testRuntime.&lt;/i&gt;In this case we declare for example the following:&lt;br /&gt;&lt;i&gt;&lt;span style=&quot;background-color: #eeeeee;&quot;&gt;testCompile group: &#39;junit&#39;, name: &#39;junit&#39;, version: &#39;4.+&#39;&lt;/span&gt;&lt;/i&gt;Which makes sure to use the JUnit version 4 and above during compilation of test files.&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
That&#39;s it.&lt;br /&gt;
It&#39;s really short and simple!&lt;br /&gt;
Now you can just run from your command line : &amp;gt; &lt;b&gt;&lt;i&gt;gradle clean build&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
And you will get your project cleaned, compiled, packaged (&quot;Jarred&quot;), tested and with a JUnit test report, all&amp;nbsp;under the &lt;i&gt;&#39;build&#39;&lt;/i&gt;&amp;nbsp;directory of your project.&lt;br /&gt;
Of course, you can also distribute the artifacts (your Jars) to your repository, or just copy them&lt;br /&gt;
flat to an &quot;Artifacts&quot; directory of your project and so on.&lt;br /&gt;
&lt;br /&gt;
But this was only to demonstrate how easy it is to create a build file, that does so much.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&lt;span style=&quot;font-size: large;&quot;&gt;Examples&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Running an Ant Task from Gradle build file:&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
You can run an Ant tasks from a Gradle build file simply by writing something like this:&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
&lt;i style=&quot;background-color: #eeeeee;&quot;&gt;ant.echo(message: &quot;Building a project....&quot;)&lt;/i&gt;&lt;/blockquote&gt;
&lt;br /&gt;
This task in particular is not that useful... it&#39;s just a print, but it demonstrates how easy it is to execute&amp;nbsp;Ant tasks! &lt;br /&gt;
Especially if you consider migrating from Ant, and you have custom Ant Tasks written&lt;br /&gt;
which you want to re-use - then you could easily do this.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Running an external Java program from an external Jar:&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
This could be handy if you want to run anything which is for example at a pre/post phase&lt;br /&gt;
of the build.&lt;br /&gt;
The snippet below shows how you would apply an XSLT on a XML file, using &lt;br /&gt;
the &lt;a href=&quot;http://xalan.apache.org/index.html&quot; target=&quot;_blank&quot;&gt;&lt;b&gt;&lt;i&gt;xalan&lt;/i&gt;&lt;/b&gt;&amp;nbsp;&lt;/a&gt;library:&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot; style=&quot;background: rgb(230, 230, 230);&quot;&gt;
ant.java(jar: &quot;lib/xalan.jar&quot;, fork: &quot;true&quot;) {&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;arg(line: &quot;-xml&quot; + &quot; abc.xml&quot;)&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;arg(line: &quot;-xsl&quot; + &quot; myXslt.xsl&quot;)&lt;br /&gt;
}&lt;/blockquote&gt;
&lt;br /&gt;
(the &lt;i&gt;&quot;lib&quot;&lt;/i&gt;&lt;b style=&quot;font-style: italic;&quot;&gt;&amp;nbsp;&lt;/b&gt;directory is at the project&#39;s root directory as were the &quot;&lt;i&gt;abc.xml&lt;/i&gt;&quot; and &quot;&lt;i&gt;myXslt.xsl&lt;/i&gt;&quot; files).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Including Sub-Projects in your Project&#39;s build dynamically:&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
When your project is comprised from sub-projects, it is necessary to tell Gradle about&lt;br /&gt;
those sub-projects&amp;nbsp;in a dedicated file called &lt;i&gt;settings.gradle.&lt;/i&gt;&lt;br /&gt;
In that file, one needs to &quot;&lt;i&gt;include&lt;/i&gt;&quot; the sub-projects that need to be built by Gradle.&lt;br /&gt;
So typically you could see something like this:&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
&lt;i style=&quot;background-color: #eeeeee;&quot;&gt;include &#39;server&#39;, &#39;client&#39;&lt;/i&gt;&lt;/blockquote&gt;
The great thing about Gradle is that in the settings file you can pretty much put just about anything&lt;br /&gt;
you put in a build file. The settings file is executed in the initialization phase of the build.&lt;br /&gt;
So if you want to dynamically include sub-projects into your build because you&#39;re generating them&lt;br /&gt;
from another process, or because you have many of them, or for any other reason, you can do&lt;br /&gt;
something like this:&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;br /&gt;
&lt;div style=&quot;background: rgb(230, 230, 230);&quot;&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
&lt;i&gt;new File(&quot;.&quot;).eachFile(groovy.io.FileType.DIRECTORIES) {&amp;nbsp;&lt;/i&gt;&lt;i&gt;f -&amp;gt;&lt;/i&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;i&gt;if(f.name.startsWith(&quot;subProjectPrefix&quot;) {&lt;/i&gt;&lt;i&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/i&gt;&lt;/blockquote&gt;
&lt;i&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; include f&lt;/i&gt;&lt;i&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/i&gt;&lt;i&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/i&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
This will just iterate over the root directory of your project, check if the current directory&lt;br /&gt;
it iterates on&amp;nbsp;starts&amp;nbsp;with the &quot;&lt;i&gt;subProjectPrefix&lt;/i&gt;&quot; prefix, and includes it if it does.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This was really just the tip of what Gradle can offer you.&lt;br /&gt;
You can find many examples on the internet as well as on Gradle&#39;s installation directory.&lt;br /&gt;
(Look under %GRADLE_HOME%/samples - there are many build files examples).&lt;br /&gt;
So if you&#39;re using Ant, Ivy or Maven I recommend you to look into it, and give it a try,&lt;br /&gt;
I don&#39;t think you will regret it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Gradle -&amp;nbsp;&lt;a href=&quot;http://www.gradle.org/&quot; target=&quot;_blank&quot;&gt;http://www.gradle.org/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://tech-drum.blogspot.com/feeds/5011818827119637522/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-drum.blogspot.com/2012/11/gradle-opinion-experience-and-examples.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/5011818827119637522'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/5011818827119637522'/><link rel='alternate' type='text/html' href='http://tech-drum.blogspot.com/2012/11/gradle-opinion-experience-and-examples.html' title='Gradle - Opinion, experience and examples'/><author><name>Nir Moav</name><uri>http://www.blogger.com/profile/05879703892878058262</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-224320715137455380.post-4484880491476907156</id><published>2012-09-28T01:12:00.000+02:00</published><updated>2012-09-28T01:12:12.672+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Design"/><category scheme="http://www.blogger.com/atom/ns#" term="VCS"/><title type='text'>Merge on check-in, is there more to this?</title><content type='html'>&lt;div style=&quot;direction: ltr;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;
&lt;span style=&quot;font-size: 12.727272033691406px;&quot;&gt;In case you find yourself merging code very frequently when trying to commit/check in/push your changes to the version control system (VCS like GIT or SVN), you should&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 12.727272033691406px;&quot;&gt;start asking yourself -&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;
&lt;span style=&quot;font-size: 12.727272033691406px;&quot;&gt;&lt;b&gt;&lt;i&gt;&quot;Why am I merging so many times? What is the reason for this?&quot;.&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;direction: ltr;&quot;&gt;
&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;direction: ltr;&quot;&gt;
&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;If you are making lots of merges to your code - it could indicate a design problem in your project.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;direction: ltr;&quot;&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-size: 12.727272033691406px;&quot;&gt;&lt;span style=&quot;font-family: arial, sans-serif;&quot;&gt;(I am trying to be very careful here, as each project is&lt;/span&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt; unique in its&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;i&gt;characteristics&lt;/i&gt;&lt;/span&gt;&lt;span style=&quot;font-family: arial, sans-serif;&quot;&gt;&lt;i&gt;&amp;nbsp;&lt;/i&gt;&lt;span style=&quot;font-size: 12.727272033691406px;&quot;&gt;- the amount of code&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;and modules, the amount of people working on it, and so on, so it does not necessarily point that out).&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;
&lt;b&gt;&lt;i&gt;&quot;How come?&quot;&lt;/i&gt;&lt;/b&gt; you might ask...&lt;br /&gt;
&lt;span style=&quot;background-color: white; font-size: 12.727272033691406px;&quot;&gt;Basically merging happens when more than one party checks out a piece of code makes changes to it and then checks it in. Only the first party that checks in is avoiding a merge, but all others that made changes (to a now stale version of a file) will have to merge their changes with the latest commits.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;I heard many times the good argument that claims that to check-in small pieces of code at a time reduces the amount of merges and helps avoiding big sudden changes to the code which could render it buggy.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;While a &quot;small&quot; size of code is something subjective the idea is clear and makes sense.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;It is easy to keep track of small changes. A single bug fix or small enhancement and so on.&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;Although this is a good practice and will help you reduce the amount of merges, there are sometimes still situations where merges happen more than they should.&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;There could be another reason why you&#39;re merging more than you should, and this reason could be - a design &quot;problem&quot; in your code.&lt;/span&gt;&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;Such &quot;problem&quot; could be for example :&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;1. &lt;u&gt;&lt;b&gt;Classes that represent two (or more) logical units or&lt;/b&gt;&amp;nbsp;&lt;b&gt;well defined purpose&lt;/b&gt;&lt;/u&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;Then it&#39;s clear that if 2 people (or more) would need to make some changes regarding different functionalities of this class, because this is the way work was distributed in their team, those people are very likely to face merging issues when they will try to check-in their code.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;While if the class would have been splitted into 2 (or more) distinguished classes with clear purpose,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;then the 2 parties wouldn&#39;&lt;/span&gt;&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;t need to face a merging issue.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;
Unless... (here comes #2)&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;2. &lt;b&gt;&lt;u&gt;Dependencies &lt;/u&gt;&lt;/b&gt;- sure almost everyone has dependencies and that is how things work.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;But what happens if you are starting to have a lot of dependencies? Then you&#39;re also likely to face a merge.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;Only this time you&#39;ll have to change your &lt;u&gt;dependants&#39;&lt;/u&gt;&amp;nbsp;code (code who uses your class/interface as API) in order not to break compilation, and in those dependants is exactly where the merge lies.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;(Someone who just worked on that class earlier using your now &#39;old&#39; API... and now you have to adapt &lt;u&gt;their&lt;/u&gt; new code! - I&#39;m not talking about changing your interface or API as part of a general change in the infrastructure of the system, that is obvious, and intended to affect client code. I&#39;m talking about the times where it was not meant to be or shouldn&#39;t be due to bad design, wrong API usage and so on.)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;Although adapting client code might sound less problematic, reducing those incidents as much as possible by reducing the amount of your dependencies, will help you avoid more merges. (Changer point of view).&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;Also as a client, It would be less likely that so&lt;/span&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;span style=&quot;background-color: white; font-size: 12.727272033691406px;&quot;&gt;meone would come and change your client code, and adapt it in a way&amp;nbsp;&lt;/span&gt;that you did not mean.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;So if you&#39;re having lots of merges, try to understand &lt;b&gt;&lt;u&gt;why&lt;/u&gt;&lt;/b&gt; you have them before trying to resolve them. Sometimes it is very tempting to go on with the merge, as today there are good automatic tools to perform a merge. But, &lt;b&gt;&lt;u&gt;m&lt;/u&gt;&lt;/b&gt;&lt;u style=&quot;font-weight: bold;&quot;&gt;aybe&lt;/u&gt;&amp;nbsp;you&#39;ll find something interesting, or come up with a way to refactor code that was taken for granted as a &quot;law of nature&quot;.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;You&#39;ll eventually earn less merges, a more modular well defined code, and&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;become&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;less error prone,&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;After all, who hasn&#39;t made a mistake once of accidentally dropping some code on a merge?&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;
So not every merge is a reason to start wondering why this is happening, but it should make you at&amp;nbsp;&lt;span style=&quot;background-color: white; font-size: 12.727272033691406px;&quot;&gt;least aware of the situation and think whether it could be different.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;
Hope&amp;nbsp;
this post&amp;nbsp;wasn&#39;t stating the obvious.&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, sans-serif; font-size: 12.727272033691406px;&quot;&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://tech-drum.blogspot.com/feeds/4484880491476907156/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-drum.blogspot.com/2012/09/merge-on-check-in-is-there-more-to-this.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/4484880491476907156'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/4484880491476907156'/><link rel='alternate' type='text/html' href='http://tech-drum.blogspot.com/2012/09/merge-on-check-in-is-there-more-to-this.html' title='Merge on check-in, is there more to this?'/><author><name>Nir Moav</name><uri>http://www.blogger.com/profile/05879703892878058262</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-224320715137455380.post-6287296642494351727</id><published>2012-08-26T19:54:00.000+03:00</published><updated>2012-08-28T23:47:15.405+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Chrome"/><category scheme="http://www.blogger.com/atom/ns#" term="Example"/><category scheme="http://www.blogger.com/atom/ns#" term="Extension"/><category scheme="http://www.blogger.com/atom/ns#" term="Front End"/><category scheme="http://www.blogger.com/atom/ns#" term="Github"/><category scheme="http://www.blogger.com/atom/ns#" term="GWT"/><category scheme="http://www.blogger.com/atom/ns#" term="java"/><category scheme="http://www.blogger.com/atom/ns#" term="Rich Client"/><category scheme="http://www.blogger.com/atom/ns#" term="Source Code"/><title type='text'>GWT Chrome extension using version 2 manifest</title><content type='html'>Hi everyone,&lt;br /&gt;
&lt;br /&gt;
A while ago I wrote a small post about how to create Chrome extension using GWT, claiming&lt;br /&gt;
you could&amp;nbsp;use GWT to make powerful Chrome extension.&lt;br /&gt;
One of the comments was regarding the usage of the manifest version.&lt;br /&gt;
When you write a Chrome extension, you must provide with a file called &lt;i&gt;manifest.json &lt;/i&gt;which&lt;br /&gt;
serves&amp;nbsp;as some kind of descriptor file to your extension.&lt;br /&gt;
It contains all sorts of things, such as the name of the extension, description, icon, action,&lt;br /&gt;
javascript files&amp;nbsp;involved, and so on...&lt;br /&gt;
&lt;br /&gt;
One of the entries in that file is the &lt;i&gt;version&lt;/i&gt;&amp;nbsp;entry.&lt;br /&gt;
As for today Chrome supports the current version - 2, and also supports (for the moment)&lt;br /&gt;
version 1.&lt;br /&gt;
However, this is changing, and Google already announced that they will stop supporting version 1&lt;br /&gt;
in the&amp;nbsp;future (see&amp;nbsp;&lt;a href=&quot;http://developer.chrome.com/extensions/manifest.html#manifest_version&quot;&gt;http://developer.chrome.com/extensions/manifest.html#manifest_version&lt;/a&gt;), due&lt;br /&gt;
to security reasons.&lt;br /&gt;
&lt;br /&gt;
So I was asked whether it was possible or how is it possible to deploy the GWT extension with the&lt;br /&gt;
&lt;i&gt;version&lt;/i&gt;&amp;nbsp;2 attribute in the &lt;i&gt;manifest.json&lt;/i&gt;&amp;nbsp;file.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Version 2, &lt;/i&gt;is stricter in terms of security than version 1. Especially when it comes to using external JavaScript files.&lt;br /&gt;
You can read about security concerns over here:&lt;br /&gt;
&lt;a href=&quot;http://developer.chrome.com/extensions/content_scripts.html#security-considerations&quot;&gt;http://developer.chrome.com/extensions/content_scripts.html#security-considerations&lt;/a&gt;
&lt;br /&gt;
&lt;a href=&quot;http://developer.chrome.com/extensions/xhr.html&quot;&gt;http://developer.chrome.com/extensions/xhr.html&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
One of the problems I faced, was the inline scripting I had (JavaScript showing inside the HTML).&lt;br /&gt;
That problem came not only on my &quot;Hosting&quot; HTML file, but also on the compiled outputs of GWT,&lt;br /&gt;
where&amp;nbsp;HTML file which was needed was created and contained JavaScript code.&lt;br /&gt;
When that happened, I couldn&#39;t execute the extension on Chrome using &lt;i&gt;version 2&lt;/i&gt;&amp;nbsp;in the&lt;i&gt;&amp;nbsp;manifest.json&lt;/i&gt;&amp;nbsp;file.&lt;br /&gt;
&lt;br /&gt;
I wrote in response to a comment someone left regarding this problem, that in case Google would have a way to separate JavaScript files from HTML, then problems would be solved.&lt;br /&gt;
Back then, I didn&#39;t see such options for the GWT compiler.&lt;br /&gt;
&lt;br /&gt;
However, after doing some more searching, I found out that it does exist (!).&lt;br /&gt;
And so by adding a simple line in the &lt;i style=&quot;font-weight: bold;&quot;&gt;.gwt.xml &lt;/i&gt;file of the application, you can compile all&lt;br /&gt;
your GWT&amp;nbsp;application output into a single JavaScript file. Meaning - no HTML files containing&lt;br /&gt;
inline JavaScripts.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;The line one needs to add is:&lt;/u&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;...&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&amp;lt;add-linker name=&quot;sso&quot; /&amp;gt;&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;...&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/b&gt;
I added it to my &lt;i&gt;Quickpik.gwt.xml &lt;/i&gt;file, and so when you run the GWT compiler, you get at the end&lt;br /&gt;
one JavaScript file containing the entire code of your app. Awesome!&lt;br /&gt;
&lt;br /&gt;
You can access the entire code on Github and download it from there:&lt;br /&gt;
&lt;a href=&quot;https://github.com/nirgit/Quickpik&quot;&gt;https://github.com/nirgit/Quickpik&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
You can simply click on the &lt;i&gt;&quot;Downloads&quot;&lt;/i&gt;&amp;nbsp;on the right hand of the screen, in order to download&lt;br /&gt;
the repository as a ZIP file.&lt;br /&gt;
&lt;br /&gt;
In case you&#39;re a GIT user, my suggestion is that you just clone the repository. It&#39;s really small.&lt;br /&gt;
Simply open your GIT shell and type:&lt;br /&gt;
&lt;b&gt;&lt;i&gt;git clone&amp;nbsp;https://github.com/nirgit/Quickpik.git&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/b&gt;
The extension is already ready to be used in Chrome, and you can deploy it by opening Chrome&#39;s&lt;br /&gt;
&lt;i&gt;Tools -&amp;gt; Extensions &lt;/i&gt;tab, and checking the &quot;&lt;i&gt;Developer mode&lt;/i&gt;&quot; box.&lt;br /&gt;
Afterwards, you will be able to deploy the extension by selecting the &quot;&lt;i&gt;Load unpacked extension...&quot;&lt;/i&gt;&lt;br /&gt;
option&amp;nbsp;and selecting the &lt;i style=&quot;font-weight: bold;&quot;&gt;war&lt;/i&gt;&amp;nbsp;directory of &lt;i&gt;Quickpik.&lt;/i&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/b&gt;
I am hoping this is somewhat useful.&lt;br /&gt;
I think GWT is an absolutely great tool, and one that can be a lot of fun writing Chrome Extensions.&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/b&gt;
Until next time!&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiREoNE2oQynpfIBOxpfQCZficXHafN5YQsUL_sYVLUYHU7_Kf0pUIf3NtEdoGeUJ_zX77IUPLhDxK7696mnfZtQwsO5QXEw5wTeuAK28pzDoqiM0UY89JPhbhgWvCQlpoGtLxk-YTmvPnU/s1600/snapshot-ver2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;301&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiREoNE2oQynpfIBOxpfQCZficXHafN5YQsUL_sYVLUYHU7_Kf0pUIf3NtEdoGeUJ_zX77IUPLhDxK7696mnfZtQwsO5QXEw5wTeuAK28pzDoqiM0UY89JPhbhgWvCQlpoGtLxk-YTmvPnU/s320/snapshot-ver2.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://tech-drum.blogspot.com/feeds/6287296642494351727/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-drum.blogspot.com/2012/08/gwt-chrome-extension-using-version-2.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/6287296642494351727'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/6287296642494351727'/><link rel='alternate' type='text/html' href='http://tech-drum.blogspot.com/2012/08/gwt-chrome-extension-using-version-2.html' title='GWT Chrome extension using version 2 manifest'/><author><name>Nir Moav</name><uri>http://www.blogger.com/profile/05879703892878058262</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiREoNE2oQynpfIBOxpfQCZficXHafN5YQsUL_sYVLUYHU7_Kf0pUIf3NtEdoGeUJ_zX77IUPLhDxK7696mnfZtQwsO5QXEw5wTeuAK28pzDoqiM0UY89JPhbhgWvCQlpoGtLxk-YTmvPnU/s72-c/snapshot-ver2.png" height="72" width="72"/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-224320715137455380.post-778599865914661140</id><published>2012-07-11T00:00:00.001+03:00</published><updated>2012-07-11T00:01:19.180+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Example"/><category scheme="http://www.blogger.com/atom/ns#" term="Free"/><category scheme="http://www.blogger.com/atom/ns#" term="Github"/><category scheme="http://www.blogger.com/atom/ns#" term="GWT"/><category scheme="http://www.blogger.com/atom/ns#" term="java"/><category scheme="http://www.blogger.com/atom/ns#" term="Source Code"/><title type='text'>Source on a Github repository</title><content type='html'>Hey everyone,&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
This is a really short note.&lt;/div&gt;
&lt;div&gt;
From now on, in case I will publish more code in the future I will try to make sure it is uploaded&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
to Github, so anyone could profit from it.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;The Github repository URL:&amp;nbsp;&lt;a href=&quot;https://github.com/nirgit/Quickpik&quot;&gt;https://github.com/nirgit&lt;/a&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Enjoy.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tech-drum.blogspot.com/feeds/778599865914661140/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-drum.blogspot.com/2012/07/source-on-github-repository.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/778599865914661140'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/778599865914661140'/><link rel='alternate' type='text/html' href='http://tech-drum.blogspot.com/2012/07/source-on-github-repository.html' title='Source on a Github repository'/><author><name>Nir Moav</name><uri>http://www.blogger.com/profile/05879703892878058262</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-224320715137455380.post-1967657325560754799</id><published>2012-07-09T12:45:00.000+03:00</published><updated>2012-07-19T23:27:19.365+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Chrome"/><category scheme="http://www.blogger.com/atom/ns#" term="Example"/><category scheme="http://www.blogger.com/atom/ns#" term="Extension"/><category scheme="http://www.blogger.com/atom/ns#" term="Free"/><category scheme="http://www.blogger.com/atom/ns#" term="Front End"/><category scheme="http://www.blogger.com/atom/ns#" term="GWT"/><category scheme="http://www.blogger.com/atom/ns#" term="java"/><category scheme="http://www.blogger.com/atom/ns#" term="Source Code"/><title type='text'>Quickpik - GWT Chrome extension - Search photos</title><content type='html'>&lt;br /&gt;
&lt;br /&gt;
As a continuation to my previous post, this isn&#39;t about discussing anything.&lt;br /&gt;
It is about &lt;b&gt;doing &lt;/b&gt;- giving an example of something quite simple &amp;amp; cool which you could do yourself using GWT, to build a chrome extension.&lt;br /&gt;
&lt;br /&gt;
Being a bit of a GWT enthusiast, I built an extension for Google Chrome called &lt;i&gt;&lt;b&gt;QuickPik &lt;/b&gt;-&lt;/i&gt;&amp;nbsp;&lt;b&gt;which allows users to search for images from right from the toolbar.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Quickpik&lt;/i&gt; is using Google Images &amp;amp; Flickr (Yahoo) APIs.&lt;br /&gt;
You can run a simple search, and get some images as results. It&#39;s really simple.&lt;br /&gt;
&lt;br /&gt;
You can just download the zip file from the link below, extract it and install the .crx file right into Google Chrome by dragging the file into it. If you&#39;re scared of some evil code running on your browser - just open the source code in the zip file, build the extension yourself, and then install it.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that the idea of this post is to show how easy it is to create a&lt;br /&gt;
cool extension for Chrome.&lt;br /&gt;
The code might not be extremely well documented, nor does it strictly follow Google&#39;s best practices like the MVP pattern or bundling CSS or Image resources and so on, but...&lt;br /&gt;
&lt;br /&gt;
You can expect something compact and simple enough once you open it and take a look.&lt;br /&gt;
I don&#39;t think there should be a problem understanding much of the code.&lt;br /&gt;
&lt;br /&gt;
Would love to get feedback if this helped anyone.&lt;br /&gt;
&lt;br /&gt;
Both source code &amp;amp; Chrome extension below are available to download in one zip file.&lt;br /&gt;
&lt;br /&gt;
Have fun !!!&lt;br /&gt;
&lt;br /&gt;
The project on &lt;b&gt;Github&lt;/b&gt;: &amp;nbsp;&lt;a href=&quot;https://github.com/nirgit/Quickpik&quot;&gt;https://github.com/nirgit/Quickpik&lt;/a&gt;&lt;br /&gt;
A &lt;b&gt;Zip&lt;/b&gt;&amp;nbsp;file to download: &amp;nbsp; &lt;a href=&quot;http://www18.zippyshare.com/v/16094412/file.html&quot;&gt;http://www18.zippyshare.com/v/16094412/file.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUrSGnmwSV90ZdTlkB0D2WwbW4oaaEx_NriJqlUFnEfV5tAZ3GmVwHNzecJh8t505ZlMbIgceb-kKBokK8xu7aOorWx3UVPE55YfyNU1Cen7DJxcqkZif_R0u6mEGJ9W2zkbZvK-YwvZJY/s1600/quickpik-snapshot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;298&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUrSGnmwSV90ZdTlkB0D2WwbW4oaaEx_NriJqlUFnEfV5tAZ3GmVwHNzecJh8t505ZlMbIgceb-kKBokK8xu7aOorWx3UVPE55YfyNU1Cen7DJxcqkZif_R0u6mEGJ9W2zkbZvK-YwvZJY/s320/quickpik-snapshot.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://tech-drum.blogspot.com/feeds/1967657325560754799/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-drum.blogspot.com/2012/07/quickpik-free-google-chrome-extension.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/1967657325560754799'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/1967657325560754799'/><link rel='alternate' type='text/html' href='http://tech-drum.blogspot.com/2012/07/quickpik-free-google-chrome-extension.html' title='Quickpik - GWT Chrome extension - Search photos'/><author><name>Nir Moav</name><uri>http://www.blogger.com/profile/05879703892878058262</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUrSGnmwSV90ZdTlkB0D2WwbW4oaaEx_NriJqlUFnEfV5tAZ3GmVwHNzecJh8t505ZlMbIgceb-kKBokK8xu7aOorWx3UVPE55YfyNU1Cen7DJxcqkZif_R0u6mEGJ9W2zkbZvK-YwvZJY/s72-c/quickpik-snapshot.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-224320715137455380.post-6371479663202411255</id><published>2012-06-05T20:38:00.000+03:00</published><updated>2012-07-22T22:46:23.097+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Chrome"/><category scheme="http://www.blogger.com/atom/ns#" term="Example"/><category scheme="http://www.blogger.com/atom/ns#" term="Extension"/><category scheme="http://www.blogger.com/atom/ns#" term="GWT"/><category scheme="http://www.blogger.com/atom/ns#" term="java"/><title type='text'>Building Chrome extensions with GWT</title><content type='html'>&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;Recently i took a look into Google Chrome Web Store.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;The web store as you can take a look for yourself, is loaded with apps, which many of them are given free.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;I decided to understand what it takes from a simple developer like myself to build such an app which I can run on my browser &amp;amp; distribute on the Chrome Web Store.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;Surprisingly, it does not take a lot of effort to write such an app/extension, especially if you&#39;re already familiar with a little bit of web development.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;Google Chrome Extensions: &lt;a href=&quot;http://code.google.com/chrome/extensions/overview.html&quot;&gt;http://code.google.com/chrome/extensions/overview.html&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;So what you really need is some knowledge of JavaScript, HTML &amp;amp; CSS to make a neat extension.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;For me the real story began when I realized that for such requirements, one could actually use the (amazing) GWT framework to write such an extension.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;If you never looked into GWT, my personal recommendation is that you absolutely must in case you&#39;re into web-development. GWT is a truly incredible tool from my experience.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;If you look at the file structure of such an extension, you can see from the &quot;Google Chrome Extensions - Getting Started&quot; tutorial (&lt;a href=&quot;http://code.google.com/chrome/extensions/getstarted.html&quot;&gt;http://code.google.com/chrome/extensions/getstarted.html&lt;/a&gt;) that we&#39;re talking about 4 important files:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;manifest.json - This file if you like is some kind of a descriptor of your extension.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;An HTML file &quot;hosting&quot; your extension.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;A JavaScript file containing all the cool interaction with your extension, and your script.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;A CSS file - for styling.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;When you write your GWT application in Java and compile it afterwards, you get such files, except for&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;the first one. That you will have to add yourself to the project.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;So enough of &quot;blabing&quot; - Lets dive right into &quot;&lt;b&gt;&lt;u&gt;How to do it&lt;/u&gt;&lt;/b&gt;&quot; (if you&#39;re impatient, just scroll to the bottom of the page to download a zip file of the project):&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;1. Start a new web-application project in Eclipse, and let it create the default skeleton of the project.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicedBFOQQ0OWm6zdJrl5XAXTbbISO22Jt_G-ZimerPLrMa9Wf0rmC2pBy0HYHEwY749N2hjp92EwQzgmr90uHCuO136tQoZrZQZTZiuCE7o1Q2Y4_72HHKnlEYA-vEpjK5pOTozHm56w2F/s1600/step1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicedBFOQQ0OWm6zdJrl5XAXTbbISO22Jt_G-ZimerPLrMa9Wf0rmC2pBy0HYHEwY749N2hjp92EwQzgmr90uHCuO136tQoZrZQZTZiuCE7o1Q2Y4_72HHKnlEYA-vEpjK5pOTozHm56w2F/s320/step1.png&quot; width=&quot;320&quot; /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;2. After the project has been created, make some clean up in the project&#39;s structure by deleting the &quot;server&quot; and the &quot;shared&quot; packages.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;3. Edit the &lt;b&gt;&lt;i&gt;.gwt.xml&lt;/i&gt;&lt;/b&gt; file and make sure the file&#39;s contents is something like:&lt;/span&gt;&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style=&quot;color: #3d85c6; font-family: inherit;&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;br /&gt;&amp;lt;module rename-to=&#39;mychromeext&#39;&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;lt;!-- Inherit the core Web Toolkit stuff. &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;--&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;inherits name=&#39;com.google.gwt.user.User&#39;/&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;!-- Inherit the default GWT style sheet. &amp;nbsp;You can change &amp;nbsp; &amp;nbsp; &amp;nbsp; --&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;!-- the theme of your GWT application by uncommenting &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;--&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;!-- any one of the following lines. &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;--&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;inherits name=&#39;com.google.gwt.user.theme.clean.Clean&#39;/&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;!-- &amp;lt;inherits name=&#39;com.google.gwt.user.theme.standard.Standard&#39;/&amp;gt; --&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;!-- &amp;lt;inherits name=&#39;com.google.gwt.user.theme.chrome.Chrome&#39;/&amp;gt; --&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;!-- &amp;lt;inherits name=&#39;com.google.gwt.user.theme.dark.Dark&#39;/&amp;gt; &amp;nbsp; &amp;nbsp; --&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;!-- Other module inherits &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;--&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;!-- Specify the app entry point class. &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; --&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;entry-point class=&#39;com.techdrum.chrome.ext.example.app.client.MyChromeExt&#39;/&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;!-- Specify the paths for translatable code &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;--&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;source path=&#39;client&#39;/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;lt;set-property name=&quot;user.agent&quot; value=&quot;safari&quot;/&amp;gt;&lt;br /&gt;&amp;lt;/module&amp;gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;4. Delete the auto-generated &lt;i style=&quot;font-weight: bold;&quot;&gt;Async&lt;/i&gt;&amp;nbsp;file and it&#39;s matching service file.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;5. Write some GWT code in the MyChromeExt.java file, something very simple like -&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span style=&quot;color: #0b5394; font-family: inherit;&quot;&gt;package com.techdrum.chrome.ext.example.app.client;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;color: #0b5394; font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;color: #0b5394; font-family: inherit;&quot;&gt;import com.google.gwt.core.client.EntryPoint;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;color: #0b5394; font-family: inherit;&quot;&gt;import com.google.gwt.user.client.ui.Button;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;color: #0b5394; font-family: inherit;&quot;&gt;import com.google.gwt.user.client.ui.RootPanel;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;color: #0b5394; font-family: inherit;&quot;&gt;import com.google.gwt.user.client.ui.TextBox;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;color: #0b5394; font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
&lt;span style=&quot;color: #0b5394; font-family: inherit;&quot;&gt;/**&lt;br /&gt;&amp;nbsp;* Entry point classes define &amp;lt;code&amp;gt;onModuleLoad()&amp;lt;/code&amp;gt;.&lt;br /&gt;&amp;nbsp;*/&lt;br /&gt;public class MyChromeExt implements EntryPoint {&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;/**&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt; * This is the entry point method.&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt; */&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;public void onModuleLoad() {&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;final Button sendButton = new Button(&quot;Send&quot;);&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;final TextBox nameField = new TextBox();&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;// We can add style names to widgets&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;sendButton.addStyleName(&quot;sendButton&quot;);&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;// Add the nameField and sendButton to the RootPanel&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;// Use RootPanel.get() to get the entire body element&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;RootPanel.get(&quot;nameFieldContainer&quot;).add(nameField);&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;RootPanel.get(&quot;sendButtonContainer&quot;).add(sendButton);&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;// Focus the cursor on the name field when the app loads&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;nameField.setFocus(true);&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;nameField.selectAll();&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;}&lt;br /&gt;}&lt;/span&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;6. Almost done! Create a new file called &quot;&lt;i style=&quot;font-weight: bold;&quot;&gt;manifest.json&lt;/i&gt;&quot; and place it under the &quot;&lt;i&gt;war&lt;/i&gt;&quot; directory.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;The file should contain the following:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
&lt;span style=&quot;color: #073763; font-family: inherit;&quot;&gt;{&lt;br /&gt;&amp;nbsp; &quot;name&quot;: &quot;My GWT ext&quot;,&lt;br /&gt;&amp;nbsp; &quot;version&quot;: &quot;1.0&quot;,&lt;br /&gt;&amp;nbsp; &quot;description&quot;: &quot;Simple GWT Extension!&quot;,&lt;br /&gt;&amp;nbsp; &quot;browser_action&quot;: {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &quot;default_popup&quot;: &quot;MyChromeExt.html&quot;&lt;br /&gt;&amp;nbsp; },&lt;br /&gt;&amp;nbsp; &quot;permissions&quot;: [&lt;br /&gt;&amp;nbsp; ],&lt;br /&gt;&amp;nbsp; &amp;nbsp;&quot;web_accessible_resources&quot;: [&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;font-family: inherit;&quot;&gt;&quot;&lt;b&gt;mychromeext&lt;/b&gt;&amp;nbsp;&lt;b&gt;/E949D2D1E7CE643145D4D3D5FC28BB31.cache.html&lt;/b&gt;&lt;/span&gt;&quot;&lt;br /&gt;&amp;nbsp; ]&lt;br /&gt;}&lt;/span&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;b&gt;*Note&lt;/b&gt; the stressed file name!&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;7. Compile the project.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;8. Match the file name with the &lt;i style=&quot;font-weight: bold;&quot;&gt;.cache.html &lt;/i&gt;suffix&amp;nbsp;under the directory &lt;i style=&quot;font-weight: bold;&quot;&gt;mychromeext &lt;/i&gt;to the one mentioned in paragraph 6.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;So if you have something like&amp;nbsp;BF13DA7B8EE69ECA8CAA8F35290E1E1E.cache.html&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;then your new &lt;i style=&quot;font-weight: bold;&quot;&gt;manifest.json&lt;/i&gt;&amp;nbsp;should look like:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
&lt;span style=&quot;color: #0b5394; font-family: inherit;&quot;&gt;{&lt;br /&gt;&amp;nbsp; &quot;name&quot;: &quot;My GWT ext&quot;,&lt;br /&gt;&amp;nbsp; &quot;version&quot;: &quot;1.0&quot;,&lt;br /&gt;&amp;nbsp; &quot;description&quot;: &quot;Simple GWT Extension!&quot;,&lt;br /&gt;&amp;nbsp; &quot;browser_action&quot;: {&lt;br /&gt;&amp;nbsp; &amp;nbsp; &quot;default_popup&quot;: &quot;MyChromeExt.html&quot;&lt;br /&gt;&amp;nbsp; },&lt;br /&gt;&amp;nbsp; &quot;permissions&quot;: [&lt;br /&gt;&amp;nbsp; ],&lt;br /&gt;&amp;nbsp; &amp;nbsp;&quot;web_accessible_resources&quot;: [&lt;br /&gt;&amp;nbsp; &amp;nbsp; &quot;&lt;b&gt;mychromeext/BF13DA7B8EE69ECA8CAA8F35290E1E1E.cache.html&lt;/b&gt;&quot;&lt;br /&gt;&amp;nbsp; ]&lt;br /&gt;}&lt;/span&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;9. That&#39;s it! Now you&#39;re ready to deploy your new extension on Google Chrome.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp; &amp;nbsp; To do that - open Chrome, and open the &lt;i&gt;Extensions&lt;/i&gt;&amp;nbsp;window:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBCAFXdy4c_wU2obYhhXl_hf0MUsk8JExg5o6wETAoXaZqhAvNXkJU7GWwPQ8YBmBeF9k_Bf8dj8f2hiSFa6Z164EGi7hUypcmqJ4Zthr1md71IJqpuyhbcUnG2Vjmui7xfnpC9Skve_M6/s1600/step9.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBCAFXdy4c_wU2obYhhXl_hf0MUsk8JExg5o6wETAoXaZqhAvNXkJU7GWwPQ8YBmBeF9k_Bf8dj8f2hiSFa6Z164EGi7hUypcmqJ4Zthr1md71IJqpuyhbcUnG2Vjmui7xfnpC9Skve_M6/s320/step9.png&quot; width=&quot;320&quot; /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;10. Make sure to check the &quot;&lt;b&gt;&lt;i&gt;Developer Mode&lt;/i&gt;&lt;/b&gt;&quot; box, and then click on &quot;&lt;b&gt;&lt;i&gt;Load unpacked extension...&lt;/i&gt;&lt;/b&gt;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;Select the &lt;i style=&quot;font-weight: bold;&quot;&gt;war&lt;/i&gt;&amp;nbsp;directory of the compiled project, and your new extension should appear on the Chrome toolbar next to the address bar.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;When clicking on it, you&#39;ll see your app:&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_hJVlthoMgssRh0xJU_Sgfy-FQD7MgrcnGEluOI55HGLg2I02Sp-Qrk_NYDlJBwAERkmiHXLU3iRJLd1yC8uekZES8zvNBlEKqQlzWzojKYk-5-251xYv029niAVaN_EnZyTqNun9hROp/s1600/step10.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_hJVlthoMgssRh0xJU_Sgfy-FQD7MgrcnGEluOI55HGLg2I02Sp-Qrk_NYDlJBwAERkmiHXLU3iRJLd1yC8uekZES8zvNBlEKqQlzWzojKYk-5-251xYv029niAVaN_EnZyTqNun9hROp/s320/step10.png&quot; width=&quot;258&quot; /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;Congratulations!&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;Get the full code of the project &lt;a href=&quot;http://www.filefactory.com/file/2f6f0uexfjl1/n/MyChromeExt.zip&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tech-drum.blogspot.com/feeds/6371479663202411255/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-drum.blogspot.com/2012/06/building-chrome-extensions-with-gwt.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/6371479663202411255'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/6371479663202411255'/><link rel='alternate' type='text/html' href='http://tech-drum.blogspot.com/2012/06/building-chrome-extensions-with-gwt.html' title='Building Chrome extensions with GWT'/><author><name>Nir Moav</name><uri>http://www.blogger.com/profile/05879703892878058262</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicedBFOQQ0OWm6zdJrl5XAXTbbISO22Jt_G-ZimerPLrMa9Wf0rmC2pBy0HYHEwY749N2hjp92EwQzgmr90uHCuO136tQoZrZQZTZiuCE7o1Q2Y4_72HHKnlEYA-vEpjK5pOTozHm56w2F/s72-c/step1.png" height="72" width="72"/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-224320715137455380.post-6636779390621662417</id><published>2012-05-07T11:27:00.000+03:00</published><updated>2012-05-07T12:49:26.404+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Comparison"/><category scheme="http://www.blogger.com/atom/ns#" term="DOM"/><category scheme="http://www.blogger.com/atom/ns#" term="Example"/><category scheme="http://www.blogger.com/atom/ns#" term="FlowPanel"/><category scheme="http://www.blogger.com/atom/ns#" term="GWT"/><category scheme="http://www.blogger.com/atom/ns#" term="HorizontalPanel"/><category scheme="http://www.blogger.com/atom/ns#" term="Performance"/><category scheme="http://www.blogger.com/atom/ns#" term="VerticalPanel"/><title type='text'>GWT - FlowPanel + CSS vs HorizontalPanel and VerticalPanel</title><content type='html'>I&#39;ve been working with &lt;a href=&quot;http://code.google.com/webtoolkit/&quot; target=&quot;_blank&quot;&gt;GWT&lt;/a&gt; for the past half year, and am extremely excited about this awesome web-framework !&lt;br /&gt;
I recommend anyone who is doing web-development to look into it. As a person that came from the world&amp;nbsp;of Java Swing, the transition was very smooth, and most importantly - fun !&lt;br /&gt;
&lt;br /&gt;
Anyhow, this is not the focus of this particular post. I&#39;m not here to say how great GWT is or&lt;br /&gt;
persuade you to use it (although you really should if you want to create amazing rich web apps!!!).&lt;br /&gt;
&lt;br /&gt;
This is about GWT&#39;s particular widget - &lt;b&gt;&lt;span style=&quot;color: #6aa84f;&quot;&gt;&lt;i&gt;FlowPanel&lt;/i&gt; &lt;/span&gt;&lt;/b&gt;and its advantages over using &lt;b&gt;&lt;span style=&quot;color: #e06666;&quot;&gt;&lt;i&gt;HorizontalPanel&lt;/i&gt; &lt;/span&gt;&lt;/b&gt;&amp;amp; &lt;i&gt;&lt;b&gt;&lt;span style=&quot;color: #e06666;&quot;&gt;VerticalPanel&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;u&gt;&lt;span style=&quot;font-size: large;&quot;&gt;The &quot;problem&quot; is as follows:&lt;/span&gt;&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
Using &lt;b&gt;&lt;span style=&quot;color: #e06666;&quot;&gt;&lt;i&gt;HorizontalPanel&lt;/i&gt; &lt;/span&gt;&lt;/b&gt;or &lt;b&gt;&lt;span style=&quot;color: #e06666;&quot;&gt;&lt;i&gt;VerticalPanel&lt;/i&gt; &lt;/span&gt;&lt;/b&gt;to layout your widgets can be very intuitive and comfortable, especially if you come from the world of Java Swing, where Layout Manager extending components help you to lay out your widgets, without forcing you to think too much how they do it.&lt;br /&gt;
GWT widgets are a little different.&lt;br /&gt;
GWT&amp;nbsp;is a compiler&amp;nbsp;in it&#39;s core, that takes Java code, and compiles it into&amp;nbsp;JavaScript that eventually runs on your browser. Different widgets compile into different HTML elements that are attached into the &lt;a href=&quot;http://en.wikipedia.org/wiki/Document_Object_Model&quot; target=&quot;_blank&quot;&gt;DOM&lt;/a&gt; and need to be rendered, so it is very important to keep your DOM as compact and simple as possible so the browser has to deal with less elements thus rendering your page faster, and is also helpful when you need to look yourself at the DOM to find a specific element or understand the hierarchy.&lt;br /&gt;
&lt;br /&gt;
Using the &lt;b&gt;&lt;span style=&quot;color: #e06666;&quot;&gt;&lt;i&gt;HorizontalPanel&lt;/i&gt; &lt;/span&gt;&lt;/b&gt;or &lt;i&gt;&lt;b&gt;&lt;span style=&quot;color: #e06666;&quot;&gt;VerticalPanel&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;, can create some serious performance overhead, and &lt;u&gt;especially&lt;/u&gt; when you have lots of those in your application.&lt;br /&gt;
The reason is because GWT compiles &lt;b&gt;&lt;span style=&quot;color: #e06666;&quot;&gt;&lt;i&gt;HorizontalPanel&lt;/i&gt; &lt;/span&gt;&lt;/b&gt;&amp;amp; &lt;b&gt;&lt;span style=&quot;color: #e06666;&quot;&gt;&lt;i&gt;VerticalPanel&lt;/i&gt; &lt;/span&gt;&lt;/b&gt;into HTML Tables.&lt;br /&gt;
When you have a lot of those tables, and with many widgets inside you will end up having&lt;br /&gt;
lots of those &quot;&lt;i&gt;&lt;b&gt;&amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&lt;/b&gt;&lt;/i&gt;&quot; , &quot;&lt;i&gt;&lt;b&gt;&amp;lt;tr&amp;gt;&amp;lt;/tr&amp;gt;&lt;/b&gt;&lt;/i&gt;&quot; tags which resemble the lines and cells of the tables,&lt;br /&gt;
and of course the encapsulating tags of the &quot;&lt;i&gt;&lt;b&gt;&amp;lt;table&amp;gt;&amp;lt;/table&amp;gt;&quot;&lt;/b&gt;&lt;/i&gt;&amp;nbsp;&amp;amp; &quot;&lt;b&gt;&lt;i&gt;&amp;lt;tbody&amp;gt;&amp;lt;/tbody&amp;gt;&quot;.&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&lt;span style=&quot;color: #6aa84f;&quot;&gt;FlowPanel &lt;/span&gt;&lt;/b&gt;&lt;/i&gt;on the other hand is compiled into a &quot;&lt;b&gt;&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;&lt;/b&gt;&quot; - plain and short.&lt;br /&gt;
&lt;br /&gt;
So as you can see, the problem is that when you have lots of those &lt;i&gt;&lt;span style=&quot;color: #e06666;&quot;&gt;&lt;b&gt;Vertical&lt;/b&gt;/&lt;b&gt;HorizontalPanel&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;b&gt; &lt;/b&gt;- you end up generating a lot&amp;nbsp;more elements in the DOM.&lt;br /&gt;
&lt;br /&gt;
This in turn reflects on the performance of your application. Each time you&#39;d want to manipulate those tables - add a cell, remove one, change content,&amp;nbsp;the look-up into the DOM is longer, and the operations consume more processing.&lt;br /&gt;
After the change you will end up making to the DOM, the browser will have to re-render those changes&amp;nbsp;in order to reflect them to the user - the more complicated hierarchy you will have the slower the&amp;nbsp;rendering will be performed.&lt;br /&gt;
&lt;br /&gt;
Ok, now I feel I repeated myself enough, so the point should be clear.&lt;br /&gt;
&lt;br /&gt;
So, after understanding why it&#39;s better to use (in many cases, although not necessarily all), here&#39;s what needs to be&amp;nbsp;done in order to make the change:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Replace your &lt;i&gt;&lt;b&gt;&lt;span style=&quot;color: #e06666;&quot;&gt;VerticalPanel &lt;/span&gt;&lt;/b&gt;&lt;/i&gt;(or &lt;i&gt;&lt;b&gt;&lt;span style=&quot;color: #e06666;&quot;&gt;HorizontalPanel&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;) widget with &lt;b&gt;&lt;span style=&quot;color: #93c47d;&quot;&gt;&lt;i&gt;FlowPanel&lt;/i&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;widget.&lt;/li&gt;
&lt;li&gt;In case you&#39;re using &lt;b&gt;&lt;span style=&quot;color: #e06666;&quot;&gt;&lt;i&gt;HorizontalPanel&lt;/i&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;and wish to place widgets next to each other, don&#39;t forget to use CSS &lt;i&gt;float &lt;/i&gt;attribute.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;u&gt;&lt;span style=&quot;font-size: large;&quot;&gt;Example:&lt;/span&gt;&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;import com.google.gwt.user.client.ui.Button;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;import com.google.gwt.user.client.ui.Composite;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;import com.google.gwt.user.client.ui.FlowPanel;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;import com.google.gwt.user.client.ui.Label;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;import com.google.gwt.user.client.ui.TextBox;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;public class MessagePanel extends Composite {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;// Using FlowPanel instead of HorizontalPanel&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;private final FlowPanel contentPanel;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;// Widgets of the message panel.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;private Label messageCaption ;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;private TextBox messageContent ;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;private Button send ;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;&lt;span style=&quot;color: #3d85c6;&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;/**&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt; * C&#39;tor&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt; */&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;public MessagePanel() {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;this.contentPanel = new FlowPanel();&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;initWidget(this.contentPanel) ;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;// Lets add contents to the panel.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;addContents();&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;// add styles !&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;addStyles() ;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;private void addContents() {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;// add a name caption&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;messageCaption = new Label(&quot;Message:&quot;);&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;contentPanel.add(messageCaption);&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;// add an input text field&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;messageContent = new TextBox();&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;contentPanel.add(messageContent);&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;// add a &quot;send&quot; button...&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;send = new Button(&quot;Send message!&quot;);&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;contentPanel.add(send);&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;&lt;span style=&quot;color: #3d85c6;&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;private void addStyles() {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;messageCaption.getElement().getStyle().setProperty(&quot;float&quot;, &quot;left&quot;) ;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;messageContent.getElement().getStyle().setProperty(&quot;float&quot;, &quot;left&quot;) ;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;send.getElement().getStyle().setProperty(&quot;float&quot;, &quot;left&quot;) ;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;font-weight: bold; text-decoration: underline;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;font-weight: bold; text-decoration: underline;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Of course, the code above is only to demonstrate what you can achieve, but not necessarily&lt;/div&gt;
&lt;div&gt;
how you should really implement it. CSS styles should be put in a CSS file and you should follow GWT&#39;s best practices.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
In any case, the outcome of instantiating this widget and adding it results the following:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZpzCkay2q6HDqMr05iL1kQ29TIRQqEPpt2Np_6c-ixf_FVgiTxDyiifwlMLlav9_rkCXbq8O2Zz-bm4Skvex13Ah9Xd9VOgZHQq5o0SSQekhkLN9AIdLvIu8M8wrbESVt5MdC_zJBEFoF/s1600/gwt-flowpanel-example.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;210&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZpzCkay2q6HDqMr05iL1kQ29TIRQqEPpt2Np_6c-ixf_FVgiTxDyiifwlMLlav9_rkCXbq8O2Zz-bm4Skvex13Ah9Xd9VOgZHQq5o0SSQekhkLN9AIdLvIu8M8wrbESVt5MdC_zJBEFoF/s400/gwt-flowpanel-example.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
And results in the following hierarchy in the DOM (from Chrome) :&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&amp;lt;div&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&amp;lt;div class=&quot;gwt-Label&quot; style=&quot;float: left; &quot;&amp;gt;Message:&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&amp;lt;input type=&quot;text&quot; class=&quot;gwt-TextBox&quot; style=&quot;float: left; &quot; id=&quot;acpro_inp0&quot;&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&amp;lt;button type=&quot;button&quot; class=&quot;gwt-Button&quot; style=&quot;float: left; &quot;&amp;gt;Send message!&amp;lt;/button&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;color: #3d85c6;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
So, as you can see this part of the DOM is very concise and straightforward.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Change to &lt;span style=&quot;color: #6aa84f;&quot;&gt;&lt;b&gt;&lt;i&gt;FlowPanel&lt;/i&gt;&lt;/b&gt; &lt;/span&gt;to boost your application&#39;s performance &amp;amp; to generate simpler DOM.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Happy tuning !&lt;/div&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tech-drum.blogspot.com/feeds/6636779390621662417/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-drum.blogspot.com/2012/02/gwt-flowpanel-css-is-better-than.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/6636779390621662417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/6636779390621662417'/><link rel='alternate' type='text/html' href='http://tech-drum.blogspot.com/2012/02/gwt-flowpanel-css-is-better-than.html' title='GWT - FlowPanel + CSS vs HorizontalPanel and VerticalPanel'/><author><name>Nir Moav</name><uri>http://www.blogger.com/profile/05879703892878058262</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZpzCkay2q6HDqMr05iL1kQ29TIRQqEPpt2Np_6c-ixf_FVgiTxDyiifwlMLlav9_rkCXbq8O2Zz-bm4Skvex13Ah9Xd9VOgZHQq5o0SSQekhkLN9AIdLvIu8M8wrbESVt5MdC_zJBEFoF/s72-c/gwt-flowpanel-example.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-224320715137455380.post-8317563502648220630</id><published>2012-04-29T13:16:00.002+03:00</published><updated>2012-12-18T12:27:50.035+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Front End"/><category scheme="http://www.blogger.com/atom/ns#" term="GWT"/><category scheme="http://www.blogger.com/atom/ns#" term="java"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC"/><category scheme="http://www.blogger.com/atom/ns#" term="RAD"/><category scheme="http://www.blogger.com/atom/ns#" term="review"/><category scheme="http://www.blogger.com/atom/ns#" term="Spring"/><category scheme="http://www.blogger.com/atom/ns#" term="Spring ROO"/><title type='text'>Spring ROO 1.2 review</title><content type='html'>&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;This post as the title mentions, is about my personal impressions and thoughts about the&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&#39;&lt;i&gt;Spring ROO&#39; &lt;/i&gt;framework, version 1.2.1.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;b&gt;&lt;u&gt;&lt;span style=&quot;font-family: inherit; font-size: 18pt;&quot;&gt;What is &lt;i&gt;ROO&lt;/i&gt;?&lt;/span&gt;&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;i&gt;ROO&lt;/i&gt; is a tool, which helps automating the development 
process of web-applications written in Java.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;It supports different kinds of technology stack, 
such as GWT &amp;amp; Spring MVC in the front end, JPA &amp;amp; Hibernate, EclipseLink in the back-end and 
such.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;The framework is entirely based on the Spring framework, 
in order to accomplish the goal of creating a full-blown, end-to-end 
web-application.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;The idea is to be able to rapidly create and maintain a web-application with a few &#39;&lt;i&gt;shell&lt;/i&gt;&#39; 
commands, and then let the users (the developers) fill in the gaps and customize business 
logic, application state and so on.&lt;/span&gt;&lt;br /&gt;
&lt;i style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i style=&quot;font-family: inherit;&quot;&gt;ROO&lt;/i&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt; monitors the changes the 
developer makes while writing code, and adapts the application&#39;s infrastructure 
to match and support the developer&#39;s actions.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;I recommend you visit the &lt;a href=&quot;http://www.springsource.org/spring-roo&quot; target=&quot;_blank&quot;&gt;&lt;i&gt;ROO &lt;/i&gt;website&lt;/a&gt; in any case to get the best understanding of the tool.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;Before I start telling you what I did and experienced I have to say that I enjoyed working with &lt;i&gt;ROO&lt;/i&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;The installation was fast &amp;amp; easy, the &lt;i&gt;ROO&lt;/i&gt; shell was easy to use and the documentation was satisfying.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;So! after some short-long intro, let me tell you - &lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;div class=&quot;MsoNormal&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;b&gt;&lt;u&gt;&lt;span style=&quot;font-family: inherit; font-size: 18pt;&quot;&gt;What did I do?&lt;/span&gt;&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;1. Created a simple web-application based on a multi-module project - Server &amp;amp; Client modules.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;2. Used GWT as the front-end, JPA over Hibernate with 
a DB in the back-end.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;3. Wrote custom code and integrated it in the auto generated files of &lt;i&gt;ROO&lt;/i&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;4. Tried to 
change/add/remove a service (BL) &amp;amp; repository (DAO).&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;5. Inspected generated 
code.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;6. Tried to remove project&#39;s dependency from &lt;i&gt;ROO&lt;/i&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;b&gt;&lt;u&gt;&lt;span style=&quot;font-family: inherit; font-size: 18pt;&quot;&gt;What I experienced&lt;/span&gt;&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&amp;nbsp;1. The amount of code generated for the 
client module (GWT) was quite overwhelming. So many files were 
created to show/edit/create/delete a 
single entity named &lt;i&gt;Product&lt;/i&gt; in the 
DB. While some of the generated code is 
absolutely necessary, a lot of code was created to support every possible option 
on the front-end.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;Unfortunately, this is not configurable, and I could not find a way to tell &lt;i&gt;ROO&lt;/i&gt; exactly what I wish to generate (&#39;&lt;i&gt;scaffold&lt;/i&gt;&#39;), like - &quot;only 
desktop support&quot;, &quot;only mobile support&quot;, &quot;only view/read&quot; capabilities, etc... You can only pick which 
&lt;i&gt;Entities &lt;/i&gt;on your model to &lt;i&gt;scaffold&lt;/i&gt; (support on the 
front-end and back-end). All this leads to a very big codebase, 
which won&#39;t necessarily be used.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;This leads to verbosity and a lot of redundancy, which makes your codebase larger and&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;more complex for no reason.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;2. Front end&#39;s design - Is following Google&#39;s 
best practices which is really great. You can learn&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;quite a bit of Google&#39;s understanding the design of a web-application on the front end.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;3. 
Generated code looks fairly neat, however all generated code managed by &lt;i&gt;ROO&lt;/i&gt; is 
&quot;hidden&quot; in AspectJ files. - Some people don&#39;t like this.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;4. No easy removal* of &lt;i&gt;ROO&lt;/i&gt; from the project in my opinion... - You could just stop &lt;i&gt;ROO&lt;/i&gt;&amp;nbsp;from monitoring your application and continue developing your project. But, all the generated AspectJ files remain. This could be 
a problem for the future, in case you want to change your classes&#39; implementation. &lt;b&gt;&lt;i&gt;(* - Please see comments at the bottom).&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;5. Writing tests &amp;amp; integrating them with Services 
layer was &lt;b&gt;&lt;u&gt;easy&lt;/u&gt;&lt;/b&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 12pt;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;6. Great&amp;nbsp;&lt;u&gt;end-to-end&lt;/u&gt;&amp;nbsp;integration tests, that run on the Browser using &lt;a href=&quot;http://seleniumhq.org/&quot; target=&quot;_blank&quot;&gt;Selenium&lt;/a&gt; (some 
kind of a web-driver script player).&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote dir=&quot;ltr&quot; style=&quot;margin-right: 0px;&quot;&gt;
&lt;div&gt;
&lt;span class=&quot;605260109-03042012&quot; style=&quot;font-family: inherit;&quot;&gt; &lt;/span&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;It feels to me that even though &lt;i&gt;ROO&lt;/i&gt;&#39;s GWT add-on tried very hard to 
give a real added value to developers, it added more complexity than simplicity, and that is in my opinion due to the fact that&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;a lot&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;of code is being generated. And that makes it hard in the beginning to dive into the code.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;Not to mention how much tweaking needs to be done to disable features for instance.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;And in case you&#39;re letting &lt;i&gt;ROO&lt;/i&gt; manage your 
project further, you will have to keep track of that&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;stuff all the time. So if you &#39;messed&#39; up by &lt;i&gt;scaffolding&lt;/i&gt; some entity which you didn&#39;t want, you&#39;ll spend&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;your time removing the unwanted code. where is the &lt;i&gt;&lt;b&gt;&lt;u&gt;Undo&lt;/u&gt;&lt;/b&gt; &lt;/i&gt;feature of the shell&lt;i&gt;?&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;i&gt;ROO&lt;/i&gt; just doesn&#39;t feel as fine grained as I would expect it to be.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;b&gt;&lt;u&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;Conclusion&lt;/span&gt;&lt;/u&gt;&lt;/b&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;I think that &lt;i&gt;ROO&lt;/i&gt; is walking in the right direction, empowering developers to deal only with the logic of their web applications and not trouble themselves with infrastructure and design problems of standard web-applications.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;I am not sure I would use it (especially not 
the front-end) in production, &lt;u&gt;yet&lt;/u&gt;.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;u&gt;Despite all that&lt;/u&gt;, it still benefits as a really nice tool for &lt;b&gt;prototyping&lt;/b&gt; (or quickly setting up a back-end &amp;amp; DB configuration), and for &lt;b&gt;learning&lt;/b&gt; how to 
implement a web app with &lt;u&gt;best practices&lt;/u&gt;.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;WordSection1&quot;&gt;
&lt;blockquote style=&quot;margin-bottom: 5pt; margin-right: 0cm; margin-top: 5pt;&quot;&gt;
&lt;/blockquote&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;i&gt;&lt;b&gt;&lt;u&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;What can you profit from it:&lt;/span&gt;&lt;/u&gt;&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;blockquote style=&quot;margin-bottom: 5pt; margin-right: 0cm; margin-top: 5pt;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;1. It is an &lt;b&gt;&lt;u&gt;amazing&lt;/u&gt;&lt;/b&gt; tool to create a web-app POC very fast!&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;2. It is an &lt;b&gt;&lt;u&gt;awesome&lt;/u&gt;&lt;/b&gt; tool to &lt;b&gt;&lt;u&gt;learn&lt;/u&gt;&lt;/b&gt; new 
technologies and see how they work with each other.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;3. Spring &lt;i&gt;ROO&lt;/i&gt; applies best practices. &lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;Explanation: &lt;i&gt;ROO&lt;/i&gt; has a &#39;plug-ins&#39; platform, which lets anyone to generate code 
following a simple&amp;nbsp;command in the shell.&amp;nbsp;&lt;/span&gt;&lt;/blockquote&gt;
&lt;blockquote style=&quot;margin-bottom: 5pt; margin-right: 0cm; margin-top: 5pt;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;Google for instance wrote such a plug-in for 
&lt;i&gt;ROO&lt;/i&gt; to integrate with GWT.&amp;nbsp;As a result you get the &lt;b&gt;BEST&lt;u&gt;,&lt;/u&gt;&lt;/b&gt; 
latest results for architectural/design/technology/practices on your web-app.&lt;/span&gt;&lt;/blockquote&gt;
&lt;blockquote style=&quot;margin-bottom: 5pt; margin-right: 0cm; margin-top: 5pt;&quot;&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;4. It&#39;s a great tool to get your backend Spring based infrastructure ready 
with a DB, in a few minutes, or see how it should be done properly.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;5. Runtime performance - Best runtime performance you could have achieved 
yourself probably.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;All generated code/configuration is processed in compile time as 
regular Java files only!&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;Following best practices of Spring &amp;amp; other 
vendors like Google, you can rest assure that there should be no 
performance issues caused by this tool. (or with very little chance for 
it to happen - even the best software giants have bugs sometimes).&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;6. Did I mention the great integration tests running automatically on the 
browser? &lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;I personally &lt;b&gt;loved &lt;/b&gt;this feature!&lt;/span&gt;&lt;/blockquote&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;I think it would be wise to keep an eye on &lt;i&gt;ROO&lt;/i&gt; for the future, as it has already 
been out there for some time, and keeps on improving.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
Visit &#39;&lt;i&gt;Spring ROO&lt;/i&gt;&#39;:&amp;nbsp;&lt;a href=&quot;http://www.springsource.org/spring-roo&quot;&gt;http://www.springsource.org/spring-roo&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://tech-drum.blogspot.com/feeds/8317563502648220630/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-drum.blogspot.com/2012/04/my-impressions-on-spring-roo-12.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/8317563502648220630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/8317563502648220630'/><link rel='alternate' type='text/html' href='http://tech-drum.blogspot.com/2012/04/my-impressions-on-spring-roo-12.html' title='Spring ROO 1.2 review'/><author><name>Nir Moav</name><uri>http://www.blogger.com/profile/05879703892878058262</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-224320715137455380.post-8673883104495741554</id><published>2012-03-20T01:32:00.000+02:00</published><updated>2013-03-23T21:06:35.428+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Dependency Injection"/><category scheme="http://www.blogger.com/atom/ns#" term="DI"/><category scheme="http://www.blogger.com/atom/ns#" term="Example"/><category scheme="http://www.blogger.com/atom/ns#" term="Front End"/><category scheme="http://www.blogger.com/atom/ns#" term="Guice"/><category scheme="http://www.blogger.com/atom/ns#" term="GWT"/><category scheme="http://www.blogger.com/atom/ns#" term="java"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC"/><category scheme="http://www.blogger.com/atom/ns#" term="MVP"/><category scheme="http://www.blogger.com/atom/ns#" term="Rich Client"/><category scheme="http://www.blogger.com/atom/ns#" term="Spring"/><category scheme="http://www.blogger.com/atom/ns#" term="Swing"/><title type='text'>DI with Guice for Java Swing</title><content type='html'>If you&#39;re familiar with Dependency Injection (DI) concepts and frameworks such as Spring,&lt;br /&gt;
you know the great benefits it introduces when developing an application.&lt;br /&gt;
Spring which I daily use (and praise), is a framework (or an application platform if to be more accurate) that one of its core features and philosophy is DI.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Some of the benefits of DI are well known:&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style=&quot;color: #6aa84f;&quot;&gt;Simplified code.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #6aa84f;&quot;&gt;Reduced dependencies.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #6aa84f;&quot;&gt;Helps &#39;modularity&#39; and creation of reusable components.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #6aa84f;&quot;&gt;Helps you test your application better.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #6aa84f;&quot;&gt;Lazy loading.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;br /&gt;
Surely there are other benefits you could think of which were not mentioned above.&lt;br /&gt;
So, &lt;b&gt;why not bring all that good stuff to your Rich Client ?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The connection of DI to the title of this post is how to integrate DI in your front-end in case you are building a Rich client application, using Java Swing or GWT for example.&lt;br /&gt;
&lt;br /&gt;
You could follow the MVC pattern (which is well known, and can be great) to build your rich client, and integrate it with a DI framework. However I &lt;b&gt;&lt;u&gt;strongly&lt;/u&gt;&lt;/b&gt;&amp;nbsp;recommend you consider the MVP pattern for an even better design of your front-end. Which I find it to be much &#39;cleaner&#39;.&lt;br /&gt;
(In MVC some of the business-logic code is scattered between the controller and the View. It&#39;s harder&lt;br /&gt;
to re-use your View objects/Widgets, especially in case you want to give it to someone else to use, or integrate them in another product).&lt;br /&gt;
&lt;br /&gt;
Smarter people than me talk about it, and you can find great talks on YouTube regarding this subject.&lt;br /&gt;
&lt;br /&gt;
You can later also check Google I/O&#39;s excellent talk for &quot;&lt;i&gt;Best Practices for Architecting GWT App&lt;/i&gt;&quot; &amp;nbsp;&lt;a href=&quot;http://www.youtube.com/watch?v=PDuhR18-EdM&quot;&gt;http://www.youtube.com/watch?v=PDuhR18-EdM&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
So, if we follow the MVP design pattern and Google&#39;s best practices (even if we don&#39;t use GWT),&lt;br /&gt;
&lt;u&gt;we end up with few key components in our app, i&#39;ll try to give some description what they do:&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style=&quot;color: #6aa84f;&quot;&gt;&quot;The&quot; Event Bus - The component where presenters &#39;listen&#39; to, and can fire events to.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #6aa84f;&quot;&gt;The Presenters - The components which encapsulate the logic of your application.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #6aa84f;&quot;&gt;The Views / Displays - Simply a view - can be a panel with widgets in it. No logic in here!&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #6aa84f;&quot;&gt;A Model - Where you keep important data that can be accessed by one or more presenters.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;&quot;&lt;i&gt;Show me the code!&lt;/i&gt;&quot;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Lets assume you&#39;re writing your rich client in Java Swing.&lt;br /&gt;
We will use the lightweight DI framework &quot;&lt;i&gt;Guice&lt;/i&gt;&quot; by Google:&lt;br /&gt;
&lt;a href=&quot;http://code.google.com/p/google-guice/&quot;&gt;http://code.google.com/p/google-guice/&lt;/a&gt;&amp;nbsp;to help us achieve our goal.&lt;br /&gt;
&lt;br /&gt;
Lets go over some steps to realize what needs to be done in order to get this to work - don&#39;t forget to download Guice and put it&#39;s Jars in the classpath.&lt;br /&gt;
(Or, scroll all the way down to download the zip file containing the source code).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) Define a simple View as a dumb object, not knowing anything about logic:&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
&lt;span style=&quot;background-color: #eeeeee;&quot;&gt;public class &lt;i&gt;ContentPaneDisplay &lt;/i&gt;extends JPanel { .... }&lt;/span&gt;&lt;/blockquote&gt;
&lt;br /&gt;
2) Define a high level &lt;i&gt;IPresenter&lt;/i&gt; interface and the&amp;nbsp;&lt;i&gt;IContentPanePresenter&lt;/i&gt;&amp;nbsp;interface:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot; style=&quot;background-color: #eeeeee;&quot;&gt;
&lt;span style=&quot;background-color: #eeeeee;&quot;&gt;public interface IPresenter {&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;/**&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt; * A method of all implementing presenters for presenting themselves on a given container.&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt; * @param c&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt; */&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;void go(Container c) ;&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;}&lt;/span&gt;&lt;/blockquote&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
&lt;span style=&quot;background-color: #eeeeee;&quot;&gt;public interface IContentPanePresenter extends IPresenter {}&lt;/span&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
3)&amp;nbsp;Define a Presenter that will use view object above as its display:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot; style=&quot;background-color: #eeeeee;&quot;&gt;
&lt;span style=&quot;background-color: #eeeeee;&quot;&gt;public class ContentPanePresenter implements IContentPanePresenter {&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;public static interface IDisplay {&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;JComponent getAsComponent() ;&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;}&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;private final IDisplay display ;&lt;br /&gt;....&lt;br /&gt;}&lt;/span&gt;&lt;/blockquote&gt;
&lt;br /&gt;
4) Make&amp;nbsp;&lt;i&gt;ContentPaneDisplay implement the&amp;nbsp;ContentPanePresenter.IDisplay &lt;/i&gt;interface.&lt;br /&gt;
&lt;br /&gt;
5) Configure the Display class and the Presenter class to be used by Guice:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot; style=&quot;background-color: #eeeeee;&quot;&gt;
&lt;span style=&quot;background-color: #eeeeee;&quot;&gt;public class ApplicationDIModule extends AbstractModule {&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;@Override&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;protected void configure() {&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;// Lets configure some stuff !&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;bind(IContentPanePresenter.class).to(ContentPanePresenter.class).in(Singleton.class) ;&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;bind(ContentPanePresenter.IDisplay.class).to(ContentPaneDisplay.class).in(Singleton.class) ;&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;}&lt;br /&gt;}&lt;/span&gt;&lt;/blockquote&gt;
&lt;br /&gt;
6) Add the &lt;i&gt;&lt;b&gt;@Inject&lt;/b&gt; &lt;/i&gt;annotation to the&amp;nbsp;&lt;i&gt;ContentPanePresenter&lt;/i&gt;&amp;nbsp;to be injected the display:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot; style=&quot;background-color: #eeeeee;&quot;&gt;
&lt;span style=&quot;background-color: #eeeeee;&quot;&gt;/**&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt; * C&#39;tor&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt; * This is where DI takes place!!!&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt; * Guice will instantiate and provide this presenter with a matching display!&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt; * @param display&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt; */&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;@Inject&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;public ContentPanePresenter(IDisplay display) {&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;this.display = display ;&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;...&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;}&lt;/span&gt;&lt;/blockquote&gt;
&lt;br /&gt;
&lt;br /&gt;
7) Now all that&#39;s left is to call the Guice injector to get the &lt;i&gt;ContentPanePresenter:&lt;/i&gt;&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot; style=&quot;background-color: #eeeeee;&quot;&gt;
&lt;span style=&quot;background-color: #eeeeee;&quot;&gt;private static void go(Container container) {&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;// Guice.createInjector() takes your Modules, and returns a new Injector instance.&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt; &amp;nbsp; &amp;nbsp;Injector injector = Guice.createInjector(new ApplicationDIModule());&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;// lets get the &#39;Main&#39; content pane Presenter !!&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt; &amp;nbsp; &amp;nbsp;IContentPanePresenter contentPanePresenter =&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; injector.getInstance(IContentPanePresenter.class) ;&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;contentPanePresenter.go(container) ;&lt;br /&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;}&lt;/span&gt;&lt;/blockquote&gt;
&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;i&gt;&lt;/i&gt;&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: -webkit-auto;&quot;&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
I hope this post was beneficial to you, and you got exposed to something new.&lt;br /&gt;
Watch the Google I/O YouTube video about &lt;i&gt;&quot;&lt;a href=&quot;http://www.youtube.com/watch?v=PDuhR18-EdM&quot; target=&quot;_blank&quot;&gt;Best Practices for Architecting GWT App&lt;/a&gt;&quot;&lt;/i&gt;, it&#39;s really worth it.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://github.com/nirgit/DIClient&quot; target=&quot;_blank&quot;&gt;Click this link to download the source code from GitHub&lt;/a&gt;.&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://tech-drum.blogspot.com/feeds/8673883104495741554/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-drum.blogspot.com/2012/03/dependency-injection-on-your-rich.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/8673883104495741554'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/8673883104495741554'/><link rel='alternate' type='text/html' href='http://tech-drum.blogspot.com/2012/03/dependency-injection-on-your-rich.html' title='DI with Guice for Java Swing'/><author><name>Nir Moav</name><uri>http://www.blogger.com/profile/05879703892878058262</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-224320715137455380.post-9193837797052930482</id><published>2012-01-22T18:52:00.000+02:00</published><updated>2012-03-14T00:04:07.395+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Carbon Dioxide"/><category scheme="http://www.blogger.com/atom/ns#" term="CPU"/><category scheme="http://www.blogger.com/atom/ns#" term="Emission"/><category scheme="http://www.blogger.com/atom/ns#" term="Energy"/><category scheme="http://www.blogger.com/atom/ns#" term="environment"/><category scheme="http://www.blogger.com/atom/ns#" term="Kilowatt"/><category scheme="http://www.blogger.com/atom/ns#" term="Performance"/><category scheme="http://www.blogger.com/atom/ns#" term="Watt"/><title type='text'>More (software) performance, less carbon dioxide</title><content type='html'>This post is a little different than the older ones.&lt;br /&gt;
This time, it&#39;s about how &quot;&lt;b style=&quot;color: #93c47d;&quot;&gt;&lt;i&gt;Making a performant software, helps reducing carbon dioxide emissions&lt;/i&gt;&lt;/b&gt;&quot;.&lt;br /&gt;
&lt;br /&gt;
So, what&#39;s the connection you ask, and why is it even important?&lt;br /&gt;
I&#39;m not writing this post to convince you that &lt;i&gt;global warming&lt;/i&gt; is &lt;i&gt;not&lt;/i&gt; &lt;i&gt;a theory&lt;/i&gt;. It sure isn&#39;t.&lt;br /&gt;
The vast majority of researches on this topic amongst the scientific community, indicate we are facing&amp;nbsp;a new reality where nature starts kicking back, corresponding our irresponsible actions as humans.&lt;br /&gt;
&lt;br /&gt;
You&#39;re encouraged to read and explore this must topic (IMHO) yourself to realize how it effects your life&amp;nbsp;directly, and how it effects our planet.&lt;br /&gt;
A great book, which I very much enjoyed reading and also inspired me to make this post is:&lt;br /&gt;
&lt;h2 class=&quot;books-view-title with-h3&quot;&gt;


&lt;span style=&quot;font-size: small; font-weight: normal;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;i&gt;&quot;&lt;a href=&quot;http://www.thomaslfriedman.com/bookshelf/hot-flat-and-crowded&quot; target=&quot;_blank&quot;&gt;Hot, Flat, and Crowded&lt;/a&gt;&lt;/i&gt;&quot; by Thomas L. Friedman. (There&#39;s also a 2nd edition of the book). &lt;/span&gt;&lt;br /&gt;(His website:&amp;nbsp;&lt;a href=&quot;http://www.thomaslfriedman.com/&quot; target=&quot;_blank&quot;&gt;http://www.thomaslfriedman.com/&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;However, I think there are many other ways you can choose to enrich and extend your knowledge about this concerning subject, from books and magazines to getting involved in your own community and raise awareness. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So, assuming we understand the importance of a change we should make, not only because of&lt;br /&gt;energy problems in the world, not only because of extreme climate changes and amounts of Greenhouse gas particles in the air, although extremely important, this is also a lot about how to make your software more competitive than others in the IT market.&lt;br /&gt;&lt;br /&gt;You create an added value in terms of &quot;&lt;b style=&quot;color: #93c47d;&quot;&gt;&lt;i&gt;green&lt;/i&gt;&lt;/b&gt;&quot; to your customers, bringing them more benefit in &lt;br /&gt;energy consumption, which translates to reduced electricity bills, and helps tagging their company&lt;br /&gt;as &quot;&lt;b style=&quot;color: #93c47d;&quot;&gt;&lt;i&gt;greener&lt;/i&gt;&lt;/b&gt;&quot;.&lt;br /&gt;&lt;br /&gt;So this is about how you as a software engineer can help make this change.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;&lt;b&gt;&lt;span style=&quot;color: #6aa84f;&quot;&gt;The idea&lt;/span&gt;&lt;/b&gt; is very simple(yet, a little harder to implement and keep in mind)&lt;/u&gt;:&lt;br /&gt;The more computations your software makes, the more CPU is needed for computation, and&lt;br /&gt;more energy is needed to cool it down.&lt;br /&gt;Since a CPU is an electronic device like anything else pretty much on your computer, and consumes&lt;br /&gt;energy (Watts). The more you use it, the more energy you consume. Rather logical!&lt;br /&gt;&lt;br /&gt;If we can reduce the amounts of computations on our CPU, than less energy will be needed.&lt;br /&gt;If our software won&#39;t perform any computations, then the CPU usage will be at minimum.&lt;/span&gt;&lt;span style=&quot;font-size: small; font-weight: normal;&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size: large;&quot;&gt;What can you do!?&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style=&quot;font-size: small; font-weight: normal;&quot;&gt;Improve your computations in the code.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-size: small; font-weight: normal;&quot;&gt;Replace for a faster algorithm than the one you&#39;re using&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-size: small; font-weight: normal;&quot;&gt;Make stress tests - measure CPU performance with profilers.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-size: small; font-weight: normal;&quot;&gt;Add
 &quot;Green&quot; Unit tests to your software to make sure CPU utilization 
doesn&#39;t exceed a certain limit you or your company set to itself.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-size: small; font-weight: normal;&quot;&gt;Perform long and &quot;heavy&quot; processing during night time or when electricity is cheaper. &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-size: small; font-weight: normal;&quot;&gt;Create
 an acceptance test for your software, making sure in all cases 
computations don&#39;t exceed a certain bar, or make sure average 
computation per day stays low.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 class=&quot;books-view-title with-h3&quot;&gt;

&lt;span style=&quot;font-size: small; font-weight: normal;&quot;&gt;So, as you can see the theory is extremely simple to understand.&lt;br /&gt;The question is, how much can we &#39;&lt;b&gt;&lt;i&gt;save&lt;/i&gt;&lt;/b&gt;&#39; or &lt;i&gt;&lt;b&gt;what&lt;/b&gt;&lt;/i&gt; do we save ?&lt;br /&gt;&lt;br /&gt;Lets make a simple example.&lt;br /&gt;This is totally not based on any scientific research, and is using only given inputs from official manufacturers and website i found on the web and using some common sense.&lt;br /&gt;&lt;br /&gt;Suppose your computer has a CPU from a known brand like Intel or AMD.&lt;br /&gt;Such CPU can consume up to 130W (Watts) for &lt;a href=&quot;http://en.wikipedia.org/wiki/Thermal_design_power&quot; target=&quot;_blank&quot;&gt;TDP&lt;/a&gt; - which is the maximum amount of power needed&amp;nbsp;to cool down that CPU so it can work properly.&lt;br /&gt;&lt;br /&gt;If you are running on a high loaded server which is operating 24h / 7d than you get&lt;br /&gt;24 x 365 (hours) = 8760 hours of using this CPU.&lt;br /&gt;&lt;br /&gt;Lets assume that the average CPU utilization stands on 80%, because of your software computations.&lt;br /&gt;This translates to an average of 104W in order to keep that CPU working.&lt;br /&gt;&lt;br /&gt;The price for a Kilo-Watt is something your local electricity company charges for, and it changes depending on many factors.&lt;br /&gt;However, I found some numbers on the web, and as I see it may vary, but since this should be &lt;br /&gt;a &lt;b&gt;constant&lt;/b&gt; in the &quot;&lt;b&gt;&lt;i&gt;cost calculation formula&lt;/i&gt;&lt;/b&gt;&quot; as the electricity price is (usually fixed, or has a fixed average), we&#39;ll just use some number, say 15 cents for a Kilowatt (kw).&lt;br /&gt;&lt;br /&gt;So now we can calculate how much we would need to pay just for this CPU to work:&lt;br /&gt;&lt;br /&gt;(104W) * (24 * 365h) * (15cents)&lt;br /&gt;----------------------------------------------- &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; =&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 13,665&amp;nbsp; cents.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1000&lt;br /&gt;&lt;br /&gt;So that&#39;s 136$ dollars for the entire year. Doesn&#39;t look so much ?&lt;br /&gt;&lt;br /&gt;If hypothetically you will be able to reduce the average CPU consumption to 25%, you will get:&lt;br /&gt;&lt;br /&gt;(32.5W) * (24 * 365h) * (15cents)&lt;br /&gt;-----------------------------------------------&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; =&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4,270&amp;nbsp; cents.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1000&lt;br /&gt;&lt;br /&gt;and that is 42.70$ dollars a year. That&#39;s about &lt;b style=&quot;color: #6aa84f;&quot;&gt;68% less to pay&lt;/b&gt;. And if you or your client have dozens of servers or more, say 100, then you could save (approx.):&amp;nbsp;&amp;nbsp; (136 - 42.70) * 100 = 9,330$.&lt;br /&gt;And that&#39;s already some money, especially as it accumulates over years and years.&lt;br /&gt;&lt;br /&gt;Not to mention all the carbon dioxide emissions you reduce by making your software more efficient!&lt;br /&gt;A coal based power plant can emit up to 1 Kilogram of Carbon Dioxide per 1 Kilowatt!&lt;br /&gt;(Again I must stress that different numbers could be found on the web, but the idea is very clear).&lt;br /&gt;Which means that by utilizing 25% of your CPU instead of 80% you reduce carbon dioxide emissions&lt;br /&gt;dramatically! And in numbers you emit 284.7 Kg, instead of 911.04 Kg ! &lt;br /&gt;And that is only for &lt;b&gt;one &lt;/b&gt;CPU!&lt;br /&gt;I&#39;m sorry, I just can&#39;t shout it loud enough.&lt;br /&gt;&lt;br /&gt;Just imagine having this amount of garbage bags pile around your own house !!!&lt;br /&gt;I&#39;d rather live without &lt;u&gt;any&lt;/u&gt; garbage bags around my house at all I can tell you that ! But I would definitely&amp;nbsp;be happy to reduce the amount as much as I can. &lt;br /&gt;&lt;br /&gt;Remember, just because it goes into the air, doesn&#39;t mean it is not there ! - it even rhymes !&lt;br /&gt;&lt;br /&gt;Change starts today.&lt;br /&gt;&lt;/span&gt;&lt;/h2&gt;</content><link rel='replies' type='application/atom+xml' href='http://tech-drum.blogspot.com/feeds/9193837797052930482/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-drum.blogspot.com/2012/01/more-performance-less-carbon-dioxide.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/9193837797052930482'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/9193837797052930482'/><link rel='alternate' type='text/html' href='http://tech-drum.blogspot.com/2012/01/more-performance-less-carbon-dioxide.html' title='More (software) performance, less carbon dioxide'/><author><name>Nir Moav</name><uri>http://www.blogger.com/profile/05879703892878058262</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-224320715137455380.post-8110458144603551833</id><published>2011-12-13T23:43:00.000+02:00</published><updated>2012-07-12T12:24:31.569+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="encryption"/><category scheme="http://www.blogger.com/atom/ns#" term="Example"/><category scheme="http://www.blogger.com/atom/ns#" term="java"/><category scheme="http://www.blogger.com/atom/ns#" term="password"/><category scheme="http://www.blogger.com/atom/ns#" term="SHA"/><category scheme="http://www.blogger.com/atom/ns#" term="Users"/><title type='text'>Password encryption in Java</title><content type='html'>This time, it&#39;s about security.&lt;br /&gt;
And specifically about how as a developer, you should protect the passwords of your users.&lt;br /&gt;
&lt;br /&gt;
I think there can&#39;t be enough emphasis of how important it is to keep the password of your users safe.&lt;br /&gt;
So, instead of &#39;lecturing&#39; about &lt;i&gt;why&lt;/i&gt; you should do it, lets dive in right away into &lt;i&gt;how&lt;/i&gt; you do it.&lt;br /&gt;
&lt;br /&gt;
So, given the fact you have different users on your system, and each of them has a password,&lt;br /&gt;
we would like to keep their passwords safe.&lt;br /&gt;
&lt;br /&gt;
This translates to storing their passwords somewhere (a DB for example), encrypted.&lt;br /&gt;
&lt;br /&gt;
So before we really give code example how it&#39;s done, a small note on encryption:&lt;br /&gt;
When you pick an encryption algorithm to apply on your passwords, try to think if you ever&lt;br /&gt;
plan on decrypting them. In most cases the answer is &#39;&lt;i&gt;NO&lt;/i&gt;&#39;.&lt;br /&gt;
(Picking a symmetrical algorithm also means that in case an attacker finds out the key,&lt;br /&gt;
they can use it to decrypt the passwords).&lt;br /&gt;
&lt;br /&gt;
Thus, we&#39;ll drop all symmetrical algorithms such as &lt;i&gt;AES(Rijndael), RSA&lt;/i&gt; based, etc.. and pick&lt;br /&gt;
an asymmetrical encrypting algorithm such as hashing.&lt;br /&gt;
&lt;br /&gt;
Hashing algorithms such as &lt;i&gt;SHA&lt;/i&gt; are &lt;i&gt;asymmetrical-key&lt;/i&gt; algorithms, meaning that for an attacker&lt;br /&gt;
that put their hands on the encrypted password it is impossible to recover the original password.&lt;br /&gt;
Different inputs for &lt;i&gt;SHA&lt;/i&gt; can yield the same output, but with a very low probability.&lt;br /&gt;
&lt;br /&gt;
Now that we understand why we should use a Hashing algorithm, we can explain the steps for&lt;br /&gt;
encrypting and give an example code how it&#39;s done in Java.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;Encryption recipe:&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
1. Take password and &lt;i&gt;salt*&lt;/i&gt; as an input.&lt;br /&gt;
2. Apply some hashing algorithm on the input. (We will choose &lt;i&gt;SHA-256&lt;/i&gt;)&lt;br /&gt;
3. Repeat step 2 a large amount of times where the input to the algorithm is the last output of the encryption.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;*salt&lt;/i&gt; - Is an additional fixed input for adding complexity for the encrypted password.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;Lets write this in Java:&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;background-color: #eeeeee;&quot;&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;package nm.example;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;import org.apache.commons.codec.binary.Base64;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;import java.security.MessageDigest;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;public class PasswordEncrypter {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private final static int NUMBER_OF_HASHING = 10000 ;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private final static String CHARSET = &quot;UTF-8&quot; ;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private final static String ENCRYPTING_ALGORITHM = &quot;SHA-256&quot;;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /**&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Encrypts a given password.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static String encryptPassword(String salt, String password) throws Exception {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // Transform the given password &amp;amp; salt to Base64 in order&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // to work on a closed set of 64 characters instead of Unicode.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Base64 base64EncoderDecoder = new Base64();&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; String b64password = base64EncoderDecoder.encodeAsString(password.getBytes(CHARSET)) ;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // Create the salt &amp;amp; transform it to Base64.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; String b64Salt = base64EncoderDecoder.encodeAsString(salt.getBytes(CHARSET));&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // The encryption!&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; byte[] proposedDigest = getHash(b64password, b64Salt);&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return base64EncoderDecoder.encodeAsString(proposedDigest) ;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /**&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* From a password, a number of iterations and a salt,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;* returns the corresponding digest&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;*/&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private static byte[] getHash(String password, String salt) throws Exception {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MessageDigest digest = MessageDigest.getInstance(ENCRYPTING_ALGORITHM);&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; digest.reset();&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; digest.update(salt.getBytes(CHARSET));&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; byte[] passwordBytes = password.getBytes(CHARSET);&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; byte[] input = digest.digest(passwordBytes);&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int i = 0; i &amp;lt; NUMBER_OF_HASHING; i++) {&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; digest.reset();&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; input = digest.digest(input);&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return input;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #eeeeee; font-family: inherit;&quot;&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #444444;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;u&gt;So the output for:&lt;/u&gt; &lt;i&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;b&gt;PasswordEncrypter.encryptPassword(&quot;secret-salt&quot;, &quot;my-password&quot;) &lt;/b&gt;&lt;br /&gt;
is &lt;i&gt;&quot;NiNP/e/NOzmoCQGaShXENFzpYXv7+EclH9st+dnfBWE=&lt;/i&gt;&quot;&lt;br /&gt;
&lt;br /&gt;
As you can see I&#39;m using the Apache Commons Codec library for Base64 encoding,&lt;br /&gt;
which is available at: &lt;a href=&quot;http://commons.apache.org/codec/download_codec.cgi&quot; target=&quot;_blank&quot;&gt;http://commons.apache.org/codec/download_codec.cgi&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Happy encrypting.</content><link rel='replies' type='application/atom+xml' href='http://tech-drum.blogspot.com/feeds/8110458144603551833/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tech-drum.blogspot.com/2011/12/encrypting-your-users-passwords.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/8110458144603551833'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/224320715137455380/posts/default/8110458144603551833'/><link rel='alternate' type='text/html' href='http://tech-drum.blogspot.com/2011/12/encrypting-your-users-passwords.html' title='Password encryption in Java'/><author><name>Nir Moav</name><uri>http://www.blogger.com/profile/05879703892878058262</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>