How can I get scala to work in the command line? - scala

I run Windows 7.
I have java (a current enough version to run scala) and scala downloaded on my computer. I've set PATH so that when I type "scala" into the command prompt it sends me to the proper interface:
Welcome to Scala version 2.9.1.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_51)
Type in expressions to have them evaluated.
Type :help for more information
However I can't execute the command "scala" or "scalac" on my test files.
scala> scala Hello
(console):8: error: object Hello is not a member of package scala
This makes me think I'm in the wrong directory. The file Hello.scala is saved in the home directory that I set PATH to.
However I get a different issue when I try to compile code.
scala> scalac Hello.scala
(console):1: error: ';' expected but '.' found.
I actually got my test file to work at one point... but I wasn't actually IN scala.
C:\scala-2.9.1.final\bin> scala Hello.scala
Hello world!
I'm not really sure how to proceed from here. If anyone has any ideas of what may be wrong I would greatly appreciate input.

It appears that you're trying to run & compile programs from within the Scala REPL (read-evaluate-print loop - a kind of Scala interpreter) and you cannot do that in the REPL. The REPL allows you to type in Scala statements and see them execute immediately. (If you're not sure how you entered the REPL, you probably just entered the command scala from the command line.) The REPL is useful for testing ideas, and for experimenting with Scala. For example:
C:\some\path> scala
Welcome to Scala version 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_91).
Type in expressions for evaluation. Or try :help.
scala> println ("Hello!")
Hello!
scala> val x = 10
x: Int = 10
scala> val y = x * 5
y: Int = 50
scala> sys.exit
C:\some\path>
However, the REPL isn't what you would use to compile & run Scala programs - you need to do that from the command line (or from a tool such as sbt). If you want to run your program directly from the command line, without using the REPL (that is, without being in Scala, as you put it) then you would need to do the following:
Firstly, compile your program using scalac:
C:\some\path> scalac Hello.scala
If that succeeds, you can then run the program with the scala command (which looks for a Hello.class file):
C:\some\path> scala Hello
(Here C:\some\path is the location of the files Hello.scala & Hello.class.)
Alternatively, as you have already discovered, you can run your Scala program as a script in the REPL. You can do this from the command line as follows (note the addition of the filetype .scala after Hello compared to the command above):
C:\some\path> scala Hello.scala
or from within the REPL:
scala> :load Hello.scala
Hope this helps!

You don't have to issue scala command when you're inside REPL. If you want to execute code from that file, load it:
here is what I have in Foo.scala
println("I'm foo")
Now I'm starting the REPL (and as you can see scala> is a sign that you're ALREADY into REPL and can start execute raw scala code):
Welcome to Scala version 2.10.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_25).
Type in expressions to have them evaluated.
Type :help for more information.
scala> :load Foo.scala
Loading Foo.scala...
I'm foo

Related

Why ClassNotFoundException from sbt console but not Scala REPL

First I delete the .sbt from my home-directory, then I make an empty project directory, and in that directory I create a build.sbt file:
echo 'ThisBuild / scalaVersion := "3.1.3"' > build.sbt
Then I run sbt console and at the console prompt attempt the following Class.forname() invocation, which produces the following ClassNotFoundException:
[info] welcome to sbt 1.7.1 (Debian Java 11.0.16)
Welcome to Scala 3.1.3 (11.0.16, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.
scala> Class.forName("java.sql.Connection")
java.lang.ClassNotFoundException: java.sql.Connection
at dotty.tools.repl.AbstractFileClassLoader.findClass$$anonfun$1(AbstractFileClassLoader.scala:46
On the other hand, if I start the REPL with the plain-old scala command, then invoke the same forName() I see this:
Welcome to Scala 3.1.3 (11.0.16, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.
scala> Class.forName("java.sql.Connection")
val res0: Class[?] = interface java.sql.Connection
So the same forName() invocation elicits different behavior in the sbt console versus the Scala REPL: a ClassNotFoundException in the former versus returning an instance of the Class class in the latter.
The sbt console also produces that ClassNotFoundException with any of the following lines in the build.sbt file:
classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.AllLibraryJars
or
classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.ScalaLibrary
or even
classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.Flat
What is it about sbt that causes the exception, and how can sbt be made to succeed?

How to pass system properites in comand line to scala 3 executable

With scala 2 it was possible to pass system properties in the command line using -D<propname>=<propvalue> like in the following example:
$scala -Dpath.to.folder=/opt/myfolder
Scala v3 does not accept -D in the command line anymore:
$ scala -Dpath.to.folder=/opt/myfolder
bad option '-Dpath.to.folder=/opt/myfolder' was ignored
Welcome to Scala 3.1.0 (11.0.9.1, Java OpenJDK 64-Bit Server VM).
One possible solution (workaround) is to pass the properties through the environment:
$ env SYS_PROPS="-Dpath.to.folder=/opt/myfolder" scala
Welcome to Scala 3.1.0 (11.0.9.1, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.
scala> println(System.getenv().get("SYS_PROPS"))
-Dpath.to.folder=/opt/myfolder
scala>
How is it possible to pass system properties in the command line of scala 3 executables?
scala --help does not provide any useful info. Actually in scala 3.1.0 scala --help and scalac --help print the same message in the stdout.

How to fire up Scala interpreter with ScalaCheck in the classpath in Ubuntu 11.10?

Scala is installed and working fine.
scalacheck.jar is placed in the /bin .
I used the following command
$ scala -cp scalacheck.jar
After that, when i tried the below command,
scala> import org.scalacheck.Prop.forAll
I got the following error.
<console>:7: error: object scalacheck is not a member of package org
import org.scalacheck.Properties
^
I might have done some mistake in using scalacheck, please correct me and give the proper commands so that I can able to work with scalacheck in Ubuntu in interpreter mode.
Putting executable on the path isn't the same as jar being on the classpath, so your jar being in /bin didn't change anything.
Just use:
scala -cp path_to_your.jar
and you should be fine.
If for example, your scalachek.jar is in /bin then use:
scala -cp /bin/scalacheck.jar
edit:
Putting jars in /bin probably isn't the best idea.
You can use it like this:
kjozsa#walrus:~$ scala -version
Scala code runner version 2.9.2 -- Copyright 2002-2011, LAMP/EPFL
kjozsa#walrus:~$ locate scalacheck.jar
/usr/share/scala/lib/scalacheck.jar
kjozsa#walrus:~$ scala -cp /usr/share/scala/lib/scalacheck.jar
Welcome to Scala version 2.9.2 (OpenJDK 64-Bit Server VM, Java 1.7.0_03-icedtea).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import org.scalacheck.Prop.forAll
import org.scalacheck.Prop.forAll
scala>

Can a Scala script reference other uncompiled scala code in the same directory?

If I have two separate uncompiled scala files in the same directory as:
// hello.scala
object hello {
def world() = println("hello world")
}
and:
// do.scala
hello.world()
I get an error when running do.scala:
$ scala do.scala
error: not found: value hello
Instead I have to compile the hello.scala file first and put it on the classpath to get it to work:
$ scalac hello.scala
$ scala -cp hello do.scala
hello world
Is there a way to get one script to call the other uncompiled scala file using the right use of import, package, classpath, the scala command line tool or something else?
Maybe not exactly what you're looking for, but from the Scala REPL shell you can do
:load hello.scala
:load do.scala
to achieve the same result:
$ scala
Welcome to Scala version 2.9.1 (Java HotSpot(TM) Server VM, Java 1.6.0_26).
Type in expressions to have them evaluated.
Type :help for more information.
scala> :load hello.scala
Loading hello.scala...
defined module hello
scala> :load do.scala
Loading do.scala...
hello world
scala>
If you're wanting something non-interactive for scripting
$ cat <<EOF | scala
:load hello.scala
:load do.scala
EOF
works too.
Use :help for more interesting things the REPL shell can do.
Looking into on the fly compilation/embedding the compiler. Twitter's util-eval is one such example.
You can just put
:load /path/file
at the first line in the file you are going to load.

Scala class path mixup java.lang.NoClassDefFoundError

I'm trying to do something in Scala with apparat library. The library is in /Applications/apparat. Compilation happens OK, imports are OK, but I still get this error when I run it.
scalac -classpath /Applications/apparat/\* SimpleObject.scala
scala -cp . SimpleObject hello.swf
java.lang.NoClassDefFoundError: apparat/utils/TagContainer$
Script:
import apparat.utils.TagContainer
object SimpleObject {
def main(args : Array[String]) : Unit = {
val tags = TagContainer.fromFile( args(0) )
}
}
I'm pretty sure I miss something either when compiling or when running it. If I use command line interpreter then the script works fine and I don't get any erros. For example can do this:
scala -cp /Applications/apparat/\*
Welcome to Scala version 2.8.0.RC3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_22).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import apparat.utils.TagContainer
import apparat.utils.TagContainer
scala> val tag = TagContainer.fromFile("hello.swf")
tag: apparat.utils.TagContainer = apparat.utils.TagContainer#533790eb
Figured it. Need to put current directory into the -cp (:.) as Daniel says when compiling. Also, when running the -cp has to point to same class path.
scala -classpath /Applications/apparat/\*:. SimpleObject hello.swf
though I thought wild cards were not allowed in class paths.