tag:blogger.com,1999:blog-43364685780699574832024-02-19T11:29:40.899+01:00XHAB: Xavier Hanin's BlogAnonymoushttp://www.blogger.com/profile/06817947075459199523noreply@blogger.comBlogger48125tag:blogger.com,1999:blog-4336468578069957483.post-21553502753306784712013-11-15T01:31:00.001+01:002013-11-15T01:35:28.243+01:00Java web development in the cloud with Restx.io and Nitrous.ioRecently I've quickly evaluated some cloud IDE solutions, and since today I've <a href="http://restx.io/news/2013/11/14/restx-0.30-release.html" target="_blank">released</a> version 0.30 of <a href="http://restx.io/">restx.io</a> I thought it was a good opportunity to give a short tuto on how to start using restx with one of these solutions: <a href="http://nitrous.io/">Nitrous.io</a>.<br />
<br />
Following these steps shouldn't take more than a few minutes, and you will see how restx auto compile can be useful when using a limited development environment.<br />
Here are the steps to follow:<br />
<div class="separator" style="clear: both; text-align: center;"><br />
</div><h3>Create an account on <a href="http://nitrous.io/">nitrous.io</a></h3>Fill in login / email / password - confirm your email and you're done.<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjz24ajS3faQQ7cOz9mPaOXfkcfCIqK2ZRxcW8JY8_lDot5ossiN2knlQauCH7dNusWHHoJK1BKiqykZZ8J5I_33ZNl1mK3NlxHlj-OwqUzu-S5AK-G91Dd5lh5SyVw94cdV6CNExujYOWo/s1600/r-t-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjz24ajS3faQQ7cOz9mPaOXfkcfCIqK2ZRxcW8JY8_lDot5ossiN2knlQauCH7dNusWHHoJK1BKiqykZZ8J5I_33ZNl1mK3NlxHlj-OwqUzu-S5AK-G91Dd5lh5SyVw94cdV6CNExujYOWo/s320/r-t-1.png" width="314" /></a></div><br />
<h3>Select the box</h3>Choose a box name, the minimal 384MB of RAM are enough for restx. Pick node for the stack, despite we won't use node at all in this tuto.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAdvi67kYgoD23ViRPAFKWzRsF8KRhfnscjWB_YtnN9goM2Wj6KC4ZLBP7aIh2txVT8S49ouwDVEwJRyuTDJenrRRrL_Gvar7m5x9e-Nn0DiXWZhVpJ49mnjTwF-yaDT_fWeM79eHDpnqc/s1600/r-t-2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAdvi67kYgoD23ViRPAFKWzRsF8KRhfnscjWB_YtnN9goM2Wj6KC4ZLBP7aIh2txVT8S49ouwDVEwJRyuTDJenrRRrL_Gvar7m5x9e-Nn0DiXWZhVpJ49mnjTwF-yaDT_fWeM79eHDpnqc/s320/r-t-2.png" width="314" /></a></div> Nitrous prepares the box for you, it's very fast, you should be up in less than a minute.<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBXSUWiHjI5m82A-Qv4fKsZYDddmwS6QRQJrax5mIecaHMpewhn7PlCHFx_DPJKsrqB9KDQZXRmiwLOi31icxggdeCrgGChlJjHhunV1yzoihDHyvjzkOzhF9_GpSYhTTvtCQypCfNfZNI/s1600/r-t-3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBXSUWiHjI5m82A-Qv4fKsZYDddmwS6QRQJrax5mIecaHMpewhn7PlCHFx_DPJKsrqB9KDQZXRmiwLOi31icxggdeCrgGChlJjHhunV1yzoihDHyvjzkOzhF9_GpSYhTTvtCQypCfNfZNI/s320/r-t-3.png" width="314" /></a></div> When the workspace is ready, you can go in the terminal at the bottom and expand it.<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIxzS_ZSHiekK8uTL_EX6ohFe4vTDWEcY374TXKLlmovXOb5Etv5_sYTrzVY5Km_OswAQOrofSgF2AeG6Dpz1dLk2IPlrwcGvGoZ0UzsPPKpyZd_4FCnXgVb_C-l6eK5aQQePt49gRLK1i/s1600/r-t-4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIxzS_ZSHiekK8uTL_EX6ohFe4vTDWEcY374TXKLlmovXOb5Etv5_sYTrzVY5Km_OswAQOrofSgF2AeG6Dpz1dLk2IPlrwcGvGoZ0UzsPPKpyZd_4FCnXgVb_C-l6eK5aQQePt49gRLK1i/s320/r-t-4.png" width="314" /></a></div><h3> Install restx</h3>type this command:<br />
<pre><code>export RESTX_BIN=~/.parts && curl -s http://restx.io/install.sh | sh</code></pre><div><br />
</div><div>nitrous has a sanboxed environment, the `export RESTX_BIN=~/.parts` part is a way to tell restx install script where it should go.</div><div><br />
</div><h3>Run restx shell and install plugins</h3><div>You're now ready to run restx shell using the restx command. But first go in the workspace directory so that restx later generate your first app in the right location:</div><div><br />
</div><pre><code>
cd workspace
restx
</code></pre><br />
<div>now in the restx shell, type `help` to get a list of commands. You will see only a limited set of commands. Type `shell install` and restx will propose a few plugins. Install them all by typing `1 2 3`.</div><div><br />
</div><div><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGgMqBmAA_xgyLvoGEtIllSko4b1SddRAwLVblBy71fB-gYSdpPSzFjwTRKpXNt-nhKGLcmTp0Jy4Vk2cAWT87tRMT2HlaZCSaGkN1rdd0I8taNf5J3ZedfM8C7Svc3iLBa6azfR2R1VSw/s1600/r-t-5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGgMqBmAA_xgyLvoGEtIllSko4b1SddRAwLVblBy71fB-gYSdpPSzFjwTRKpXNt-nhKGLcmTp0Jy4Vk2cAWT87tRMT2HlaZCSaGkN1rdd0I8taNf5J3ZedfM8C7Svc3iLBa6azfR2R1VSw/s320/r-t-5.png" width="314" /></a></div><h3> Create and run your app</h3><div>now that you have installed the shell plugins, you can generate an app using `app new` command in restx shell. You will have to answer a few questions, you can accept all the defaults except for:</div><div>- app name: choose your app name, like `mydemo`</div><div>- admin password: restx randomly selects a 4 digit password, note it or choose the one you like</div><div>- port to listen to: choose 3000, on nitrous.io it is mapped to port 80 so you won't need to add a port in the URL</div><div><br />
</div><div>Then restx propose to generate an example resource and run your app, accept it, you should get the app running.</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHjsT-za_ZHBrnOyjlCUTTDMP67CxxXMdUQapnAE5jK5z8cGYFMHJh3BDM61-zVPqmDHtYNCotceULTWsTLcF95rxsYZ8DwE8U6Eglj82Dr20zDqerb784DNOF7FlblxwPlgUd-T8BNQa6/s1600/r-t-6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHjsT-za_ZHBrnOyjlCUTTDMP67CxxXMdUQapnAE5jK5z8cGYFMHJh3BDM61-zVPqmDHtYNCotceULTWsTLcF95rxsYZ8DwE8U6Eglj82Dr20zDqerb784DNOF7FlblxwPlgUd-T8BNQa6/s320/r-t-6.png" width="314" /></a></div><h3> Preview the app</h3>Now you can use the preview and choose to preview on port 3000.<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkcFyGCLH2wuXT2QiSctQTafWBUc_q5CkzAgkm0qLWVOswm8rnvPUkPY7gUeasVQ5B31ZxG80yLJrK4ciQv_vgARJy37s_wlvKJ8qMo1quqkK70JCRSnvre3DbGrrJsRqEbLJ_CIuZXnpH/s1600/r-t-7.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkcFyGCLH2wuXT2QiSctQTafWBUc_q5CkzAgkm0qLWVOswm8rnvPUkPY7gUeasVQ5B31ZxG80yLJrK4ciQv_vgARJy37s_wlvKJ8qMo1quqkK70JCRSnvre3DbGrrJsRqEbLJ_CIuZXnpH/s320/r-t-7.png" width="314" /></a></div> This will open a new browser window, you will have to add `api/@/ui/` to the URL to go restx admin console, where you can enter the user admin and password you have chosen when creating the app.<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWonDbly7H3sVSAA8J9iZ-6r0EcifRcoJ4uNRHqOfuCRS8Ln7GotK3bsQxdPGQYD5utjv3icjHICwNYY_DLt6fGwCP3TnKs0RsQ0z385A781IvxsdkAoV1L2r15LI7KQ_LMr3NbRG5bwTr/s1600/r-t-8.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWonDbly7H3sVSAA8J9iZ-6r0EcifRcoJ4uNRHqOfuCRS8Ln7GotK3bsQxdPGQYD5utjv3icjHICwNYY_DLt6fGwCP3TnKs0RsQ0z385A781IvxsdkAoV1L2r15LI7KQ_LMr3NbRG5bwTr/s320/r-t-8.png" width="314" /></a></div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEil7uhxunuCuBBycfYr2yPZ3y6s1-RtKHmMtlnYOE-XuBA5YbHrKOo1Bex27O48ShuPtKGCfQ6DFQ0QixJWtjJmSbWPWk4SG3i7lHHnHijR-XdrEQQtNSONVdJmmvjGva6MfJlVAL-XwR8S/s1600/r-t-9.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEil7uhxunuCuBBycfYr2yPZ3y6s1-RtKHmMtlnYOE-XuBA5YbHrKOo1Bex27O48ShuPtKGCfQ6DFQ0QixJWtjJmSbWPWk4SG3i7lHHnHijR-XdrEQQtNSONVdJmmvjGva6MfJlVAL-XwR8S/s320/r-t-9.png" width="314" /></a></div> Now select the API-DOCS to get the docs of a few endpoints. The hello resource is the one defined by your generated app.<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUfSW359NmCCoNTx_oleXDAfhmP230UPfPp-dzE9tAftbw-YmZPYfJtBGw-ULuFYGsmucy-54rLeUQQ1p3foLb0qlS17_6HZLCDx2Xos575Ht52dvSdqFmjJqd0SdyRs5-PkGXCZBe71h4/s1600/r-t-10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUfSW359NmCCoNTx_oleXDAfhmP230UPfPp-dzE9tAftbw-YmZPYfJtBGw-ULuFYGsmucy-54rLeUQQ1p3foLb0qlS17_6HZLCDx2Xos575Ht52dvSdqFmjJqd0SdyRs5-PkGXCZBe71h4/s320/r-t-10.png" width="314" /></a></div> Check the GET /message operation and try it out<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhozmB0U21CdqKvwQS2OZEJTYI8-0xZwRCNPkrSOtFqS86SEEiNHrgoofPIAJq8fY15Gjg1guqVZKeUUKvoRK6c-zExrooz_VGGKy710VWtIxLoQTLds0j8zuS2zC3Fx_GQMEk_JPFIoF71/s1600/r-t-11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhozmB0U21CdqKvwQS2OZEJTYI8-0xZwRCNPkrSOtFqS86SEEiNHrgoofPIAJq8fY15Gjg1guqVZKeUUKvoRK6c-zExrooz_VGGKy710VWtIxLoQTLds0j8zuS2zC3Fx_GQMEk_JPFIoF71/s320/r-t-11.png" width="314" /></a></div><h3> Modify the source</h3><div>Because this is a cloud IDE, you can go in workspace > mydemo > src > main > java > mydemo > rest > HelloResource.java and modify the source code. For instance, change hello to bonjour and save. </div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEha4Gby_yR4hu2tBWXwKG9J_U9ISc5vfvAVT86-hfd0C8Q1vevIHz_ptSW8ubxj7a9ucT7NHFtk7iA3apIHCBguGYCwf8WavhjDMIOA_Uka4EcNygowsKFmxZ9gkogs1XbrJkwsdAEZOWxa/s1600/r-t-12.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEha4Gby_yR4hu2tBWXwKG9J_U9ISc5vfvAVT86-hfd0C8Q1vevIHz_ptSW8ubxj7a9ucT7NHFtk7iA3apIHCBguGYCwf8WavhjDMIOA_Uka4EcNygowsKFmxZ9gkogs1XbrJkwsdAEZOWxa/s320/r-t-12.png" width="314" /></a></div> When you save, restx will detect the change and automatically recompile. So you can go back to your console and try again. You don't even need to refresh the page, simply press the send button or use cmd+enter or ctrl+enter.<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-bdABMj0uYJugTZIMNgoyMCEsgFQy7Rv_Vcvx4NTI868qpxT1cBVb4gxb0BsotOPky8ZNZNrU5tWzf4Q5lYAr7rH7iB5gte55N3mvs0EV2nTH8yKBmNsX9_3-LlNquuHtf-EZhRxzo8HQ/s1600/r-t-13.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-bdABMj0uYJugTZIMNgoyMCEsgFQy7Rv_Vcvx4NTI868qpxT1cBVb4gxb0BsotOPky8ZNZNrU5tWzf4Q5lYAr7rH7iB5gte55N3mvs0EV2nTH8yKBmNsX9_3-LlNquuHtf-EZhRxzo8HQ/s320/r-t-13.png" width="314" /></a></div><br />
<br />
That's it, you are now developing in the cloud!<br />
<br />
<h3>Going further</h3>You can try a more complete sample with more endpoints and persistency on <a href="http://www.mongodb.org/" target="_blank">MongoDB</a> very easily:<br />
<br />
- stop the running app with `stop` command in the restx shell,<br />
- exit shell with `exit` command<br />
- run these commands in the terminal<br />
<br />
<pre><code>
cd ~/workspace
parts install mongodb
parts start mongodb
git clone https://github.com/xhanin/rxinvoice.git
cd rxinvoice
export PORT=3000
restx deps install + app run --quiet
</code></pre><br />
Open the api docs and experience the java based REST API, available in the cloud, with persistency in MongoDB, everything within the 384MB of RAM available for free with <a href="http://nitrous.io/">Nitrous.io</a>!<br />
<br />
Sure the perfs are slow in such a limited environment when using the dev mode, but you can also try the prod mode (with no auto compile / hot reload), which provides better perfs in this sandbox:<br />
restx app run --quiet --mode=prod<br />
<br />
And obviously, restx app development is not limited to the cloud IDE. It's plain Java so you can <a href="http://restx.io/docs/ide.html" target="_blank">develop with your favorite Java IDE</a>, build with maven, <a href="http://restx.io/docs/ref-deploy.html" target="_blank">deploy in tomcat</a>, you name it!<br />
<br />
Anonymoushttp://www.blogger.com/profile/06817947075459199523noreply@blogger.com1tag:blogger.com,1999:blog-4336468578069957483.post-70045974279390552152013-05-27T12:34:00.000+02:002013-05-27T12:34:03.386+02:00RESTX 0.2.6 is out!<p>Today I'm pleased to announce version 0.2.6 of <a href="http://restx.io/">RESTX, the lightweight open source Java REST framework</a>.</p><br />
<p>2 weeks after the first release, this release comes with a few improvements and bug fixes:</p><br />
<ul><li><a href='http://restx.io/docs/samples.html'>4 samples</a> demonstrating several features of restx, such as the integration with MongoDB or using custom routes</li>
<li>improved JUnit rule for starting and stopping server, which now allow to use another server than Jetty, and to use the rule for tests other than specs</li>
<li>upgrade jongo from 0.3 to 0.4 in restx-jongo module</li>
<li>several bug fixes</li>
</ul><br />
<p>Check <a href="http://restx.io/">RESTX web site</a> for more information on the project!</p>Anonymoushttp://www.blogger.com/profile/06817947075459199523noreply@blogger.com0tag:blogger.com,1999:blog-4336468578069957483.post-20570391597660533222013-05-13T16:41:00.000+02:002013-05-13T16:41:41.505+02:00Introducing RESTX, the lightweight open source Java REST framework<p>Last January while we were starting a project at <a href=""http://4sh.fr/">4SH</a>, I was responsible for setting up the server part. As for many of our developments, we use HTML/CSS/JS on the front (with Angular or Backbone), so that the back is only responsible to provide a RESTful API, and not to serve dynamic pages.</p><br />
<p>As we do our back developments mostly in Java, I first started with the usual suspects (like JAX RS or Spring MVC) but was unsatisfied with the startup time (around 2 seconds for an empty app). And because I have ideas about REST frameworks for several years, and probably suffer from a deep NIH syndrom, I started developing a small, lightweight, REST framework.</p><br />
<p>So without further ado, today I'm really excited to announce the first public release of this project called RESTX. Check the web site at <a href="http://restx.io/">http://restx.io/</a> to get an idea of what it is and what it does. If you are interested, the project is open source and open to community development!</p><br />
<p style="text-align:center"><a href="http://restx.io/"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEip6Swid5KOrnVkvQcpWgjOwld14IFq2S95uGTkJ-bfx6KcapsyC9CJOGrREzmNSqlW9zyeaYw5-FEsigxbC3ZTLUc9hck5aV3f9lOT7f6TJUdD8ulqXSadNPHSIo6xTZhkUjjFobhV88cV/s320/restx-twitter.png" /></a><br />
</p>Anonymoushttp://www.blogger.com/profile/06817947075459199523noreply@blogger.com2tag:blogger.com,1999:blog-4336468578069957483.post-81051950005870134442013-02-12T23:16:00.001+01:002013-02-13T23:21:49.413+01:00Playing with IntellijEval<br />
Tonight I've been playing with <a href="https://github.com/dkandalov/intellij_eval">IntellijEval</a> plugin, which is a kind of meta plugin which allows you to create your own plugins for IntelliJ IDEA in groovy.<br />
<br />
With examples packaged and the easy settings to attach IDEA jars and IntellijEval jar including a very helpful helper, I've managed to create 2 simple new actions:<br />
<h3>Generate MongoDB ObjectId</h3><div>This plugin registers a new action which simply generates a Mongo ObjectId. When I create datasets for my integration tests with MongoDB, I used to switch to iterm and run "<span style="font-family: Courier New, Courier, monospace;">mongo --eval 'printjson(new ObjectId())'</span>", and then copy paste the result in my editor in IDEA.</div><div>Now I can simply hit alt+shift+O and I'm done.</div><div><br />
</div><div>Here is the code for this plugin:</div><div class="gistLoad" data-id="4948868" id="gist-4948868">Loading ....</div><div><br />
</div><div>It's very simple, it just requires to have mongo java driver 2.10.1 in your local m2 repository</div><h3>Convert epoch to ISO 8601 date time, and vice versa</h3><div>Another thing I do frequently on my current project, is converting ISO8601 date times to epoch, or the opposite. Indeed my mongo datasets use its import mechanism which represents dates like this:</div><pre>{ "$date": 1358840400000 }
</pre><div>As you can see this is an epoch timestamp, which I previously obtained using the <a href="http://www.epochconverter.com/">epochconverter</a> web site. But these timestamps represent data that we represent as ISO 8601 encoded datetimes in the json we send/receive from our server, so in my integration tests I very frequently have corresponding ISO 8601 date times like this:</div><pre>"2013-01-22T08:40:00.000+01:00"
</pre><div><br />
</div><div>Therefore I've created a plugin which allows to convert an epoch timestamp to an ISO 8601 and vice versa. Being able to go both ways is useful even if you don't need ISO 8601 date times: if I want to edit or just "human read" an epoch timestamp, I put my caret anywhere on the timestamp, hit ctrl+alt+shift+T once to get the ISO 8601 date (which is much more readable / editable), optionally edit it, and hit ctrl+alt+shift+T again without even having to select the ISO date. Very handy!</div><div><br />
</div><div class="separator" style="clear: both; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuRIUYZEBJUB2QsFFhs8Euk2KVMzw0T6uj6Q4k90rWAl4m6TzeQ3ZX7bJoUIs7Z_l-sEp9VFgihKVtoenPYbn63HWjiRvPIISopEmWT_5CMYsPj3kl-9CF3_KSLVQDUU1XHnzkhZ6WejcD/s1600/date-plugin.png" /></div><div><br />
</div><div><br />
</div><div>Here is the code for this plugin:</div><div class="gistLoad" data-id="4948901" id="gist-4948901">Loading ....</div><div><br />
</div><div>It may be possible to improve it much (especially the selection expansion part which I'm not proud of), but it works for me, that's good enough.</div><h3>Conclusion</h3><div>In one hour I've just gone from "never seen an Intellij plugin code" to "I've done 2 small plugins which will help me in my day to day job". Not too bad. The workflow to develop these small plugins is very nice, being able to test them right in the currently launched Intellij instance is so useful! I guess I'll develop more little "just for my use case" plugins in the future.</div><div><br />
</div><div>I love IntelliJ!</div><br />
<script src="https://raw.github.com/moski/gist-Blogger/master/public/gistLoader.js" type="text/javascript"></script><br />
Anonymoushttp://www.blogger.com/profile/06817947075459199523noreply@blogger.com0tag:blogger.com,1999:blog-4336468578069957483.post-63393890425873444462012-08-14T12:16:00.001+02:002012-08-14T12:16:50.261+02:00Vert.x with Java 8 LambdaI'm currently doing some experimentations with <a href="http://vertx.io/">Vert.x</a>, the asynchronous polyglot application development framework. <br />
<br />
With vert.x you can develop in several languages, including Java, but Java's lack of closure support makes asynchronous code rather ugly. Still I like the tool support you get with Java, so I was wondering if vert.x with java 8 Lambdas wouldn't be a good combination. The good news is that vert.x with java 8 lambdas in their current state (developer preview only) just works! The setup is very easy:<br />
<br />
1) download and install java 8 developer preview with lambda support: <a href="http://jdk8.java.net/lambda/">http://jdk8.java.net/lambda/</a><br />
2) download and install vert.x: <a href="http://vertx.io/install.html">http://vertx.io/install.html</a><br />
3) check you have installed it properly:<br />
<pre>$ vertx version
vert.x-1.2.3.final
$ java -version
openjdk version "1.8.0-ea"
OpenJDK Runtime Environment (build 1.8.0-ea-lambda-nightly-h219-20120726-b50-b00)
OpenJDK 64-Bit Server VM (build 24.0-b16, mixed mode)
</pre>4) write your first Java 8 verticle in a file called Server.java:<br />
<div class="gistLoad" data-id="3347906" id="gist-3347906">Loading ....</div>5) run<br />
<pre>$vertx run Server.java
</pre>6) open <a href="http://localhost:8086/Server.java">http://localhost:8086/Server.java</a><br />
<br />
<br />
Tooling support for Java 8 lambdas is not perfect yet, I've tried <a href="http://confluence.jetbrains.net/display/IDEADEV/IDEA+12+EAP">IntelliJ IDEA 12 EAP</a>, it seems to work fine but I didn't manage to get breakpoints inside a Lambda to work (and debugging vert.x java app is painful anyway, but that's another story).<br />
<br />
Obviously this can't be used for production yet, but it's nice to see it working so easily.<br />
<br />
<script src="https://raw.github.com/moski/gist-Blogger/master/public/gistLoader.js" type="text/javascript"></script>Anonymoushttp://www.blogger.com/profile/06817947075459199523noreply@blogger.com2tag:blogger.com,1999:blog-4336468578069957483.post-6700456494608384052010-10-16T22:14:00.005+02:002010-10-16T23:52:23.521+02:00Play! framework Flex module development<h2>Playing around</h2>
<p>
I've been recently starrting to evaluate <a href="http://playframework.org">Play!</a> to use as a basis for future developments at <a href="http:/www.4sh.fr">4SH</a>. What I've seen so far is really pleasant, I like the productivity you get, and especially the hot reload experience: I'm used to develop in Java with pretty good hot reload capabilities, but with Play! I almost never have to restart my server, even when I touch my JPA entities to add or remove properties. It's really a pleasure. Moreover I really like the architecture, the concepts of plugins and class enhancers opens a set of interesting possibilities without relying on a complex build mechanism which causes problems in your IDE (I've experienced that with AspectJ): in playframework the complex build is part of the runtime, so you can just rely on the framework whatever you use for development.
</p>
<h2>My use case: calling methods in my Play app classes from a Flex client</h2>
<p>
While conducting my evaluation I had to test how good I could integrate a <a href="http://www.adobe.com/products/flex/">Flex</a> client with the Play backend, partly because some customers request a shiny Flex UI, and partly because I really like the productivity we have with Flex. It's also a good way to see how difficult it is to go outside the Play! box... <br />
My intention in this module is to allow to perform remote calls from the flex application to public static methods on my Play classes (something similar to action methods). Indeed I have like the domain driven approach you can take with Play!, and thus I want to be able to perform remote calls directly on that static methods we get for free on the domain classes.
</p>
<h2>First steps</h2>
<p>
So my first step was to investigate how Flex performs its remote invocation, having a look at BlazeDS classes really helped for that. Integrating this in Play is not too difficult, thanks to the very high level hook plugins provide: rawInvocation is called before the HTTP request is route, so you can do whatever you want here without going through the whole action routing. It's nice to have this kind of very low level hook. With this approach I had something working in less than a day, not too bad considering that I was just beginning with Play. I even quickly hacked something to make the serialization understand the JPA lazy initialization so that it doesn't serialize collections which have not been fetched, so you can easily control what get serialized to the client, without requiring copies to DTOs.<br/>
From a Play! perspective, what I was doing was just a plugin, that I was putting in the classpath of my application (with a mere project dependency in eclipse). So my contract was almost fulfilled: calling methods was possible, but still I needed to write all the client side code, including kind of duplicating the code of my domain classes to convert them in ActionScript3...
</p>
<h2>Improving productivity: generating client side code</h2>
<p>
Writing the client side code manually when you have such a productive framework on the server side is just too painful. Moreover FlashBuilder 4, the tool Adobe offers for Flex development, has very good code generation features when you use BlazeDS on the server side, so it was not acceptable to drop this productivity boost on the client just for better productivity on the server... So I first tried to see how FlashBuilder gets meta information from BlazeDS to generate the code, but unfortunately it relies on the server side on the configuration of a Servlet (flex.rds.server.servlet.FrontEndServlet) which is provided in BlazeDS binaries but not in BlazeDS sources :( <br/>
Therefore I considered using the code generation tool that <a href="http://www.graniteds.org/">GraniteDS</a> provides: <a href="http://www.graniteds.org/confluence/display/DOC/3.+Gas3+Code+Generator">Gas3</a>. But while commuting to work friday morning on my bike, I thought that Play! already offers a pretty easy way to generate source code: its regular template mechanism to serve HTTP requests. The advantage is that it's fully integrated, and I thought it was going to be very fast to develop: a controller with 3 actions: one to give the list of classes from which generation is possible, one to generate the actionscript to represent a value object (based on my entities on java side) and one to generate the service (on client side I prefer to distinguish classes to represent the remote objects from the value objects). With that you can simply copy / paste the generated code (that you get in the browser).<br />
When I started to further read the document on how to do that from py plugin, I realized that what I needed was a Play! module rather than a mere plugin. Indeed <a href="http://groups.google.com/group/play-framework/msg/abfa72ba8e3c40b3">Guillaume Bort is clear about the difference</a>:
<blockquote>A plugin is a java class that extends PlayPlugin. A module is an
application fragment that can contain anything like any application.
And of course it can contain some plugin too. </blockquote>
</p>
<h2>Enter module development</h2>
So I first searched for documentation on how to write a module, and the main source of information is <a href="http://www.playframework.org/documentation/1.1RC1/modules">this page</a> in the documentation. Ok, so here the documentation is mixing information on what you can do inside a module and what you need to do to install a module in your app. I tihnk for some people it may be confusing, most users only need to use a module, and actually most of that page describes this use case.<br />
Still based on that doc I could quickly start up with the <code>play new-module</code> command, which gives you the structure to get started, nice! But quickly I had trouble figuring out where my classes should go, and I think the documentation is not clear on that subject. From what I've understood, it's important to understand that in the module you need to distinguish between different kind of classes:
<ul>
<li>Plugin and utility classes</li>
This is the kind of classes which are in plain Java, not enhanced by Play, and that may be used by your application classes like any library, and may participate to the framework using provided hooks (plugin classes). It's also there that you put the play.plugins file which describes the plugins you are contributing in the module. The source of these classes go in the <code>src</code>directory of your module if you follow the regular directory layout, and these classes are compiled by the <code>play build-module</code> or <code>ant</code> command inside the <code>lib</code> directory of your module.
These classes need to be in the regular classpath of your application, so if you use an IDE you need to regenerate its configuration for your application using your module once you declare the module in your application.conf. Moreover you HAVE TO build the jar in the lib directory to have the compiled classes available in your app (if like me you test your module in an application).
<li>Play classes and views of your module</li>
As Guillaume says, a module is an application fragment, and as such it can provides model classes, controllers routes and views. These classes and resources which are managed by Play! (loaded and enhanced by the Play! classloader, with the famous full hot reload capability). These go in the <code>app</code> directory of your module, and since they are loaded by Play! you don't have to worry about the classpath: all you need is to have your module properly setup in the application.conf of your application (and the <a href="http://www.playframework.org/documentation/1.1RC1/modules">documentation on the subject</a> is perfect to describe that).
</ul>
Once I had properly understood that, I was ready to actually develop my module controller to generate my source code. I still had some minor issues due to my inexperience with Play (like an OutOfMemory error after an exctract method in my controller class, because I moved a recursive <code>public static void</code> to my controller, which was considered by Play as an action chaining... making it private was enough to fix the problem). Still the code generation pages were ready pretty fast.
</p>
<h2>Still not enough productivity: enter commands</h2>
<p>
Once I got my code generation working, I quickly felt that the copy/paste from browser to sources was going to be annoying. So I decided to go further in the automation and try to provide commands to generate the code directly in the proper files. After all Play! provides a skeleton of commands.py in the module skeleton provided by <code>play new-module</code>, so adding a command which more or less performs a <code>wget</code> shouldn't be too complicated.<br />
It shouldn't, but I underestimated the time I had to spend. First of all, it was my very first time that I wrote Python. With my 15 years of development I'm not afraid by this kind of challenge, still my productivity in this case is not good, and sometimes the spaces dependent interpretation of python was making me remember my very old days of COBOL in 1994. Don't get me wrong, python seems very productive when you're used to it, it's just far enough from my mostly Java background to get me fall in every possible trap.<br />
Moreover I had some troubles to get my commands integrate in play. When I tried my first command with confidence I got that:
<pre>
sample1-client $ play flex:gen
~ _ _
~ _ __ | | __ _ _ _| |
~ | '_ \| |/ _' | || |_|
~ | __/|_|\____|\__ (_)
~ |_| |__/
~
~ play! 1.1RC1-76-g2e8d571, http://www.playframework.org
~
~ Usage: play cmd [app_path] [--options]
~
~ with, new Create a new application
~ run Run the application in the current shell
~ help Show play help
~
~ Invalid command: flex:gen
~
</pre>
Invalid command, mmm, it seems my module is not properly recognized...
<pre>
sample1 $ play modules
~ _ _
~ _ __ | | __ _ _ _| |
~ | '_ \| |/ _' | || |_|
~ | __/|_|\____|\__ (_)
~ |_| |__/
~
~ play! 1.1RC1-76-g2e8d571, http://www.playframework.org
~
~ Application modules are:
~
~ /Users/xavierhanin/dev/tools/play/play-trunk/modules/flex
~
</pre>
Mmm, it's there, so what's going wrong? I double checked my command declaration in my commands.py, googled for this kind of problem, even started to investigate on how the play command line mechanism is working, but with my poor knowledge of python I didn't even know how to enter in step by step debug mode. I decided to revert back to the initially generated commands.py, and then:
<pre>
sample1 $ play flex:hello
~ _ _
~ _ __ | | __ _ _ _| |
~ | '_ \| |/ _' | || |_|
~ | __/|_|\____|\__ (_)
~ |_| |__/
~
~ play! 1.1RC1-76-g2e8d571, http://www.playframework.org
~
~ hello
~
</pre>
Ok, so the problem is actually in my commands.py when I add my new command. Fortunately at a point in time I just wanted to generate my eclipse settings and then did something like this:
<pre>
sample1 $ play eclipsify
~ _ _
~ _ __ | | __ _ _ _| |
~ | '_ \| |/ _' | || |_|
~ | __/|_|\____|\__ (_)
~ |_| |__/
~
~ play! 1.1RC1-76-g2e8d571, http://www.playframework.org
~
Traceback (most recent call last):
File "/Users/xavierhanin/dev/tools/play/play-trunk/play", line 111, in <module>
cmdloader.commands[play_command].execute(command=play_command, app=play_app, args=remaining_args, env=play_env, cmdloader=cmdloader)
File "/Users/xavierhanin/dev/tools/play/play-trunk/framework/pym/play/commands/eclipse.py", line 121, in execute
execfile(commands)
File "/Users/xavierhanin/dev/tools/play/play-trunk/modules/flex/commands.py", line 46
for c in entities.splitlines():
^
IndentationError: unindent does not match any outer indentation level
</pre>
OK, now I get enough details on the compilation error in my commands.py! With that in my mind, every time I got a <code>Invalid command</code> message I return to <code>play eclipsify</code> to get the details, and it's good enough to fix the problem. I still had to fight a couple of times against my habits to get the code working, but now I have my code generation working like a charm, being able to generate the classes I want, with patterns to select which one like this:
<pre>
sample1-client $ play flex:gen --class models.**
~ _ _
~ _ __ | | __ _ _ _| |
~ | '_ \| |/ _' | || |_|
~ | __/|_|\____|\__ (_)
~ |_| |__/
~
~ play! 1.1RC1-76-g2e8d571, http://www.playframework.org
~
~ models.Comment entity generated in src/models/Comment.as
~ models.User entity generated in src/models/User.as
~ models.details.UserDetails entity generated in src/models/details/UserDetails.as
~ models.details.UserDetails entity delegate generated in src/models/details/UserDetailsDelegate.as
~ models.Post entity generated in src/models/Post.as
~ models.User service generated in src/services/UserService.as
~ models.details.UserDetails service generated in src/services/details/UserDetailsService.as
~ models.Post service generated in src/services/PostService.as
</pre>
I'm pretty happy with that, even though I still have a lot of work to do on the doc, error management, security and yet improve productivity (to avoid a security black hole I force to add <code>@RemotingInclude</code> on every method to expose, but then it's difficult to expose methods provided by Play like findAll and sisters). But my conclusion is that my overall feeling with Play! is very good, the module development part is not very well documented but that's why I wrote this blog entry, hoping it could help others.<br/>
Have fun!
</p>Anonymoushttp://www.blogger.com/profile/06817947075459199523noreply@blogger.com7tag:blogger.com,1999:blog-4336468578069957483.post-34899352390077865852009-11-18T12:37:00.005+01:002009-11-20T00:51:24.322+01:00ForEach / Generics java puzzler<p>While assisting at Mark Reinhold talk on JDK 7 updates at <a href="http://devoxx.com">devoxx</a>, it reminded me a problem we had very recently in a project.</p>
<p>Here is a small piece of java code:
<pre>
import java.util.ArrayList;
import java.util.List;
public class TestForEachLoop {
public static void main(String[] args) {
List<String> listOfStrings = new ArrayList<String>();
doSomethingWithListInPreJava5(listOfStrings);
for (Object o : listOfStrings) {
System.out.println(o);
}
}
private static void doSomethingWithListInPreJava5(List list) {
list.add(new Integer(12));
}
}
</pre>
</p>
<p>So, do you have an idea of what will happen if I compile and run this piece of code? I'll let you comment if you have an idea, and I promise the final answer is not obvious!</p>Anonymoushttp://www.blogger.com/profile/06817947075459199523noreply@blogger.com2tag:blogger.com,1999:blog-4336468578069957483.post-55539636242848097642009-11-18T10:51:00.002+01:002009-11-18T11:04:01.321+01:00Strange NPE in jboss 4.2.2<p>A customer for which I work currently recently reported an error when deploying a new version of the application we just delivered to them. A jboss MBean (annotated with @Service) wasn't starting successfully, with an NPE in the logs in jboss code:
<pre>
java.lang.NullPointerException
at org.jboss.ejb3.service.ServiceContainer.start(ServiceContainer.java:179)
</pre>
</p>
<p>Googling for this, I didn't get much clue on what was going wrong. It seems nobody reported such problem before, that's why I thought it may be worth sharing the conclusion. Digging into the logs and in the jboss configuration setup by my customer, I found this:
<pre>
TIMER SERVICE IS NOT INSTALLED
</pre>
</p>
<p>looking at their ejb-deployer.xml, I realized they had commented out the timer mbean (org.jboss.ejb.txtimer.EJBTimerServiceImpl). What's really strange is that enabling this again fixed the NPE problem, at least in our case. So in case you met such an issue yourself, check that first, it may save you a couple of hours.</p>Anonymoushttp://www.blogger.com/profile/06817947075459199523noreply@blogger.com0tag:blogger.com,1999:blog-4336468578069957483.post-19856597014671102022009-04-23T04:05:00.003+02:002009-04-23T04:21:25.142+02:00Maven leadership in question<p>While reading my feeds tonight I stumbled upon a post by Nicolas Deloof: <a href="http://blog.loof.fr/2009/04/maven-devient-un-projet-prive.html">OPA hostile sur Maven</a>, that I would translate with the help of google "<a href="http://translate.google.fr/translate?u=http%3A%2F%2Fblog.loof.fr%2F2009%2F04%2Fmaven-devient-un-projet-prive.html&sl=fr&tl=en&hl=fr&ie=UTF-8">Hostile takeover on Maven</a>".
</p><p>
The content of this post is interesting, I've already heard people complaining about the way the maven project is lead which doesn't seem to follow the "Apache way". I'm surprised that it comes to an extremity where a Maven committer ends up a blog post with a sentence like "At this rate I'll end up back to the good old Ant and his buddy Ivy.". Maybe it's a good time to switch to Maven alternatives like <a href="http://www.easyant.org/">EasyAnt</a> or <a href="http://gradle.codehaus.org/">Gradle</a> :-)
</p>Anonymoushttp://www.blogger.com/profile/06817947075459199523noreply@blogger.com1tag:blogger.com,1999:blog-4336468578069957483.post-52898249176899668882009-01-25T19:17:00.004+01:002009-01-26T16:40:31.361+01:00Apache Ivy 2.0 final is out!<div style="float:right;"><img src="http://ant.apache.org/ivy/images/logo.png" /></div>
<p>I'm very pleased to relay the announcement made on the Ivy mailing list: <a href="http://ant.apache.org/ivy/history/2.0.0/release-notes.html">Ivy 2.0 is finally out</a>! After a little more than 2 years since the last official stable release (1.4.1), Ivy has gone a long journey toward this 2.0 release: it started incubation at the Apache Software foundation in late 2006, it graduated as a sub project of Ant in october 2007. In the mean time, we produced 2 alpha releases, 2 beta releases, and 2 release candidates before finally releasing 2.0.0. </p>
<p>
This is definitely a major release for Ivy, for several reasons:
<ul>
<li>This is the first final stable release of Ivy as an Apache project</li>
<li>The code base has been fully reworked to make it more modular, easier to understand and to maintain</li>
<li>Maven 2 compatibility has never been as good, Ivy is used by many projects to leverage public maven 2 repositories</li>
<li>As often requested by users, cache management is now much more flexible, allowing to address complex development and integration environments</li>
<li>More flexible dependency management, with module wide exclude, transitive dependency version overriding, dynamic resolve mode, ...</li>
<li>A new packager resolver, which allow to use a repository declaring how to package modules instead of storing them, used in <a href="http://code.google.com/p/ivyroundup/">Ivy roundup repository</a></li>
<li>Ivy core has still no dependency at all, now even for command line use. So using Ivy can be as simple as java -jar ivy.jar. Ivy is now also an osgi bundle, which adds one more way to use it.</li>
<li><a href="http://ant.apache.org/ivy/ivyde/">IvyDE</a>, the Ivy eclipse plugin, has also been improved a lot. A <a href="http://code.google.com/p/ivybeans/">Netbeans plugin</a> and an <a href="http://code.google.com/p/ivyidea/">IDEA plugin</a> are also available</li>
<li>A growing community, with 4 committers, 70 contributors and active mailing lists</li>
<li>As always, <a href="http://ant.apache.org/ivy/history/2.0.0/index.html">documentation</a> has been fully updated with all new features and improvements (the <a href="http://ant.apache.org/ivy/history/2.0.0/book.html">printer friendly version</a> counts now more than 180 pages).</li>
<li>220 bug fixes, 84 improvements and 24 new features since 1.4.1!</li>
</ul>
</p>
<p>
Here are the stats of number of issues per release:<br/>
<a href="http://spreadsheets.google.com/pub?key=pcsKjmJOwgOuuDZKarT0JOQ"><img src="http://spreadsheets.google.com/pub?key=pcsKjmJOwgOuuDZKarT0JOQ&oid=1&output=image" /></a>
</p>
<p>
So if you haven't tried Ivy yet, <a href="http://ant.apache.org/ivy/history/2.0.0/tutorial.html">go ahead</a>, it's hot! And if you already use it, upgrade now, this release is mostly backward compatible with previous ones, and has been extensively tested!
</p>Anonymoushttp://www.blogger.com/profile/06817947075459199523noreply@blogger.com2tag:blogger.com,1999:blog-4336468578069957483.post-64719172032675182632009-01-22T22:18:00.003+01:002009-01-22T22:24:49.153+01:00Strange RuntimeException with Seam on JBoss ASI'm currently setting up a <a href="http://seamframework.org">seam</a> application, and I ran into a strange problem recently:
<pre>
--- MBEANS THAT ARE THE ROOT CAUSE OF THE PROBLEM ---
ObjectName: jboss.j2ee:service=EJB3,module=jboss-seam.jar
State: FAILED
Reason: java.lang.RuntimeException: You did not specify a @Resource.mappedName() on javax.ejb.TimerService org.jboss.seam.async.TimerServiceDispatcher.timerService and there is no binding for enc name env/org.jboss.seam.async.TimerServiceDispatcher/timerService in XML
ObjectName: jboss.j2ee:service=EJB3,module=app.jar
State: FAILED
Reason: java.lang.RuntimeException: @javax.annotation.PostConstruct annotated method has the wrong signature - public void org.jboss.seam.intercept.SessionBeanInterceptor.postConstruct(javax.interceptor.InvocationContext)
ObjectName: jboss.j2ee:module=jboss-seam.jar,uid=33039820,service=EJB3
State: FAILED
Reason: java.lang.RuntimeException: You did not specify a @Resource.mappedName() on javax.ejb.TimerService org.jboss.seam.async.TimerServiceDispatcher.timerService and there is no binding for enc name env/org.jboss.seam.async.TimerServiceDispatcher/timerService in XML
</pre>
Googling around didn't really help, so I had to figure out myself what I did wrong. Actually I messed up my ear lib directory, and had the ejb-api.jar there. Obviously this jar shouldn't go in the ear lib directory, since it's provided by the server.<br/>
Unfortunately the error message doesn't really help to understand what can be wrong, so I thought posting this may help other people facing a similar situation.Anonymoushttp://www.blogger.com/profile/06817947075459199523noreply@blogger.com1tag:blogger.com,1999:blog-4336468578069957483.post-40627876310234759252008-11-06T08:32:00.003+01:002008-11-06T08:34:56.770+01:00Apache Ivy 2.0.0-RC2<p>Maarten has just posted the announcement for Ivy 2.0-rc2. We are getting very close to 2.0.0 final, should be a matter of a couple of weeks now! </p>
<p>
Here is the announcement :
<pre>
Nov 4, 2008 - The Apache Ivy project is pleased to announce the
release of Ivy 2.0.0-rc2, the second release candidate for Ivy 2.0.0.
Ivy is a tool for managing (recording, tracking, resolving and
reporting) project dependencies, characterized by flexibility,
configurability, and tight integration with Apache Ant.
This is a release candidate for 2.0.0 final, meaning that no changes
except bug fixes will occur between this release candidate and 2.0.0 final.
Problems found at this phase can be fixed in the final release, so now
is a good time to download and use it. If no outstanding bugs are reported
in the coming weeks, this release candidate will be promoted as the 2.0.0
final release.
Key changes in this 2.0.0-rc2 version are
* enhanced Maven2 compatibility, with several bug fixes
* 20+ bug fixes as documented in Jira and in the release notes
Issues should be reported to:
<a href="https://issues.apache.org/jira/browse/IVY">https://issues.apache.org/jira/browse/IVY</a>
Download the 2.0.0-rc2 release files at:
<a href="http://ant.apache.org/ivy/download.cgi">http://ant.apache.org/ivy/download.cgi</a>
More information can be found on the Ivy website:
<a href="http://ant.apache.org/ivy/">http://ant.apache.org/ivy/</a>
Regards,
Maarten Coene (2.0.0-rc2 release manager)
</pre>
</p>Anonymoushttp://www.blogger.com/profile/06817947075459199523noreply@blogger.com0tag:blogger.com,1999:blog-4336468578069957483.post-73960737149109135372008-06-24T06:25:00.002+02:002008-06-24T06:49:21.129+02:00A gasless week<p>Last tuesday morning after a lengthy and opinionated discussion with friends about global warming, I decided to go to work by bike. I mostly work at less than 10kms away from home, so biking there takes less than half an hour. </p>
<p>
But why stop with one day... So the day after I used my bike again, to go to work, then to go climbing, then go visit a friend, and then come back home at 1am. About 40 kms in a day, not that hard after all.
</p>
<p>
Then I had two days working at home, avoiding to use my scooter was easy :-)
</p>
<p>
Friday night I went to a party with friends from tennis club. 8kms each way, by bike again. Saturday I went to a friend's birthday party, only 4kms, but I had to bring charcoal for the BBQ and paper tabblecloth... I used my bike again, keeping balance more or less easily. Going back home was pretty funny, a storm started just when I left, so I was fully soaking wet when I get back home. Fortunately human body is waterproof :-)
</p>
<p>
Sunday I went to a volley ball tournament, and it was only 1km away from my home, so I enjoyed using my bike to go there. And yesterday I worked at home, fulfilling my gasless week. Today I plan to go to work with my bike again, it's a small contribution to decreasing the carbon dioxyd emission, but it's better than nothing. And you, what do you do for the earth?
</p>Anonymoushttp://www.blogger.com/profile/06817947075459199523noreply@blogger.com3tag:blogger.com,1999:blog-4336468578069957483.post-78775927389646610492008-05-07T10:05:00.002+02:002008-05-07T10:11:10.396+02:00SpringSource RepositoryA new public java module repository has just come into the dance: the <a href="http://www.springsource.com/repository/">spring source repository</a>. This repository is both a Maven repository and an Ivy repository. It means that it contains metadata not only in maven 2 pom format (which BTW Ivy is able to recognize) but also in Ivy native format: Ivy files.
<p>
The modules contained are not plain open source jars, most of them have been repackaged in OSGi bundles (all that were not already). I'm not sure about what this will mean for the future of public repositories, but it's great to see that spring source continue its commitment to support both Maven and Ivy.Anonymoushttp://www.blogger.com/profile/06817947075459199523noreply@blogger.com0tag:blogger.com,1999:blog-4336468578069957483.post-87786042960090612832008-04-24T20:02:00.002+02:002008-04-24T20:21:24.091+02:00Gradle, a new Groovy based build systemHans Dockter recently <a href="http://www.theserverside.com/news/thread.tss?thread_id=49165">announced</a> the availability of first public version of Gradle, a new build system leveraging Grovvy, Ant and ... Ivy!
<p>
I won't comment too much on the tool yet, I've only read a few pages out of the 50+ pages the <a href="http://gradle.org/userguide.html">user guide</a> counts.
<p>
What really pleased me while reading the comments on the server side announcement, is the praise made to Ivy:
<blockquote>And I must say I'm absolutely thrilled with Gradle's choice for Ivy integration, which is a gem in its own right.</blockquote>
<br/>
<blockquote>I was solely using Maven2 for years. I just knew that Ivy existed and I thought it plays more or less in the same league as Maven's dependency management. I couldn't have been more wrong.<br/>
<br/>
I completely agree that Ivy is a true gem. Starting from the quality of the code base to the fantastic solution of the problem space of dependency management. And its getting better and better. If I had to choose now between Ant & Ivy or Maven, my decision would be very clear. Well, but now there is Gradle :) It adds one missing piece to Ivy. A build system that offers a build-by-convention integration for it.</blockquote>
<p>
It's nice to hear this kind of thing, it's one of the best reward of the time and energy involved in this project.Anonymoushttp://www.blogger.com/profile/06817947075459199523noreply@blogger.com0tag:blogger.com,1999:blog-4336468578069957483.post-58481282393355671402008-04-17T19:50:00.004+02:002008-05-14T14:00:36.897+02:00IvyBeans wins Netbeans innovator grant!<p>Winners of Netbeans innovator grants have <a href="http://www.netbeans.org/grant/">just been announced</a>, and IvyBeans, a project submitted by Laurent Foret with my collaboration is amoung the 10 large projects selected!</p>
<p>This is a very good news both for the <a href="http://ant.apache.org/ivy/">Ivy</a> community and the Netbeans community. I can't tell too much about the content of this project yet, but you already have good hints of what it is about.</p>
<p><i>Update: The project is now started, hosted at google code: <a href="http://code.google.com/p/ivybeans/">http://code.google.com/p/ivybeans/</a></i></p>Anonymoushttp://www.blogger.com/profile/06817947075459199523noreply@blogger.com4tag:blogger.com,1999:blog-4336468578069957483.post-52055475229514278702008-04-17T16:41:00.003+02:002008-04-17T17:38:36.578+02:00Ivy ramblingsToday I spent some time setting up and developing a project for a customer, which involved some Ivy tricks for dependency management. I thought sharing this might interest some Ivy users or contemplators ;-)
<p>
First my Ivy settings:
<pre>
<ivysettings>
<settings defaultResolver="default" />
<include url="${ivy.default.settings.dir}/ivysettings-shared.xml"/>
<include url="${ivy.default.settings.dir}/ivysettings-local.xml"/>
<resolvers>
<chain name="public">
<!-- official maven2 repo -->
<ibiblio name="maven2" m2compatible="true" />
<!-- apache incubating maven2 repo, used for CXF -->
<ibiblio name="apache-incubating" m2compatible="true"
root="http://people.apache.org/repo/m2-incubating-repository" />
<!-- jboss maven2 repo, used for jbpm -->
<ibiblio name="jboss" m2compatible="true"
root="http://repository.jboss.org/maven2/" />
<!-- some jbpm modules seem to be missing from jboss repo, here is one where we can get what we need -->
<ibiblio name="elca-services" m2compatible="true"
root="http://el4.elca-services.ch/el4j/maven2repository/"/>
<!-- java.net repo, containing useful java apis -->
<ibiblio name="java.net" root="http://download.java.net/maven/1/"
pattern="[organisation]/[type]s/[artifact]-[revision].[ext]"/>
<!-- restlet maven 2 repo -->
<ibiblio name="restlet" m2compatible="true" root="http://maven.restlet.org/" />
</chain>
<!-- eventbus is not available on any repo, we access it directly from its web site -->
<url name="eventbus">
<artifact pattern="https://eventbus.dev.java.net/files/documents/4303/75132/EventBus-[revision].jar" />
</url>
</resolvers>
<include url="${ivy.default.settings.dir}/ivysettings-main-chain.xml"/>
<include url="${ivy.default.settings.dir}/ivysettings-default-chain.xml"/>
<modules>
<!-- use eventbus repo for eventbus only -->
<module organisation="net.java.eventbus" name="eventbus" resolver="eventbus"/>
<!-- use shared resolver for all modules developed internally, to improve perf -->
<module organisation="com.foobar" name="*" resolver="shared"/>
</modules>
</ivysettings>
</pre>
<p>
These settings are based on default Ivy settings, as such I follow the recommendations given <a href="http://ant.apache.org/ivy/history/latest-milestone/tutorial/defaultconf.html">here</a>.
<p>
Besides the chain of public maven repos I use for the set of tools used in this project (ranging from hibernate to spring, jbpm, groovy, restlet, flex...), there is one very specific trick used for eventbus. Eventbus doesn't seem to be available on any public repo, but its jar is available on its java.net home page. Thanks to Ivy flexibility, I can use this location as a "repository". But this repository will "find" almost any module, because there is no [module] or [artifact] tokens in the pattern. So I must be careful and put this resolver outside of the default chain resolver. Hence this resolver will never be used, except when I instruct Ivy to do so. That's exactly what I do with the module line, telling to use this resolver for modules whose name is "eventbus" and org is "java.net.eventbus".
<p>
Then in my Ivy file I can declare my dependency as if it where available like any other module:
<pre>
<dependency org="net.java.eventbus" name="eventbus" rev="1.1" />
</pre>
<p>
The other trick I use is to tell Ivy to use the shared resolver for all modules from "com.foobar". This trick is very useful to improve performance, it tells Ivy to look for the modules I develop for my customer in the shared resolver only, avoiding the latency of the public repo for these modules.
<p>
Ok, that's it for the settings. Now here is a very specific conflict management issue I had to deal with. As I said earlier I use both groovy and hibernate in my project. So here's my pretty simple first attempt to get the two dependencies in my module:
<pre>
<dependency org="org.codehaus.groovy" name="groovy" rev="1.5.4" />
<dependency org="org.hibernate" name="hibernate" rev="3.2.6.ga" />
</pre>
<p>
The problem is that groovy 1.5.4 depends on asm 2.2, and hibernate 3.2.6.ga depends on cglib 2.1_3, which in turn depends on asm 1.5.3. Ivy resolves the conflict automatically according to my settings, and use the latest version between the two: 2.2. The problem is that I then have a classloader issue at runtime: java.lang.NoClassDefFoundError: org/objectweb/asm/CodeVisitor
<p>
A quick search on the net and I find this <a href="http://www.lumidant.com/blog/hibernate-asm-incompatibilities/">solution</a>:
<blockquote>
The easiest solution I’ve found is to remove the CGLib and ASM (1.5.3), which come with Hibernate and instead replace them with a copy of cglib-nodep.
</blockquote>
<p>
Allright, let's convert this in instructions for Ivy. First, we need to exclude the dependency on cglib that you have in hibernate metadata:
<pre>
<dependency org="org.hibernate" name="hibernate" rev="3.2.6.ga">
<exclude module="cglib"/> <!-- we use cglib-nodep instead, to fix a conflict with groovy asm usage -->
</dependency>
</pre>
Then I add the dependency on cglib nodep instead:
<pre>
<!-- this is to replace the regular dependency of hibernate on regular cglib -->
<dependency org="cglib" name="cglib-nodep" rev="2.1_3" />
</pre>
I'm not really happy with this, because I have to add a dependency cglib-nodep, while my module doesn't depend on cglib-nodep. But Ivy conflict management engine can't really help since I want to replace one module (cglib) by another (cglib-nodep). But I'll come back to this later.
<p>
Let's run my test again... allright, it seems to work properly! Let's have a look at the dependencies and the version of asm I now get in my classpath:
<pre>
asm-2.2.jar
asm-util-2.2.jar
asm-tree-2.2.jar
asm-analysis-2.2.jar
asm-attrs-1.5.3.jar
</pre>
Mmm, I don't like this: I have a mix of versions of asm modules. Checking Ivy report, I clearly see why: hibernate has a direct dependency on asm-attrs 1.5.3, while groovy doesn't depend at all on asm-attrs. Thus there is no conflict on this module, and Ivy selects the only revision of this module that was requested. Too bad in this particular case, I'd prefer to have all asm modules aligned in version.<br/>
With the override mechanism introduced recently, it's easy:
<pre>
<override org="asm" rev="2.2" />
</pre>
This is enough to tell Ivy to use revision 2.2 of all modules from asm organization, whatever is actually requested. Since I don't use Ivy trunk version in this project, I had to circumvent the problem this way:
<pre>
<dependency org="org.hibernate" name="hibernate" rev="3.2.6.ga">
<exclude module="cglib"/> <!-- we use cglib-nodep instead, to fix a conflict with groovy asm usage -->
<exclude module="asm.*" matcher="regexp" /> <!-- we want to take care of asm dependency ourself -->
</dependency>
<!-- this is to replace the regular dependency of hibernate on regular cglib -->
<dependency org="cglib" name="cglib-nodep" rev="2.1_3" />
<!-- this would better be handled by new override mechanism -->
<dependency org="asm" name="asm-attrs" rev="2.2" />
</pre>
<p>
Ok, so now it works properly and I have aligned versions for all asm jars. That's nice, but it was a bit cumbersome, and my metadata is cluttered with bad information: I have declared a dependency on cglib-nodep that I don't really have (same for asm, but with trunk version this would be avoided). Maybe we could find a way to improve the metadata or conflict management to be able deal with this kind of case... But the real problem is that these "modules" don't match the concept of module in Ivy:
<blockquote>
A module in ivy is a piece of software that is reusable, and that follow a unique cycle of revision.
</blockquote>
In this case, all asm artifacts (attrs, tree, ...) would better fit in a single module in Ivy, with a configuration for each artifact (if it makes sense, I don't know asm enough). The same applies for cglib and cglib-nodep: it's actually a single module, it's just different packaging and usage, hence different configurations in Ivy. <br/>
So with actual Ivy metadata, getting asm-attrs in one version and asm-tree in another would almost be impossible (well, you'd need to use some Ivy tricks to get them if you really want to). And the problem with cglib could be handled with the conflict management or override system. Metadata would be kept consistent, and easier to maintain. But unfortunately I have to use maven 2 repos for this customer, and there is no such clean Ivy metadata... <a href="http://www.nabble.com/Ivy-RoundUp-Repository---feedback-requested-to16704469.html">yet</a>.Anonymoushttp://www.blogger.com/profile/06817947075459199523noreply@blogger.com1tag:blogger.com,1999:blog-4336468578069957483.post-81464573253846349072008-04-03T20:59:00.002+02:002008-04-03T21:22:32.346+02:00A day for Ivy developmentYesterday my main customer cancelled a meeting which was planned for today, so I decided to take advantage of this free day to fix some of the <a href="https://issues.apache.org/jira/browse/IVY/fixforversion/12312237">open issues targeted for Ivy 2.0 final</a>.
<p>
I started with the final touch to the implementation of transitive override support (<a href="http://issues.apache.org/jira/browse/IVY-784">IVY-784</a>). This will allow users to override the dependency constraint declared by a transitive dependency. This complement the already powerful support for transitive excludes, and fine grain conflict manager configuration. Together, those features are a very nice way to deal with bad metadata over which you don't have control. Actually, this implementation was required due to a change in dependency management handling introduced in maven 2.0.6: now the dependencyManagement section override transitive dependencies versions, so we had to implement this as well as part of our maven compatibility feature.
</p>
<p>
Then I worked on <a href="http://issues.apache.org/jira/browse/IVY-297">IVY-297</a>, improving name consistency and readibility, deprecating allownomd="true | false" in favour of descriptor="required | optional" on resolvers. I also updated buildlist to replace skipbuildwithoutivy="true | false" by onMissingDescriptor="head | tail | skip | warn | fail", which is both more readable and give more control about what to do when a module is missing a module descriptor.
</p>
<p>
The next job consisted in fixing an issue with properties and included files: properties used to be local to the settings file in which they were defined. Therefore it was not possible to define properties in an included file and use them in the including file.
</p>
<p>
Later I fixed <a href="http://issues.apache.org/jira/browse/IVY-777">IVY-777</a>, which required to introduce a new interface: Validatable. Now any Ivy plugin can be validated at the end of settings parsing, simply by implementing this interface. It's the case for dependency resolvers, which now checks that the configured cache manager, latest strategy and name space actually exist.
</p>
<p>
The next issue was a maven 2 compatibility issue: supporting SNAPSHOT versions used to be rather limited in Ivy: with no specific handling, Ivy didn't know how to handle SNAPSHOT versions with a unique revision (where a timestamp and build number is used) and didn't try to update the revision when you don't use unique revision. This is now implemented, relying on maven-metadata.xml to get the required information.
</p>
<p>
To end up my day, I resolved some easy to fix issues, like IVY-579, IVY-592, IVY-437, IVY-722 and IVY-774.
</p>
<p>
So it's been a pretty busy day, but we now have 12 less issues on our road map toward Ivy 2.0!
</p>Anonymoushttp://www.blogger.com/profile/06817947075459199523noreply@blogger.com1tag:blogger.com,1999:blog-4336468578069957483.post-14557677494387121932008-03-12T17:45:00.003+01:002008-03-12T18:10:29.303+01:00New Maven 2 repository search sitemvnrepository.com has been unavailable for a few days, so I finally decided to quickly develop a new site, providing only one very basic but very useful feature: maven 2 repository search.
<p>
The site is available here:<br/>
<a href="http://javarepo.xoocode.org/">http://javarepo.xoocode.org/</a>
<p>
Nothing terrible here, just a very simple web interface. The advantage over mvnrepository.com:
<h4>it is available now</h4>
I'm just kidding, it may be down in a couple of minute, and I guess mvnrepository will be back pretty soon
<h4>More Ivy friendly</h4>
JavaRepo uses Ivy terminology instead of maven one, and also provides snippets to add a dependency in Ivy as well as in a Maven pom on each module revision page like <a href="http://javarepo.xoocode.org/module/org.apache.ivy/ivy/2.0.0-beta2">this one</a>.
<h4>More searchs</h4>
JavaRepo provides several kind of searches: the classic general search, but also more constrained searches, like the list of organizations, or the list of modules in an organization, or the list of revisions per module, and in any case you can restrict the result to names starting with a given prefix.
<h4>RESTful interface</h4>
I've developed the site using restlet, to keep control over the URLs. With no way to modify the data, being RESTful is pretty easy... But I've tried to follow some of the principles I've learned in "Restful Web services" book to design the URLs pattern, and the returned XHTML, which should be usable by human and computers.
<p>
These two last things are actually my main motivation behind this site. In the future I'd like to provide better code completion and easy dependency adding by search in IvyDE when using maven 2 repository, and we first need a service like this one to implement that.
<p>
Will I improve it in the future? Will it say at this location? Will I maintain it alone? I really don't know, there's no big plan, just a simple solution to a problem of my own.Anonymoushttp://www.blogger.com/profile/06817947075459199523noreply@blogger.com9tag:blogger.com,1999:blog-4336468578069957483.post-34436805088106460432008-02-22T14:42:00.002+01:002008-02-22T14:48:38.730+01:00Ant + Ivy team growing!Yesterday I <a href="http://www.nabble.com/-VOTE--add-Nicolas-Lalev%C3%A9e-as-committer-to15452682.html">published the end result of the vote</a> I started last week to accept a new committer on the <a href="http://ant.apache.org/">Apache Ant</a> project, for his contribution to <a href="http://ant.apache.org/ivy/">Ivy</a> and IvyDE: Nicolas Lalevée has joined the team, congratulations Nicolas, keep up your good work, and continue to help make <a href="http://ant.apache.org/ivy/ivyde/">IvyDE</a> a kick ass tool :-)Anonymoushttp://www.blogger.com/profile/06817947075459199523noreply@blogger.com0tag:blogger.com,1999:blog-4336468578069957483.post-90880764585808564962008-01-10T15:29:00.000+01:002008-01-10T15:57:41.782+01:00EasyAnt: Ant based pre packaged build system for java projects<p>Here is a copy of an <a href="http://www.nabble.com/-DISCUSS--EasyAnt%3A-Ant-based-pre-packaged-build-system-for-java-projects-td14735371.html">e-mail I've just posted on dev@ant.apache.org</a> mailing list. I thought it might interest some of this blog readers too.</p>
<blockquote>
<p>It's been a long time since I'm thinking about this, and thought it might be interesting to share with you and see where the idea can go.</p>
<p>I see many developers adopt Maven because they want a build system able to provide common features with no effort. Most of them don't want to spend much time writing an Ant script, or have seen or heard that maintaining Ant build scripts is troublesome. So they choose to use Maven only because it's easy to use for common use cases: install, write a simple pom of a few lines or generate it using an archetype, and you're ready to compile, test and package your new project following the Maven standard structure. They also get dependency management for free, and with only a few more effort they have multi module builds, and some nice features like code analysis, coverage, and a set of report gathered in a web site. That's really nice and that's what I like about Maven.</p>
<p>But Maven suffers from a lack of flexibility and robustness IMHO. And later the same people who first adopted Maven because of its perceived ease of use become frustrated when they need to tweek the system to their own needs or don't understand how the release plugin work. Then some of them go back to Ant, first having to go through a sometimes painful road to describe their whole build system in xml, especially if they aren't Ant experts. Others try to use new build tools like raven, buildr or others.</p>
<p>I really like Ant, and think it is a very good basis for robust and flexible build systems. People with enough knowledge of Ant can write very good build systems, testable, maintainable and adaptable. But you need to get your hands dirty, and you need to get a good knowledge of some of the mechanisms which can make an Ant based build system manageable: import, scripts and scriptdef, macrodef, presetdef, and so on.</p>
<p>Hence I'm wondering if it wouldn't be a good idea to package a set of Ant build files, providing all the basic features of a build system for java projects: dependency management, compilation, testing and packaging, plus maybe some more advanced features like code coverage and code auditing. Multi module build support would be nice to have too. Then someone needing only those features could simply have a build file per project mostly consisting of a single import of the common build file provided. Some needing more could provide plugins to the build system itself. Some needing to tweak the system could simply override some target definitions or properties. Others with very specific needs could simply use the build scripts as examples or basis.</p>
<p>I guess most people on this list know the benefit of having such a build system and how well it scales, and most of us already have developed such a set of build files. But providing the basis of such a good build system well packaged and documented could improve the Ant community IMO. With some efforts from our community we could end up with something interesting pretty easily. Most of us don't have much time, but we probably already have a good basis from the build files we work with around, and if this can be done in a community effort it could remain affordable in terms of time required.</p>
<p>So, what do you think? Do you think this would be useful? Would you be interested in contributing? Do you think a new Ant sub project would be a good fit?</p>
</blockquote>Anonymoushttp://www.blogger.com/profile/06817947075459199523noreply@blogger.com17tag:blogger.com,1999:blog-4336468578069957483.post-38916768162485434342007-11-11T19:08:00.000+01:002007-11-11T19:18:32.567+01:00Wicket and Databinder new releases<p>This week-end Apache Wicket has released its <a href="http://wicket.apache.org/wicket-130-rc1.html">first release candidate for the 1.3 version</a>. That's very good news, I'm using 1.3 beta versions for a while now, and getting closer to the 1.3 final release is exciting! Kudos to the Wicket developer team for their work!
</p><p>
A couple of hours after this release, Nathan released a <a href="http://databinder.net/forum/viewtopic.php?p=677#677">new beta version of databinder</a>, upgraded to the new wicket version. Nathan you're so fast!
</p><p>
An interesting detail about this databinder beta: it now includes the <a href="http://xhab.blogspot.com/2007/06/wicket-hibernate-query-panel.html">Query Panel</a> I developed some months ago, and make it even easier to use. Indeed, Nathan had the neat idea to provide a Data Browser page, which is mounted by default on the /dbrowser URL only in development mode. So if you have a databinder application, you benefit from this page for free! Good job Nathan!
</p>Anonymoushttp://www.blogger.com/profile/06817947075459199523noreply@blogger.com0tag:blogger.com,1999:blog-4336468578069957483.post-32323807285354319912007-10-16T16:46:00.000+02:002007-10-16T16:56:14.656+02:00Ivy has graduated!<div style="float:right;"><a href="http://ant.apache.org/ivy/"><img src="http://ant.apache.org/ivy/images/logo.png"/></a></div> After almost one year of incubation, two incubating releases, 1800+ e-mails on the user list, 1400+ e-mails on the developer list, with the help of 4 mentors, 3 committers, 38 contributors and many more users, Ivy has officially graduated as a sub project of Apache Ant!
<p>
This means that Ivy is now an official Apache project, and I hope this will help us attract more contributors and committers in our community. Being a subproject of Ant, all Ant committers now have right access to Ivy svn repository, so this is already an important increase in the number of committers! And since we are about to decide to use the same development mailing list, hopefully the development community behind Ant+Ivy will soon be only a single and stronger community.
<p>
As a direct consequence of graduation, Ivy's web site is now reachable at <a href="http://ant.apache.org/ivy/">http://ant.apache.org/ivy/</a>. Update your bookmarks!Anonymoushttp://www.blogger.com/profile/06817947075459199523noreply@blogger.com2tag:blogger.com,1999:blog-4336468578069957483.post-48222804118719119802007-08-21T17:30:00.000+02:002007-08-21T17:36:18.783+02:00Upcoming talksLast week I've been contacted by Eelco Hillenius to replace him to give a talk on <a href="http://wicket.apache.org">Wicket</a> at <a href="http://www.javazone.no/">JavaZone</a>. After some questions about my skils to prepare and give this talk, I accepted. This will be my first trip to Norway, and my first talk on Wicket.
<p>
I'm not a Wicket expert, but I hope the lessons I've learned since I'm using it for some of my open source projects will help me give an interesting talk and answer questions.
<p>
What's pretty funny is that almost the same day I've been contacted by some <a href="http://www.javapolis.org/">Javapolis</a> folks to give short talk on <a href="http://incubator.apache.org/ivy/">Ivy</a>. And if ever I'm accepted to give a talk on Ivy at the Asia OS Summit in Hong Kong, the end of the year will be booked with quite a lot of conferences and traveling!
<p>
Now it's time for me to prepare the Wicket talk, and return to <a href="http://xooctory.xoocode.org/">Xooctory</a> and <a href="http://incubator.apache.org/ivy/">Ivy</a> development, we have a beta to release pretty soon on both projects. In october I'll have much less time for open source with my courses at ENSEIRB starting again, and probably a consultancy for Thales Avionics, and some training sessions.Anonymoushttp://www.blogger.com/profile/06817947075459199523noreply@blogger.com3tag:blogger.com,1999:blog-4336468578069957483.post-74341356531475592172007-07-04T11:49:00.000+02:002007-07-04T14:05:34.960+02:00Top 10 reasons why you should try WicketIf you haven't already tried <a href="http://incubator.apache.org/wicket/">Wicket</a> so far, here are my top ten reasons why you should:
<ol>
<li>Wicket is now Apache Wicket</li>
Wicket entered Apache incubation last october, and has recently <a href="http://martijndashorst.com/blog/2007/06/20/3-2-1/">graduated as a top level Apache project</a>. This means that it is now a real Apache project. Why is it important? Because it means that all the legal bits have been cleaned to meet the ASF requirements (and your legal department should be concerned about that :-)), that the project has demonstrated a diverse and active community which is a very good sign of project health, and that the project releases are archived and mirrored all over the world.
<br/><br/>
<li>Wicket 1.3 beta 2 is available</li>
A few days after their graduation, the wicket team has <a href="http://martijndashorst.com/blog/2007/07/02/apache-wicket-130-beta-2-released/">released a second beta version of their 1.3 stream</a>. This version is a huge improvement over the 1.2.x versions, with 339 new features, improvements and bug fixed issues addressed in <a href="http://issues.apache.org/jira/browse/WICKET">their JIRA</a>. This version should provide a pretty stable API, so it's a very good time to give it a try.
<br/><br/>
<li>Very active community</li>
If you are not afraid of <a href="http://sourceforge.net/mailarchive/forum.php?forum_name=wicket-user">receiving 1300+ mail a month</a>, I strongly suggest subscribing to the wicket user mailing list. Got a question? 600+ subscribed users will probably provide an answer in the following hours, or even minutes. And since most of the wicket developer team takes time to participate to this list, you will have precise, clear and from the source information in case of real problems. Last but not least, Wicket team has a very good sense of humor :-)
<br/><br/>
<li>Proven web framework</li>
Wicket released its 1.0 version in June 2005, and has regularly provided new versions since then. Even though it's <a href="http://chillenious.wordpress.com/2007/06/20/wicket-is-now-a-top-level-apache-project/">difficult to know exactly the number of wicket application running today</a>, the trend seems to be growing, and having graduated as an Apache project shouldn't reverse the trend :-). Another important fact is how wicket team lead their development: they often provides maintenance release on their production stream (wicket 1.2.6 has been released last April) while they develop the new major version.
<br/><br/>
<li>Neat component model</li>
Wicket provides a neat component model which makes building feature rich and consistent web applications much easier. Anybody with a basic Java knowledge can develop AJAX applications with Wicket, thanks to the AJAX components available. You don't need to have advanced javascript and browser compatibility skills. Moreover, components in Wicket allow to have a clean separation between team members responsibilities. Senior web developers can develop new components, with fancy javascript effects and AJAX behaviors, while junior developers can keep focused on business centric development reusing the component palette available.
<br/><br/>
<li>Creating components is <b>really</b> easy</li>
One of the main benefits of component oriented frameworks is the re usability of components. But is it really interesting if creating a component is too complex? Have you ever tried creating a JSF component? Forget about that, creating components in Wicket is as easy as creating an HTML file and a corresponding (and simple) Java class. And since the HTML file is a regular HTML file, you can very easily test your javascript effects or your CSS within your browser without even launching a web server.
<br/><br/>
<li>Large set of existing components</li>
Out of the box wicket <a href="http://wicketstuff.org/wicket13/compref/">provides a large set of components</a>, including data tables, forms, trees, along with corresponding AJAX versions. With a vibrant community, you can find more and more components contributions, like the wicket contrib dojo project which provides a mapping of many <a href="http://www.dojotoolkit.com/">dojo</a> components in wicket, or <a href="http://databinder.net/">databinder</a> which provides a very easy to use mapping between wicket and hibernate, with some very nice components too. Since creating component in wicket is easy, many people share their ideas and code about reusable components, providing a large growing source of reusable components.
<br/><br/>
<li>No XML</li>
Wicket is entirely based on plain Java and plan HTML. No XML. No maintenance nightmare of overly big and complex configuration file. Just Java, with excellent IDE support for code completion, refactorings, source code navigation and documentation.
<br/><br/>
<li>Separation of concerns</li>
In Wicket templates are plain HTML files, with only a few ids used to relate HTML tags to Java objects. It makes it very easy for teams with web designers and web developers to work concurrently without stepping on each other.
And since templates are plain HTML, the framework ensure you won't <b>ever</b> get business logic in your templates. Do you remember any JSP maintenance nightmare?
<br/><br/>
<li>Clean rendered web application</li>
In wicket component rendering is not too complex, and you can easily read and understand the HTML code produced, and adjust it to your own needs if required. There is no over complex javascript involved. The Java code used to generate HTML is clean, and you can often override rendering by overriding Java methods. Simple yet powerful.
Furthermore wicket provide an easy and powerful way to provide clean URLs, by mounting pages and providing a flexible URL coding strategy.
<br/><br/>
</ol>Anonymoushttp://www.blogger.com/profile/06817947075459199523noreply@blogger.com6