Scala projects with Eclipse PDE Build

PDE Build is the standard build tool from Eclipse. It is used to export OSGi bundles, plugins, features, or products. Running in headless mode, PDE Build can be used for automatic builds without a GUI. The Scala IDE does not support PDE Build yet. In order to compile Scala projects, you have to do some manual work.

This article applies to an old version of the Scala IDE for Eclipse. An updated Ant script can be found in a newer post!

First of all, you need an Ant script that can be hooked into the build process. The script’s name should be customBuildCallbacks.xml and it should be located at the project’s root:

de.michel-kraemer.myplugin/
  |- bin
  |- META-INF
  |- src
  |- build.properties
  |- customBuildCallbacks.xml

The same directory contains the plugin’s build.properties file. (Please do not mix this one up with the more general build.properties file used for headless builds!) The following lines have to be added to this file to hook the new Ant script into the build process:

customBuildCallbacks=customBuildCallbacks.xml
customBuildCallbacks.inheritall=true

The second line enables access to global properties such as ${build.result.folder}.

The Ant script can contain targets with predefined names. They will be called by PDE Build eventually during the build process. You can copy a template, that already contains all predefined targets (but empty) from the following directory:
${eclipse.home}/plugins/org.eclipse.pde.build_*/templates/plugins/

The post.compile.@dot target will be called when the source files are about to be compiled. That’s the best point to execute the Scala compiler manually, but some additional Ant tasks have to be defined. These can be found in the Scala Library which is delivered with the Scala IDE. You can automatically search for the required jar files using the following snippet:

<!-- find eclipse.home -->
<pathconvert property="eclipse.home">
    <path location="${eclipse.launcher}" />
    <mapper>
        <!-- map "${eclipse.home}/eclipse.exe" to "${eclipse.home}" -->
        <globmapper from="*/eclipse.exe" to="*" handledirsep="true" />
    </mapper>
</pathconvert>
 
<!-- find scala bundle -->
<pathconvert property="scala_bundle">
    <path>
        <fileset dir="${eclipse.home}/plugins">
            <include name="scala.library_*" />
        </fileset>
    </path>
</pathconvert>
 
<!-- find scala tools -->
<pathconvert property="scala_tools_jar">
    <path>
        <fileset dir="${eclipse.home}/plugins">
            <include name="scala.tools.nsc_*" />
        </fileset>
    </path>
</pathconvert>

This places the path to the Scala OSGi bundle in the variable ${scala_bundle}. The variable ${scala_tools_jar} will point to the jar file that contains the Scala Tools and, thus, the Ant tasks.

The library bundle has to be extracted first, so the actual Scala library scala-library.jar can be used in the classpath during the build. For this, you can use the temporary build directory ${build.result.folder}:

<unjar dest="${build.result.folder}/scala-library" src="${scala_bundle}" />
<property name="scala_library_jar"
    location="${build.result.folder}/scala-library/lib/scala-library.jar" />

After this, the Ant targets can be defined:

<!-- define scalac task -->
<taskdef resource="scala/tools/ant/antlib.xml">
    <classpath>
        <pathelement location="${scala_tools_jar}" />
        <pathelement location="${scala_library_jar}" />
    </classpath>
</taskdef>

Before the source files can be compiled, a valid classpath has to be created. It consists of the classpath defined by PDE Build @dot.classpath and the Scala library:

<pathconvert property="my.classpath">
    <restrict>
        <path>
            <path refid="@dot.classpath" />
            <pathelement location="${scala_library_jar}" />
        </path>
        <!-- remove libraries from classpath that don't exist (optional) -->
        <rsel:exists />
    </restrict>
</pathconvert>

Removing non-existing libraries using <rsel:exists /> is optional. To make it work, you have to add the following namespace to the Ant script’s root node:

<project name="Build specific targets and properties"
    xmlns:rsel="antlib:org.apache.tools.ant.types.resources.selectors">
    ...

Finally, the source code can be compiled:

<!-- compile scala source files -->
<mkdir dir="${target.folder}" />
<scalac srcdir="${source.folder1}"
    destdir="${target.folder}"
    classpath="${my.classpath}">
    <include name="**/*.scala" />
</scalac>

For production use, it is also a good idea to delete the source files from the target folder, so they are not deployed together with the binaries:

<!-- delete scala source files in output folder -->
<delete>
    <fileset dir="${target.folder}" includes="**/*.scala" />
</delete>

Conclusion

The method presented here uses the possibility to hook custom Ant targets into the PDE build process. The scripts try to find the Scala library and tools delivered with the IDE. If you don’t like that, you may also copy the files scala-library.jar and scala-compiler.jar (contains the Ant task) from the Scala distribution into some directory of your project and change the classpath respectively.

The complete source of the generic customBuildCallbacks.xml file can be downloaded with the following link:

customBuildCallbacks-old.xml (3.8 KiB)

This article applies to an old version of the Scala IDE for Eclipse. An updated Ant script can be found in a newer post!

This file can be copied without changes into every OSGi bundle that should be compiled with PDE and that contains Scala code. You only have to change the build.properties file as described above.


Profile image of Michel Krämer

Posted by Michel Krämer
on 30 March 2010


Next post

Multilingual websites with Lift and OSGi

The Scala web framework Lift is able to load strings from property bundles, which allows you to publish a website in different languages. With OSGi, you need a resource bundle factory to load the property bundles with the correct classloader.

Previous post

5 Anti-Spam-Maßnahmen für phpBB 3.0

phpBB-basierte Foren sind ein häufiges Ziel von Spammern. Version 3 führt zwar bereits ein besseres Captcha ein, es gibt aber noch mehr Möglichkeiten, Spam einzudämmen. In diesem Artikel stelle ich fünf sinnvolle Maßnahmen vor.

Related posts

Build Scala projects with Eclipse Buckminster

Buckminster is a tool to build Eclipse RCP applications. It contains a lightweight Eclipse SDK and features but no means to build Scala projects yet. This post tries to bridge this gap.

10 recipes for gradle-download-task

gradle-download-task is a Gradle plugin that allows you to download files during the build process. This post summarizes common patterns and use cases of gradle-download-task and provides useful tips and tricks.

Scala projects with Eclipse PDE Build (2)

Since my last article about building Scala projects with Eclipse PDE, the OSGi bundle names of the Scala library and the compiler have changed. This article gives an update and explains how you need to modify your configuration.