Wednesday, April 8, 2009

Scala on the Google AppEngine

Good News - It was fairly trivial to use Scala with the new Java support in AppEngine.


I used a text editor and ant instead of mucking about with Eclipse. It was pretty much a case of following the docs for Java, just using Scala instead of Java for writing the servlet. The main difference between using Java and Scala is that you need to merge some Scala specific items into the build.xml file. Here's my build.xml




<project>
<property name="scala.home" location="../scala-2.7.3.final" />
<property name="sdk.dir" location="../appengine-java-sdk-1.2.0" />
<property name="sources.dir" value="${base.dir}/src" />
<property name="build.dir" value="${base.dir}/build"/>

<import file="${sdk.dir}/config/user/ant-macros.xml" />

<path id="project.classpath">
<pathelement path="war/WEB-INF/classes" />
<fileset dir="war/WEB-INF/lib">
<include name="**/*.jar" />
</fileset>
<fileset dir="${sdk.dir}/lib">
<include name="shared/**/*.jar" />
</fileset>
</path>

<target name="init">
<property
name="scala-library.jar"
value="${scala.home}/lib/scala-library.jar"
/>
<path id="build.classpath">
<pathelement location="${scala-library.jar}" />

<pathelement location="${build.dir}" />
</path>
<taskdef resource="scala/tools/ant/antlib.xml">
<classpath>
<pathelement location="${scala.home}/lib/scala-compiler.jar" />
<pathelement location="${scala-library.jar}" />
</classpath>
</taskdef>
</target>


<target name="copyscala"
description="Copies the App Engine JARs to the WAR.">
<copy
todir="war/WEB-INF/lib"
flatten="true">
<fileset dir="${scala.home}/lib">
<include name="**/scala-library.jar" />
</fileset>
</copy>
</target>

<target name="copyjars"
description="Copies the Scala JARs to the WAR.">
<copy
todir="war/WEB-INF/lib"
flatten="true">
<fileset dir="${sdk.dir}/lib/user">
<include name="**/*.jar" />
</fileset>
</copy>
</target>

<target name="compile" depends="copyscala, copyjars, init"
description="Compiles Scala source and copies other source files to the WAR.">
<mkdir dir="war/WEB-INF/classes" />
<copy todir="war/WEB-INF/classes">
<fileset dir="src">
<exclude name="**/*.scala" />
</fileset>
</copy>
<scalac
srcdir="src"
destdir="war/WEB-INF/classes"
classpathref="project.classpath"
/>
</target>


<target name="runserver" depends="compile"
description="Starts the development server.">
<dev_appserver war="war" />
</target>

</project>

4 comments:

Enrico said...

Hi, thanks for the post. I will try your way,
I started using eclipse, creating a new project, and wrote a scala class instead of a java one, but I always get this error:

org.datanucleus.exceptions.ClassNotResolvedException: Class "it.enricod.referentialdata.server.GreetingServiceImpl"

Don't know if it's a scala problem or a datanucleus one.

sadie said...

Where can I find that build.xml? It's not in my Google App Engine project.

Scot said...

You'll need to create one - follow Google's instructions for using ant - http://code.google.com/appengine/docs/java/tools/ant.html

You'll then need to add in scala specific bits.

Anonymous said...

Its working

Thanks,
Kalyan Thirumala

American IT Sol Inc.