views:

105

answers:

5

I have two Java class files: primegen and primecheck sitting in the same directory. primegen calls a public static function from primecheck. primecheck compiles fine.

However, I receive the following compilation error in primegen:

primegen.java:31: cannot find symbol
symbol  : variable primecheck
location: class primegen
          } while (!primecheck.prime(primeCandidate));
                ^

Shouldn't Java be checking other (compiled) classes within the same directory? Does Java have a problem with primecheck being in lower-case letters (e.g. Is it treating primecheck as a variable instead of a class?)?

Update with Complete Code

Code for primegen:

import java.math.BigInteger;
import java.util.Random;

public class primegen
{

    public static void main(String args[])
    {
        try
        {
            int numBits = Integer.parseInt(args[0].trim());
            System.out.println(generatePrime(numBits));
        }
        catch (Exception e)
        {
            System.out.println("You must enter a positive integer number of bits.");
        }
    }

    private static BigInteger generatePrime(int numBits) throws Exception
    {
        if (numBits < 1)
            throw new Exception("You must enter a positive integer number of bits.");

        BigInteger primeCandidate;
        Random rand = new Random();

        do
        {
            primeCandidate = new BigInteger(numBits, rand);
        } while (!primecheck.prime(primeCandidate));

        return primeCandidate;
    }

}

Code for primecheck:

import java.math.BigInteger;
import java.util.Random;

public class primecheck
{

    public static void main(String args[])
    {
        try
        {
            BigInteger primeCandidate = new BigInteger(args[0].trim());
            if (prime(primeCandidate))
                System.out.println("True");
            else
                System.out.println("False");
        }
        catch (Exception e)
        {
            System.out.println("You must enter a positive integer.");
        }
    }

    public static boolean prime(BigInteger n) throws Exception
    {
        if (n.compareTo(BigInteger.ZERO) == -1)
            throw new Exception("You must enter a positive integer.");
        else if (n.equals(BigInteger.ZERO) || n.equals(BigInteger.ONE))
            return false;

        int maxIterations = 1000;
        BigInteger a;

        for (int i = 0; i < maxIterations; i++)
        {
            a = randomBase(n);
            a = a.modPow(n.subtract(BigInteger.ONE), n);

            if (!a.equals(BigInteger.ONE))
                return false;
        }

        return true;
    }

    private static BigInteger randomBase(BigInteger n)
    {
        Random rand = new Random(); 
        BigInteger a;

        do
        {
            a = new BigInteger(n.bitLength(), rand);
        } while ( !(BigInteger.ONE.compareTo(a) <= 0 && a.compareTo(n) < 0) );

        return a;
    }

}
+2  A: 
T.J. Crowder
My CLASSPATH is ".;C:\Program Files\Java\jre6\lib\ext\QTJava.zip", so that must not be the problem, but thanks for your quick answer.
DT3
I'm using lowercase letters only because it is required by the spec :)
DT3
These classes aren't in a "package" -- just in the same directory with no "fancy" import statements, only basic ones.
DT3
@DT3: *"I'm using lowercase letters only because it is required by the spec"* What spec? Certainly no Java spec I'm aware of, it's in direct contravention of Sun's coding guidelines.
T.J. Crowder
@TJ: The homework spec :)
DT3
@DT3: So, basically take everything that teacher tells you with a grain of salt, then. If they're ignorant of the conventions of the language, heaven only knows what else they're ignorant of. ;-)
T.J. Crowder
+2  A: 

Java does not care about names being all lowercase or uppercase. These are just naming conventions (Java is case sensitive, but will not enforce any particular naming convention).

Edit: (after a few iterations :)

The code you posted compiles fine. The problem is obviously somewhere else (javac command line arguments, classpath...)

Grodriguez
Typically the compiler will report something like "unable to invoke non-static method from a static context" if that's the case.
Mark Peters
The function prime() is already declared to be static.
DT3
Can you post a self-contained example? It's difficult to guess without seeing the code.
Grodriguez
I will update the question with code.
DT3
+2  A: 

Java is case sensitive. Perhaps your class is defined as PrimeCheck or something similar?

Mark Peters
No, it is declared as "primecheck."
DT3
@DT3: Well then you'll have to post more information than you have so far. The scenario as you're reporting it doesn't seem likely, sorry.
Mark Peters
It is so unlikely that no one seems to have an answer! :)
DT3
A: 

Since this is a compilation error, rather than a runtime one, it is important to understand that the compiler cannot find the primecheck class when compiling primegen. The current directory (by inference, the current package) is included by default, by the javac compiler in the user classpath, whenever any symbols have to be resolved during compilation. However, if this is overridden by the CLASSPATH environment variable, then symbol resolution will fail.

There is also a likelihood (I haven't verified this) that the '.' symbol in the classpath environment variable is not expanded into the current working directory, and hence it would be better to explicitly specify the location of the .class files.

Therefore, it is important to specify the location of the primecheck class when compiling primegen, either by the -classpath option (to indicate where the .class files can be found) or the -sourcepath option (to indicate where the compiler can find the source code of the class).

Reference:

  1. The javac tech notes.
  2. Setting the classpath for javac
Vineet Reynolds
*"There is also a likelihood (I haven't verified this) that the '.' symbol in the classpath environment variable is not expanded into the current working directory,"* Yes, it is. I use this all the time.
T.J. Crowder
@T.J. Crowder, I wasn't disputing whether it works at all. I was hinting at the possibility of a bug in the specific version of the JDK that OP is using.
Vineet Reynolds
@Vineet: Ah, gotcha.
T.J. Crowder
A: 

There appears to be a symbol conflict in your primegen class.

Declaring another variable primecheck within the same scope results in confusing the compiler on how it should be treating the reference - is the code referencing the class or the object? It ends up treating it as an object reference, and since the object's class does not have the method prime() defined in it, it throws up the error. Of course, the example also vindicates why naming conventions are a good idea.

Consider the following snippets of code, and the resulting error when compiling primegen.

Class primegen

import java.math.BigInteger;
import java.util.Random;

public class primegen
{
    public static void main(String args[]){}
    private static BigInteger generatePrime(int numBits) throws Exception
    {
        if (numBits < 1)
            throw new Exception("You must enter a positive integer number of bits.");

        BigInteger primeCandidate;
        Random rand = new Random();
        String primecheck = "";
        do
        {
            primeCandidate = new BigInteger(numBits, rand);
        } while (!primecheck.prime(primeCandidate));

        return primeCandidate;
    }
}

Class primecheck

import java.math.BigInteger;

public class primecheck
{
    public static void main(String args[]){}
    private static BigInteger randomBase(BigInteger n){return null;}
    public static boolean prime(BigInteger n) throws Exception
    {
        if (n.compareTo(BigInteger.ZERO) == -1)
            throw new Exception("You must enter a positive integer.");
        else if (n.equals(BigInteger.ZERO) || n.equals(BigInteger.ONE))
            return false;

        int maxIterations = 1000;
        BigInteger a;

        for (int i = 0; i < maxIterations; i++)
        {
            a = randomBase(n);
            a = a.modPow(n.subtract(BigInteger.ONE), n);

            if (!a.equals(BigInteger.ONE))
                return false;
        }

        return true;
    }
}

The resulting error is:

primegen.java:18: cannot find symbol
symbol  : method prime(java.math.BigInteger)
location: class java.lang.String
        } while (!primecheck.prime(primeCandidate));
                            ^
1 error
Vineet Reynolds
This is the first (uhm.. second :) thing I thought about, but does not seem to be the problem after he posted the complete source code..
Grodriguez
@Grodriguez, yeah I noticed that as well. But the similarity of the message with the original wants me to leave this behind, just in case it helps. For some reason, the compiler appears to be failing to resolve primecheck , going by the error message that he's posted.
Vineet Reynolds
"Declaring another variable primecheck within the same scope..." I think you may be confusing "primecheck" and "primeCandidate."
DT3