Sunday 11 September 2011

OSGi, Scala, Maven and Netbeans

So, I finally got around to trying the combo in the title out. Was it hard? Did it require alot of work? Does it slice bread? No.

Actually, I had "allocated" a few hours to get this working but, to my surprise, found out that it requires less than half an our to get started. So, don't get discouraged by the number of steps needed!

First of all, here is what you will need:
  • Netbeans 7.0
  • The zipped scala-plugin for Netbeans found here
  • An OSGi container, like Apache Felix
  • The osgi-fied version of scala libraries found here
First, unzip the netbeans plugin and place them somewhere on your disk. Then start Netbeans and go to Tools->Plugins and choose the tab Downloaded. Click the button "Add Plugins..." and browse to where you just unziped. Select all the unziped files and install. These files aren't signed so Netbeans might ask you if you want to continue anyway. You want that.

Now we have our environment set up. That's actually the real beauty of this. No need to download scala, set environment variables or anything like that. Just, install plugin and we're ready to go. Next, create a new project in Netbeans and choose a maven project. Choose the standard Java Application option and click ok. See, we don't want a standard Java Application but I couldn't find a maven archetype for scala at the maven central repository so, this will do for now.

Browse to the pom.xml file in your newly created project and cut and paste the following xml over the current build tag. Note that you want to edit some of the rows, most notably the Private-Package and Bundle-Activator tags.


   
      
      org.apache.felix
      maven-bundle-plugin
      1.4.3
      true
      
         
            
            *
            org.acme.impl*
            ${project.artifactId}
            org.acme.impl.Main
         
      
   
   
      org.scala-tools
      maven-scala-plugin
      2.15.2
         
            
               process-resources
               
                  add-source
                  compile
               
            
            
               scala-test-compile
               process-test-resources
               
                  testCompile
               
            
         
         
            ${scala.version}
            true
            
               -g:vars
               -deprecation
               -dependencyfile
               ${project.build.directory}/.scala_dependencies
            
         
      
   


Still in the pom file, change

jar

to

bundle

Finally, make sure you have the dependencies set to (at least)


   org.osgi
   org.osgi.core
   4.0.0


   org.scala-lang
   scala-library
   2.9.0


Enough with the xml (and if you know your way around netbeans, some of the xml can be fixed from the GUI, such as dependencies). At this point you want to create a bundle activator. So, create a new scala class and name it anything you want (just make sure that the pom has the fully qualified class name in the Bundle-Activator tag). As you see in the pom above, I chose Main. Now, let that class extend BundleActivator (or implement if you're still caught up in Java-not-Scala lingu) and implement the start and stop methods. You'll end up with something similar to this:

package org.acme.impl

import org.osgi.framework.BundleActivator
import org.osgi.framework.BundleContext

class Main extends BundleActivator {
  def start(context : BundleContext) : Unit = {
    println("Hello, OSGi container")
  }
  
  def stop(context : BundleContext) : Unit = {
    println("Goodbye container")
  }
}

If your netbeans scala plugin was installed successfully, this should now be able to compile. Give it a shot!

Wow, lots of code and xml! But at least we now have our OSGI-bundle. It is written in "pure" scala (wich of course gets compiled into even more pure java byte code). Time then to deploy this into the felix OSGi container (or any other OSGi container). But wait! We still need those scala libraries, otherwise we will not be able to run our scala code! Fine. Remember the osgi-fied version of scala libraries? The link above takes you to a site where the Eclipse scala plugin resides. From there you should be able to download a zip-file containing (including a heap of other things) a file named org.scala-ide.scala.library_2.9.1.final.jar. Deploy that first, then your module (or the other way around, just make sure to deploy both) and start both of them. Done! Simple and sweet. At least simple as compared to what I had hoped for. Basically, this is exactly what I do for any OSGi-bundle (of course I have archetypes creating the pom-file), and nothing really out of the ordinary. That surprised me alot!

A final disclaimer though is that the osgi-fied scala libraries file seem to be a draft and it also includes some other libraries not in the official scala-library file. This, in my eyes, breaks modularity, but it seems that you could just bundle up the official scala-library file yourself. Also, the file contain sources, so it is a heckofalot bigger than necessary. So, remember to NOT Require-Bundle but rather Import-Package, and you're bundles should be fine!

For once, maven will help modularization of OSGi related code rather than the other way around, since your pom only states a dependency on scala-library, your code will not compile if you try to use things from the deployed version that is not in the official one.

Now, off to scala and felix!

No comments:

Post a Comment