I have a successfully compiled a Java class called bnc.Encryption
in my lib directory: /Users/satchwinston/Development/test/lib
.
I'm using Java 21 and Scala 3.3.1, I'm NOT using the Metals extension.
I execute my Scala script like this: ./encryptor
which in turns runs scala -explain -classpath "/Users/satchwinston/Development/test/lib"
I get the following result:
-- [E006] Not Found Error: /Users/satchwinston/Development/test/scala-cli/src/main/scala/./encryptor:7:7
7 |import bnc.Encryption
| ^^^
| Not found: bnc
|-----------------------------------------------------------------------------
| Explanation (enabled by `-explain`)
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| The identifier for `bnc` is not bound, that is,
| no declaration for this identifier can be found.
| That can happen, for example, if `bnc` or its declaration has either been
| misspelt or if an import is missing.
-----------------------------------------------------------------------------
1 error found
Errors encountered during compilation
Here is my encryptor Scala script:
#!/usr/bin/env scala -explain -classpath "/Users/satchwinston/Development/test/lib"
/* $Id$ */
import java.nio.file.Files
import java.nio.file.Path
import bnc.Encryption
val usage = """
Usage: encryptor ([-e] | [-d]) ([-in filename] | <arg>) > <filename>
"""
def encrypt(string: String): String =
Encryption.encrypt(string)
def decrypt(string: String): String =
Encryption.decrypt(string)
@main def encryptor(args: String*): Unit =
if (args.isEmpty || args.length != 2 || args.length != 3) {
println(usage)
sys.exit(1)
}
val e: Boolean = args(0) == "-e"
val d: Boolean = args(0) == "-d"
val in: String = if (args(1) == "-in") args(2) else ""
val str: String = if (args(1) != "-in") args(1) else ""
if (e && str.length() > 0)
println(encrypt(str))
else if (e)
println(encrypt(Files.readString(Path.of(in))))
else if (d && str.length > 0)
println(decrypt(str))
else if (d)
println(decrypt(Files.readString(Path.of(in))))
else {
println(usage)
sys.exit(1)
}
sys.exit(0)
I was able to make your script work like this:
Addressing what you wrote:
.scala
extension if you are building a "program" rather than a "script" - programs have entrypoints which tells JVM where to start (@main
), while scripts evaluate everything from top to the bottom within a file you are executing (so they do not need any main). Remove@main
, and call your method yourself withargs
and you return to "script" mode@main
exists if Scala CLI is for scripts: it is not only for scripts. Create several.scala
files in a directory, in 1 of them (preferablyproject.scala
) putusing
directives with Scala version, JVM version, platform, dependencies, etc. Thenscala-cli compile .
will build a normal project, which would need an entrypoint if you didscala-cli run .
. These Scala files do need the.scala
extension..scala
or.java
files), can be written as scripts, where their whole body is a main of sort. These files use.sc
extension, although with a shebang you can also use no extension at allcoursier java --available
allows printing all versions that can be used there. Bloop makes sure that you are using a server to keep JVM warm between consecutive calls. You can disable it with a--server=false
flag.-classpath
or--classpath
- there is an--extra-jars
flag for adding JARs (or.class
es) to the runtime, as well as//> using jar
///> using jars
directive for adding a JAR. Because a situation where you have a standalone.class
which is not a part of JAR but also there is no source (which you could add with//> using file filename.java
) is rather rare.