[英]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.