{"id":2040,"date":"2011-10-18T20:32:27","date_gmt":"2011-10-18T19:32:27","guid":{"rendered":"http:\/\/www.gamlor.info\/wordpress\/?p=2040"},"modified":"2021-11-25T11:08:44","modified_gmt":"2021-11-25T10:08:44","slug":"running-scala-on-android","status":"publish","type":"post","link":"https:\/\/www.gamlor.info\/wordpress\/2011\/10\/running-scala-on-android\/","title":{"rendered":"Running Scala on Android"},"content":{"rendered":"<p>For my little pet project <a href=\"https:\/\/www.gamlor.info\/wordpress\/2011\/10\/akka-mobile-the-idea\/\">Akka-Mobile<\/a> I need to run Scala on Android. In theory this is dead simple. However in practice there are some issues. When you simply add the Scala runtime library to an Android project you will get an error during dexing. The reason is that the Scala runtime library is just too large. The way to get around this issue is to remove the class-files which aren\u2019t required by your application. This is usually done with <a href=\"http:\/\/proguard.sourceforge.net\/\">Proguard<\/a>.<\/p>\n<div id=\"attachment_2047\" style=\"width: 268px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/10\/android-scala.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-2047\" class=\"size-medium wp-image-2047\" title=\"android-scala\" src=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/10\/android-scala-258x300.png\" alt=\"Scala on Android\" width=\"258\" height=\"300\" srcset=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/10\/android-scala-258x300.png 258w, https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/10\/android-scala.png 500w\" sizes=\"(max-width: 258px) 100vw, 258px\" \/><\/a><p id=\"caption-attachment-2047\" class=\"wp-caption-text\">Scala on Android<\/p><\/div>\n<h2>The Build Script<\/h2>\n<p>So you need to include Proguard in your build script. There are different ways to do it. I tried several existing build scripts from different people with mixed results. Finally I\u2019ve settled with a script from <a href=\"http:\/\/lamp.epfl.ch\/~michelou\/android\/scala-to-android.html\">here<\/a>. This site contains a description and steps you need to take.<\/p>\n<p>Basically you can download the <a href=\"http:\/\/lampsvn.epfl.ch\/svn-repos\/scala\/android-examples\/trunk\/android-sdk\/HelloActivity\/build-scala.xml\">build-scala.xml<\/a> and the <a href=\"http:\/\/lampsvn.epfl.ch\/svn-repos\/scala\/android-examples\/trunk\/android-sdk\/HelloActivity\/proguard-template.cfg\">proguard-template<\/a> from that website. Then you add this task to the default build.xml, right below the \u2018setup\u2019-tag:<\/p>\n<script src=\"https:\/\/gist.github.com\/1295985.js?file=build.xml\"><\/script><noscript><pre><code class=\"language-ant build system ant build system\">&lt;setup \/&gt;\n\n&lt;import file=&quot;build-scala.xml&quot; \/&gt;\n\n&lt;!-- Converts this project&#039;s .class files into .dex files --&gt;\n&lt;target name=&quot;-post-compile&quot; depends=&quot;-post-compile-scala&quot; \/&gt;<\/code><\/pre><\/noscript>\n<p>Of course you need to set the right paths in the local.properties file on your dev machines. For example on mine:<\/p>\n<script src=\"https:\/\/gist.github.com\/1295985.js?file=local.properties\"><\/script><noscript><pre><code class=\"language-ini ini\">sdk.dir=C:\\\\progs\\\\android\\\\sdk\n\nscala.dir=C:\\\\progs\\\\scala<\/code><\/pre><\/noscript>\n<p>Note that Proguard doesn\u2019t like spaces and other special characters in file paths. I had trouble initially because of that. You either can ensure that everything is properly escaped or that you put everything in an appropriate location.<\/p>\n<p>I also added a newer version Proguard to my project, because the version shipped with Android had some bugs. So in the build.properties I have:<\/p>\n<script src=\"https:\/\/gist.github.com\/1295985.js?file=build.properties\"><\/script><noscript><pre><code class=\"language-java properties java properties\"># Current proguard location for this project\nproguard.dir=.\/tools\/proguard\/<\/code><\/pre><\/noscript>\n<p>That\u2019s all. Of course I\u2019ve done some project specific modifications to the original build file. Anyway, when you follow the instructions of the original page you <a href=\"http:\/\/lamp.epfl.ch\/~michelou\/android\/scala-to-android.html\">should be fine<\/a>.<\/p>\n<h2>The IDE Setup<\/h2>\n<p>Of course the build script is only half the story. I want to use my IDE to edit and debug the code. I\u2019m an IntelliJ user, so this is my IntelliJ setup. (I should check out Eclipse\u2019s Scala support, I\u2019ve heard that they put a lot of effort into it).<\/p>\n<p>First create (or import) the project like a regular Android project. Then also add the Scala facetted to the project. Now in theory you can compile and run that project. Unfortunately the dexing step will fail due to the large Scala runtime.<\/p>\n<div id=\"attachment_2042\" style=\"width: 471px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/10\/intellij-project-setup.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-2042\" class=\"size-full wp-image-2042\" title=\"intellij-project-setup\" src=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/10\/intellij-project-setup.png\" alt=\"Android and Scala Facette\" width=\"461\" height=\"224\" srcset=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/10\/intellij-project-setup.png 461w, https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/10\/intellij-project-setup-300x145.png 300w\" sizes=\"(max-width: 461px) 100vw, 461px\" \/><\/a><p id=\"caption-attachment-2042\" class=\"wp-caption-text\">Android and Scala Facette<\/p><\/div>\n<p>&nbsp;<\/p>\n<p>Basically you need to replace the build step with your costume build step. I \u2018unchecked\u2019 the \u2018make\u2019 step in the run configuration and added an Ant step. Like this:<\/p>\n<div id=\"attachment_2043\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/10\/intellij-run-config.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-2043\" class=\"size-medium wp-image-2043\" title=\"intellij-run-config\" src=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/10\/intellij-run-config-300x190.png\" alt=\"Run Configuration\" width=\"300\" height=\"190\" srcset=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/10\/intellij-run-config-300x190.png 300w, https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/10\/intellij-run-config.png 800w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-2043\" class=\"wp-caption-text\">Run Configuration<\/p><\/div>\n<p>&nbsp;<\/p>\n<p>You can run any Ant target which builds the .apk for you. The only thing you need to ensure is that IntelliJ finds the apk-file. I created a special \u2018debug-install\u2019 target which compiles the project and copies the apk to the location where IntelliJ usually puts it. An alternative would be to configure IntelliJ to use your location. Here\u2019s the Ant-Task for my IDE debugging:<\/p>\n<script src=\"https:\/\/gist.github.com\/1295985.js?file=build-2.xml\"><\/script><noscript><pre><code class=\"language-xml xml\">&lt;target name=&quot;debug-install&quot; depends=&quot;debug&quot;&gt;\n\t&lt;copy file=&quot;.\/bin\/AkkaDroidApp-debug.apk&quot;\n\t\ttofile=&quot;.\/out\/production\/AkkaDroidApp\/AkkaDroidApp.apk&quot;\/&gt;\n&lt;\/target&gt;<\/code><\/pre><\/noscript>\n<p>After these steps everything should run in IntelliJ. When you use Run \/ Debug the Ant script will build the apk and IntelliJ will load it into the Emulator \/ Phone. Afterwards it just attaches to the process like normal. Everything should work, like the debugger etc.<br \/>\n<a name=\"update40\"><\/a><\/p>\n<h2>Update For Android 4.0 SDK<\/h2>\n<p>With the 4.0 SDK the standard Android build file has changed, so that the original script above doesn&#8217;t seem to work anymore. You will get an error telling you that the build script is outdated. Here&#8217;s what I&#8217;ve done to get it to run:<\/p>\n<ul>\n<li>I followed the instructions of the error message. I deleted the existing build.xml and then upgraded the project with: &#8216;android update project &#8211;path .\/&#8217;. (You need the android tools path in your PATH variable. Or use the complete path to the &#8216;android&#8217; command of your SDK).<\/li>\n<li>Then I re.added my Scala tasks in the build.xml:<br \/>\n<script src=\"https:\/\/gist.github.com\/1299279.js?file=build.xml\"><\/script><noscript><pre><code class=\"language-ant build system ant build system\">&lt;!-- version-tag: 1 --&gt;\n&lt;import file=&quot;${sdk.dir}\/tools\/ant\/build.xml&quot; \/&gt;\t\n\n&lt;import file=&quot;build-scala.xml&quot; \/&gt;\n\n&lt;target name=&quot;-post-compile&quot; depends=&quot;-post-compile-scala&quot; \/&gt;<\/code><\/pre><\/noscript><\/li>\n<li>Unfortunately the &#8216;build-scala.xml&#8217; file still had issues with the new SDK. I fixed two things. First the &#8216;compile-scala&#8217; task new depends on &#8216;-compile&#8217; instead of &#8216;compile&#8217;. I also removed the &#8216;&lt;src refid=&#8221;project.libraries.src&#8221;\/&gt;&#8217; entry. Looks like this property isn&#8217;t there anymore, but it wasn&#8217;t used anyway in my project. The compile-scala task look now like this:<br \/>\n<script src=\"https:\/\/gist.github.com\/1299279.js?file=build-scala.xml\"><\/script><noscript><pre><code class=\"language-xml xml\">&lt;target name=&quot;compile-scala&quot; depends=&quot;-compile&quot;\n            if=&quot;contains.scala.sources&quot; unless=&quot;do.not.compile&quot;\n            description=&quot;Compiles project&#039;s .scala files into .class files&quot;&gt;\n        &lt;condition property=&quot;logging&quot; value=&quot;verbose&quot; else=&quot;none&quot;&gt;\n            &lt;istrue value=&quot;${verbose}&quot;\/&gt;\n        &lt;\/condition&gt;\n        &lt;echo message=&quot;${scalac.banner}&quot; level=&quot;info&quot; taskname=&quot;scalac&quot;\/&gt;\n        &lt;scalac\n                destdir=&quot;${out.classes.absolute.dir}&quot;\n                bootclasspathref=&quot;android.target.classpath&quot;\n                logging=&quot;${logging}&quot; addparams=&quot;${scalac.addparams}&quot;\n                classpath=&quot;${extensible.classpath}&quot;\n                classpathref=&quot;jar.libs.ref&quot;&gt;\n            &lt;src path=&quot;${source.absolute.dir}&quot;\/&gt;\n            &lt;src path=&quot;${gen.absolute.dir}&quot;\/&gt;\n            &lt;classpath&gt;\n                &lt;pathelement location=&quot;${scala-library.jar}&quot;\/&gt;\n                &lt;fileset dir=&quot;${akka-lib-dir}&quot; includes=&quot;*.jar&quot;&gt;&lt;\/fileset&gt;\n                &lt;pathelement location=&quot;&quot;\/&gt;\n                &lt;!-- include compiled resources --&gt;\n                &lt;pathelement location=&quot;${out.classes.absolute.dir}&quot;\/&gt;\n                &lt;fileset dir=&quot;${extensible.libs.classpath}&quot; includes=&quot;*.jar&quot;\/&gt;\n            &lt;\/classpath&gt;\n        &lt;\/scalac&gt;\n    &lt;\/target&gt;<\/code><\/pre><\/noscript><\/li>\n<li>I added the property &#8216;manifest.package&#8217; which holds name of the top package. Looks like this property isn&#8217;t defined anymore by the standard build. This property is used for Progard to keep those classes in your project. So for my project the &#8216;ant.properties&#8217; file now looks like this:<br \/>\n<script src=\"https:\/\/gist.github.com\/1299279.js?file=ant.properties\"><\/script><noscript><pre><code class=\"language-ini ini\">scalac.addparams=-deprecation\nproguard.dir=.\/tools\/proguard\nmanifest.package=info.gamlor.akkamobile<\/code><\/pre><\/noscript><\/li>\n<li>The last change I&#8217;ve done is in the &#8216;-post-compile-scala&#8217; task. Here the &#8216;build.mode.debug&#8217; and &#8216;build.mode.release&#8217; flags are no longer set. Instead the &#8216;build.target&#8217; property contains the build type. So I&#8217;ve changed that in the &#8216;-post-compile-scala&#8217; task:<script src=\"https:\/\/gist.github.com\/1299279.js?file=build-scala-second-change.xml\"><\/script><noscript><pre><code class=\"language-xml xml\">&lt;target name=&quot;-post-compile-scala&quot; depends=&quot;compile-scala&quot; unless=&quot;do.not.compile&quot;\n\t\tdescription=&quot;Shrink project class files and Scala library into one .jar file&quot;&gt;\n\t&lt;condition property=&quot;debug.mode&quot; value=&quot;&quot; else=&quot;#DEBUG#&quot;&gt;\n\t\t &lt;equals arg1=&quot;${build.target}&quot; arg2=&quot;debug&quot;\/&gt;\n\t&lt;\/condition&gt;\n\t&lt;condition property=&quot;release.mode&quot; value=&quot;&quot; else=&quot;#RELEASE#&quot;&gt;\n\t\t &lt;equals arg1=&quot;${build.target}&quot; arg2=&quot;release&quot;\/&gt;\n\t&lt;\/condition&gt;\n\t&lt;!-- priority is given to local ProGuard configuration if present --&gt;<\/code><\/pre><\/noscript><\/li>\n<\/ul>\n<h2>Second &amp; Third Update<\/h2>\n<p>First I&#8217;ve fixed another thing above so that debugging works with the Android 4.0 SDK. Then I&#8217;ve created an example project which should work with the Android 4.0 SDK and incorporates all my changes as explained above. Then Patrick Boos improved that even further. Thanks a lot. You can find the <a href=\"https:\/\/github.com\/pboos\/scala-on-android-example#readme\">example project on GitHub (https:\/\/github.com\/pboos\/scala-on-android-example#readme)<\/a> . Don&#8217;t forget to fix the local.properties for your environment. And remember that Proguard doesn&#8217;t like spaces in paths. My build file won&#8217;t work with spaces in file paths right now =(.<\/p>\n<h2>Conclusion<\/h2>\n<p>That\u2019s it for now. If you know a better way, have tips or problems: Tell me =).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>For my little pet project Akka-Mobile I need to run Scala on Android. In theory this is dead simple. However in practice there are some issues. When you simply add&hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[243,15,17],"tags":[245,297,244,226],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts\/2040"}],"collection":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/comments?post=2040"}],"version-history":[{"count":16,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts\/2040\/revisions"}],"predecessor-version":[{"id":3918,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts\/2040\/revisions\/3918"}],"wp:attachment":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/media?parent=2040"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/categories?post=2040"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/tags?post=2040"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}