1

I have a Java class with a main method that expects arguments. If I run the class without arguments I get an error like this, meaning that Java finds the class, runs it, and generates a runtime ArrayIndexOutOfBoundsException.

zookeeper@zookeeper-virtual-machine:~/zookeeper-3.4.5$ java -cp .:zookeeper-3.4.5.jar org.zookeeper.LsGroup
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
    at org.zookeeper.LsGroup.main(LsGroup.java:50)

But when I try the same statement with requisite command line arguments, (zookeeper@zookeeper-virtual-machine:~/zookeeper-3.4.5$ java -cp .:zookeeper-3.4.5.jar org.zookeeper.LsGroup Test) then I get a class not found error:

zookeeper@zookeeper-virtual-machine:~/zookeeper-3.4.5$ java -cp .:zookeeper-3.4.5.jar org.zookeeper.LsGroup Test
Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
    at org.apache.zookeeper.ZooKeeper.<clinit>(ZooKeeper.java:94)
    at org.zookeeper.LsGroup.connect(LsGroup.java:19)
    at org.zookeeper.LsGroup.main(LsGroup.java:50)
Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
    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)
    ... 3 more
zookeeper@zookeeper-virtual-machine:~/zookeeper-3.4.5$ 

I was having a similar problem earlier this morning, but the particular issue on that thread was resolved. Why can't java find my class?

Why do I get a class not found error when I pass command line arguments? How can I fix this?

This is the java code:

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();
    }
}
Community
  • 1
  • 1
bernie2436
  • 22,841
  • 49
  • 151
  • 244
  • case of missing dependency, add the slf4j api jar and other dependencies in one single directory and load all the jars in the particular directory – Acewin Nov 12 '13 at 19:36

3 Answers3

7

It seems like your ZooKeeper class has a dependency on slf4j. If you don't specify any command line arguments, this line

lsGroup.connect(args[0]);

will fail with the ArrayIndexOutOfBoundsException that you see. Because of this the ZooKeeper class will never be initialized and the depedency to slf4j will never be resolved by the JVM.

If you do specify command line argument. The JVM will try to load your class but fail because slf4j is not on the classpath. You need to add the relevant jars to your classpath.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
0

The java classpath is missing the slf4j implementation (I guess is slf4j.jar).

Is this jar bundled into your JAR ? Or is this JAR somewhere in the classpath?

You need to provide all your class' dependencies in order to run it

Cristian Meneses
  • 4,013
  • 17
  • 32
0

Pack all the api jars inside one single directory

use below option on linux env

java -cp 'PATH_TO_DIR/*' className

Acewin
  • 1,657
  • 4
  • 17
  • 36