views:

464

answers:

1

I know this is a common error, but bear with me. I've pursued the CLASSPATH problem and I don't think that is the issue. I'm getting an error like this.

./src/process.java:2: package javax.servlet does not exist
import javax.servlet.*;

I installed Tomcat and the Java SDK, and I know that Tomcat is supposed to supply the servlet API. But what file is it exactly looking for?

I have the following settings: JAVA_HOME=/usr/java/jdk1.6.0_16 CLASSPATH=/usr/share/java;/usr/share/java/tomcat6

The base directory for tomcat: /usr/share/tomcat6 In this directory, /usr/share/tomcat6/lib is simply a symlink to /usr/share/java/tomcat6

tomcat6-servlet-2.5-api-6.0.18.jar is in /usr/share/java/tomcat6, is there anything else I need to be telling javac about so it will use this library? Is there another library that I need?

For background, I'm trying to get a hello world servlet running. The code is as follows:

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class process extends HttpServlet {

public void doGet( HttpServletRequest request, 
                   HttpServletResponse response)
              throws ServletException, IOException {

    PrintWriter out = response.getWriter();
    out.println("Hello World");

}
}

When I compile this with javac I get the following errors (amongst others of which this is the root cause):

./src/process.java:2: package javax.servlet does not exist
import javax.servlet.*;
^
./src/process.java:3: package javax.servlet.http does not exist
import javax.servlet.http.*;
^

I tried specifying the classpath on the command line as well with the -cp option, but I ended up with the same results.

+3  A: 

You need to set your classpath to point specifically to your JAR:

CLASSPATH=/usr/share/java/tomcat/tomcat6-servlet-2.5-api-6.0.18.jar

When you specify a folder in classpath, it's only used to locate all classes within that folder. JARs by themselves are libraries (packaged folders, if you will) of classes and thus have to be listed individually. So, for example, you could do something like:

CLASSPATH=/some/location/myjar1.jar:/other/location/myjar2.jar:/some/classes/folder

in which case all classes from myjar1.jar, myjar2,jar and /some/classes/folder directory will be available to you. If you had myjar3.jar in /some/classes/folder, the above declaration would NOT add it to classpath.

Update As McDowell pointed out, Java 6 allows wildcards in classpath that would pick up all jars in the specified folder. Wildcards work for JARs only, classes are not picked up unless the folder is specified again with no wildcard. Wildcards are also not recursive. So:

CLASSPATH=/loc1/*:/loc1:/loc2/*

would make all jars and all classes within /loc1 folder and all jars (but not classes) within /loc2 folder available. Deeper nested jars (/loc1/nested/some.jar) would not be picked up.

ChssPly76
It may be worth pointing out that Java 6 introduced wildcards for picking up jars from a directory. Documentation here: http://java.sun.com/javase/6/docs/technotes/tools/solaris/javac.html#searching
McDowell
It was the CLASSPATH then! :) Thanks for clarifying that. I suppose I wrongfully assumed that CLASSPATH is like LD_LIBRARY_PATH and what not.
Dr. Watson