lørdag 20. juni 2009

Using MicroLog over Bluetooth with Ubuntu and Eclipse

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: http://blog.jayway.com/2008/12/17/java-me-logging-over-bluetooth-using-microlog/). The Bluetooth server is a small application that accepts connections from the clients and prints them out to the console.

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.


Making the MicroLog server compatible with Ubuntu

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-jar-with-dependencies.jar) was not compatible with the OS. It did not start and printed out this error message:

BluetoothSerialServerThread started.

Failed to init the Bluetooth connection. javax.bluetooth.BluetoothStateException: BlueCove com.intel.bluetooth.BluetoothStackBlueZ not available

We are finally closing the logging.


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 “libbluetooth-dev” package. When this is installed go to http://www.bluecove.org 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.

The next step is to create a shell script that will start the server application. Open a terminal window and type “gedit start-microlog-server.sh” (you can call the file whatever you want). Copy and past this into the file:

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

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:

Failed to init the Bluetooth connection. javax.bluetooth.BluetoothStateException: Bluetooth Device is not ready. [1] Operation not permitted

Try to add gksu in front and "-around the java -cp....

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 “chmod u+x start-microlog-server.sh”. You can now test that the script works by entering the following command in the terminal “sh start-microlog-server.sh”. You should see something like this:

BluetoothSerialServerThread started.

BlueCove version 2.1.1-SNAPSHOT on bluez

Waiting for a client to connect to:
btspp://000000000000:;authenticate=false;encrypt=false;master=false
where should be replaced with the channel that is actually in use. This is usually a low number 1 or 2.


Integrate MicroLog with Eclipse

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.

Press the “New launch configuration” and enter a name, like “microlog bluetooth server”. In the location input field, press either “Browse Workspace” (like in the picture below) or “Browse File System”. This depends on where you have saved the shell script. Select the “start-microlog-server.sh” 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.

Now you should be able to run the “External tools” configuration and start the MicroLog server in Eclipse. The output should be similar to this:

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.

torsdag 12. februar 2009

Ant, Maven, Gant & Gradle

For Java there are a range of different build tools/systems available. It can be difficult to know what is the best choice for your 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.


Ant
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 (http://ant.apache.org/manual/develop.html).

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.

The example below shows two simple targets, compile and package.jar. 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.

<path id="lib.classpath">
<fileset dir="${lib.dir}">
<include name="*.jar"/>
</fileset>
</path>

<target name="compile" depends="init">
<javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="lib.classpath" />
</target>

<target name="package.jar" depends="compile">
<jar basedir="${build.dir}" destfile="${jar.filepath}">
<manifest>
<attribute name="Main-Class" value="${main.class}" />
<attribute name="Class-Path" value="${classpath.entries}" />
</manifest>
<fileset dir="${res.dir}">
<include name="*.xml" />
</fileset>
</jar>
</target>


Maven
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, convention over configuration, 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.

Continuing with the HelloWorld example, here is the pom.xml file:

<project>
<modelVersion>4.0.0</modelVersion>
<groupId>net.jarlehansen.helloworld.maven
</groupId>
<artifactId>maven-helloworld</artifactId>
<name>Maven HelloWorld</name>
<version>1.0.0</version>
<packaging>jar</packaging>

<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.6</version>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
<scope>compile</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>net.jarlehansen.helloworld.maven.HelloWorldMain
</mainClass>
<addClasspath>true</addClasspath>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
When following the standard Maven project layout (http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html) it will compile and package the source code. In this case a jar-file is created.


Gant
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.

The example shows how it uses the same tasks as Ant, but with Groovy syntax:


includeTargets << gant.targets.Clean
cleanDirectory << targetDir

ant.path(id : 'libClasspath') {
fileset(dir : libDir, includes : '*.jar')
}

target(compile : 'Compiles source code') {
depends(init)
echo('compile')

ant.javac(srcdir : srcDir, destdir : buildDir, classpathref : 'libClasspath')
}

target(packageJar : 'Package the class files in a jar file') {
depends(compile)
echo('packageJar')

ant.jar(destfile : jarFilepath, basedir : buildDir) {
manifest() {
attribute(name : 'Main-Class', value : 'net.jarlehansen.helloworld.gant.HelloWorldMain')
attribute(name : 'Class-Path', value : '../lib/spring.jar ../lib/commons-logging.jar')
}
fileset(dir : resDir, includes : '*.xml')
}
}

setDefaultTarget (packageJar)


Gradle
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, if you want to. 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: ant.echo('hello'). 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.

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):

usePlugin('java')

sourceCompatibility = '1.5'
targetCompatibility = '1.5'

project.group = "net.jarlehansen.helloworld.gradle"
project.version = "1.0.0"
manifest.mainAttributes("Main-Class" : "net.jarlehansen.helloworld.gradle.HelloWorldMain",
"Class-Path" : "../lib/spring-2.5.6.jar ../lib/commons-logging-1.1.1.jar")

defaultTasks 'libs'

dependencies {
addMavenRepo()
compile "org.springframework:spring:2.5.6"
compile "commons-logging:commons-logging:1.1.1"
}

Conclusion
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.



References