How o run a NetBeans-built Scala application jar from command line outside IDE? - scala

A program of mine (written in Scala 2.8) works fine when launched by means of NetBeans IDE. But when I try to run it from outside, with "java- jar", it says "Exception in thread "main" java.lang.NoClassDefFoundError: scala/ScalaObject...". Putting all the libraries, incl. Scala runtime inside the same dir as the jar to be run doesn't help. If i try to run the jar with scala itself, it complains that it can't decode it as utf-8 (it expects a scala source rather than a jar, I suppose). So how do I run a Scala application at all?
UPDATE: For those who come here later having the same question I'd recommend to read comments under barjak's answer (including those latest ones hidden), the answer is there. VonC also gives some interesting links on the subject.

The -jar and -classpath of the java command are mutually exclusive : you can't do java -jar YourScalaProg.jar -classpath scala-library.jar
If you want to run your application with java -jar, then the full classpath must be specified in the Class-Path section of the jar's manifest.
You can run your application using only -classpath, like that : java -classpath YourScalaProg.jar:scala-library.jar your.package.MainClass.

Are you using scala-library.jar as described in Adventures with Scala blog post?
java -classpath scala-library.jar:. YourClass
or:
java -classpath scala-library.jar:yourApp.jar YourClass
Where YourClass is was your scalac compiled Scala code.
You will find the same scala-library.jar used in the SO question "Creating a jar file from a Scala file" (or in the blog post "the not so elegant way of creating an executable jar from scala code").

Related

No such file or class on classpath: com.<name>.<abc>.<classname> when executing scala jar using command line

I am getting the
No such file or class on classpath: com
when executing the scala uber jar using the below command.
scala -classpath kafka-scala-1.0-SNAPSHOT.jar com.< name >.< abc >.KafkaAggregateConsumerApp
I am using scala 2.11.12
From the error it looks like you might have a space after the com in your command. Re-check that please.
Also, if you already have an uber jar you can run the jar directly using the java command.
java -cp kafka-scala-1.0-SNAPSHOT.jar com.foo.bar.KafkaAggregateConsumerApp

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.

Run junit4 test from cmd

I tried to run junit4 test case from command line using:
java -cp junit-4.8.1.jar;test\Dijkstra;test\Dijkstra\bin org.junit.runner.JUnitCore Data0PathTest00
but I got the following error:
java.lang.NoClassDefFoundError: graph/shortestgraphpath;
while the test case is working without any problems in eclipse.
Hint: in eclipse, shortestgraphpath was added in Referenced Libraries.
You need to the jar file containing shortestgraphpath to java class path.
java -cp junit-4.8.1.jar;test\Dijkstra; test\Dijkstra\bin org.junit.runner.JUnitCore Data0PathTest00
The class path is the value that you pass to java with -cp so in your question you just supply junitand your compiled classes.
Try updating it with the jar file with the missing class.
java -cp junit-4.8.1.jar;<path to jar file>;test\Dijkstra;test\Dijkstra\bin org.junit.runner.JUnitCore Data0PathTest00
You might have to add additional jar files as well. I recommend that you take a look at some build tool to help you build and run your java applications for example Maven, Gradle, Buildr.

Scala SBT: standalone jar

The answer: Making stand-alone jar with Simple Build Tool seems like what I need, but it did not have enough information for me, so this is a followup.
(1) How do I adapt the answer to my need? I don't understand what would need to be changed.
(2) What command do I run to create the standalone jar?
(3) Where can I find the jar after it has been created?
What I've tried:
Pasting the code in the linked answer verbatim into my: project/build/dsg.scala file. The file now has a
class ForkRun(info: ProjectInfo) extends DefaultProject(info)
(from before, used for running projects in a separate VM from SBT) and the new:
trait AssemblyProject extends BasicScalaProject
from the linked answer.
I also tried pasting the body (all defs and the lazy val of the AssemblyProject into the body of ForkRun.
To create a jar I ran package at the SBT prompt and get:
[info] Packaging ./target/scala_2.8.1/dsg_2.8.1-1.0.jar ...
[info] Packaging complete.
So I tried running the dsg_2.8.1-1.0.jar from the shell via:
java -jar dsg_2.8.1-1.0.jar
But I get:
Failed to load Main-Class manifest attribute from
dsg_2.8.1-1.0.jar
Could this be caused by having multiple entry points into my project? I select from a list when I execute run from the SBT prompt. Perhaps I need to specify the default when creating the package?
Here's a writeup I did on one way to make an executable jar with SBT:
http://janxspirit.blogspot.com/2011/01/create-executable-scala-jar-with-sbt.html
sbt-assembly is a sbt plugin to create a standalone jar of Scala sbt project with all of its dependencies.
Refer this post for more details with an example.

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.