什么是Scala类路径?

huangapple go评论78阅读模式
英文:

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不是你做那个的方式,那仅仅是命名类型的快捷方式,仅此而已。定位表示该类型的类文件的工作__不是源文件的一部分__ - 它是构建过程的一部分,即传递给javacscalac的参数。

那么,解决方案是什么?

你在这里犯了多个错误。第一个错误是没有包的类__根本无法被导入__。你必须有一个包声明。

第二个错误是在编译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.

huangapple
  • 本文由 发表于 2020年8月15日 05:36:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/63420296.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定