英文:
What is the Scala classpath?
问题
我一直在尝试在我的项目中使用一个名为 PasswordHash.jar
的 JAR 文件。我正在使用 sbt
,所以我将该 JAR 文件放在 lib/
目录下。现在它已经在类路径中,但我不知道这是什么意思。
我尝试过:
import PasswordHash
import PasswordHash.jar
import com.PasswordHash
import com.PasswordHash.jar
import org.PasswordHash
import org.PasswordHash.jar
import java.PasswordHash
import java.PasswordHash.jar
import jar.PasswordHash
该 JAR 文件是从一个没有 package
声明的 Java 文件构建而来。
编辑:
Scala 文件:
~/FileShare/shared/src/main/scala/com/michael/fileshare/shared/Collatz.scala
package com.michael.fileshare.shared
import com.michael.fileshare.shared.PasswordHash
Java 文件:
~/FileShare/shared/src/main/java/com/michael/fileshare/shared/PasswordHash.java
package com.michael.fileshare.shared
错误消息:
object PasswordHash 不是包 com.michael.fileshare.shared 的成员
这个 Scala 文件未能成功导入这个 Java 文件,但另一个 Scala 文件成功导入了这个 Scala 文件。
如果有帮助的话,我使用的是 Ubuntu Focal。
英文:
I've been trying to use a jar called PasswordHash.jar
in my project. I am using sbt
, so I put the jar in lib/
. Now it is in the classpath, but I don't know what that means.
I've tried:
import PasswordHash
import PasswordHash.jar
import com.PasswordHash
import com.PasswordHash.jar
import org.PasswordHash
import org.PasswordHash.jar
import java.PasswordHash
import java.PasswordHash.jar
import jar.PasswordHash
The jar was built from a Java file which didn't have a package
statement.
EDIT:
Scala file:
~/FileShare/shared/src/main/scala/com/michael/fileshare/shared/Collatz.scala
package com.michael.fileshare.shared
import com.michael.fileshare.shared.PasswordHash
Java file:
~/FileShare/shared/src/main/java/com/michael/fileshare/shared/PasswordHash.java
package com.michael.fileshare.shared
Error message:
object PasswordHash is not a member of package com.michael.fileshare.shared
The Scala file unsuccessfully tries to import the Java file, but a different Scala file successfully imports this Scala file.
If it helps, I'm on Ubuntu focal.
答案1
得分: 5
import foo.bar.x;
的意思非常简单:
“在这个源文件中,任何时候只要提到类型x
,就假定它是foo.bar.x
”,这就是它的全部含义。它并不意味着在导入语句被“运行”时从磁盘加载文件(实际上,导入语句根本不会被“运行”),如果你从未提到过x
,它就是一个字面上的无操作。
在Scala中基本上是一样的,尽管诸如隐式转换之类的东西会被处理,如果我没记错的话。
所有的import x.jar
语句都是错误的,import
不是你做那个的方式,那仅仅是命名类型的快捷方式,仅此而已。定位表示该类型的类文件的工作__不是源文件的一部分__ - 它是构建过程的一部分,即传递给javac
或scalac
的参数。
那么,解决方案是什么?
你在这里犯了多个错误。第一个错误是没有包的类__根本无法被导入__。你必须有一个包声明。
第二个错误是在编译Scala文件时,类文件必须在类路径中。类路径的规则如下:类路径中的每个条目都是一个目录或一个jar文件。然后,包对应目录。
所以,如果你有:
import com.foo.PassHash;
public class Example {
PassHash hash = new PassHash();
}
并且你的类路径是,比如:javac -cp whatever/x.jar Example.java
,那么whatever/x.jar
必须存在,必须是一个jar文件(或目录),并且在该jar文件或目录中,必须有一个名为com
的目录,其中包含一个名为foo
的目录,其中包含一个名为PassHash.class
的文件。一旦你有了这个,上面的代码就会编译通过,在Scala中类似。
英文:
import foo.bar.x;
means something very very simple:
"In this source file, any time any mention of a type is just x
, assume it reads foo.bar.x
", and that is all it means. It doesn't mean that a file is loaded from disk when the import statement is 'run' (in fact, an import statement isn't "run" at all), and it is a literal no-op if you never mention x.
In scala it's mostly the same, though stuff like implicits are processed IIRC.
All your import x.jar
statements are definitely wrong, import
is not how you do that, at all. You just name type shortcuts, that's all that does. The job of locating the class file with the representation of that type is not part of your source file - it's part of the build, i.e., the arguments passed to javac or scalac.
Okay, what's the solution?
you've made multiple errors here. The first one is that package-less classes cannot be imported at all. You MUST have a package declaration.
The second is that the class file must then be in the classpath as you compile your scala file. The rule for class path is as follows: Each entry in a classpath is either a directory or a jar file. Then, packages follow directories.
So, if you have:
import com.foo.PassHash;
public class Example {
PassHash hash = new PassHash();
}
and your classpath is, say: javac -cp whatever/x.jar Example.java
, then whatever/x.jar
must exist, must be a jar file (or directory), and within that jar file or directory, there needs to be a directory named com
, containing a directory named foo
, containing a file named PassHash.class
. Once you have that, the above will compile fine, and it's analogous in scala.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论