繁体   English   中英

Java CLASSPATH在命令行上不起作用

[英]java CLASSPATH not working on command-line

系统细节:

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程序。 我不知道为什么找不到班。 它使用-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类?

我必须设置-classpath以包括当前目录。 根据文档, classpath:分隔。 正确的类路径字符串为:

javax.mail.jar:.

下面是一个工作示例。

$ javac -classpath javax.mail.jar:. Example.java  
$ java -classpath javax.mail.jar:. Example 
Sending...
Email sent!

还要注意的另一件事是,Example.java的顶部最初有一个package定义。 我不得不将其删除。

您似乎在这里缺少了一些基本概念。

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

但是请注意,它按完全限定的名称进行搜索。 对于作为目录的类路径条目,这意味着它将查找相对于目录的foo/bar/MyClass.class 对于作为JAR文件的类路径条目,它将查找相对于JAR根目录的foo/bar/MyClass.class 属于未命名默认软件包的类似乎有些特殊,因为它们的类文件(例如InDefaultPackage.class )应直接位于指定JAR的根目录中或直接位于指定目录中。

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

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

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

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

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

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

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

运行程序会产生以下错误:

 $ 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语句:

package com.my;

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

还要注意,将Java源文件布置在与它们的包结构相匹配的目录结构中也是常规且有用的。 因此,类com.my.Example的源文件通常位于com/my/Example.java Java编译器将依靠此方案找到它找不到的类的源。

在不带-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) 

否, javax/mail/Address 不在目录中。 它在目录中的JAR文件中。 那根本不是一回事,而且区别是巨大的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM