tag:blogger.com,1999:blog-90705848947691499082024-02-07T19:52:51.465-08:00Jarle Hansen's BlogJarle Hansenhttp://www.blogger.com/profile/12306986377142218956noreply@blogger.comBlogger10125tag:blogger.com,1999:blog-9070584894769149908.post-18499607612980552412013-04-02T01:47:00.002-07:002013-04-02T02:30:52.719-07:00The simple way to add a prepopulated SQLite DB in PhoneGapA common scenario for PhoneGap applications is that you want to include a prepopulated database that contains required information for the app. The plugin often used is the SQLitePlugin for <a href="https://github.com/brodyspark/PhoneGap-SQLitePlugin-iOS">iOS</a> and <a href="https://github.com/brodyspark/PhoneGap-SQLitePlugin-Android">Android</a>.<br />
<br />
There are several ways to accomplish this:<br />
<ol>
<li>Use the <a href="http://docs.phonegap.com/en/2.5.0/cordova_storage_storage.md.html#Storage">storage API</a> directly and populate the database with SQL statements (<a href="http://www.intelligrape.com/blog/2012/09/24/creating-database-in-phonegap/">ref</a>).</li>
<li>Write the code to manually to copy the prepopulated DB (<a href="http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/">ref1</a>, <a href="http://gauravstomar.blogspot.ca/2011/08/prepopulate-sqlite-in-phonegap.html">ref2</a>).</li>
</ol>
<br />
Option 1 quickly becomes considerable work for a DB containing a lot of data. The performance of this solution when requiring many queries can also be quite poor. Option 2 might be considerably better, because it gives you the option to populate the SQLite DB and bundle it with your PhoneGap application. This method uses the SQLitePlugin for both <a href="https://github.com/brodyspark/PhoneGap-SQLitePlugin-Android">Android</a> and <a href="https://github.com/brodyspark/PhoneGap-SQLitePlugin-iOS">iOS</a>. However, you will need to write a bit of code manually to create the copy functionality, where the bundled DB-file is copied to the correct location for both implementations.<br />
<br />
Because of these issues I decided to update the SQLitePlugins for <a href="https://github.com/jarlehansen/PhoneGap-SQLitePlugin-Android">Android</a> and <a href="https://github.com/jarlehansen/PhoneGap-SQLitePlugin-iOS">iOS </a>to support prepopulated SQLite DB files. This blog article will show how to setup and use the plugins in your own PhoneGap projects.<br />
<br />
I will not show how to create and setup PhoneGap projects, there are Getting Started guides available for both <a href="http://docs.phonegap.com/en/2.5.0/guide_getting-started_android_index.md.html#Getting%20Started%20with%20Android">Android</a> and <a href="http://docs.phonegap.com/en/2.5.0/guide_getting-started_ios_index.md.html#Getting%20Started%20with%20iOS">iOS</a>.<br />
<br />
The first step after the PhoneGap projects are created is to setup the prepopulated DB files. This can easily be achieved using several SQLite tools, for example <a href="https://addons.mozilla.org/en-US/firefox/addon/sqlite-manager/?src=search">SQLite Manager</a> for Firefox. Next we move on to how the DB files should be included in your projects.<br />
<br />
<h2>
Android</h2>
Plugin source code: <a href="https://github.com/jarlehansen/PhoneGap-SQLitePlugin-Android">https://github.com/jarlehansen/PhoneGap-SQLitePlugin-Android</a><br />
<br />
For Android the DB file should be placed in the assets-folder, remember to use the file name *.db.<br />
For example: TestDB.db<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-temk11SRSwWNFF8R1LqPj_d57Hre_3JrjfMcXWRcnkYa4nUDWxk2fGUvQnrSidECYI__Q1ZGJHufBAoCP5e53qAxGBrE-vTz145QJNFJQm7B2DaaIbkgXNf-pPXUDfnOCY_6Zq-WtBEz/s1600/Screen+Shot+2013-04-02+at+10.22.55+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="126" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-temk11SRSwWNFF8R1LqPj_d57Hre_3JrjfMcXWRcnkYa4nUDWxk2fGUvQnrSidECYI__Q1ZGJHufBAoCP5e53qAxGBrE-vTz145QJNFJQm7B2DaaIbkgXNf-pPXUDfnOCY_6Zq-WtBEz/s200/Screen+Shot+2013-04-02+at+10.22.55+AM.png" width="200" /></a></div>
<br />
<br />
The DB files are loaded the same way as a standard database, with the command:<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin0wl_M9P39eL7YONnxVLqp-s3Kf7OZaaMT_FHeISNcDrbrfdxpDjp48akBvSQqSyMvAffwOfJr6A-fSjVt1x0iEaaL7S4bJZKJjj2P-xAUuU425CwSRYfbzKxU0nK-Avi6zdbkjnsNYy_/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> var db = window.sqlitePlugin.openDatabase({
name : "TestDB"
});
</code></pre>
<br />
You do not need to include the .db file-extension, this is done automatically by the plugin.<br />
<br />
What happens next is that the SQLitePlugin will first see if the DB already exists, if it does not it will try to find the prepopulated DB-file in the assets folder and copy this to the correct location. If no prepopulated DB file is found, this step is simply skipped. For all executions after this initial setup, the plugin will use the copied database.<br />
<br />
<h2>
</h2>
<h2>
iOS</h2>
Plugin source code: <a href="https://github.com/jarlehansen/PhoneGap-SQLitePlugin-iOS">https://github.com/jarlehansen/PhoneGap-SQLitePlugin-iOS</a><br />
<br />
The iOS setup is very similar. Copy the db-file into the project, for example directly under the project root.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWk43swyJ_UjqrWrrKsL3LOkOfWDVgWDMUYimJNYUWi_G1v0ZqAHeST_DMfl4ObANlC97fDzWRJ9Q7DH6Qnsi3Kylp4kmZC_nd_SAYoza5WV2siJBbS-eWULe-JfSvBnnR2Iq1yGDxXn_w/s1600/Screen+Shot+2013-04-02+at+10.31.26+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="69" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWk43swyJ_UjqrWrrKsL3LOkOfWDVgWDMUYimJNYUWi_G1v0ZqAHeST_DMfl4ObANlC97fDzWRJ9Q7DH6Qnsi3Kylp4kmZC_nd_SAYoza5WV2siJBbS-eWULe-JfSvBnnR2Iq1yGDxXn_w/s200/Screen+Shot+2013-04-02+at+10.31.26+AM.png" width="200" /></a> </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The files are loaded exactly the same way as in the Android example shown. The plugin also works similar to Android, in that it only copies the prepopulated DB the first time and only if it is found in the application bundle.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
And that is it, no need to manually write the insert statements or write custom code. Hopefully this will make it easier to add a prepopulated SQLite DB to your project. Let me know what you think in the comments :)<br />
<br />
<br />
<b>References</b> (used when I created the plugin code):<br />
- <a href="http://gauravstomar.blogspot.ca/2011/08/prepopulate-sqlite-in-phonegap.html">http://gauravstomar.blogspot.ca/2011/08/prepopulate-sqlite-in-phonegap.html</a><br />
- <a href="http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications">http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications</a><br />
<br />Jarle Hansenhttp://www.blogger.com/profile/12306986377142218956noreply@blogger.com0tag:blogger.com,1999:blog-9070584894769149908.post-74521546245899778882013-03-01T03:17:00.003-08:002013-04-03T01:56:47.053-07:00Quick start guide for Google Cloud MessagingThis is a guide for setting up a working Android push-messaging project. It uses the following dependencies:<br />
<ul>
<li><b>android-gcm-quickstart</b> archetype (<a href="https://github.com/akquinet/android-archetypes">https://github.com/akquinet/android-archetypes</a>), currently version 1.0.10-SNAPSHOT</li>
<li><b>GCMUtils</b> (<a href="http://gcmutils.googlecode.com/">http://gcmutils.googlecode.com/</a>)</li>
</ul>
<br />
<iframe allowfullscreen="" frameborder="0" height="440" src="http://www.youtube.com/embed/Cx14UotBHLs" width="640"></iframe>
<br />
<br />
<br />
Start by running the android-gcm-quickstart archetype:<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin0wl_M9P39eL7YONnxVLqp-s3Kf7OZaaMT_FHeISNcDrbrfdxpDjp48akBvSQqSyMvAffwOfJr6A-fSjVt1x0iEaaL7S4bJZKJjj2P-xAUuU425CwSRYfbzKxU0nK-Avi6zdbkjnsNYy_/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> mvn archetype:generate -DarchetypeGroupId=de.akquinet.android.archetypes \
-DarchetypeArtifactId=android-gcm-quickstart -DarchetypeVersion=1.0.10-SNAPSHOT \
-DgroupId=my.project.package -DartifactId=my-project-name -DsenderId=[my-sender-id]
</code></pre>
<br />
Add you own project settings for<i> groupId, artifactId</i> and <i>senderId</i>. See the GCM getting started guide for information on how to get the senderId and apiKey: <a href="http://developer.android.com/google/gcm/gs.html">http://developer.android.com/google/gcm/gs.html</a><br />
<br />
<br />
<h3>
Configure the API Key, you can do this in three ways:</h3>
<h3>
</h3>
<b>1. Add a property in the <i>.m2/settings.xml</i> file:</b><br />
<profiles><profile><properties></properties> </profile></profiles><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIUj3LJHWi7Mre_eM2uudW5mDgEc1u_xcEgesa8aFp68uB01k8Ikq0JJ3Ufto_-v-dhTyzyJhUVrl4D8S61wNrPB9_6DY1v44iJWqLaNrFzyC1SyebmbZtB8kx25htwQaKmNrevKrh8Rlh/s1600/Screen+Shot+2013-02-28+at+1.30.10+PM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="159" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIUj3LJHWi7Mre_eM2uudW5mDgEc1u_xcEgesa8aFp68uB01k8Ikq0JJ3Ufto_-v-dhTyzyJhUVrl4D8S61wNrPB9_6DY1v44iJWqLaNrFzyC1SyebmbZtB8kx25htwQaKmNrevKrh8Rlh/s320/Screen+Shot+2013-02-28+at+1.30.10+PM.png" width="320" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<b>2. In the maven command, add a system property:</b><br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin0wl_M9P39eL7YONnxVLqp-s3Kf7OZaaMT_FHeISNcDrbrfdxpDjp48akBvSQqSyMvAffwOfJr6A-fSjVt1x0iEaaL7S4bJZKJjj2P-xAUuU425CwSRYfbzKxU0nK-Avi6zdbkjnsNYy_/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> gcmutils:run-server -DapiKey=
</code></pre>
<br />
<br />
<b>3. Add the <apikey> tag in the pom.xml (not recommended):</apikey></b><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaROZ6HlBdMPsLdkfeuw5Pc_tqbryAwQhzxUQ-oIG17X7JokTxvY1iGgk6mc09zgb2d0NkEgJfu0K1tYGKOkd75iAwQEdjvlMvxQwnPhKYBoHjBztZ8ffj4jhyphenhyphenyTvMZna_26sDY-Cbw1k7/s1600/Screen+Shot+2013-02-28+at+1.30.52+PM.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="249" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaROZ6HlBdMPsLdkfeuw5Pc_tqbryAwQhzxUQ-oIG17X7JokTxvY1iGgk6mc09zgb2d0NkEgJfu0K1tYGKOkd75iAwQEdjvlMvxQwnPhKYBoHjBztZ8ffj4jhyphenhyphenyTvMZna_26sDY-Cbw1k7/s640/Screen+Shot+2013-02-28+at+1.30.52+PM.png" width="640" /></a><br />
<br />
<br />
Start the test-server by running the following maven command:<br />
<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin0wl_M9P39eL7YONnxVLqp-s3Kf7OZaaMT_FHeISNcDrbrfdxpDjp48akBvSQqSyMvAffwOfJr6A-fSjVt1x0iEaaL7S4bJZKJjj2P-xAUuU425CwSRYfbzKxU0nK-Avi6zdbkjnsNYy_/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> mvn gcmutils:run-server
</code></pre>
<br />
Open your browser on:<i> http://localhost:9595</i><br />
Start the main Android activity in the project and try to send a push message from the webpage to the connected device. By default the message should be shown by Logcat.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://i49.tinypic.com/9lfnzc.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="179" src="http://i49.tinypic.com/9lfnzc.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
Now you hopefully have a working GCM project in Android!<br />
For more detailed information, see the <a href="http://gcmutils.googlecode.com/">GCMUtils webpage</a>Jarle Hansenhttp://www.blogger.com/profile/12306986377142218956noreply@blogger.com0tag:blogger.com,1999:blog-9070584894769149908.post-2542260283028077372013-02-20T08:44:00.003-08:002013-02-20T08:51:48.922-08:00GCMUtils - utility classes for Google Cloud MessagingDuring Google IO 2012 Google updated their push messaging service (from C2DM), releasing Google Cloud Messaging. GCM includes features such as:<br />
<ul>
<li>Ease of use, no sign-up forms</li>
<li>Battery efficiency</li>
<li>Statistics available through the Developer Console</li>
<li>Rich set of new APIs</li>
</ul>
<br />
While C2DM was a really cool technology, it was somewhat complicated to get implemented correctly. GCM have improved this by providing a much simpler API. Let me show a few examples.<br />
<br />
These two lines of code provides verification for the device (that it supports push messaging) and the Manifest-file:<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin0wl_M9P39eL7YONnxVLqp-s3Kf7OZaaMT_FHeISNcDrbrfdxpDjp48akBvSQqSyMvAffwOfJr6A-fSjVt1x0iEaaL7S4bJZKJjj2P-xAUuU425CwSRYfbzKxU0nK-Avi6zdbkjnsNYy_/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> GCMRegistrar.checkDevice(context);
GCMRegistrar.checkManifest(context);
</code></pre>
<br />
To get the registration id, code similar to this example can be used:<br />
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin0wl_M9P39eL7YONnxVLqp-s3Kf7OZaaMT_FHeISNcDrbrfdxpDjp48akBvSQqSyMvAffwOfJr6A-fSjVt1x0iEaaL7S4bJZKJjj2P-xAUuU425CwSRYfbzKxU0nK-Avi6zdbkjnsNYy_/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> String regId = GCMRegistrar.getRegistrationId(context);
if ("".equals(regId)) {
GCMRegistrar.register(context, SENDER_ID);
} else {
Log.i("Already registered, regId:" + regId);
}
</code></pre>
<br />
For more information, go to the <a href="http://developer.android.com/google/gcm/index.html">official GCM page</a>. <br />
<br />
As shown above, the GCMRegistrar-class contains several useful methods. However, there are aspects that the standard GCM-library does not support.<br />
<br />
<h4>
GCMUtils (<a href="https://code.google.com/p/gcmutils/">https://code.google.com/p/gcmutils</a>)</h4>
This is why my new open source project, GCMUtils, was created. This library is a collection of helpful utility classes and methods, built on top of the standard GCM API. It is created to be used in combination with GCM.<br />
<br />
<b>It provides features such as:</b><br />
<ul>
<li><i>Registration id handling </i></li>
</ul>
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin0wl_M9P39eL7YONnxVLqp-s3Kf7OZaaMT_FHeISNcDrbrfdxpDjp48akBvSQqSyMvAffwOfJr6A-fSjVt1x0iEaaL7S4bJZKJjj2P-xAUuU425CwSRYfbzKxU0nK-Avi6zdbkjnsNYy_/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> GCMUtils.getAndSendRegistrationId(this);
</code></pre>
<ul>
<li><i>Extended verification </i></li>
</ul>
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin0wl_M9P39eL7YONnxVLqp-s3Kf7OZaaMT_FHeISNcDrbrfdxpDjp48akBvSQqSyMvAffwOfJr6A-fSjVt1x0iEaaL7S4bJZKJjj2P-xAUuU425CwSRYfbzKxU0nK-Avi6zdbkjnsNYy_/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> GCMUtils.checkExtended(this);
</code></pre>
<ul>
<li><i>Simple configuration </i></li>
</ul>
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin0wl_M9P39eL7YONnxVLqp-s3Kf7OZaaMT_FHeISNcDrbrfdxpDjp48akBvSQqSyMvAffwOfJr6A-fSjVt1x0iEaaL7S4bJZKJjj2P-xAUuU425CwSRYfbzKxU0nK-Avi6zdbkjnsNYy_/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> # Required
receiver-url=
sender-id=
# optional
# values: enabled/disabled
check-extended=enabled
</code></pre>
<ul>
<li><i>Alternative base intent service with more functionality </i></li>
</ul>
<pre style="background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin0wl_M9P39eL7YONnxVLqp-s3Kf7OZaaMT_FHeISNcDrbrfdxpDjp48akBvSQqSyMvAffwOfJr6A-fSjVt1x0iEaaL7S4bJZKJjj2P-xAUuU425CwSRYfbzKxU0nK-Avi6zdbkjnsNYy_/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;"> public class GCMIntentService extends GCMUtilsBaseIntentService {
@Override
protected void onMessage(Context context, String msg) {
Log.i(TAG, "Message received: " + msg);
}
@Override
protected void onError(Context context, String error) {
Log.e(TAG, "onError: " + error);
}
}
</code></pre>
<br />
Adding it to your project is easy (copy 2 jar files) and it is created to make to development of GCM apps simpler and more efficient. In my own project this has been a big help, and hopefully this will be useful for others as well.<br />
<br />
For more information, go to the <a href="https://code.google.com/p/gcmutils/wiki/Features">features page</a> and the <a href="https://code.google.com/p/gcmutils/wiki/QuickStart">quick start guide</a>.<br />
<br />
It is still early in the development of this project, so all feedback is appreciated. There are more features planned to get implemented before a final release is ready.Jarle Hansenhttp://www.blogger.com/profile/12306986377142218956noreply@blogger.com0tag:blogger.com,1999:blog-9070584894769149908.post-4638384076041810532011-02-26T01:31:00.001-08:002011-02-26T01:31:50.167-08:00protobuf-javame 1.1.0 releasedAdded support for using repeated (lists) on custom types. For more information go to the <a href="http://code.google.com/p/protobuf-javame/wiki/UserDocumentation" rel="nofollow">user documentation</a>, Recursion section.<br /><br />Project webpage: <a href="http://code.google.com/p/protobuf-javame/">http://code.google.com/p/protobuf-javame/</a>Jarle Hansenhttp://www.blogger.com/profile/12306986377142218956noreply@blogger.com0tag:blogger.com,1999:blog-9070584894769149908.post-4981957598832481302010-10-02T05:18:00.000-07:002010-10-13T03:25:33.753-07:00Microlog4android, 1.0-version releasedTry it out at: <a href="http://code.google.com/p/microlog4android/">http://code.google.com/p/microlog4android/</a><br /><br />Lots ideas, too little time, so we are also looking for developers to help us out.<br />If you are interested in open source and Android development please contact us (either <a href="http://myossdevblog.blogspot.com/">Johan</a> or me: hansjar at gmail dot com).Jarle Hansenhttp://www.blogger.com/profile/12306986377142218956noreply@blogger.com0tag:blogger.com,1999:blog-9070584894769149908.post-49721404528803848432010-09-05T06:19:00.001-07:002010-09-05T06:21:48.074-07:00protobuf-javame 1.0.0 releasedFinally, 1.0.0 version of the protobuf-javame project is released.<br />The main features added in the new release are support for nested messages and enums.<br /><br />Please try it out and let me know what you think :)<br /><a href="http://code.google.com/p/protobuf-javame/">protobuf-javame</a>Jarle Hansenhttp://www.blogger.com/profile/12306986377142218956noreply@blogger.com0tag:blogger.com,1999:blog-9070584894769149908.post-52776273401339663022010-06-02T14:34:00.000-07:002010-06-02T14:44:50.996-07:00Using Bluetooth and Microlog, updatedI previously described <a href="http://hansjar.blogspot.com/2009/06/using-microlog-over-bluetooth-with.html">how to use the Bluetooth logging features</a> (both appender and server) in Microlog with Ubuntu. There has been a few updates to Microlog that changes a few small details of this earlier blog post.<br /><br />The following setup should now be used:<br /><ol><li>The Ubuntu package “<span style="font-style: italic;">libbluetooth-dev</span>”<span style="font-style: italic;"><span style="font-style: italic;"> </span></span>still needs to be installed.</li><li>Download bluecove jar files (use 2.1.1 snapshot and download both the standard jar and the gpl jar-file).</li><li>Download the <a href="http://sourceforge.net/projects/microlog/files/">microlog distribution</a>. The Bluetooth server is the file called microlog-server-bluetooth-{version}.jar. Put all the jar files in the same folder and create a start script.<br /></li><li>Create a startup script for the server. This updated script will use the new main class and does not have any hardcoded version numbers.</li></ol><span style="font-size:100%;"><span style="font-family: courier new;">bluecove</span><span style="font-family: courier new;" class="hl sym">=</span><span style="font-family: courier new;">$</span><span style="font-family: courier new;" class="hl sym">(</span><span style="font-family: courier new;" class="hl kwc">ls</span><span style="font-family: courier new;"> bluecove</span><span style="font-family: courier new;" class="hl sym">-[</span><span style="font-family: courier new;" class="hl num">0</span><span style="font-family: courier new;" class="hl sym">-</span><span style="font-family: courier new;" class="hl num">9</span><span style="font-family: courier new;" class="hl sym">]</span><span style="font-family: courier new;">.</span><span style="font-family: courier new;" class="hl sym">*</span><span style="font-family: courier new;">.jar</span><span style="font-family: courier new;" class="hl sym">)</span></span><span style="font-family: monospace;"><br /></span><span style="font-family: courier new;">bluecovegpl</span><span style="font-family: courier new;" class="hl sym">=</span><span style="font-family: courier new;">$</span><span style="font-family: courier new;" class="hl sym">(</span><span style="font-family: courier new;" class="hl kwc">ls</span><span style="font-family: courier new;"> bluecove</span><span style="font-family: courier new;" class="hl sym">-</span><span style="font-family: courier new;">gpl</span><span style="font-family: courier new;" class="hl sym">-*</span><span style="font-family: courier new;">.jar</span><span style="font-family: courier new;" class="hl sym">)</span><span style="font-family: courier new;"><br />microlog</span><span style="font-family: courier new;" class="hl sym">=</span><span style="font-family: courier new;">$</span><span style="font-family: courier new;" class="hl sym">(</span><span style="font-family: courier new;" class="hl kwc">ls</span><span style="font-family: courier new;"> microlog</span><span style="font-family: courier new;" class="hl sym">-</span><span style="font-family: courier new;">server</span><span style="font-family: courier new;" class="hl sym">-</span><span style="font-family: courier new;">bluetooth</span><span style="font-family: courier new;" class="hl sym">-*</span><span style="font-family: courier new;">.jar</span><span style="font-family: courier new;" class="hl sym">)</span><span style="font-family: courier new;" class="hl kwb"><br />echo</span><span style="font-family: courier new;"> </span><span style="font-family: courier new;" class="hl str">"The Microlog Bluetooth server loading: "</span><span style="font-family: courier new;"> </span><span style="font-family: courier new;" class="hl kwb">$bluecove $bluecovegpl $microlog</span><span style="font-size:100%;"><span style="font-family: courier new;"><br />gksu </span><span style="font-family: courier new;" class="hl str">"java -cp $bluecovegpl:$bluecove:$microlog net.sf.microlog.server.btspp.gui.MicrologBluetoothServerUI"</span></span><br /><pre><span style="font-family: arial;"><br /><span style="font-weight: bold;">If you have any problems with this script please let me know!</span><br /></span></pre>Jarle Hansenhttp://www.blogger.com/profile/12306986377142218956noreply@blogger.com0tag:blogger.com,1999:blog-9070584894769149908.post-55881137034367571322010-02-14T02:48:00.000-08:002010-02-14T03:40:33.587-08:00How I use IntelliJ IDEA 9 and GradleThe newest version of IntelliJ IDEA includes a few very nice gradle features, <a href="http://blogs.jetbrains.com/idea/2009/08/gradle-support/">reference1</a> <a href="http://mrhaki.blogspot.com/2009/10/use-gradle-support-in-intellij-idea.html">reference2</a> <a href="http://kensipe.blogspot.com/2009/12/intellij-9-and-gradle.html">reference3</a>.<br /><br />Running gradle tasks works by simply opening the build.gradle file and pressing ctrl+shift+f10, this will run the tasks specified as "defaultTasks". If you want to run a specific task you just have to select it and press the same key combination. Nice!<br /><br />I just wanted to share how I use a few other features as well. Many times I find myself wanting to use tasks that are not directly implemented in my own build script, but added by a plugin. One example is the "eclipse" plugin, since gradle does not (as of version 0.8) support the creation of IntelliJ IDEA project files. This is identified in the missing features section of the user guide:<br /><ul><li>Creating IDE project and classpath files for IntelliJ and NetBeans. Gradle supports IDE project file generation for Eclipse.</li></ul>So, to be able to run these tasks I have created an "External tools" entry specifically for custom tasks. In IntelliJ open Settings -> External tools and press Add. Point to gradle_home in program. When you add $Prompt$ to Parameters this means you will get an input dialog when you run the task. In Working directory add $ProjectFileDir$, this will make sure it runs from your project directory.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSQYytAS_5FPGVK72Bjzsn607exc1gbia43jVTnbUtqcbiaY7cVg4PQ0n0mtQ6Nxq4Bye4Wy5Czx3uGcPbC0KC1np8HqgSXd5P9U9veKJA5QL5JpJEAoxwmXzU89MT4j1oi8RWSWh6cACE/s1600-h/custom-task.png"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 400px; height: 216px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSQYytAS_5FPGVK72Bjzsn607exc1gbia43jVTnbUtqcbiaY7cVg4PQ0n0mtQ6Nxq4Bye4Wy5Czx3uGcPbC0KC1np8HqgSXd5P9U9veKJA5QL5JpJEAoxwmXzU89MT4j1oi8RWSWh6cACE/s400/custom-task.png" alt="" id="BLOGGER_PHOTO_ID_5438054407784151314" border="0" /></a><br />When you run this task you will be able to enter a custom task, like "eclipse" or "-t" (list all available tasks). The tasks you enter here does not need to be specified in "defaultTasks" or directly in build.gradle.<br /><br />If you use the <a href="http://www.gradle.org/0.8/docs/userguide/artifact_dependencies_tutorial.html#N10680">gradle dependency management</a> you can now easily generate the eclipse project files by running the "custom task" and entering eclipse. In IntelliJ IDEA you can then import these project files by pressing File -> Open Project... and selecting the newly generated eclipse .project-file. IntelliJ will then prompt for your input on how to import the project settings. I usually select Reimport -> Yes (you want to reuse the project files) -> This window.<br /><br />You have now generated the project files with all dependencies from the build script. Be aware of one issue; make sure you check that the Modules -> Sources under Project Structure is correct. Sometimes it adds a few of the Test Source Folders under Source Folders. Just take a quick look and verify that everything looks correct.<br /><br />Once you have done it a few times this process only takes a few seconds. Also it makes the build.gradle file the only place you need to keep track of your dependencies. I have been mixing project-local and repository dependencies in several of my own project, and this method works execellent when setting up your development environment.<br /><br />Lets just hope the next gradle version includes an IntelliJ IDEA plugin...Jarle Hansenhttp://www.blogger.com/profile/12306986377142218956noreply@blogger.com1tag:blogger.com,1999:blog-9070584894769149908.post-31298024586781408732009-06-20T14:21:00.000-07:002009-06-21T07:13:28.902-07:00Using MicroLog over Bluetooth with Ubuntu and Eclipse<style type="text/css"> @page { margin: 0.79in } P { margin-bottom: 0.08in } A:link { so-language: zxx } --> </style> <p style="margin-bottom: 0in;">MicroLog is a great tool for logging in Java ME. One of the cool features that is supported is logging over Bluetooth. This means that you can easily set up the application to connect to a lightweight server application running on your computer. MicroLog takes care of all the boilerplate code associated with creating the Bluetooth connection, sending the data and so on. All you have to do is add a BluetoothSerialAppender to you Logger-object and you are good to go (for more information on implementation details: <a href="http://blog.jayway.com/2008/12/17/java-me-logging-over-bluetooth-using-microlog/">http://blog.jayway.com/2008/12/17/java-me-logging-over-bluetooth-using-microlog/</a>). The Bluetooth server is a small application that accepts connections from the clients and prints them out to the console.</p> <p style="margin-bottom: 0in;">The main purpose of this article is to show how you can use the Bluetooth feature of MicroLog with Ubuntu and Eclipse. There are some additional challenges when using Linux and MicroLog, but as presented here they are not too hard to fix. The jar-files used in this example are snapshot versions, so do not be surprised if you find a few bugs.</p><p style="margin-bottom: 0in; font-weight: bold;"><br /></p><p style="margin-bottom: 0in; font-weight: bold;"><span style="font-size:130%;">Making the MicroLog server compatible with Ubuntu</span> <style type="text/css"> <!-- @page { margin: 0.79in } P { margin-bottom: 0.08in } A:link { so-language: zxx } --> </style> </p><p style="margin-bottom: 0in; font-weight: normal;">The first problem I had was with the MicroLog server. I use Ubuntu for all my tasks, including software development and the BlueCove version included in the MicroLog server package (microlog-servers-<version>jar-with-dependencies.jar) was not compatible with the OS. It did not start and printed out this error message:</version></p> <p style="margin-bottom: 0in; font-weight: normal; font-style: italic;">BluetoothSerialServerThread started. </p> <p style="margin-bottom: 0in; font-weight: normal; font-style: italic;">Failed to init the Bluetooth connection. javax.bluetooth.BluetoothStateException: BlueCove com.intel.bluetooth.BluetoothStackBlueZ not available </p> <p style="margin-bottom: 0in; font-weight: normal; font-style: italic;">We are finally closing the logging.</p> <p style="margin-bottom: 0in; font-weight: normal;"><br /></p><p style="margin-bottom: 0in; font-weight: normal;">BlueCove is the Bluetooth library used in the MicroLog server library. It does support Linux, but the difference from the Windows version is that you have to add an additional runtime library called BlueCove-GPL. First, to get Bluetooth on Ubuntu working with BlueCove you have to download and install an extra package. Open up Synaptic Package Manager or a terminal window and install the “<span style="font-style: italic;">libbluetooth-dev</span>” package. When this is installed go to <a href="http://www.bluecove.org/">http://www.bluecove.org</a> and download the Java library. I would recommend the snapshot version (2.1.1) since the current stable version (2.1.0) has a few problematic bugs. Place these two files together with the Microlog server application.</p> <ul style="font-weight: normal;"><p style="margin-bottom: 0in; font-weight: bold;">Download these files to the same folder:</p><li style="font-style: italic;"><p style="margin-bottom: 0in;"><span style="font-size:85%;"><a href="http://snapshot.bluecove.org/distribution/download/2.1.1-SNAPSHOT/2.1.1-SNAPSHOT.48/bluecove-2.1.1-SNAPSHOT.jar">http://snapshot.bluecove.org/distribution/download/2.1.1-SNAPSHOT/2.1.1-SNAPSHOT.48/bluecove-2.1.1-SNAPSHOT.jar</a></span></p> </li><li style="font-style: italic;"><p style="margin-bottom: 0in;"><span style="font-size:85%;"><a href="http://snapshot.bluecove.org/distribution/download/2.1.1-SNAPSHOT/2.1.1-SNAPSHOT.48/bluecove-gpl-2.1.1-SNAPSHOT.jar">http://snapshot.bluecove.org/distribution/download/2.1.1-SNAPSHOT/2.1.1-SNAPSHOT.48/bluecove-gpl-2.1.1-SNAPSHOT.jar</a></span></p> </li><li style="font-style: italic;"><span style="font-size:85%;"><a href="http://sourceforge.net/project/downloading.php?group_id=138008&filename=microlog-servers-2.0.0-SNAPSHOT-jar-with-dependencies.jar&a=97806068">http://sourceforge.net/project/downloading.php?group_id=138008&filename=microlog-servers-2.0.0-SNAPSHOT-jar-with-dependencies.jar</a></span></li><li style="font-style: italic;"><span style="font-size:85%;">You can download the file microlog-servers-2.0.0-SNAPSHOT.jar as well, to avoid having unnecessary BlueCove dependencies.<br /></span></li></ul> <p style="margin-bottom: 0in; font-weight: normal;">The next step is to create a shell script that will start the server application. Open a terminal window and type “<span style="font-style: italic;">gedit start-microlog-server.sh</span>” (you can call the file whatever you want). Copy and past this into the file:</p> <p style="margin-bottom: 0in; font-weight: normal; font-style: italic;">java -cp bluecove-2.1.1-SNAPSHOT.jar:bluecove-gpl-2.1.1-SNAPSHOT.jar:microlog-servers-2.0.0-SNAPSHOT-jar-with-dependencies.jar net.sf.microlog.server.btspp.MicrologBtsppServer</p> <p style="margin-bottom: 0in; font-weight: normal;">Make sure all the version numbers are correct and that you have the jar-files in the same folder as the script. If you choose to use the microlog-servers-2.0.0-SNAPSHOT.jar file you have to update the script with this file. Also, if you get an error message like this:</p><p style="margin-bottom: 0in; font-weight: normal;"><span style="font-style: italic;">Failed to init the Bluetooth connection. javax.bluetooth.BluetoothStateException: Bluetooth Device is not ready. [1] Operation not permitted</span><br /></p><p style="margin-bottom: 0in; font-weight: normal;">Try to add<span style="font-style: italic;"> gksu </span>in front and "-around the java -cp....<br /></p><p style="margin-bottom: 0in; font-weight: normal;">This will start the MicroLog Bluetooth server application with the correct BlueCove jar-files. Save and close gedit. This is the script that Eclipse will run and therefore it needs to be executable. In the terminal write “<span style="font-style: italic;">chmod u+x start-microlog-server.sh</span>”. You can now test that the script works by entering the following command in the terminal “<span style="font-style: italic;">sh start-microlog-server.sh</span>”. You should see something like this:</p> <p style="margin-bottom: 0in; font-style: italic; font-weight: normal;">BluetoothSerialServerThread started. </p> <p style="margin-bottom: 0in; font-style: italic; font-weight: normal;">BlueCove version 2.1.1-SNAPSHOT on bluez </p> <p style="margin-bottom: 0in; font-style: italic; font-weight: normal;">Waiting for a client to connect to:<br />btspp://000000000000:<channel>;authenticate=false;encrypt=false;master=false<br />where <channel> should be replaced with the channel that is actually in use. This is usually a low number 1 or 2.</channel></channel></p> <p></p><p style="margin-bottom: 0in;"><br /></p><p style="margin-bottom: 0in;"><span style="font-weight: bold;"><span style="font-size:130%;">Integrate MicroLog with Eclipse<style type="text/css"> <!-- @page { margin: 0.79in } P { margin-bottom: 0.08in } --> </style> </span></span></p><p style="margin-bottom: 0in;">The second task is to get this integrated in Eclipse. It is good to have access to the terminal application, but much nicer to get the log output in Eclipse. All you need to do is add a new “External tools” configuration.</p> <p style="margin-bottom: 0in;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifgwcPhKfERpg2ugjOQM8FTVkBpLjHM2M6fTBuRaZNyVsDy-ZHdChQH-Uva6EvfXaMvihZdIhTAwFpTDp0NUUZp_7fxn4byeO3E6ophTGQfk5ZZXpCxG4KTUaViQxcvk91SnfuI9rShWEs/s1600-h/external-tools1.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 78px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifgwcPhKfERpg2ugjOQM8FTVkBpLjHM2M6fTBuRaZNyVsDy-ZHdChQH-Uva6EvfXaMvihZdIhTAwFpTDp0NUUZp_7fxn4byeO3E6ophTGQfk5ZZXpCxG4KTUaViQxcvk91SnfuI9rShWEs/s320/external-tools1.jpg" alt="" id="BLOGGER_PHOTO_ID_5349523854423235826" border="0" /></a></p> <p style="margin-bottom: 0in; font-weight: normal;">Press the “New launch configuration” and enter a name, like “<span style="font-style: italic;">microlog bluetooth server</span>”. In the location input field, press either “<span style="font-style: italic;">Browse Workspace</span>” (like in the picture below) or “<span style="font-style: italic;">Browse File System</span>”. This depends on where you have saved the shell script. Select the “<span style="font-style: italic;">start-microlog-server.sh</span>” file and press OK. In the working directory select the folder where the shell script is and press OK. The working directory must be the same folder as where all the jar-files were saved. Finally press Apply to save the changes.</p> <p style="margin-bottom: 0in; font-weight: normal;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi82FBPMJuo7ZSrmQ6vjcoOgiCYp6D729vJYJd_D4t_jDn3kZaer2TtkgeGLvj2byoV2ALsUuJLBT1z3JwAGqK0lTH2wPCVK9FPxe86RsGYH_xViMyk4kcU-L8QhRXqJ3fjCUitqXI42Bej/s1600-h/external-tools2.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 304px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi82FBPMJuo7ZSrmQ6vjcoOgiCYp6D729vJYJd_D4t_jDn3kZaer2TtkgeGLvj2byoV2ALsUuJLBT1z3JwAGqK0lTH2wPCVK9FPxe86RsGYH_xViMyk4kcU-L8QhRXqJ3fjCUitqXI42Bej/s400/external-tools2.jpg" alt="" id="BLOGGER_PHOTO_ID_5349524569138388226" border="0" /></a></p><p style="margin-bottom: 0in; font-weight: normal;">Now you should be able to run the “<span style="font-style: italic;">External tools</span>” configuration and start the MicroLog server in Eclipse. The output should be similar to this:</p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHNmJSfYEIJwTNhdiPy64d8__LqzQ2IcSyTjkYgLjtS0uEaHxyQcsJeacm29R0hqsbNOyJo7OuvVLE7i_-8IzyswGRKcoHv_ST5Wk3-nFu10xQ9IGv2uJysMBiwUxfnbfJm9prkyVd-8u9/s1600-h/console.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 77px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHNmJSfYEIJwTNhdiPy64d8__LqzQ2IcSyTjkYgLjtS0uEaHxyQcsJeacm29R0hqsbNOyJo7OuvVLE7i_-8IzyswGRKcoHv_ST5Wk3-nFu10xQ9IGv2uJysMBiwUxfnbfJm9prkyVd-8u9/s400/console.jpg" alt="" id="BLOGGER_PHOTO_ID_5349524652855375826" border="0" /></a><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNCmEHHJXKiJA-IYBnDxDr7X1MoLIKmDfHZKifNgnIgqeZnhYSURAkky1KtPQH9sB-E22h-k9H5GJnOeANe7Bsij39fWu8H4wB9ECuFMgVomqD4DHGTORvuk4CWApn4KNfmf6mgNlrLhIh/s1600-h/console.jpg"></a><p style="margin-bottom: 0in; font-weight: normal;">This has been a great help for me since I really like having everything included in Eclipse. Hopefully this can help others to get MicroLog up and running on Linux and in Eclipse as well. Please do not hesitate to add a comment if you have any questions.</p> <p></p>Jarle Hansenhttp://www.blogger.com/profile/12306986377142218956noreply@blogger.com6tag:blogger.com,1999:blog-9070584894769149908.post-18982242720581445842009-02-12T13:29:00.000-08:002009-02-12T14:32:10.752-08:00Ant, Maven, Gant & Gradle<span style="color: rgb(0, 0, 0);font-size:85%;" >For Java there are a range of different build tools/systems available. It can be difficult to know what is the best choice for <span style="font-style: italic;">your</span> project. And to make things even worse there is no right or wrong answer. I will try to give a short introduction to some of the more popular tools starting with good old Ant. For each tool I will give a compact HelloWorld example to show the differences, it uses two dependencies (spring and commons-logging) to show how the tools handles dependency management. The examples are not complete. To make them easy to read I have only added a few of the important elements.</span><span style="font-weight: bold; color: rgb(0, 0, 0);font-size:100%;" ><br /><br /><br /></span><span style="font-weight: bold; color: rgb(0, 0, 0);font-size:100%;" >Ant<br /></span><span style="color: rgb(0, 0, 0);font-size:85%;" >Ant is a Java-based build tool that uses xml-files to define the build commands. It supports a wide range of tasks and if you for some reason can't find one for your needs you can always create your own (<a href="http://ant.apache.org/manual/develop.html">http://ant.apache.org/manual/develop.html</a>).<br /><br />There is no doubt that Ant is a good and powerful tool, but it has several well-known problems. First of all xml is not a programming language, this can make it difficult to do simple tasks like if-statements and loops (it is certainly possible to get it done, but often it becomes complex and hard to read). Secondly the build-files quickly become very verbose.<br /><br />The example below shows two simple targets, <span style="font-style: italic;">compile</span> and <span style="font-style: italic;">package.jar</span>. Despite the problems mentioned earlier, I like Ant. You have total control of what is going on and it supports just about everything you would need to do in a build.</span><span style="font-weight: bold; color: rgb(0, 0, 0);font-size:100%;" ><br /></span><span style="font-weight: bold; color: rgb(0, 0, 0);font-size:100%;" ><blockquote><pre><span style="font-weight: normal;"><path id="lib.classpath"></span><br /><span style="font-weight: normal;"> <fileset dir="${lib.dir}"></span><br /><span style="font-weight: normal;"> <include name="*.jar"/></span><br /><span style="font-weight: normal;"> </fileset></span><br /><span style="font-weight: normal;"></path></span><br /><br /><span style="font-weight: normal;"><target name="compile" depends="init"></span><br /><span style="font-weight: normal;"> <javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="lib.classpath" /></span><br /><span style="font-weight: normal;"></target></span><br /><br /><span style="font-weight: normal;"><target name="package.jar" depends="compile"></span><br /><span style="font-weight: normal;"> <jar basedir="${build.dir}" destfile="${jar.filepath}"></span><br /><span style="font-weight: normal;"> <manifest></span><br /><span style="font-weight: normal;"> <attribute name="Main-Class" value="${main.class}" /></span><br /><span style="font-weight: normal;"> <attribute name="Class-Path" value="${classpath.entries}" /></span><br /><span style="font-weight: normal;"> </manifest></span><br /><span style="font-weight: normal;"> <fileset dir="${res.dir}"></span><br /><span style="font-weight: normal;"> <include name="*.xml" /></span><br /><span style="font-weight: normal;"> </fileset></span><br /><span style="font-weight: normal;"> </jar></span><br /><span style="font-weight: normal;"></target></span><br /><br /><br /></pre></blockquote><span>Maven<br /></span></span><span style="color: rgb(0, 0, 0);font-size:85%;" >Maven has tried to solve most of the problems with Ant. Maven attempts to create a standard way to build projects and make the build process easy. Like Ant it uses xml-files for the build configuration. In addition to supporting regular tasks like compiling code it adds support for dependency management. The main issue with maven, in my opinion at least, is the lack of flexibility. You are basically locked in the default configuration, <span style="font-style: italic;">convention over configuration</span>, making it a real pain if you need something different. There are other issues as well, like repository problems, but lets just go on with the example.<br /><br />Continuing with the HelloWorld example, here is the pom.xml file:</span><span style="color: rgb(0, 0, 0);font-size:100%;" ><br /></span><blockquote style="color: rgb(0, 0, 0);"><pre><span style="font-size:100%;"><project><br /><modelVersion>4.0.0</modelVersion><br /><groupId>net.jarlehansen.helloworld.maven<br /></groupId><br /><artifactId>maven-helloworld</artifactId><br /><name>Maven HelloWorld</name><br /><version>1.0.0</version><br /><packaging>jar</packaging><br /><br /><dependencies><br /><dependency><br /><groupId>org.springframework</groupId><br /><artifactId>spring</artifactId><br /><version>2.5.6</version><br /><scope>compile</scope><br /></dependency><br /><br /><dependency><br /><groupId>commons-logging</groupId><br /><artifactId>commons-logging</artifactId><br /><version>1.1.1</version><br /><scope>compile</scope><br /></dependency><br /></dependencies><br /><br /><build><br /><plugins><br /><plugin><br /> <groupId>org.apache.maven.plugins</groupId><br /> <artifactId>maven-jar-plugin</artifactId><br /> <configuration><br /> <archive><br /> <manifest><br /> <mainClass>net.jarlehansen.helloworld.maven.HelloWorldMain<br /> </mainClass><br /> <addClasspath>true</addClasspath><br /> </manifest><br /> </archive><br /> </configuration><br /></plugin><br /></plugins><br /></build><br /></project><span style="font-size:85%;"><br /></span></span></pre></blockquote><span style="color: rgb(0, 0, 0);font-size:85%;" >When following the standard Maven project layout (<a href="http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html">http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html</a>) it will compile and package the source code. In this case a jar-file is created.</span><span style="font-weight: bold; color: rgb(0, 0, 0);font-size:100%;" ><span><br /><br /><br /><span>Gant<br /></span></span></span><span style="color: rgb(0, 0, 0);font-size:85%;" >Gant tries to take a different approach, instead of using xml it supports Ant tasks with Groovy. By getting rid of the xml and adding an actual programming language it should solve all the problems right? Well, I haven't used it in any large projects, but I must admit I really like the idea.<br /><br />The example shows how it uses the same tasks as Ant, but with Groovy syntax:</span><span style="color: rgb(0, 0, 0);font-size:100%;" ><br /></span><span style="font-weight: bold; color: rgb(0, 0, 0);font-size:100%;" ><blockquote><pre style="font-weight: normal;"><br />includeTargets << gant.targets.Clean<br />cleanDirectory << targetDir<br /><br />ant.path(id : 'libClasspath') {<br /> fileset(dir : libDir, includes : '*.jar')<br />}<br /><br /> target(compile : 'Compiles source code') {<br /> depends(init)<br /> echo('compile')<br /><br /> ant.javac(srcdir : srcDir, destdir : buildDir, classpathref : 'libClasspath')<br />}<br /><br />target(packageJar : 'Package the class files in a jar file') {<br /> depends(compile)<br /> echo('packageJar')<br /><br /> ant.jar(destfile : jarFilepath, basedir : buildDir) {<br /> manifest() {<br /> attribute(name : 'Main-Class', value : 'net.jarlehansen.helloworld.gant.HelloWorldMain')<br /> attribute(name : 'Class-Path', value : '../lib/spring.jar ../lib/commons-logging.jar')<br /> }<br />fileset(dir : resDir, includes : '*.xml')<br />}<br />}<br /><br />setDefaultTarget (packageJar)<br /><br /></pre><br /></blockquote></span><span style="font-weight: bold; color: rgb(0, 0, 0);font-size:100%;" ><span><span><span>Gradle<br /></span></span></span></span><span style="color: rgb(0, 0, 0);font-size:85%;" >Gradle tries to behave more like Maven than Ant. Like Gant, it uses Groovy. And instead of the flexibility issues with Maven, it offers the best of both worlds. You can use the conventions from Maven,<span style="font-weight: bold;"> if you want to</span>. Another pleasant sight is that Ant tasks are first class citizens. I really can't stand the AntRun plugin for Maven. In Gradle it is very simple to use Ant tasks, for example: <span style="font-style: italic;">ant.echo('hello')</span>. One of the major issues I have found with both Gant and Gradle are the lack of IDE support. This will probably improve when these tools get more mature, but at the moment it is not available.<br /><br />The example shows how Gradle can use the Maven repository to download the dependencies. It also compiles and packages the jar-file just like all the other examples (this is due to the 'java'-plugin):</span><br /><span style="font-weight: bold; color: rgb(0, 0, 0);font-size:100%;" ><blockquote><pre style="font-weight: normal;">usePlugin('java')<br /><br />sourceCompatibility = '1.5'<br />targetCompatibility = '1.5'<br /><br />project.group = "net.jarlehansen.helloworld.gradle"<br />project.version = "1.0.0"<br />manifest.mainAttributes("Main-Class" : "net.jarlehansen.helloworld.gradle.HelloWorldMain",<br /> "Class-Path" : "../lib/spring-2.5.6.jar ../lib/commons-logging-1.1.1.jar")<br /><br />defaultTasks 'libs'<br /><br />dependencies {<br /> addMavenRepo()<br /> compile "org.springframework:spring:2.5.6"<br /> compile "commons-logging:commons-logging:1.1.1"<br />}<br /><br /></pre></blockquote></span><span style="font-weight: bold; color: rgb(0, 0, 0);font-size:100%;" ><span><span><span><span>Conclusion<br /></span></span></span></span></span><span style="color: rgb(0, 0, 0);font-size:85%;" >What is the best build tool? In my opinion the use of Groovy scripts for the builds makes a lot sense. And I must admit that both Gant and Gradle has a lot of potential. Hopefully the IDE support will arrive soon. In any case I will start using Gradle on a regular basis.</span><span style="font-weight: bold; color: rgb(0, 0, 0);font-size:100%;" ><br /><br /><br /><br /></span><span style="color: rgb(0, 0, 0);font-size:100%;" ><span><span style="font-weight: bold;">References</span><br /></span></span><ul style="font-weight: bold; color: rgb(0, 0, 0);"><li style="font-weight: normal;"><span style="font-size:85%;">Ant vs Maven, Episode 2 : Gant or Gradle? - <a href="http://codetojoy.blogspot.com/2008/10/ant-vs-maven-episode-2-gant-or-gradle.html">http://codetojoy.blogspot.com/2008/10/ant-vs-maven-episode-2-gant-or-gradle.html</a></span></li><li style="font-weight: normal;"><span style="font-size:85%;">alternatives to ant: gant, gradle and pjmake - <a href="http://blog.punchbarrel.com/2008/09/29/alternatives-to-ant-gant-gradle-and-pjmake/">http://blog.punchbarrel.com/2008/09/29/alternatives-to-ant-gant-gradle-and-pjmake/</a></span></li><li style="font-weight: normal;"><span style="font-size:85%;">Why maven sucks! - <a href="http://www.jumpingbean.co.za/blogs/mark/maven_problems">http://www.jumpingbean.co.za/blogs/mark/maven_problems</a></span></li><li style="font-weight: normal;"><span style="font-size:85%;">The Problem With Maven - <a href="http://www.alittlemadness.com/2007/08/01/the-problem-with-maven/">http://www.alittlemadness.com/2007/08/01/the-problem-with-maven/</a></span></li><li style="font-weight: normal;"><span style="font-size:85%;">XML is not the build system you're looking for - <a href="http://paulgrenyer.blogspot.com/2008/08/xml-is-not-build-system-youre-looking.html">http://paulgrenyer.blogspot.com/2008/08/xml-is-not-build-system-youre-looking.html</a></span></li><li><span style="font-size:100%;"><span style="font-weight: normal;font-size:85%;" >Maven - Pain = Gradle? - <a href="http://www.alittlemadness.com/2008/11/28/maven-pain-gradle/">http://www.alittlemadness.com/2008/11/28/maven-pain-gradle/</a></span><br /></span></li></ul>Jarle Hansenhttp://www.blogger.com/profile/12306986377142218956noreply@blogger.com0