User Tools

Site Tools


documents:121106scalasetup

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
documents:121106scalasetup [2012/11/13 07:37]
kota [Scripting]
documents:121106scalasetup [2016/05/24 05:46] (current)
Line 1: Line 1:
 +====== Coding in Scala ======
  
 +===== Environment =====
 +
 +Though Scala could be a highly efficient tool for writing codes using ImageJ as library, there is no default setup in any of ImageJ distributions. One needs to setup the environment. Some IDEs seems to be usable for Scala coding: ​
 +  * [[http://​scala-ide.org/​|Eclipse scala IDE]]
 +  * [[http://​confluence.jetbrains.net/​display/​SCA/​Scala+Plugin+for+IntelliJ+IDEA|Scala Plugin for IntelliJ IDEA]]
 +  * [[http://​wiki.netbeans.org/​Scala|Scala Plugins for NetBeans]]
 +
 +To go simpler, I tried to setup environment with vim. One advantage of doing so is that it will enable streamed compiling (which will be more like runtime debugging) by combining [[https://​github.com/​Shougo/​vimshell|vimshell]](there are several different "​vimshell",​ but this one is the latest and most functional) and [[http://​www.scala-sbt.org/​|sbt]]. [[Here are more details on the setting]].
 +
 +===== Basics: Interactive Session (with ImageJ API) =====
 +
 +<​code>​
 +scala
 +</​code>​
 +In your command line will startup the interactive session (read-evaluate-print looping, or REPL mode).
 +
 +To use external classes, you could either ​
 +  * copy corresponding jars to {SCALA_HOME}/​lib/​ directory
 +  * in the scala prompt, do :cp={path to ij.jar} ​
 +  * use SBT to include the classpath ([[http://​www.scala-sbt.org/​release/​docs/​Detailed-Topics/​Scripts|details]]).
 +    * in this case, start your scala session by a command screpl (a shell script that runs SBT in REPL mode) with dependency argument. The argument is similar to Maven: GroupId%Artifact%Version and if the dependency target is not locally saved, then URL is required. ​
 +<​code>​
 +screpl "​imagej.releases at http://​maven.imagej.net/​content/​repositories/​releases"​ "​net.imagej%ij%1.47e"​
 +</​code>  ​
 +    * Once ImageJ (ij.jar) is downloaded to your repository, of which the default location would be ~/.ivy2, you could use command without URL.
 +<​code>​
 +screpl "​net.imagej%ij%1.47e"​
 +</​code> ​
 +
 +===== Basics: Scripting (with ImageJ API) =====
 +
 +The fastes way if you want test:
 +  * Copy ij.jar under scala home directory
 +    * If you installed scala in Windows using binary, lib/
 +    * If you installed scala using homebrew, under /​usr/​local/​Cellar/​scala/​{version.number}/​libexec/​lib/​
 +  * Run the code by
 +<​code>​
 +scala -howtorun:​script testscript.scala
 +</​code>​
 +
 +
 +===== Basics: Compiling and Run =====
 +<​code>​
 +javac -cp {whatever path}/​scala-library.jar:​{imagej_home}/​ij.jar my_plugin.scala
 +java -cp {whatever path}/​scala-library.jar:​{imagej_home}/​ij.jar my_plugin
 +(you could prepare plugins.config)
 +jar cvf my_plugin.jar *
 +cp my_plugin.jar {imagej_home}/​plugins/​
 +</​code>​
 +
 +Or If you have scala compiler (scalac) in your path, then 
 +<​code>​
 +scalac -classpath {imagej_home}/​ij.jar my_plugin.scala
 +</​code>​
 +
 +===== SBT-Scala ===== 
 +
 +SBT stands for Simple Build Tool, and is a build tool for Scala. It's function is similar to Make, Ant or Maven. ​
 +
 +==== Scripting ====
 +
 +SBT could be used in ScriptMode to load Scala scripts and execute ([[http://​www.scala-sbt.org/​release/​docs/​Detailed-Topics/​Scripts|details]]). Merit of using SBT is that you could write the dependency directly in the scala file as a header. This header works like a pom.xml dependency nodes in Maven, searches for library in internet and downloads if necessary. ​
 +
 +For this to work, a short shell script that runs java command "​scalas"​ is used. How to prepare this script is written in the above "​details"​ link.
 +
 +=== example script ===
 +The code below, the file name is, say, testsc.scala. Then you could run the script by
 +<​code>​
 +scalas testsc.scala
 +</​code>​
 +
 +If scalas is within $PATH then
 +<​code>​
 +./​testsc.scala
 +</​code>​
 +
 +Dont forget to chmod u+x the script file. 
 +
 +<​code>​
 +#​!/​usr/​bin/​env scalas
 +!#
 +
 +/***
 +scalaVersion := "​2.9.2"​
 +
 +libraryDependencies ++= Seq(
 +   "​net.imagej"​ % "​ij"​ % "​1.47e"​
 +)
 +*/
 +import ij._
 +println("​scala script running by SBT script mode")
 +IJ.log("​here is via IJ.log"​)
 +
 +</​code>​
 +==== Compile ====
 +
 +To compile scala code and generate .class files that could be then packaged as a jar file, you should prepare a build.sbt file (similar to pom.xml in Maven but much shorter). ​
 +
 +To use ImageJ API, below is an example of build.sbt file to automatically fullfil the dependency for ij.jar. This build file should be placed in the root directory of the project. ​
 +
 +<​code>​
 +name := "​hello"​
 +
 +version := "​1.0"​
 +
 +scalaVersion := "​2.9.2"​
 +
 +resolvers += "​imagej.releases"​ at "​http://​maven.imagej.net/​content/​repositories/​releases"​
 +
 +libraryDependencies += "​net.imagej"​ % "​ij"​ % "​latest.integration"​
 +</​code>​
 +First three lines (note: there should always be a blank row between lines in build.sbt file) are standard declaration of project. 4th line defines extra Maven repository site (called [[http://​www.scala-sbt.org/​release/​docs/​Detailed-Topics/​Resolvers.html|"​resolver"​]]) and 5th line for the  library ([[http://​www.scala-sbt.org/​release/​docs/​Detailed-Topics/​Library-Management.html|automatic dependency management]]). ​
 +
 +With this build setting, declared dependencies,​ which in the above case would be the latest ij.jar, will be downloaded under local repository in ~/​.ivy2. ​
 +
 +ImageJ related library'​s groupID, name of the artefact, versions could be searched in the following site:
 +
 +http://​maven.imagej.net/​
 +
 +The repository at the Maven Central offers ImageJ builds, but this is not the official release. ​
 +<​quote>​
 +The builds on Maven Central with groupId gov.nih.imagej were done by a third party, but the official ImageJ builds are available from Maven—just not from Maven Central yet.
 +
 +The official builds are currently deployed to maven.imagej.net,​ with groupId net.imagej. The ImageJ 1.x builds have artifactId of ij while the ImageJ2 builds consist of several artifacts all prefixed by ij-.
 +
 +Are ImageJ Maven dependencies in maven central? StackOverFlow,​ 20110917
 +[[http://​stackoverflow.com/​questions/​12458688/​are-imagej-maven-dependencies-in-maven-central|Link]]
 +</​quote>​
 +
 +Compile and run the code for the first time with the above build file will download ij.jar. ​
 +<​code>​
 +$ sbt run
 +[info] Set current project to hello (in build file:/​Users/​miura/​tmp/​sbttest2/​)
 +[info] Updating {file:/​Users/​miura/​tmp/​sbttest2/​}default-74f0ba...
 +[info] Resolving com.github.scijava#​pom-scijava;​1.4 ...
 +[info] downloading http://​maven.imagej.net/​content/​repositories/​releases/​net/​imagej/​ij/​1.47d/​ij-1.47d.jar ...
 +[info] [SUCCESSFUL ] net.imagej#​ij;​1.47d!ij.jar (2394ms)
 +[info] Done updating.
 +[info] Running Hi 
 +Hi!
 +[success] Total time: 6 s, completed Nov 6, 2012 1:01:34 PM
 +</​code>​
 +If you want to compile only, then
 +<​code>​
 +$ sbt compile
 +</​code>​
 +If you want to let the compiler to automatically react when you change a source file (meaning when you save the file), keep it running by
 +<​code>​
 +$ sbt ~compile
 +# in case of VimShell, you should escape tilda and do "sbt \~compile"​
 +</​code> ​
 +
 +=== sbt build using pom.xml ===
 +
 +Dependency could be set using Maven pom.xml. It might be better to do so, as many ImageJ developers are using Maven as build tool. I have not tested this Maven-Sbt method, but if this is possible then simply copy pom.xml example file like the one shown in [[http://​wiki.imagej.net/​Maven|here]] to the project root directory and write build.sbt file to refer to that pom.xml. ​
 +<​code>​
 +externalPom()
 +</​code>​
 +
 +For ImageJ2, one could refer to the pom.xml example shown [[https://​github.com/​imagej/​imagej-tutorials/​blob/​master/​load-and-display-dataset/​pom.xml|here]].
 +
 +**Note:** it might not be straightforward,​ as relative path in pom.xml [[http://​blog.markfeeney.com/​2010/​12/​maven-sbt-and-impossible-to-load-parent.html|could be problematic for sbt]]. ​
 +=== Example Code ===
 +
 +Here is a very simple code, placed in the same directory as the build.sbt above. ​
 +<sxh scala>
 +import ij._
 +
 +object Hi { 
 +
 +  def main(args: Array[String]) {
 +    println("​Hi!"​)
 +    IJ.log("​test ij")
 +    IJ.log(IJ.getVersion())
 +    var imp = IJ.openImage("​http://​imagej.nih.gov/​ij/​images/​blobs.gif"​)
 +    imp.show()
 +
 +  }
 +}
 +</​sxh>​
 +
 +THe code could be compiled and executed by **sbt run**.
 +
 +<​code>​
 +vimshell% sbt run
 +[info] Set current project to hello (in build file:/​Users/​miura/​tmp/​sbttest2/​)
 +[info] Compiling 1 Scala source to /​Users/​miura/​tmp/​sbttest2/​target/​scala-2.9.2/​classes...
 +[info] Running Hi
 +Hi!
 +test ij
 +1.47d
 +[success] Total time: 3 s, completed Nov 6, 2012 1:32:48 PM
 +</​code>​
 +
 +===== Maven-Scala =====
 +
 +A bit more traditional way that Scala people has been using for building is Maven (I rephrase traditional. As long I have observed, Scala people are moving towards sbt, simple-build tool). There is [[http://​scala-tools.org/​mvnsites/​maven-scala-plugin/​example_script.html|Maven-Scala plugin]](some information in this site is outdated) that enables to build Scala code using Maven pom.xml. ​
 +
 +Since Maven is consistently used in Fiji and ImageJ2 development,​ it might be better to keep the consistency and use Maven. ​
 +
 +==== Running Scala Script using ImageJ as library ====
 +
 +Scala has three modes of execution: compile, script and interactive. Here is an example of running script. Place a pom.xml as follows in a directory. ​
 +
 +<sxh xml>
 +<?xml version="​1.0"​ encoding="​UTF-8"?>​
 +<!-- >
 +This pom.xml is for running Scala Script with ImageJ. ​
 +run the script with the following command. ​
 +mvn scala:​script
 +<-->
 +<project xmlns="​http://​maven.apache.org/​POM/​4.0.0"​ xmlns:​xsi="​http://​www.w3.org/​2001/​XMLSchema-instance"​
 + xsi:​schemaLocation="​http://​maven.apache.org/​POM/​4.0.0
 + http://​maven.apache.org/​xsd/​maven-4.0.0.xsd">​
 + <​modelVersion>​4.0.0</​modelVersion>​
 +
 + <​parent>​
 + <​groupId>​org.scijava</​groupId>​
 + <​artifactId>​pom-scijava</​artifactId>​
 + <​version>​1.19</​version>​
 + </​parent>​
 +
 + <​groupId>​de.embl.cmci</​groupId>​
 + <​artifactId>​testscript</​artifactId>​
 + <​name>​test-scala-ij-script</​name>​
 + <​description></​description>​
 +
 + <​!-->​ repos: ImageJ release + scala tools <-->
 + <​repositories>​
 + <​repository>​
 + <​id>​imagej.releases</​id>​
 + <​url>​http://​maven.imagej.net/​content/​repositories/​releases</​url>​
 + </​repository> ​   ​
 + <​repository>​
 + <​id>​scala-tools.org</​id>​
 + <​name>​Scala-tools Maven2 Repository</​name>​
 +<​!-- <​url>​http://​scala-tools.org/​repo-releases</​url>​ -->
 + <​url>​http://​oss.sonatype.org/​content/​groups/​scala-tools</​url>​
 + </​repository>​
 + </​repositories>​
 + <​!-->​ plugin repo: Maven - Scala <-->
 + <​pluginRepositories>​
 + <​pluginRepository>​
 + <​id>​scala-tools.org</​id>​
 + <​name>​Scala-tools Maven2 Repository</​name>​
 +<​!-- <​url>​http://​scala-tools.org/​repo-releases</​url>​ -->
 + <​url>​http://​oss.sonatype.org/​content/​groups/​scala-tools</​url>​
 + </​pluginRepository>​
 + </​pluginRepositories>​
 +
 + <​dependencies>​
 + <​dependency>​
 + <​groupId>​net.imagej</​groupId>​
 + <​artifactId>​ij</​artifactId>​
 + <​version>​${imagej1.version}</​version>​
 + </​dependency>​
 + <​dependency>​
 + <​groupId>​org.scala-lang</​groupId>​
 + <​artifactId>​scala-library</​artifactId>​
 + <​version>​2.9.2</​version>​
 + </​dependency>​
 +<​!-- <​dependency>​
 + <​groupId>​org.scala-tools</​groupId>​
 + <​artifactId>​maven-scala-plugin</​artifactId>​
 + <​version>​2.15.2</​version>​
 + </​dependency>​ -->
 + </​dependencies>​
 +
 + <​!-->​ build environment<​-->​
 + <​build>​
 + <​sourceDirectory>​src/​main/​scala</​sourceDirectory>​
 + <​testSourceDirectory>​src/​test/​scala</​testSourceDirectory>​
 + <​plugins>​
 + <​plugin>​
 + <​groupId>​org.scala-tools</​groupId>​
 + <​artifactId>​maven-scala-plugin</​artifactId>​
 + <​version>​2.15.2</​version>​
 + <​executions>​
 + <​execution>​
 + <​phase>​package</​phase>​
 + <​goals>​
 + <​goal>​script</​goal>​
 + </​goals>​
 + </​execution>​
 + </​executions>​
 +<​!-- to set the exact version
 + <​configuration>​
 + <​scalaVersion>​${scala.version}</​scalaVersion>​
 + </​configuration>​
 +-->
 +<​!-- if you want write script here
 + <​configuration>​
 + <​script>​
 + println ("​Hello from pom.xml"​)
 +
 + </​script>​
 + </​configuration>​
 +-->​
 +<!-- or set the script file name here 
 + <​configuration>​
 + <​scriptFile>​helloscript.scala</​scriptFile>​
 + </​configuration>​
 +-->
 + </​plugin>​
 + </​plugins>​
 + </​build>​
 +</​project>​
 +</​sxh>​
 +[[https://​gist.github.com/​4038656|Gist]]
 +
 +Then in the same directory, save the following script as "​helloscript.scala"​. ​
 +
 +<sxh scala>
 +import ij._
 +
 +println ("​Hello from external script :-)")
 +IJ.log("​test ij")
 +IJ.log(IJ.getVersion())
 +val imp = IJ.openImage("​http://​imagej.nih.gov/​ij/​images/​blobs.gif"​)
 +imp.show()
 +IJ.wait(2000)
 +imp.close()
 +</​sxh>​
 +[[https://​gist.github.com/​4038817|Gist]]
 +
 +To run the script, use the following command:
 +<​code>​
 +mvn scala:​script -DscriptFile=helloscript.scala
 +</​code>​
 +
 +If this is the first time that you are using scala in this way, Maven downloads all the required libraries from oss.sonatype.org and maven.imagej.net. These files will be saved under ~/.m2 directory, and for executing the script. From the second time, Maven only checks the presence of the library under ./m2.
 +
 +Instead of passing file name as command line argument, you could write the script directly in the file (see line 86 - 91) or set the script file path (see line 93-96). In this case, you could run the script by
 +<​code>​
 +mvn scala:​script
 +</​code>​
 +In these cases, you could only have one of either <​script>​ or <​scriptFile>​ within <​configure>​. ​
 +
 +==== Compiling Scala code ====
 +
 +In compiler mode, source files should be placed under
 +<​code>​
 +src/​main/​scala
 +src/​test/​scala
 +</​code>​
 +
 +Maven could also startup a server that awaits changes in the source file and as soon there is change, then the source is compiled automatically. To use this feature (like "sbt ~compile"​) use this command:
 +<​code>​
 +mvn scala:cc
 +</​code>​
 +
 +And a pom.xml with scala dependency should be placed in the root (just like Maven with Java). Below is a sample pom.xml for this. 
 +<sxh xml>
 +<?xml version="​1.0"​ encoding="​UTF-8"?>​
 +<!-- >
 +This pom.xml is for building Scala code that uses ImageJ. ​
 +<-->
 +<project xmlns="​http://​maven.apache.org/​POM/​4.0.0"​ xmlns:​xsi="​http://​www.w3.org/​2001/​XMLSchema-instance"​
 + xsi:​schemaLocation="​http://​maven.apache.org/​POM/​4.0.0
 + http://​maven.apache.org/​xsd/​maven-4.0.0.xsd">​
 + <​modelVersion>​4.0.0</​modelVersion>​
 +
 + <​parent>​
 + <​groupId>​org.scijava</​groupId>​
 + <​artifactId>​pom-scijava</​artifactId>​
 + <​version>​1.19</​version>​
 + </​parent>​
 +
 + <​groupId>​de.embl.cmci</​groupId>​
 + <​artifactId>​testscalaCompile</​artifactId>​
 + <​name>​test-scala-ij</​name>​
 + <​description></​description>​
 +
 + <​!-->​ repos: ImageJ release + scala tools <-->
 + <​repositories>​
 + <​repository>​
 + <​id>​imagej.releases</​id>​
 + <​url>​http://​maven.imagej.net/​content/​repositories/​releases</​url>​
 + </​repository> ​   ​
 + <​repository>​
 + <​id>​scala-tools.org</​id>​
 + <​name>​Scala-tools Maven2 Repository</​name>​
 +<​!-- <​url>​http://​scala-tools.org/​repo-releases</​url>​ -->
 + <​url>​http://​oss.sonatype.org/​content/​groups/​scala-tools</​url>​
 + </​repository>​
 + </​repositories>​
 + <​!-->​ plugin repo: Maven - Scala <-->
 + <​pluginRepositories>​
 + <​pluginRepository>​
 + <​id>​scala-tools.org</​id>​
 + <​name>​Scala-tools Maven2 Repository</​name>​
 +<​!-- <​url>​http://​scala-tools.org/​repo-releases</​url>​ -->
 + <​url>​http://​oss.sonatype.org/​content/​groups/​scala-tools</​url>​
 + </​pluginRepository>​
 + </​pluginRepositories>​
 +
 + <​dependencies>​
 + <​dependency>​
 + <​groupId>​net.imagej</​groupId>​
 + <​artifactId>​ij</​artifactId>​
 + <​version>​${imagej1.version}</​version>​
 + </​dependency>​
 + <​dependency>​
 + <​groupId>​org.scala-lang</​groupId>​
 + <​artifactId>​scala-library</​artifactId>​
 + <​version>​2.9.2</​version>​
 + </​dependency>​
 + </​dependencies>​
 +
 + <​!-->​ build environment<​-->​
 + <​build>​
 + <​sourceDirectory>​src/​main/​scala</​sourceDirectory>​
 + <​testSourceDirectory>​src/​test/​scala</​testSourceDirectory>​
 + <​plugins>​
 + <​plugin>​
 + <​groupId>​org.scala-tools</​groupId>​
 + <​artifactId>​maven-scala-plugin</​artifactId>​
 + <​version>​2.15.2</​version>​
 + <​executions>​
 + <​execution>​
 + <​goals>​
 + <​goal>​compile</​goal>​
 + <​goal>​testCompile</​goal>​
 + </​goals>​
 + </​execution>​
 + </​executions>​
 +<​!-- to set the exact version
 + <​configuration>​
 + <​scalaVersion>​${scala.version}</​scalaVersion>​
 + </​configuration>​
 +-->
 + </​plugin>​
 + </​plugins>​
 + </​build>​
 +</​project>​
 +
 +</​sxh>​
 +
 + 
 +
 +
 +
 +
 +
 +
 + 
documents/121106scalasetup.txt · Last modified: 2016/05/24 05:46 (external edit)