views:

120

answers:

4

In my code I have the following statement import com.apple.dnssd.*; and compiler (javac) complains about this line. It writes that the package does not exist. But I think that it could be that "javac" search the package in a wrong place (directory). In this respect I have two questions:

  1. How can I know where javac search for the packages?

  2. I think that it is very likely that I have the above mentioned package but I do not know where it is located. What are the typical place to look for the packages?

ADDED:

On another Windows machine I tried the same thing and the "javac" does not complain (as before I compiled without any options like "-cp"). I check values of the "classpath" environment variable. It is equal to "C:\Program Files\Java\jdk1.6.0_18\bin;.;..". I went to the first classpath directory and did not find there something that could be the "com.apple.dnssd" library (no jar files, no files containing "apple"). So, I do not understand why javac do NOT complain on the second Windows machine.

ADDED 2:

On the machine #2 I have installed Bonjour after JDK. On the machine #1 JDK was installed after Bonjour.

ADDED 3:

On the machine #1 (where I cannot import the package) I found the jar file (it is located in "C:\Program Files\Bonjour" and its name is "dns_sd.jar"). I tried to add the above mentioned directory to the PATHCLASS environment variable on Windows 7 (and I restarted the system). It does not help. I still cannot import the package. I also tried to specify the "-classpath" in the command line. It also does not help. Now I will try to reinstall Bonjour (as it was advised).

ADDED 4:

I have uninstall Bonjour and Bonjour SDK. I have reload Window. Then I have installed Bonjour and Bonjour SDK. I have reload the Window. It did not solve the problem. I still cannot import the package (javac writes that package does not exist). I have also copied the *.jar file to the same directory there the source is located. It does not work. I used "javac -cp .". It does not work. Now I am out of options. I do not know what else can I try. Can anybody help me pleas?

ADDED 5:


My classpath is: C:\Program Files\Java\jdk1.6.0_18\bin;.;..;"C:\Program Files\Bonjour"
I try to compile from this directory: C:\Users\myname\java\bonjour\example
I compile by the following command: javac ServiceAnnouncer.java
I get the following error message: ServiceAnnouncer.java:1: package com.apple.dnssd does not exist

ADDED 6:

Finally I have managed to import the library. I did it in the following way:

javac -cp "C:\Program Files\Bonjour\dns_sd.jar" ServiceAnnouncer.java

The important thing is that I have specified the jar file after the -cp (not the directory where the jar file is located). It works also if I replace "dns_sd.jar" by "*". So, my conclusion is that after the "-cp" I need to specify jar files (not directories).

+2  A: 

http://java.sun.com/javase/6/docs/technotes/tools/windows/classpath.html

To answer your first question (How to know where javac searches for packages):

Check what your $CLASSPATH variable is set to.

echo $CLASSPATH

This is where you JRE will search for class files and resources. You can either set it as an environment variable,

set CLASSPATH=path1;path2  ... 

or set it when your run javac.

C:> javac -classpath C:\java\MyClasses src_dir

(Great examples for javac are found here)

In this case, your jar file containing 'com.apple.dnssd.*' should be located in your classpath. Just download that jar, and put it in the place where your classpath is searching.

Tim Drisdelle
A: 

This link suggests that the JAR containing this package is part of Bonjour for Windows. Look for it there.

javac.exe only searches where you tell it with the CLASSPATH. If you don't understand how to set CLASSPATH, I'd recommend reading something like this.

duffymo
+3  A: 

Java/javac will search for classes in the classpath.

The default classpath covers the /path/to/jre/lib and /path/to/jre/lib/ext folders. Any classes and JAR files which are found there will be taken in the classpath. You can in theory put your classes and JAR files there so that you don't need to do anything to get java/javac to find them. But this is actually an extremely bad practice. It's recipe for portability trouble, because this isn't the same in all machines. Leave those folders intact.

Then there's the environment variable %CLASSPATH% wherein you can specify full paths to root folders where classes are located and/or full paths to JAR files (including the JAR file name itself!). Multiple paths are in Windows to be separated by semicolon ; and in *Nix by colon :. Paths with spaces inside needs to be quoted with "". Here's an example:

SET CLASSPATH = .;/path/to/File.jar;"/spacy path to some pkg/with/classes"

Note the period . at the beginning of the argument. This indicates the current path (the current working directory from where the java/javac command is to be executed). It will only find classes in the current path that way, and thus not JAR files! You need to specify full path for them. Since Java 1.6 you can also use wildcards to specify multiple JAR files in some path. E.g.

SET CLASSPATH = .;/path/to/all/jars/*;"/spacy path to some pkg/with/classes"

This environment variable is actually a convenience way to manage the classpath so that you don't need to type the same thing down again and again in the command console everytime. But this is only useful for new-to-java users and the cause of all future confusion because they will think that this is "the" classpath. This assumption is actually wrong and again the cause of portability trouble because this isn't the same in all machines.

The right way to define the classpath is using the -cp or -classpath argument wherein you actually specify the same information as you'd like to enter for %CLASSPATH%, i.e. (semi)colon separated and paths-with-spaces quoted, for example:

javac -cp .;/path/to/File.jar;"/spacy path to some pkg/with/classes" Foo.java

Note that when you use either -cp or -classpath (or -jar) arguments, then java/javac will ignore the %CLASSPATH% environment variable (which is actually a Good ThingTM).

To save the time in retyping the same again and again, just create a bat or cmd file (or if you're on *Nix, a sh file). Basically just put therein the same commands as you'd enter "plain" in the console and then execute it the usual platform specific way.

To save more time, use an IDE. The classpath which is to be used during both compiletime and runtime inside the IDE is called the "build path". Explore the project properties and you'll see.

BalusC
*"Note the period . at the beginning of the argument. This indicates the current path."* - I think you mean "current **directory** ". If you say "current path" that could be construed as meaning the "current classpath".
Stephen C
That's true. path != classpath.
BalusC
"... *receipt* for portability trouble" should be *recipe*...
Mark E
@Mark: Fixed, much appreciated.
BalusC
+1  A: 

Assuming that dns_sd.jar is installed in 'C:\Program Files\Bonjour', then try to compile your code like this:

cd C:\Users\myname\java\bonjour\example
javac -classpath C:\Program Files\Bonjour ServiceAnnouncer.java
Tim Drisdelle
Well, I tried it and it did not worked. It started to work when I put file name": javac -cp "C:\Program Files\Bonjour\dns_sd.jar" ServiceAnnouncer.java
Roman
so it's working now?
Tim Drisdelle
@timmyd, now it works :)
Roman