6

My code compiled fine with the following command:

javac -cp "../lib/*" AvroReader.java

(lib is where i put my jar files)

At run time I get a ClassNotFoundException on the following line:

DatumReader<?> dtmrdr = new GenericDatumReader();

It says it can't find org.apache.avro.generic.GenericDatumReader even though I've imported it.

Why is this happening?

desertnaut
  • 57,590
  • 26
  • 140
  • 166
Dao Lam
  • 2,837
  • 11
  • 38
  • 44
  • 1
    How are you running the program? You have to provide the classpath with all your dependencies when you run your application as well. – wkl Jul 13 '12 at 00:03
  • I ran it by running `java Generator` . Generator is a class that calls a method in AvroReader.java – Dao Lam Jul 13 '12 at 00:19

3 Answers3

15

Importing has nothing to do with loading classes or setting CLASSPATH.

Try this:

java -cp .;../lib/* Generator

Using the dot '.' as the first entry in the CLASSPATH assumes that the Generator.class file exists in the directory from which you're running java, and /lib is one level up from that directory. Adjust as needed if both of these are not correct.

duffymo
  • 305,152
  • 44
  • 369
  • 561
  • I'm not sure I understand what you mean by "using . as the first entry in the CLASSPATH" – Dao Lam Jul 13 '12 at 00:39
  • Look very carefully at the compilation string I posted. See the dot just before the semi-colon? That's the step you missed that caused the JVM to not be able to find your Generator.class. – duffymo Jul 13 '12 at 00:56
  • @DaoLam - The argument after `-cp` is the classpath. It is a list of directories separated by `;` characters. The first item is `.` which means `the current directory`. The second item is `../lib/*` which means everything in the `../lib` directory. Duffymo is telling you that you need to include the `current directory` (the location of Generator.class) to your classpath. – jahroy Jul 13 '12 at 01:54
  • 1
    @duffymo: you don't have to be so harsh & discouraging. The fact that I'm here shows that I'm not a pro at Java yet and I'm still learning. After reading jahroy's comment, I realized what it means and I already know it from before. My brain was probably just dead at the time I posted that comment. – Dao Lam Jul 13 '12 at 16:22
  • Thanks though. It works but there's something I don't understand. After reading other posts (before you posted yours), I added the current directory to the classpath (which is supposed to be the same as "."), but it didn't work. Why is that? – Dao Lam Jul 13 '12 at 16:53
  • On Mac OS the file separator is colon(:) and need to enclose directories in quotes. So do `java -cp .:"../lib/*" Generator` – Net Dawg Jul 12 '17 at 06:51
  • Yes. Nobody seemed to mind that missing detail when I answered this five years ago. Surely there are better uses for your time here than writing comments like these. – duffymo Jul 12 '17 at 09:26
8

You should run the program including again the same cp:

java -cp "lib directory where i put all the jars" MainClassOfYourApplication

After you compiled it with:

javac -cp "lib directory where i put all the jars" AvroReader.java

More applied to your example:

First step(compile all the needed java files): javac -cp "path/to/jars/*" AvroReader.java //here you should include all the java files not yet compiled but which you need to run your app
Second step: java -cp "path/to/jars/*" package.subpackage1.subpackage2.Generator
Razvan
  • 9,925
  • 6
  • 38
  • 51
  • You can't just use a directory of jars; you'd need a wildcard. A directory classpath entry is only for class files, AFAIK--a pointer to docs stating otherwise would be helpful. I'm looking at the [1.7 classpath docs](http://docs.oracle.com/javase/7/docs/technotes/tools/windows/classpath.html). – Dave Newton Jul 13 '12 at 00:13
  • 1
    I'm calling a method from AvroReader in another class. This is how I ran it: `javac -cp "jar directory" AvroReader.java` `javac Generator.java` `java Generator` I tried what you suggested java -cp "jar directory" Generator, but now it's saying that it can't find Generator. – Dao Lam Jul 13 '12 at 00:13
  • @Dave Newton: Yea I actually have a wildcard. It's basically something like "../lib/*" Sorry I wasn't being clear in my original post. – Dao Lam Jul 13 '12 at 00:18
  • @DaoLam - If you're just calling `java Generator` it won't work because you're not specifying a classpath. Your comment seems to contradict the info in your question, however... – jahroy Jul 13 '12 at 00:26
  • @jahroy Can you be more specific on how to run it? Thank you! :) – Dao Lam Jul 13 '12 at 00:41
  • @DaoLam - Read this answer, it tells you what to do: You need to include the classpath when you run the program **AND** when you compile it. – jahroy Jul 13 '12 at 02:02
-1

To compile and execute java file on Linux System with external jar files :

javac -cp jar_file1.jar:jar_file2:jar_file3.jar:. java_program_name.java

java -cp new_mail_api.jar:activation.jar:additional.jar:.java_program_name

To compile and execute java file on Windows System with external jar files :

javac -cp jar_file1.jar;jar_file2;jar_file3.jar;. java_program_name.java

java -cp new_mail_api.jar;activation.jar;additional.jar;.java_program_name

In Unix of Linux, Java Classpath contains names of the directory with colon “:” separated, On Windows Java Classpath will be semicolon “;” separated while if you defined java classpath in Manifest file those will be space separated.

For more knowledge about Classpath, visit https://javarevisited.blogspot.com/2011/01/how-classpath-work-in-java.html

desertnaut
  • 57,590
  • 26
  • 140
  • 166
Sumit
  • 529
  • 5
  • 13