2

Summary

Java environment variables correctly set, as seen from echo-ing them. However, jars are only seen when explicitly included with javac command.

Details

This is not specifically related to graphics and OpenGl, certain the problem is related to classpaths, ie the importing of third-party jar files.

Using Windows XP SP3, JDK 1.7.0_13

On Windows xp, the system environment variables PATH/JAVA_HOME/CLASSPATH have been set/added-to to include these directories:

C:\Documents and Settings\Administrator\My Documents\project\jar;
C:\Java\jdk1.7.0_13;
C:\Java\jdk1.7.0_13\bin;
C:\Java\jdk1.7.0_13\lib;

There are no user-defined variables which may be conflicting. Assurance from the Terminal (which I restarted after changing the environment variables so that it would be updated, to set environment variables in windows xp, see Environment variables for java installation):

>echo %classpath%
  C:\Documents and Settings\Administrator\My Documents\project\jar;C:\Java\jdk1.7.0_13;C:\Java\jdk1.7.0_13\bin;C:\Java\jdk1.7.0_13\lib;

>echo %java_home%
  C:\Documents and Settings\Administrator\My Documents\project\jar;C:\Java\jdk1.7.0_13;C:\Java\jdk1.7.0_13\bin;C:\Java\jdk1.7.0_13\lib;

>echo %path%
  C:\WINDOWS\System32;... ...C:\Java\jdk1.7.0_13;C:\Java\jdk1.7.0_13\bin;C:\Java\jdk1.7.0_13\lib;C:\Documents and Settings\Administrator\My Documents\project\jar;

Overkill, yes... when it works I'll trim them appropriately

Relevant files:

C:\Documents and Settings\Administrator\My Documents\project\jar\jogl-all.jar
C:\Documents and Settings\Administrator\My Documents\project\Mush.java

C:\Documents and Settings\Administrator\My Documents\project\JarDir.java

jogl-all.jar contains "javax.media.opengl.GL2", Mush.java is a program which displays simple 3D mushrooms through importing java-OpenGL libraries; specifically it imports "javax.media.opengl.GL2".

JarDir.java is a program I found at http://www.java2s.com/Code/Java/File-Input-Output/Listfilesinajarfile.htm which shows what classes are within a jar, I am using it to prove the jar contents. It also demonstrates that compilation is possible on the machine.

JarDir.java is as follows:

import java.io.*;
   import java.util.*;
   import java.util.jar.*;

   public class JarDir {
     public static void main (String args[]) 
         throws IOException {

       JarFile jarFile = new JarFile("C:\\Documents and Settings\\Administrator\\My Documents\\project\\jar\\jogl-all.jar");
       Enumeration enumy = jarFile.entries();
       while (enumy.hasMoreElements()) {
         process(enumy.nextElement());
       }
     }

     private static void process(Object obj) {
       JarEntry entry = (JarEntry)obj;
       String name = entry.getName();
       long size = entry.getSize();
       long compressedSize = entry.getCompressedSize();
       System.out.println(
           name + "\t" + size + "\t" + compressedSize);
     }
   }

and gives the output:

>javac JarDir.java

>java JarDir
... (lots of stuff)
javax/media/opengl/GL2.class   94123   28513
... (lots of stuff)

which demonstrates successful compilation and the presence of the class within the jar file. Attempting to run Mush.java gives many errors, significantly the first one:

>javac Mush.java
Mush.java:21: error: package javax.media.opengl does not exist:
import javax.media.opengl.GL2;
                         ^

To determine if this was a classpath problem, I ran:

>javac Mush.java -cp ./jar/jogl-all.jar

Which gave errors based on the lack of presence of related classes (such as MushScene.java which is instantiated by Mush.java and lives in the same project folder ...) BUT no problems in finding javax.media.opengl ! So the problem must be an environment variable problem!

This then means, that although according to echo %classpath% the classpath is set correctly, java disagrees. What have I done wrong?

Note: the Mush.java program has demonstratively worked on Linux.

Note2: I have multiple jars, if I end up using N jars within the jar folder, I'd like to be able to include the folder, rather than naming each jar specifically =)

Community
  • 1
  • 1
xxjjnn
  • 14,591
  • 19
  • 61
  • 94
  • 1
    why dont u add full jar path in classpath `C:\Documents and Settings\Administrator\My Documents\project\jar\jogl-all.jar`. Check with full path – Subin Sebastian Feb 02 '13 at 11:51
  • see that when you do `>javac Mush.java -cp ./jar/jogl-all.jar` u are giving full path – Subin Sebastian Feb 02 '13 at 11:53
  • Thanks to JB Nizet and Subin. Although the jar folder is in the classpath, the contents of the jars are not, its like jars are folders unto themselves. The question then becomes, how do we recursively add a folder so that all subfolders (and jar contents) are added to the Classpath (where the program will look)? This question is separate and has already been asked here: http://stackoverflow.com/questions/402330/is-it-possible-to-add-to-classpath-dynamically-in-java – xxjjnn Feb 02 '13 at 14:58

3 Answers3

4

jogl-all.jar is not in your CLASSPATH environment variable. So obviously, javac can't find any class from this jar if you don't include it explicitely in the -cp option. The jar itself must be in the CLASSPATH, and not the directory containing it. just like in the -cp option.

I wouldn't use a global CLASSPATH environment variable anyway, but only the -cp option. It will make everything easier when you'll compile or run another Java project, with different dependencies.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • What if I have multiple jars? Also, when I use the -cp option, it no longer "sees" the other files in the project folder... – xxjjnn Feb 02 '13 at 11:56
  • setting the CLASSPATH or passing the classpath with the -cp option doesn't change what must be in the classpath. If you have several jars, you need to include them all in the classpath, whatever option you choose. The jars should be separated by `:` on *nix and by `;` on Windows: -cp c:\path\to\first.jar;c:\path\to\second.jar. The classpath must contain your project's jar file or classes directory, AND all the jar files your code relies on. – JB Nizet Feb 02 '13 at 12:04
1

The solution for doing it with environment variables. (Warning - may not be best practice, see accepted answer)

Classpath environment variable:

C:\Documents and Settings\Administrator\My Documents\project\jar\*;

Path environment variable:

...;C:\Documents and Settings\Administrator\My Documents\project\jar;C:\Java\jdk1.7.0_13;C:\Java\jdk1.7.0_13\bin;C:\Java\jdk1.7.0_13\lib;C:\Documents and Settings\Administrator\My Documents\project\lib;

Note that adding the jar folder is wrong - you need the backslash and the star: " jar\* " in your classpath variable. This adds all the jars in that folder.

As for the path variable, as well as the bin folder of your sdk, you also need the lib folder of your sdk, AND any lib folders which your jars expect to use.

Then you can javac Mush.java and java Mush and watch as everything works perfectly =)

xxjjnn
  • 14,591
  • 19
  • 61
  • 94
1

Be careful not to use semicolons in your JAVA_HOME variable, since it would ruin all convenient paths like: %JAVA_HOME%\bin. As you have written it above, it would result in: C:\Java\jdk1.7.0_13;\bin which is obviously wrong.

not2qubit
  • 14,531
  • 8
  • 95
  • 135