0

我有一个编译没有错误的类。该类有一个主要方法。但是当我尝试从类目录在 ubuntu linux 上运行它时,我得到一个类未找到错误。我很确定我错过了一些明显的东西,但我没有看到。

这是我的 ls 操作:

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

这是我运行 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.

这是 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();
    }
}
4

7 回答 7

4

最初的问题是您的类在一个包中,但您试图加载它,就好像它不在包中一样。你通常会组织你的源代码以匹配你的包层次结构,然后从层次结构的,你会运行类似的东西:

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

现在您已经通过将代码移出包来临时解决包问题,下一个问题是当前目录不在类路径中。所以代替这个:

java -cp "zookeeper-3.4.5.jar" LsGroup

你要:

java -cp .:zookeeper-3.4.5.jar LsGroup

一旦你完成了这项工作,你应该按照正常的 Java 最佳实践将这些类移回包中。

于 2013-11-12T16:37:24.123 回答
2

您可以删除包声明:

package org.zookeeper;

...或者只是将您的LsGroup课程放在org/zookeeper目录中。

于 2013-11-12T16:04:57.873 回答
1

类文件应该位于如下路径中:

 org/zookeeper/LsGroup.class

-cp 必须包括包含 org/ 目录的目录。那么你就可以

java -cp parent-of-org org.zookeeper.LsGroup
于 2013-11-12T16:04:51.693 回答
1

消息“错误名称:org/zookeeper/LsGroup”的意思是,你必须尊重 Java 的包结构。使用以下目录结构:

./org/zookeeper/LsGroup.class

然后从当前目录中启动 java org.zookeeper.LsGroup。包分隔符“.” 将被翻译到相应的目录。

于 2013-11-12T16:06:40.347 回答
0

您的文件不在包 org.zookeeper 下

您应该从 ~/zookeeper-3.4.5/org/zookeeper 运行您的课程

否则 JVM 将找不到要加载的类。

于 2013-11-12T16:07:27.913 回答
0

您的类是org.zookeeper包的一部分,但您将其保存在项目的根文件夹中 ( /zookeeper-3.4.5/programs)。
包成员的限定名和文件的路径名是平行的(请参阅管理源和类文件),所以如果你的包是org.zookeeper类文件应该保存在/zookeeper-3.4.5/programs/org/zookeeper

于 2013-11-12T16:07:46.103 回答
0

你犯了两个错误:

1) 你试图运行java LsGroup,但你必须使用完整的名称,包括包java org.zookeeper.LsGroup

2)你的目录结构不正确:包org.zookeeper对应的目录结构./org/zookeeper/

如果您更改目录结构,然后从该目录结构的顶部运行 java 它应该可以工作

于 2013-11-12T16:10:49.563 回答