运行Scala脚本时Classpath失效问题求助
我已在目录/Users/satchwinston/Development/test/lib下成功编译了一个名为bnc.Encryption的Java类,使用Java 21和Scala 3.3.1,未启用Metals扩展。通过执行./encryptor运行Scala脚本,该脚本的shebang为#!/usr/bin/env scala -explain -classpath "/Users/satchwinston/Development/test/lib"。
执行后出现以下错误:
-- [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
我的encryptor Scala脚本内容如下:
#!/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)
1. 检查Java类的目录结构
Java类的包名bnc对应实际目录结构,编译后的Encryption.class必须放在/Users/satchwinston/Development/test/lib/bnc/目录下,而非直接放在lib根目录。如果当前lib下只有Encryption.class,需要创建bnc子目录并将class文件移入。
2. 修复shebang参数传递问题
#!/usr/bin/env仅支持单个参数,当前shebang中的scala -explain -classpath "..."会被当作一个整体参数,导致env无法识别。可通过两种方式解决:
方式一:拆分shebang与运行参数
将脚本开头的shebang改为:
#!/usr/bin/env scala
然后通过命令行直接传递参数运行:
scala -explain -classpath "/Users/satchwinston/Development/test/lib" ./encryptor
方式二:用bash脚本包装
创建bash脚本encryptor:
#!/bin/bash scala -explain -classpath "/Users/satchwinston/Development/test/lib" "$0".scala "$@"
将原Scala代码保存为encryptor.scala,给bash脚本添加执行权限:chmod +x encryptor,之后直接运行./encryptor即可。
3. 验证classpath有效性
先通过Scala REPL测试classpath是否正确:
scala -classpath "/Users/satchwinston/Development/test/lib"
进入REPL后尝试执行import bnc.Encryption,若能成功导入,说明classpath和目录结构无问题。
内容的提问来源于stack exchange,提问作者user4202824

