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.
Related
I have a Scala application that successfully runs on the JVM using an uber jar via the command: java -jar myapp.jar. I need to create a separate, but related Scala job that utilizes many of the same objects/functions/dependencies as the first, making it a great candidate to keep in the same code repository & uber jar. Please note that these Scala jobs do not utilize Spark, so spark2-submit is out of the equation.
Question: How can I run 2 separate Scala jobs from the same uber jar on the JVM? (I am using Scala 2.11.8 and SBT for jar assembly)
Additional Context:
I've already looked into related StackOverflow discussions, namely this post about specifying Java classes using java -cp myapp.jar MyClass and this post, which only presented the solution of running the Scala equivalent using scala -classpath myapp.jar MyClass.
While the scala -classpath solution may have worked for the OP of the second linked discussion, I'll be deploying my code to an environment that doesn't have executables for scala or sbt, only java.
Let's say these are the 2 Scala jobs I want to run:
// MyClass.scala
package mypackage
object MyClass {
def main(args: Array[String]): Unit = {
println("Hello, World!")
}
}
// MyClass2.scala
package mypackage
object MyClass2 {
def main(args: Array[String]): Unit = {
println("Hello, World! This is the second job!")
}
}
Is there a way to run Scala code using java -cp myapp.jar MyClass?
I've tried this and receive the following error:
Error: Could not find or load main class MyClass
The main alternative I can think of would be to create a Scala object that serves as a main entry point and takes a parameter to determine which job gets run. I'd like to avoid that solution if possible, but it would allow me to continue using java -jar myapp.jar, which has been working fine.
You need to use a fully qualified name for the App instance:
java -cp myapp.jar mypackage.MyClass
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.
I am attempting to use ScalaCheck. Below is my HelloWorld.scala Scala code which imports from ScalaCheck and uses the Gen.const method.
package com
import org.scalacheck._
import org.scalacheck.Gen._
import org.scalacheck.Arbitrary.arbitrary
sealed abstract class Tree
case class Node(left: Tree, right: Tree, v: Int) extends Tree
case object Leaf extends Tree
object HelloWorld {
val genLeaf = Gen.const(Leaf)
def main(args: Array[String]) {
println("Hello, world!")
}
}
Compile by typing (this works)
scalac -cp scalacheck_2.11-1.11.5.jar com/HelloWorld.scala
Execute by typing (2 alternatives)
scala -cp scalacheck_2.11-1.11.5.jar com.HelloWorld
scala -cp "scalacheck_2.11-1.11.5.jar;./com" com.HelloWorld
Output of scala
No such file or class on classpath: com.HelloWorld
When I remove all ScalaCheck code in HelloWorld.scala and compile without using the -cp flag everything works. When adding the ScalaCheck code and the jar to the -cp flag, I get the above error.
How do I correctly setup the classpath?
(Versions:
scalac -version
Scala compiler version 2.11.2 -- Copyright 2002-2013, LAMP/EPFL
scala -version
Scala code runner version 2.11.2 -- Copyright 2002-2013, LAMP/EPFL
)
OS: Linux
Which OS are you using? If not Windows, the path separator should be :, try this
scala -cp "scalacheck_2.11-1.11.5.jar:." com.HelloWorld
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
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>