Can compile Scala programs but can't run them - scala

I am able to compile scala programs using scalac in terminal but I get the warning.
Charless-Macintosh:src Charles$ scalac hello.scala
Charless-Macintosh:src Charles$ scala HelloWorld
No such file or class on classpath: HelloWorld
Is this to do with .profile on scala. I'm pretty confused as to what is happening. Many thanks

The current directory is typically not in the classpath by default. So you need to give explicitly:
$ scala -cp . HelloWorld

The problem is that you have set the CLASSPATH environment variable.
From > man scalac:
The default class path is the current directory. Setting the CLASSPATH variable or using the -classpath command-line option overrides that default, so if you want to include the current directory in the search path, you must include "." in the new settings.
When you have the CLASSPATH variable set, scala will not include the current directory in its search, you must explicitly add it. This is why scala -cp . HelloWorld works.
To verify, perform echo CLASSPATH and it should give some non-empty string. Check your .bashrc/.zshrc files for any export CLASSPATH=... and remove these lines.

This was also happening to me but I think the better solution is to modify the CLASSPATH variable to include the current directory in addition to what you already had. e.g.
export CLASSPATH=.:$CLASSPATH
Now, you can simply use scala HelloWorld without that additional argument.

Related

Making jar files available to the scala REPL

I can't seem to get this to work, so i have tried what's probably the most straightforward case--ie, retrieve the jar file and into a given directory then start the scala REPL from that directory--still no luck.
I know the jar files are fine and correctly references (eg, i can access them from project directories via eclipse/scala ide)
I also know that my import statements (one is shown below) are valid.
cd ~/my_scala_jars
retrieve the artifact from the maven repo
wget -q -nd -np -r \
http://repo1.maven.org/maven2/org/scalaz/scalaz-core_2.12.0-M1/7.1.2/scalaz-core_2.12.0-M1-7.1.2.jar
start the scala REPL and add the jar to the REPL classpath:
scala -cp scalaz-core_2.12.0-M1-7.1.2.jar
scala> import scalaz.stream.io
<console>:7: error: object stream is not a member of package scalaz
import scalaz.stream.io
in case it's useful, trying this with different jars (that i downloaded as i showed with scalaz above) will sometimes cause the REPL to throw a not found error instead
scala> import breeze.linalg._
<console>:7: error: not found: value breeze
import breeze.linalg._
it seems to me that the REPL should recognize these jars because the directory has been added to my CLASSPATH, but also because i believe the current directory is also added to the classpath (at least during the REPL session)--and still both fail.
I am not sure why the jar files are not picked up as I haven't really tried to do that. What I do, and find useful, is to create a number of build.sbt files for specific purposes, e.g. for working with a specific suite of libraries at a REPL.
If you do this, and then launch a REPL using the command sbt console, from the directory containing the appropriate build.sbt, then you can have a console with the libraries you want available on the classpath to that console.
This might not be ideal, but it does work and I find it quite useful.

Add multiple classpath entries to scala REPL classpath

:cp seems to only accept a single entry
scala> :cp /usr/lib/hadoop/*:/usr/lib/hadoop/lib/*:/usr/lib/hbase/*:/usr/lib/hbase/lib/*:
/home/sboesch/spark-master/lib_managed/jars/*:/home/sboesch/spark-master/lib_managed/bundles/*:
The path '/usr/lib/hadoop/*:/usr/lib/hadoop/lib/*:/usr/lib/hbase/*:/usr/lib/hbase/lib/*:/home/sboesch/spark-master/lib_managed/jars/*:/home/sboesch/spark-master/lib_managed/bundles/*:'
doesn't seem to exist.
Any thoughts on how to do this when already in the REPL. Yes I know how to set it up from outside the REPL :
CLASSPATH=/usr/lib/hadoop/*:/usr/lib/hadoop/lib/*:/usr/lib/hbase/*:/usr/lib/hbase/lib/*
:/home/sboesch/spark-master/lib_managed/jars/*:
/home/sboesch/spark-master/lib_managed/bundles/*: scala
EDIT It seems the intent were not clear. I am working on code in the REPL. Then have a new snippet of code that requires a few classpath entries. It is a ONE OFF affair: so I do not want to add to build.sbt or to the scala/lib dir , etc. I did not receive any answer really satisifying this use case, but awarded the best efforts anyways.
scala -cp "path1:path2" now seems to work.
scala -version Picked up _JAVA_OPTIONS: -Xms512m -Xmx4096m
-XX:MaxPermSize=1024m -XX:ReservedCodeCacheSize=128m Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=1024m; support
was removed in 8.0 Scala code runner version 2.11.8 -- Copyright
2002-2016, LAMP/EPFL
The help text for :cp says:
:cp <path> add a jar or directory to the classpath
So I'm guessing there's no exact way for you to get that. I'd use this:
:load <path> interpret lines in a file
I confirmed that it works for REPL commands as well as Scala code.
Addendum:
If you use SBT then all your projects dependencies are in the class-path for the REPL launched by SBT's console task.
A quick and dirty approach, add a link from $SCALA_HOME/lib/ to a folder with additional jar files. Then from REPL you can import packages of interest.

Compiling a scala class and make it available in Scala Context

I have a class written in Scala and I am trying to make it available to the Scala Context so that I can make use of it for further processing. The problem is that I need to run this from the shell and I am having a hard time figuring out how to compile the class and make it available to the context.
I am aware of compiling the class and making use of directly, but I am not able to figure out how to do the same on the Scala shell. Any pointers in this regard would be great.
In the Scala REPL you can use the command :cp <path> to add a directory or JAR (that contains your compiled Scala class) to the classpath, so that it is available for the REPL to use.
(Ofcourse, replace <path> in that command with the actual directory or JAR path).
To see what other commands are available in the Scala REPL, use the command :help.

How can scala see classes from files in command line mode?

Say, I have an eclipse project located in D:\DanHenderson\scala\MyProject. MyProject has 2 directories: src and bin. In src I have scala code itself, it might be some classes or an application. So how can I use those classes or run whole application from command line? I.e., there is a file with class A, and I want to have a possibility to type val a = new A in command line. How can I do this?
By command line I assume you mean the Scala REPL. Add the directory of your class files to the classpath when starting the Scala REPL:
scala -classpath "path to some dir where your .class files reside"
Note that if your project relies on some libraries then those need to be on the classpath as well.

Scala : trying to get log4j working

Scala newb here (it's my 2nd day of using it). I want to get log4j logging working in my Scala script. The script and the results are below, any ideas as to what's going wrong?
[sean#ibmp2 pybackup]$ cat backup.scala
import org.apache.log4j._
val log = LogFactory.getLog()
log.info("started backup")
[sean#ibmp2 pybackup]$ scala -cp log4j-1.2.16.jar:. backup.scala
/home/sean/projects/personal/pybackup/backup.scala:1: error: value apache is not a member of package org
import org.apache.log4j._
^
one error found
I reproduce it under Windows: delimiter of '-classpath' must be ';' there (not ':'). Are you use cygwin or some sort of unix emulator?
But Scala script works anywhere without current dir in classpath. Try to use:
$ scala -cp log4j-1.2.16.jar backup.scala
JFI: LogFactory is a class of slf4j library (not log4j).
UPDATE
Another possible case: broken jar in classpath, maybe during download or something else. Scala interpreter does report only about unavailable member of the package.
$ echo "qwerty" > example.jar
$ scala -cp example.jar backup.scala
backup.scala:1: error: value apache is not a member of package org
...
Need to inspect content of the jar-file:
$ jar -tf log4j-1.2.16.jar
...
org/apache/log4j/Appender.class
...
Did you remember to put log4j.jar in your classpath?
Had Similar issue when started doing Scala Development using Eclipse, doing a clean build solved the problem.
Guess the Scala tools are not matured et.
Instead of using log4j directly, you might try using Configgy. It's the Scala Way™ to work with log4j, as well as configuration files. It also plays nicely with SBT and Maven.
I asked and answered this question myself, have a look:
Put it under src/main/resources/logback.xml. It will be copied to the right location when SBT is doing the artifact assembly.