Why can't scala find what sbt can? - scala

With sbt everything is fine:
» sbt console
[info] Loading project definition from /repos/myrepo/project
[info] Set current project to bpavscan (in build file:/repos/myrepo/)
[info] Starting scala interpreter...
[info]
Welcome to Scala 2.11.8 (OpenJDK 64-Bit Server VM, Java 1.8.0_131).
Type in expressions for evaluation. Or try :help.
scala> import play.api.libs.json._
import play.api.libs.json._
scala>
But if I do it with the scala tool:
» scala
Welcome to Scala version 2.11.6 (OpenJDK 64-Bit Server VM, Java 1.8.0_131).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import play.api.libs.json._
<console>:7: error: not found: value play
import play.api.libs.json._
^
scala>
I need to run a simple script, which I usually do with:
scala myscript.scala
But since now my script has a play dependency, I can not run it with scala anymore, since scala does not find play.
I need to either:
Be able to load the play framework with the simple scala tool
Be able to run a simple script with sbt: sbt run runs my project, which I do not want. I want to run a simple script (to try out some simple things)

sbt console with load the same console/REPL as of scala but with additional loaded dependencies defined in build.sbt. So before loading the console, all the dependent libraries are added. And this is reason you could import play libraries while using sbt console.
On the other hand scala starts the console with the libraries inside scala-package of the system. Thus needs additional jars being included inside the package for importing. For the above case if play library jar was included in scala directory then import play.api.libs.json._ should have worked for scala console too.

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?

Why I am not able to find spark.implicits._ in scala REPL / Shell?

I am on MacOS.
scala> import spark.implicits._
^
error: not found: value spark
WHY?
scala
Welcome to Scala 2.13.2 (OpenJDK 64-Bit Server VM, Java 13.0.2).
Type in expressions for evaluation. Or try :help.
java -version
openjdk version "14.0.1" 2020-04-14
OpenJDK Runtime Environment (build 14.0.1+7)
OpenJDK 64-Bit Server VM (build 14.0.1+7, mixed mode, sharing)
How to solve this problem?
If I try spark-shell
scala> import spark.implicits._
Works fine.
If you're running the scala repl you have to add the jar to the classpath by executing:
:require <path-to-jar>
Importation in Scala is a mechanism that enables more direct reference of different entities such as packages, classes, objects, instances, fields and methods.
import spark.implicits._ are provided by the Spark includes and various libraries for the Spark api, program, run-time, classes whatever you want to call it.
scala inside Spark is simply the interface for using spark-shell, it can be java, scala or python known as pyspark then.
scala on its own has no notion of where to get that specific import from, i.e. not in the scala supplied binaries, apis, methods, classes, libraries.
If using tools like SBT, IntelliJ then you provide dependencies that allow that import to be found, resolved.

Scala sbt jar allows import when class path is passed on command line, but not in REPL

I've built a small test jar with Scala and SBT. If I put the classpath argument on the Scala REPL command line, it imports the package perfectly. However if I get into the shell and then add the classpath, it does not recognize the import. Being new to Scala this confuses me so I hope someone can explain. I'll try to provide enough information without going overboard.
scala -cp configparser_2.10-1.0.jar
Welcome to Scala version 2.10.4 (OpenJDK 64-Bit Server VM, Java 1.7.0_75).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import com.oaktreepeak.util._
import com.oaktreepeak.util._
scala> val c = new OakConfig()
c: com.oaktreepeak.util.OakConfig = com.oaktreepeak.util.OakConfig#58d9a418
Now I'll wait and load the classpath to the jar after I'm in the shell:
scala
Welcome to Scala version 2.10.4 (OpenJDK 64-Bit Server VM, Java 1.7.0_75).
Type in expressions to have them evaluated.
Type :help for more information.
scala> :cp configparser_2.10-1.0.jar
Added '/home/*****/Dyn/projects/DynECT2/scala/common/ConfigParser/test-configs/configparser_2.10-1.0.jar'. Your new classpath is:
".:/home/*****/Dyn/projects/DynECT2/scala/common/ConfigParser/test-configs/configparser_2.10-1.0.jar"
Nothing to replay.
scala> import com.oaktreepeak.util._
<console>:7: error: object oaktreepeak is not a member of package com
import com.oaktreepeak.util._
^
scala>
Here is my build.sbt file:
name := "ConfigParser"
version := "1.0"
scalaVersion := "2.10.4"
organization := "com.oaktreepeak"
And the single Scala source file:
package com.oaktreepeak.util
import scala.io._
import scala.util.parsing.json._
class OakConfig {
var iRollupAfter: Int = -1;
def Load(sPath: String) {
val config = Source.fromFile(sPath).mkString
val json:Option[Any] =JSON.parseFull(config)
val map:Map[String,Any] = json.get.asInstanceOf[Map[String, Any]]
iRollupAfter = map.get("RollupAfter").get.asInstanceOf[Double].toInt
}
}
Anyone have any ideas or explanations?
Thanks
:cp was broken in Scala 2.10, and has been replaced with (a working) :require in Scala 2.11.
If you're new to Scala I would recommend using the latest, stable version of Scala, which currently is 2.11.6.
Also, as you're new to Scala, if you want to try things out from your project in the REPL (which is a great workflow) from sbt just run console, which will compile your code and give you REPL with all of Scala's classes, your projects classes and the classes for all your dependencies! No need to feed manually feed the REPL a classpath.

Using eval to println elements of library-dependencies in SBT 0.12.x shell

Trying to master SBT and Scala makes my live tough at times when simple things in theory turn themselves into not so simple in practise.
I'm working with Apache Spark 0.9.0-incubating that uses SBT 0.12.4.
While poking around in their SBT build configuration I ran across an issue of how to println elements of library-dependencies in SBT (interactive) shell. It's a more general question of how to eval more complex Scala expressions in sbt shell?
> external-mqtt/library-dependencies
[info] List(org.scala-lang:scala-library:2.10.3, io.netty:netty-all:4.0.13.Final, org.eclipse.jetty:jetty-server:7.6.8.v20121106, org.eclipse.jetty.orbit:javax.servlet:2.5.0.v201103041518, org.scalatest:scalatest:1.9.1:test, org.scalacheck:scalacheck:1.10.0:test, com.novocode:junit-interface:0.9:test, org.easymock:easymock:3.1:test, org.mockito:mockito-all:1.8.5:test, commons-io:commons-io:2.4:test, commons-io:commons-io:2.4, org.eclipse.paho:mqtt-client:0.4.0)
I managed to do the following
> eval libraryDependencies in externalMqtt
[info] ans: sbt.SettingKey[Seq[sbt.ModuleID]] = sbt.Scoped$$anon$1#aa3170e
but am struggling with getting the Seq[sbt.ModuleID] out of sbt.SettingKey.
A concise explanation on how to proceed would be very appreciated. Thanks.
Instead of you using eval, if you first drop into:
consoleProject
then you can attach .eval to settings, so e.g.
> consoleProject
[info] Starting scala interpreter...
[info]
import sbt._
import Keys._
import currentState._
import extracted._
import cpHelpers._
Welcome to Scala version 2.10.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_51).
scala> (fullClasspath in Compile).eval.foreach(println)
Attributed(/Users/tisue/Dropbox/repos/euler/target/scala-2.10/classes)
Attributed(/Users/tisue/.sbt/boot/scala-2.10.3/lib/scala-library.jar)
This doesn't answer your question directly; I don't know how to make eval do what you want. As documented at http://www.scala-sbt.org/release/docs/Detailed-Topics/Console-Project.html , and as actually visible in the above transcript, consoleProject does a number of imports that bring useful names and implicits into scope, which is what makes the above work. You might expect that eval would evaluate code you pass it in a context where the same identifiers and implicits are in scope, but it doesn't. (I tried putting the same imports into a call into eval but it didn't work.)
Not the greatest answer — perhaps someone else can be more authoritative.

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>