简体   繁体   English

为什么Java找不到我的班级?

[英]Why can't java find my class?

I have a class that compiles without error. 我有一类可以正确编译的类。 The class has a main method. 该类具有main方法。 But when I try to run it on ubuntu linux from the classes' directory I get a class not found error. 但是,当我尝试从类目录在ubuntu linux上运行它时,出现未找到类错误。 I am pretty sure I am missing something dead obvious but I don't see it. 我很确定我缺少明显的东西,但看不到。

Here is my ls operation: 这是我的ls操作:

zookeeper@zookeeper-virtual-machine:~/zookeeper-3.4.5/programs$ ls
CreateGroup.java  LsGroup.class  LsGroup.java  zookeeper-3.4.5.jar

Here is what happens when I to run LsGroup 这是我运行LsGroup时发生的情况

zookeeper@zookeeper-virtual-machine:~/zookeeper-3.4.5/programs$ java -cp "zookeeper-3.4.5.jar" LsGroup
Exception in thread "main" java.lang.NoClassDefFoundError: LsGroup
Caused by: java.lang.ClassNotFoundException: LsGroup
    at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
Could not find the main class: LsGroup. Program will exit.

Here is the code for LsGroup 这是LsGroup的代码

package org.zookeeper;    
import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch;

import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.Watcher.Event.KeeperState;

public class LsGroup implements Watcher {

    private static final int SESSION_TIMEOUT = 5000;
    private ZooKeeper zk;
    private CountDownLatch connectedSignal = new CountDownLatch(1);

    public void connect(String hosts) throws IOException, InterruptedException {
        zk = new ZooKeeper(hosts, SESSION_TIMEOUT, this);
        connectedSignal.await();
    }

    @Override
    public void process(WatchedEvent event) { // Watcher interface
        if (event.getState() == KeeperState.SyncConnected) {
            connectedSignal.countDown();
        }
    }

    public void ls(String groupName) throws KeeperException, InterruptedException {
        String path = "/" + groupName;
        try {
            List<String> children = zk.getChildren(path, false);
            for (String child : children) {
                System.out.println(path+"/"+child);
                System.out.println(zk.getChildren(path +"/"+ child, false));
            }
        } catch (KeeperException.NoNodeException e) {
            System.out.printf("Group %s does not exist\n", groupName);
            System.exit(1);
        }
    }

    public void close() throws InterruptedException {
        zk.close();
    }

    public static void main(String[] args) throws Exception {
        LsGroup lsGroup = new LsGroup();
        lsGroup.connect(args[0]);
        lsGroup.ls(args[1]);
        lsGroup.close();
    }
}

The original problem was that your class was in a package, but you were trying to load it as if it weren't in a package. 最初的问题是您的类在软件包中,但是您试图像在软件包中一样加载它。 You'd normally organize your source code to match your package hierarchy, then from the root of the hierarchy, you'd run something like: 通常,您需要组织源代码以匹配您的程序包层次结构,然后从层次结构的根开始运行以下内容:

java -cp .:zookeeper-3.4.5.jar org.zookeeper.LsGroup

Now that you've temporarily worked around the package issue by moving the code out of a package, the next problem is that the current directory isn't in the classpath. 现在您已经通过将代码移出软件包来临时解决了软件包问题,下一个问题是当前目录不在类路径中。 So instead of this: 所以代替这个:

java -cp "zookeeper-3.4.5.jar" LsGroup

You want: 你要:

java -cp .:zookeeper-3.4.5.jar LsGroup

Once you've got that working, you should move the classes back into packages, as per normal Java best practice. 一旦完成工作,就应该按照常规的Java最佳实践将类移回包中。

You could remove the package declaration: 您可以删除包声明:

package org.zookeeper;

...or just place your LsGroup class in org/zookeeper directory. ...或者只是将您的LsGroup类放在org/zookeeper目录中。

The class file is supposed to live in a path like: 该类文件应该位于以下路径中:

 org/zookeeper/LsGroup.class

The -cp must include the directory that contains the org/ directory. -cp必须包含包含org /目录的目录。 Then you can 那么你也能

java -cp parent-of-org org.zookeeper.LsGroup

The message "wrong name: org/zookeeper/LsGroup" means, you have to respect the package structure of Java. 消息“错误名称:org / zookeeper / LsGroup”表示,您必须尊重Java的包结构。 Use the following directory structure: 使用以下目录结构:

./org/zookeeper/LsGroup.class

Then launch java org.zookeeper.LsGroup from within the current directory. 然后从当前目录中启动java org.zookeeper.LsGroup。 The package separator "." 包分隔符“。” will be translated to corresponding directory. 将被翻译到相应的目录。

Your files are not under package org.zookeeper 您的文件不在org.zookeeper软件包下

You should be running your class from ~/zookeeper-3.4.5/org/zookeeper 您应该从〜/ zookeeper-3.4.5 / org / zookeeper运行您的课程

Otherwise JVM won't find the classes to load. 否则,JVM将找不到要加载的类。

Your class is part of the org.zookeeper package but you keep it in the root folder of your project ( /zookeeper-3.4.5/programs ). 您的类是org.zookeeper软件包的一部分,但您将其保存在项目的根文件夹中( /zookeeper-3.4.5/programs )。
The qualified name of the package member and the path name to the file are parallel ( see Managing Source and Class Files ), so if your package is org.zookeeper the class file should be kept in /zookeeper-3.4.5/programs/org/zookeeper 软件包成员的限定名称和文件的路径名称是并行的( 请参阅管理源文件和类文件 ),因此,如果您的软件包是org.zookeeper则该类文件应保存在/zookeeper-3.4.5/programs/org/zookeeper

You made two mistakes: 您犯了两个错误:

1) You tried to run java LsGroup but you have to use the complete name including packages java org.zookeeper.LsGroup 1)您尝试运行java LsGroup但必须使用完整名称,包括软件包java org.zookeeper.LsGroup

2) your directory structure is not correct: the package org.zookeeper corresponds with the directory structure ./org/zookeeper/ 2)您的目录结构不正确:包org.zookeeper与目录结构./org/zookeeper/相对应

If you change the directory structure and then run java from the top of this directory structure it should work 如果您更改目录结构,然后从该目录结构的顶部运行java,它应该可以工作

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

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