Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Westi on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

compiles but get NoSuchMethodError when run

Status
Not open for further replies.

jcaulder

Programmer
Apr 22, 2002
241
US
I am trying to follow a simple example to get a basic servlet to run using a desktop install of Tomcat.

Using the browser, I receive this when trying to load the class:

"The requested resource (/HelloServlet) is not available."

If I go to the command prompt and compile the HelloServlet.java file, I receive no errors and a HelloServlet.class file is created. However, if I try to run the HelloServlet.class file from the command prompt like:
java HelloServlet

I receive:
"Exception in thread "main" java.lang.NoSuchMethodError: main"

As far as I can tell, my CLASSPATH seems to be set correctly. What else could cause this?


 
Servlets cannot be run from the command line because they are designed to run within a servlet container - ie Tomcat. They cannot be run from the command line for two reasons - one because there is no "main" method (ie the error message NoSuchMethodError : main) and two because they require HTTP info (HttpServletRequest and HttpServletResponse classes) as part of the servicable methods - which is waht, among other things, the servlet container provides. I suggest you reda up on the documentation for the servlet API and Tomcat docs for further info.

The reason for your Tomcat generated error "The requested resource (/HelloServlet) is not available." is I suspect either due to a configuration error (again, read the manual/docs) or that the URL you are attempting to hit is incorrect. If you have installed Tomcat correctly, you should be able to view *something* at
Code:
[URL unfurl="true"]http://127.0.0.1:8080[/URL]
, and (depending on your config) should be able view your example servlet at
Code:
[URL unfurl="true"]http://127.0.0.1:8080/servlet/HelloServlet[/URL]
.

Hope this helps ...
 
Thanks for the reply.

I am able to access tomcat's default page at And I can run all the examples provided with tomcat's install including jsp's and servlets.

The example says to copy the .class file to the /servlet/ directory but I do not have this directory. So I created one underneath the /ROOT/ directory and placed the class file in there but still the same error.

It would appear to me that tomcat expects the class file to be in a certain location and that perhaps I don't have it there. The example later mentions a /moreservlets/ directory which I also don't see. Maybe my installation hasn't created all the directories it should have?

Is the final compile of the .java file a .class file that should be accessible by tomcat? I have been reading and looking on the web for two hours for a better HelloWorld sample and can't seem to find it. If you can provide a good example of installing tomcat followed up with a basic servlet, maybe I could get it to work.

This is my first experience with java, tomcat, jboss, ant and eclipse and it's quite a lot of information and configuring. I have been using Microsoft products for executables and Apache with PHP for web development. I am trying to investigate the advantages of java and its many suite of tools over PHP.

Thanks again! I'll keep looking. I probably just need a break. Sounds like tomcat is looking in a directory other than the one I think it is for class files.
 
If you have your own application and you wish to deploy it using Tomcat, you have to defin that application name in server.xml file (tomcat configuration file that gets read at the beginning of the tomcat startup). That's how you manage to run the "example" application - because it is defined in the server.xml file.

For each application listed in server.xml, you have web.xml file that defines resources etc for that particular application to run.

~za~
You can't bring back a dead thread!
 
Sorry maxpower1, but I disagree ... while it is valid to define your context in server.xml (which incidentally is under TOMCAT_HOME/conf), it is not necessary.

The layout of the directory structure (this is discussed in the Tomcat documentation -
is as such (for the default or ROOT context) :

classes must be put in TOMCAT_HOME/webapps/ROOT/WEB-INF/classes

In TOMCAT_HOME/conf/web.xml there is something called the "invoker" servlet which is a mapping tool, and allows you to access a servlet in WEB-INF/classes (as above) by hitting this URL pattern :

Code:
[URL unfurl="true"]http://localhost:8080/servlet/MyServlet[/URL]

If you have your own context, then the dir structure is like this :

TOMCAT_HOME/webapps/myContext
TOMCAT_HOME/webapps/myContext/WEB-INF
TOMCAT_HOME/webapps/myContext/WEB-INF/classes

and you put your classes in TOMCAT_HOME/webapps/myContext/WEB-INF/classes.

(as long as they are not in a package (if they are its a bit different - ie if your class was called com.acme.MyServlet, then it would reside in TOMCAT_HOME/webapps/myContext/WEB-INF/classes/com/acme).

------------------------

If this is all too much (contexts and so on), just stick to putting everything under the default context ROOT. So, under TOMCAT_HOME/webapps/ROOT/WEB-INF/classes, put this compiled class (obviously compile it first) -

Code:
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;


public class TestServlet extends HttpServlet {

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

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

		String param1 = request.getParameter("param1");
		String param2 = request.getParameter("param2");

		PrintWriter out = response.getWriter();
		out.println(&quot;<html><body>&quot;);
		out.println(&quot;A test servlet !<br>Here is some HTTP header info ... <hr>&quot;);

		Enumeration enum = request.getHeaderNames();
		while (enum.hasMoreElements()) {
			String ne = (String)enum.nextElement();
			out.println(ne+&quot; : &quot; +request.getHeader(ne));
		}

		out.println(&quot;<hr>And here were some parameters passed on the URL : <br><b>&quot; +param1 +&quot; &quot; +param2 +&quot;</b>&quot;);


		out.println(&quot;</body></html>&quot;);

	}
}

You can hit this servlet by doing this URL :
Code:
[URL unfurl="true"]http://localhost:8080/servlet/TestServlet?param1=Hello&param2=World[/URL]

Hope this gets you started ...
 
Sedj,

Your reply lead me to the problem. I had the class file in the correct location and had the DefaultContext defined correctly. However, the step by step I followed mentioned nothing about the web.xml file having the 'invoker servlet' commented out by default. Maybe they changed this recently as the default? In any case, I found this section and uncommented it, restarted tomcat and, lo and behold, my servlet loaded the first time!!

Thanks for the replies! Things are making much more sense when I look through the server.xml and web.xml files now.
 
As a note, you can leave the invoker commented out, and map servlets in your own context's web.xml, something like this :

Code:
<?xml version=&quot;1.0&quot; encoding=&quot;ISO-8859-1&quot;?>

<!DOCTYPE web-app
    PUBLIC &quot;-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN&quot;
    &quot;[URL unfurl="true"]http://java.sun.com/dtd/web-app_2_3.dtd&quot;>[/URL]

<web-app>
   <servlet>
      <servlet-name>SopsServlet</servlet-name>
      <servlet-class>com.acme.SopsServlet</servlet-class>
      <load-on-startup>1</load-on-startup>
   </servlet>
   <servlet-mapping>
      <servlet-name>SopsServlet</servlet-name>
      <url-pattern>/servlet/SopsServlet</url-pattern>
   </servlet-mapping>
</web-app>
 
thanks sedj. glad to contribute and I learn something new everyday...

~za~
You can't bring back a dead thread!
 
general side question to anyone looking at this thread, is it more efficient to comment out the invoker and map things in web.xml? I'm assuming that's why Apache decided to do it that way... <p>Liam Morley<br><A HREF="mailto:"></A><br>&quot;light the deep, and bring silence to the world.<br>light the world, and bring depth to the silence.&quot;
 
imotic : good question, and I don't know for sure, but I am guessing that maybe it is.

Again, I'm not sure exactly how it works, but suppose that with the &quot;invoker&quot; servlet working (ie uncommented in the /conf xml file) it is the first point of contact for HTTP requests on the port, so I guess even for contexts where you are not interested in such mappings, requests go through it (and hence making all requests marginally slower) - but I could be way off here ... anybody any thoughts ?!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top