0

I'm trying to run some scala codes from the book "Scala in Action". Here are the codes:

MongoClient.scala:

package com.scalainaction.mongo

import com.mongodb._

class MongoClient(val host: String, val port: Int){
    require(host != null, "You have to provide a host name")
    private val underlying = new Mongo(host, port)
    def this() = this("127.0.0.1", 27017)

    def version = underlying.getVersion
    def dropDB(name: String) = underlying.dropDatabase(name)
    def createDB(name: String) = DB(underlying.getDB(name))
    def db(name: String) = DB(underlying.getDB(name))
}

DB.scala:

package com.scalainaction.mongo

import com.mongodb.{DB => MongoDB}
import scala.collection.convert.Wrappers._

class DB private(val underlying: MongoDB) {
    def collectionName = for(name <- new
    JSetWrapper(underlying.getCollectionNames)) yield name
}

object DB {
    def apply(underlying: MongoDB) = new DB(underlying)
}

test.scala:

package com.scalainaction.mongo

import com.scalainaction.mongo._

class test{
    def client = new MongoClient
    def db = client.createDB("mydb")

    for (name <- db.collectionName) println(name)
}

After compiling using

scalac -cp /.../mongo-java-driver-2.11.3.jar MongoClient.scala DB.scala test.scala

I got:

MongoClient.scala:7: warning: constructor Mongo in class Mongo is deprecated: see corresponding Javadoc for more information.
    private val underlying = new Mongo(host, port)
                                 ^
one warning found

It seems OK(?). But after invoking

scala -cp /.../mongo-java-driver-2.11.3.jar -deprecation  test.scala

it showed:

/.../test.scala:1: error: illegal start of definition
package com.scalainaction.mongo
^
one error found

How can I run test.scala without error? Thanks a lot for your help!

0__
  • 66,707
  • 21
  • 171
  • 266
Pauli
  • 1,159
  • 1
  • 11
  • 22

1 Answers1

2

With scala ... test.scala, you are running test.scala in script mode. That doesn't allow a package definition. You have two options: Either you format test.scala according to script requirements, or you write a full class (which seems you are intending) and run scala ... test just with the class name.

If you run man scala, you can see the explanation of the difference:

The scala utility runs Scala code using a Java runtime environment. The Scala code to run is specified in one of three ways:

  1. With no arguments specified, a Scala shell starts and reads commands interactively.

  2. With -howtorun:object specified, the fully qualified name of a top-level Scala object may be specified. The object should previously have been compiled using scalac(1).

  3. With -howtorun:script specified, a file containing Scala code may be specified.

If -howtorun: is left as the default (guess), then the scala command will check whether a file of the specified name exists. If it does, then it will treat it as a script file; if it does not, then it will treat it as the name of an object.

The last paragraph is significant.


First the second case, using a full class:

To run the compiled class, the following should work:

scala -cp /.../mongo-java-driver-2.11.3.jar:. test

This is shorthand for the following more verbose call:

java -cp /.../mongo-java-driver-2.11.3.jar:/path/to/scala/scala-library.jar:. test

But you still need to make an adjustment for that to work—you need a main class object. The following should do

object test extends App { ... }  // instead of class test { ... }

Alternatively, remove the package declaration and the test class definition, and just put the contents of the test body into test.scala which should run fine using the script engine.


A good starting point is the Getting Started article from the main Scala site. If you read up on Odersky's "Programming in Scala" (the first edition is freely available on the internet), section 4.4 covers compiling a full application class, whereas script mode is explained in chapter 2 step 4.

0__
  • 66,707
  • 21
  • 171
  • 266