Gregory
Gregory

Reputation: 26

NoClassDefFoundError: com/google/common/base/Preconditions, but Preconditions is in the .jar file in my runtime classpath

I have a project that uses ImmutableList and ImmutableSet from Guava. It compiles just fine, but at runtime, with the same -cp, it gives this error message:

Exception in thread "main" java.lang.NoClassDefFoundError: com/google/common/base/Preconditions
    at com.google.common.collect.RegularImmutableList.get(RegularImmutableList.java:81)
    at BasicPoint.pointAsArray(BasicPoint.java:93)
    at BasicPoint.inflate(BasicPoint.java:134)
    at BasicEdgeLength.<clinit>(BasicEdgeLength.java:32)
Caused by: java.lang.ClassNotFoundException: com.google.common.base.Preconditions
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 4 more

I compile it in the terminal with this command

javac -cp '.:/MYPROJECTDIRECTORY/guava-14.0.1.jar'  BasicEdgeLength.java

and it compiles. Then I run it with this command

java -cp '.:/MYPROJECTDIRECTORY/guava-14.0.1.jar'  BasicEdgeLength

and I get the aforementioned error message. There are other questions on stackoverflow about the exact same issue, but the answer is always to download the guava libraries, which I have already done. Indeed, when I poke around in guava-14.0.1.jar, I can see the file com/google/common/base/Preconditions. The fact that I can see in the .jar file the very class mentioned in the error message makes me imagine that I can't solve this problem just by downloading more files. So I'm not sure what to do, and any suggestions that you could offer would be greatly appreciated.

I'm including the code from BasicPoint below, because that's the class that calls RegularImmutableList.get(i), although please be aware that BasicPoint won't compile without AbstractPoint, IntMatrix, Initializer, and possibly some other stuff (and it doesn't contain the main method, which is found in BasicEdgeLength). I'm happy to append the code to some of these other classes if anyone thinks it's necessary.

Thank you all for your time!

/**
*    This class implements a point.
*    It uses a representation as a vector of integers.  
*/

import com.google.common.collect.*;
//import com.google.common.base.*; // same error occurs whether or not I include this line

final public class BasicPoint implements AbstractPoint<BasicPoint, BasicAngle> {

// static variables for all points.
private static final int length = Initializer.N - 1;

private static final IntMatrix ROT = Initializer.ROT;

private static final IntMatrix REF = Initializer.REF;

private static final IntMatrix INFL = Initializer.INFL;

// A vector identifying the point.  
private final ImmutableList<Integer> point;

// Constructor methods.

private BasicPoint(Integer[] vector) {
    if (vector.length != length) {
        throw new IllegalArgumentException("Point length is incorrect.");
    }
    this.point = ImmutableList.copyOf(vector);
}

private BasicPoint() {
    Integer[] vector = new Integer[length];
    for (int i = 0; i < length; i++) {
        vector[i] = 0;
    }
    point = ImmutableList.copyOf(vector);
}

// public static factory method
static public BasicPoint createBasicPoint(Integer[] vector) {
    return new BasicPoint(vector);
}

static final public BasicPoint zeroVector() {
    return new BasicPoint();
}

static final public BasicPoint unitVector() {
    Integer[] vector = new Integer[length];
    vector[0] = 1;
    for (int i = 1; i < length; i++) {
        vector[i] = 0;
    }
    return new BasicPoint(vector);
}

// toString method.
public String toString() {
    String outString = "(";
    for (int i = 0; i < point.size() - 1; i++) {
        outString = outString + point.get(i) + ",";
    }
    outString = outString + point.get(length) + ")";
    return outString;
}

// equals method.
public boolean equals(Object obj) {
    if (obj == null || getClass() != obj.getClass())
        return false;
    BasicPoint p = (BasicPoint) obj;
    for (int i = 0; i < length; i++) {
        if (p.point.get(i) != this.point.get(i))
            return false;
    }
    return true;
}

// hashCode override.
public int hashCode() {
    int prime = 53;
    int result = 11;
    for (int i = 0; i < length; i++) {
        result = prime*result + point.get(i);
    }
    return result;
}

// a private helper method to turn point into an array of Integers.
private Integer[] pointAsArray() {
    Integer[] output = new Integer[length];
    for (int i = 0; i < length; i++)
        output[i] = point.get(i);
    return output;
}

// Manipulation methods.  
public BasicPoint add(BasicPoint p) {
    Integer[] q = new Integer[length];
    for (int i = 0; i < length; i++) {
        q[i] = this.point.get(i) + p.point.get(i);
    }
    return new BasicPoint(q);
}

public BasicPoint scalarMultiple(int c) {
    Integer[] q = new Integer[length];
    for (int i = 0; i < length; i++) {
        q[i] = c * this.point.get(i);
    }
    return new BasicPoint(q);
}

public BasicPoint subtract(BasicPoint p) {
    return this.add(p.scalarMultiple(-1));
}

public BasicPoint rotate(BasicAngle a) {
    int i = a.getAsInt();
    if (i < 0)
        throw new IllegalArgumentException("You must perform a positive number of rotations.");

    Integer[] result  = new Integer[length];
    for (int j = 0; j < i; j++)
        result = ROT.rowTimes(result);
    return new BasicPoint(result);
}

public BasicPoint reflect() {
    return new BasicPoint(REF.rowTimes(this.pointAsArray()));
}

public BasicPoint inflate() {
    return new BasicPoint(INFL.rowTimes(this.pointAsArray()));
}

} // end of class BasicPoint

Upvotes: 4

Views: 17805

Answers (1)

Gregory
Gregory

Reputation: 26

A friend took a look at the files in my project and identified the problem for me. He noticed that my version of guava had a bad checksum. I tried installing it again, and the problem persisted. Both times that I installed it I opened and saved the .jar file to disk using the linux archive manager (which was the default behavior in my web browser). I tried one more time, this time using wget to download the .jar file, and that solved the problem. So the moral of the story appears to be: don't save .jar files to disk with the linux archive manager.

Upvotes: 4

Related Questions