gpt4 book ai didi

java CLASSPATH 不能在命令行上工作

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:04:06 25 4
gpt4 key购买 nike

系统详情:

Ubuntu 17.10
openjdk version "1.8.0_151"
OpenJDK Runtime Environment (build 1.8.0_151-8u151-b12-0ubuntu0.17.10.2-b12)

我的 java 程序无法运行。我不知道为什么它找不到类(class)。它使用 -classpath 标志编译,但在运行时找不到类。

$ ls -ltra
total 668
-rw-rw-r-- 1 bvpx bvpx 653275 Jan 19 14:45 javax.mail.jar
drwxr-xr-x 3 bvpx bvpx 4096 Jan 19 14:59 ..
-rw-r--r-- 1 bvpx bvpx 960 Jan 19 15:07 Example.java
drwxr-xr-x 2 bvpx bvpx 4096 Jan 19 15:07 .

没有 -classpath 的编译不起作用(我认为 -classpath 默认为 .?)

$ javac Example.java 
Example.java:2: error: package javax.mail does not exist

指定 -classpath 有帮助,程序现在编译并生成 Example.class:

$ javac -classpath javax.mail.jar Example.java
$

这是源代码:

import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;

public class Example {
static final int PORT = 587;
/* ... */

public static void main(String[] args) throws Exception {
/* ... */
Transport transport = session.getTransport();
try
{
System.out.println("Sending...");
transport.connect(HOST, SMTP_USERNAME, SMTP_PASSWORD);
transport.sendMessage(msg, msg.getAllRecipients());
System.out.println("Email sent!");
}
catch (Exception ex) {
System.out.println("Error message: " + ex.getMessage());
}
}
}

运行程序产生这个错误:

$ java -Xdiag -classpath javax.mail.jar Example 
Error: Could not find or load main class Example
java.lang.ClassNotFoundException: Example
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:495)

在没有 -classpath 的情况下运行 java 会导致 JNI 找不到 javax/mail,即使它在目录中也是如此。

$ java -Xdiag Example 
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: javax/mail/Address
at java.lang.Class.getDeclaredMethods0(Native Method)

为什么java找不到Example类?

最佳答案

您似乎在这里遗漏了一些基本概念。

类路径给出了目录和 JAR 文件的列表,用于搜索所需的类。当尝试加载不属于标准库的类 foo.bar.MyClass 时,默认类加载器将依次在每个类路径元素中查找它,直到找到类或元素用完。

但是请注意,它按完全限定名称进行搜索。对于作为目录的类路径条目,这意味着它会查找相对于目录的 foo/bar/MyClass.class。对于作为 JAR 文件的类路径条目,它会查找相对于 JAR 根目录的 foo/bar/MyClass.class。属于未命名默认包的类有点特殊,或者看起来可能是这样,因为它们的类文件(例如 InDefaultPackage.class)预计直接位于指定 JAR 的根目录或直接在指定目录下。

Compiling without -classpath does not work (I thought -classpath defaulted to .?)

$ javac Example.java 
Example.java:2: error: package javax.mail does not exist

类路径确实默认为.。这是目录的名称,因此当在其中搜索 javax.mail 包中的类时,它会查找子目录 javax/mail,如果是找到后,它会检查其中的类文件。请注意,它不会进入它在目录树中发现的 JAR 文件。它只在类路径中明确命名的那些 JAR 中查找。

错误消息告诉您 javac 根本没有从 javax.mail 包中找到任何类。您可以通过在编译类路径中指定 JAR(正如您最终所做的那样)或通过在当前目录中解压缩 JAR 来解决它。

Specifying the -classpath helps, the program now compiles and produces Example.class:

$ javac -classpath javax.mail.jar Example.java
$

请注意,编译器会将类文件存储在与其包相对应的目录结构中,java 命令将在其中查找它。

Running the program produces this error:

$ java -Xdiag -classpath javax.mail.jar Example 
Error: Could not find or load main class Example
java.lang.ClassNotFoundException: Example
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:495)

您在回答中阐明,您通过从 Example.java 中删除 package 语句解决了这个问题。没关系,但这并不能真正解释问题,即 java 希望您为它提供类的完全限定 名称。如果类在命名包中,则包括包名称。因此,如果 Example.java 包含此包语句:

package com.my;

那么您需要指定给 java 的类名将是 com.my.Example。您只指定了 Example,它在默认包中指定了一个名为“Example”的类,您解决类未找到问题的方法是将您的类移动到默认包中。

另请注意,将 Java 源文件放置在与其包结构相匹配的目录结构中也是一种常规且有帮助的做法。因此,类 com.my.Example 的源文件通常位于 com/my/Example.java 中。 Java 编译器将依赖此方案来定位它找不到的类的源代码。

Running java without -classpath causes the JNI to not find javax/mail even though it's in the directory.

$ java -Xdiag Example 
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: javax/mail/Address
at java.lang.Class.getDeclaredMethods0(Native Method)

不,javax/mail/Address 不在目录中。它在目录中的一个 JAR 文件中。这根本不是一回事,差异很大。

关于java CLASSPATH 不能在命令行上工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48348922/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com