为什么可以';java找不到我的类吗?
我有一个编译没有错误的类。这个类有一个main方法。但是当我试图在ubuntu linux上从类目录运行它时,我得到一个类未找到错误。我很确定我错过了一些非常明显的东西,但我没有看到 以下是我的ls操作:为什么可以';java找不到我的类吗?,java,Java,我有一个编译没有错误的类。这个类有一个main方法。但是当我试图在ubuntu linux上从类目录运行它时,我得到一个类未找到错误。我很确定我错过了一些非常明显的东西,但我没有看到 以下是我的ls操作: zookeeper@zookeeper-virtual-machine:~/zookeeper-3.4.5/programs$ ls CreateGroup.java LsGroup.class LsGroup.java zookeeper-3.4.5.jar 下面是我运行LsGrou
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();
}
}
package org.zookeper;
导入java.io.IOException;
导入java.util.List;
导入java.util.concurrent.CountDownLatch;
导入org.apache.zookeeper.KeeperException;
导入org.apache.zookeeper.WatchedEvent;
导入org.apache.zookeeper.Watcher;
导入org.apache.zookeeper.zookeeper;
导入org.apache.zookeeper.Watcher.Event.KeeperState;
公共类LsGroup实现了Watcher{
专用静态最终int会话_超时=5000;
私人动物园管理员zk;
专用倒计时锁存器连接信号=新倒计时锁存器(1);
公共void connect(字符串主机)引发IOException、InterruptedException{
zk=新的ZooKeeper(主机、会话超时、此);
connectedSignal.await();
}
@凌驾
公共作废进程(WatchedEvent事件){//Watcher接口
if(event.getState()==KeeperState.SyncConnected){
connectedSignal.countDown();
}
}
public void ls(字符串组名)抛出KeeperException、InterruptedException{
字符串路径=“/”+组名;
试一试{
List children=zk.getChildren(路径,false);
for(字符串子项:子项){
System.out.println(路径+“/”+子级);
System.out.println(zk.getChildren(path+“/”+child,false));
}
}catch(KeeperException.NoNodeException){
System.out.printf(“组%s不存在,\n”,组名);
系统出口(1);
}
}
public void close()引发InterruptedException{
zk.close();
}
公共静态void main(字符串[]args)引发异常{
LsGroup LsGroup=新的LsGroup();
lsGroup.connect(args[0]);
lsGroup.ls(args[1]);
lsGroup.close();
}
}
类文件应该位于如下路径中:
org/zookeeper/LsGroup.class
-cp必须包含包含org/目录的目录。那你可以
java -cp parent-of-org org.zookeeper.LsGroup
您可以删除包声明:
package org.zookeeper;
…或者将您的LsGroup
类放在org/zookeeper
目录中。消息“错误名称:org/zookeeper/LsGroup”意味着您必须尊重Java的包结构。使用以下目录结构:
./org/zookeeper/LsGroup.class
然后从当前目录中启动java org.zookeeper.LsGroup。包分隔符“.”将被转换到相应的目录。您的文件不在package org.zookeeper下 您应该从~/zookeeper-3.4.5/org/zookeeper运行您的类
否则JVM将找不到要加载的类。您的类是
org.zookeeper
包的一部分,但您将其保存在项目的根文件夹中(/zookeeper-3.4.5/programs
)。包成员的限定名和文件的路径名是并行的(),因此,如果包是
org.zookeeper
,则类文件应保存在/zookeeper-3.4.5/programs/org/zookeeper
中,您犯了两个错误:
1) 您试图运行java LsGroup
,但必须使用完整的名称,包括包java org.zookeeper.LsGroup
2) 您的目录结构不正确:包org.zookeeper
与目录结构/org/zookeeper/
如果您更改目录结构,然后从该目录结构的顶部运行java,它应该可以工作最初的问题是您的类在一个包中,但您试图加载它,就像它不在包中一样。您通常会将源代码组织为与包层次结构相匹配,然后从层次结构的根开始运行以下内容:
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最佳实践,将类移回包中。我从Java类中删除了package语句,这不是一个好主意-使用包是一个好做法,但你应该组织源代码以匹配包结构,并且知道如何执行包中的类。@JonSkeet,这很公平。也就是说,即使在删除包声明时,我仍然会遇到错误。这意味着还有其他问题出错。您现在已经对问题进行了实质性的更改,因此所有原始答案看起来都很疯狂。那不酷。(问题是现在您的类路径中没有当前目录。)一切正常,我刚刚了解了一些java包/目录和stackoverflow礼仪。谢谢你的帮助。