Saturday, May 04, 2013

scala REPL classpath hack

While writing code I often want to take a quick look at the behavior of some class or module, and might wind up writing a short test program just to verify that some method does what I expect or that I'm obeying some DSL's state machine or whatever. One of the great things about Scala (and groovy, javascript, clojure, ...) is its REPL, which allows me to test little blocks of code without the hassle of compiling a test file.

Unfortunately, Scala's REPL launch scripts (scala.bat, scala.sh) do not provide command-line options for manipulating the REPL's classpath, so the REPL can't see the jars IVY assembles for my project ( javasimon, joda-time, guava, gson, guice, ... ).

Anyway - it's easy to just copy %SCALA_HOME%/bin/scala.bat (or ${SCALA_HOME}/scala if not on Windows - whatever), and modify it, so the REPL runs with the same classpath as your project, and at the same time set the heap size, logging config-file system property, and whatever else is needed. For example, here's the shell.bat launch-script from a project I was playing with recently.

@echo off

if not defined JAVACMD set JAVACMD=java.exe
if defined JAVA_HOME set JAVACMD="%JAVA_HOME%\bin\java.exe"

@rem echo "mojo:  .\runTestCase.bat 2>&1 | out-file output.txt utf8"


%JAVACMD% -Xmx1024m -Xms1024m 
   "-Djava.util.logging.config.file=%~dps0logging.properties"  
   -cp "%SCALA_HOME%\lib\*;%~dps0\lib\*;%~dps0\*;." 
   scala.tools.nsc.MainGenericRunner -usejavacp %*

The "mojo" line is a reminder to me that
bla 2>&1 | out-file output.txt utf8
is the Windows powersell equivalent of
bla > output.txt 2>&1
in bash shell - something like that. I'm terrible in bash, and worse in powershell, but I try to at least be able to send output to a file, grep, and run commands in a loop ... ugh!

Anyway - once the classpath is all set, then it's REPL playtime!

> .\cli\shell.bat
Welcome to Scala version 2.10.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_0
9).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import org.joda.{time => jtime}
import org.joda.{time=>jtime}
                                                    ^

scala> val t = jtime.DateTime.parse( jtime.DateTime.now().toString() )
t: org.joda.time.DateTime = 2013-05-03T16:34:48.496-05:00

scala> import com.google.common.{io => gio}
import com.google.common.{io=>gio}


scala> val UTF8 = java.nio.charset.Charset.forName( "UTF-8" )
UTF8: java.nio.charset.Charset = UTF-8

scala> gio.Files.write( jtime.DateTime.now().toString(), 
         new java.io.File( "bla.txt" ), UTF8 )

scala> val t = jtime.DateTime.parse( 
      gio.Files.toString( new java.io.File( "bla.txt" ), UTF8 ) 
    )
t: org.joda.time.DateTime = 2013-05-03T16:37:35.561-05:00

scala>

No comments: