"Cannot allocate servlet instance for path " when trying to run servlet on Tomcat

Hi,

I am trying to run a servlet on Apache Tomcat, I can do a HelloWorld one, but when I try and look at a SaxonServlet example, it falls over with the above  error.  The sevlet source and a summary of the exceptions are below:

Cheers, Steve



Exceptions ===================

HTTP Status 500 -

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

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

javax.servlet.ServletException: Cannot allocate servlet instance for path /saxon/servlet/SaxonServlet
      at org.apache.catalina.servlets.InvokerServlet.serveRequest(InvokerServlet.java:435)

........

root cause

java.lang.NoClassDefFoundError: SaxonServlet (wrong name: com/churchillchina/saxon/SaxonServlet)
      at java.lang.ClassLoader.defineClass1(Native Method)
      at java.lang.ClassLoader.defineClass(ClassLoader.java:620)






SaxonServer.java ===============

package com.churchillchina.saxon;

import net.sf.saxon.value.StringValue;
import net.sf.saxon.xpath.DynamicError;
import net.sf.saxon.functions.SystemProperty;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.*;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;

/**
 * SaxonServlet. Transforms a supplied input document using a supplied stylesheet
 */

public class SaxonServlet extends HttpServlet {

    public void init() throws ServletException {
        super.init();
        System.setProperty("javax.xml.transform.TransformerFactory", "net.sf.saxon.TransformerFactoryImpl");
    }

    /**
    * service() - accept request and produce response<BR>
    * URL parameters: <UL>
    * <li>source - URL of source document</li>
    * <li>style - URL of stylesheet</li>
    * <li>clear-stylesheet-cache - if set to yes, empties the cache before running.
    * </UL>
    * @param req The HTTP request
    * @param res The HTTP response
    */

    public void service(HttpServletRequest req, HttpServletResponse res)
      throws ServletException, IOException
    {
        String source = req.getParameter("source");
        String style = req.getParameter("style");
        String clear = req.getParameter("clear-stylesheet-cache");

        if (clear!=null && clear.equals("yes")) {
            clearCache();
        }

        apply(style, source, req, res);

    }

    /**
    * getServletInfo<BR>
    * Required by Servlet interface
    */

    public String getServletInfo() {
        return "Calls SAXON to apply a stylesheet to a source document";
    }

    /**
    * Apply stylesheet to source document
    */

    private void apply(String style, String source,
                           HttpServletRequest req, HttpServletResponse res)
                           throws java.io.IOException {

        ServletOutputStream out = res.getOutputStream();

        if (style==null) {
            out.println("No style parameter supplied");
            return;
        }
        if (source==null) {
            out.println("No source parameter supplied");
            return;
        }
        try {
            Templates pss = tryCache(style);
            Transformer transformer = pss.newTransformer();

            String mime = pss.getOutputProperties().getProperty(OutputKeys.MEDIA_TYPE);
            if (mime==null) {
               // guess
                res.setContentType("text/html");
            } else {
                res.setContentType(mime);
            }

            Enumeration p = req.getParameterNames();
            while (p.hasMoreElements()) {
                String name = (String)p.nextElement();
                if (!(name.equals("style") || name.equals("source"))) {
                    String value = req.getParameter(name);
                    transformer.setParameter(name, new StringValue(value));
                }
            }

            String path = getServletContext().getRealPath(source);
            if (path==null) {
                throw new DynamicError("Source file " + source + " not found");
            }
            File sourceFile = new File(path);
            transformer.transform(new StreamSource(sourceFile), new StreamResult(out));
        } catch (Exception err) {
            out.println(err.getMessage());
            err.printStackTrace();
        }

    }

    /**
    * Maintain prepared stylesheets in memory for reuse
    */

    private synchronized Templates tryCache(String url) throws TransformerException {
        String path = getServletContext().getRealPath(url);
        if (path==null) {
            throw new DynamicError("Stylesheet " + url + " not found");
        }

        Templates x = (Templates)cache.get(path);
        if (x==null) {
            TransformerFactory factory = TransformerFactory.newInstance();
            x = factory.newTemplates(new StreamSource(new File(path)));
            cache.put(path, x);
        }
        return x;
    }

    /**
    * Clear the cache. Useful if stylesheets have been modified, or simply if space is
    * running low. We let the garbage collector do the work.
    */

    private synchronized void clearCache() {
        cache = new HashMap(20);
    }

    private HashMap cache = new HashMap(20);
}
LVL 5
steve_bagnallAsked:
Who is Participating?
 
bloodredsunConnect With a Mentor Commented:
Right,

the class should be in the folder that matches the package, e.g.:

WEB-INF/classes/com/churchillchina/saxon;

and the web.xml should be like this as it's currently incorrect.
.........
      <servlet>
            <servlet-name>SaxonServlet</servlet-name>
            <servlet-class>com.churchillchina.saxon.SaxonServlet</servlet-class>
      </servlet>
..........
//blah
.........
      <servlet-mapping>
            <servlet-name>SaxonServlet</servlet-name>
            <url-pattern>/SaxonServlet.do</url-pattern>
      </servlet-mapping>

and you should go to "<your_webapp>/SaxonServlet.do" to get it. Servlets by common practise have the suffix ".do" appended. You don't have to but it's good to do.
0
 
bloodredsunCommented:
So you've compiled the code into a class file, put the class file in the correct folder in WEB-INF/classes and mapped it correctly in the web.xml?

And why have you over-writtten service() rather than doPost or doGet?
0
 
steve_bagnallAuthor Commented:
Hi,

Thanks for your response.  I've put the compiled class in the correct folder yeah.  I have tried a few configerations of the web.xml file from some tutorials on-line, but it may not be right.  I will post the file below.

As for the class itself - this is the sample class that comes with Saxon, so I have not written this, and I presumed it would be correct.


WEB.XML ==========================

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>

    <display-name>Tomcat Examples</display-name>
    <description>
      Tomcat Example servlets and JSP pages.
    </description>

    <!-- Define servlet-mapped and path-mapped example filters -->
    <filter>
        <filter-name>Servlet Mapped Filter</filter-name>
        <filter-class>filters.ExampleFilter</filter-class>
      <init-param>
          <param-name>attribute</param-name>
          <param-value>filters.ExampleFilter.SERVLET_MAPPED</param-value>
      </init-param>
    </filter>
    <filter>
        <filter-name>Path Mapped Filter</filter-name>
        <filter-class>filters.ExampleFilter</filter-class>
      <init-param>
          <param-name>attribute</param-name>
          <param-value>filters.ExampleFilter.PATH_MAPPED</param-value>
      </init-param>
    </filter>
    <filter>
        <filter-name>Request Dumper Filter</filter-name>
        <filter-class>filters.RequestDumperFilter</filter-class>
    </filter>

    <!-- Example filter to set character encoding on each request -->
    <filter>
        <filter-name>Set Character Encoding</filter-name>
        <filter-class>filters.SetCharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>EUC_JP</param-value>
        </init-param>
    </filter>

    <filter>
        <filter-name>Compression Filter</filter-name>
        <filter-class>compressionFilters.CompressionFilter</filter-class>

        <init-param>
          <param-name>compressionThreshold</param-name>
          <param-value>10</param-value>
        </init-param>
        <init-param>
          <param-name>debug</param-name>
          <param-value>0</param-value>
        </init-param>
    </filter>

    <!-- Define filter mappings for the defined filters -->
    <filter-mapping>
        <filter-name>Servlet Mapped Filter</filter-name>
      <servlet-name>invoker</servlet-name>
    </filter-mapping>
    <filter-mapping>
        <filter-name>Path Mapped Filter</filter-name>
      <url-pattern>/servlet/*</url-pattern>
    </filter-mapping>


<!-- Example filter mapping to apply the "Set Character Encoding" filter
     to *all* requests processed by this web application -->
<!--
    <filter-mapping>
        <filter-name>Set Character Encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
-->

<!--
    <filter-mapping>
      <filter-name>Compression Filter</filter-name>
      <url-pattern>/CompressionTest</url-pattern>
    </filter-mapping>
-->

<!--
    <filter-mapping>
        <filter-name>Request Dumper Filter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
-->

    <!-- Define example application events listeners -->
    <listener>
        <listener-class>listeners.ContextListener</listener-class>
    </listener>
    <listener>
        <listener-class>listeners.SessionListener</listener-class>
    </listener>

    <!-- Define servlets that are included in the example application -->

    <servlet>
        <servlet-name>SendMailServlet</servlet-name>
        <servlet-class>SendMailServlet</servlet-class>
    </servlet>
   
    <servlet>
                    <servlet-name>SaxonServlet</servlet-name>
                    <servlet-class>SaxonServlet</servlet-class>
    </servlet>

    <servlet>
        <servlet-name>
            snoop
        </servlet-name>
        <servlet-class>
            SnoopServlet
        </servlet-class>
<!--
        <init-param>
            <param-name>foo</param-name>
            <param-value>bar</param-value>
        </init-param>
-->
        <run-as>
            <description>Security role for anonymous access</description>
            <role-name>tomcat</role-name>
        </run-as>
    </servlet>

    <servlet>
      <servlet-name>
          servletToJsp
      </servlet-name>
      <servlet-class>
          servletToJsp
      </servlet-class>
    </servlet>
        <servlet>
        <servlet-name>
            CompressionFilterTestServlet
        </servlet-name>
        <servlet-class>
            compressionFilters.CompressionFilterTestServlet
        </servlet-class>

    </servlet>

    <servlet-mapping>
        <servlet-name>invoker</servlet-name>
        <url-pattern>/servlet/*</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>
            CompressionFilterTestServlet
        </servlet-name>
        <url-pattern>
            /CompressionTest
        </url-pattern>
    </servlet-mapping>
   
    <servlet-mapping>
                    <servlet-name>
                        SaxonServlet
                    </servlet-name>
                    <url-pattern>
                        /servlet/com/churchillchina/saxon/SaxonServlet
                    </url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>SendMailServlet</servlet-name>
        <url-pattern>/SendMailServlet</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>
            snoop
        </servlet-name>
        <url-pattern>
            /snoop
        </url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>
            servletToJsp
        </servlet-name>
        <url-pattern>
            /servletToJsp
        </url-pattern>
    </servlet-mapping>

    <taglib>
        <taglib-uri>
         http://jakarta.apache.org/tomcat/debug-taglib
        </taglib-uri>
        <taglib-location>
           /WEB-INF/jsp/debug-taglib.tld
        </taglib-location>
    </taglib>

    <taglib>
        <taglib-uri>
         http://jakarta.apache.org/tomcat/examples-taglib
        </taglib-uri>
        <taglib-location>
           /WEB-INF/jsp/example-taglib.tld
        </taglib-location>
    </taglib>

    <resource-ref>
      <res-ref-name>mail/Session</res-ref-name>
      <res-type>javax.mail.Session</res-type>
      <res-auth>Container</res-auth>
    </resource-ref>

    <security-constraint>
      <display-name>Example Security Constraint</display-name>
      <web-resource-collection>
         <web-resource-name>Protected Area</web-resource-name>
       <!-- Define the context-relative URL(s) to be protected -->
         <url-pattern>/jsp/security/protected/*</url-pattern>
       <!-- If you list http methods, only those methods are protected -->
       <http-method>DELETE</http-method>
         <http-method>GET</http-method>
         <http-method>POST</http-method>
       <http-method>PUT</http-method>
      </web-resource-collection>
      <auth-constraint>
         <!-- Anyone with one of the listed roles may access this area -->
         <role-name>tomcat</role-name>
       <role-name>role1</role-name>
      </auth-constraint>
    </security-constraint>

    <!-- Default login configuration uses form-based authentication -->
    <login-config>
      <auth-method>FORM</auth-method>
      <realm-name>Example Form-Based Authentication Area</realm-name>
      <form-login-config>
        <form-login-page>/jsp/security/protected/login.jsp</form-login-page>
        <form-error-page>/jsp/security/protected/error.jsp</form-error-page>
      </form-login-config>
    </login-config>

    <!-- Security roles referenced by this web application -->
    <security-role>
      <role-name>role1</role-name>
    </security-role>
    <security-role>
      <role-name>tomcat</role-name>
    </security-role>

    <!-- Environment entry examples -->
    <!--env-entry>
      <env-entry-description>
         The maximum number of tax exemptions allowed to be set.
      </env-entry-description>
      <env-entry-name>maxExemptions</env-entry-name>
      <env-entry-value>15</env-entry-value>
      <env-entry-type>java.lang.Integer</env-entry-type>
    </env-entry-->
    <env-entry>
      <env-entry-name>minExemptions</env-entry-name>
      <env-entry-value>1</env-entry-value>
      <env-entry-type>java.lang.Integer</env-entry-type>
    </env-entry>
    <env-entry>
      <env-entry-name>foo/name1</env-entry-name>
      <env-entry-value>value1</env-entry-value>
      <env-entry-type>java.lang.String</env-entry-type>
    </env-entry>
    <env-entry>
      <env-entry-name>foo/bar/name2</env-entry-name>
      <env-entry-value>true</env-entry-value>
      <env-entry-type>java.lang.Boolean</env-entry-type>
    </env-entry>
    <env-entry>
      <env-entry-name>name3</env-entry-name>
      <env-entry-value>1</env-entry-value>
      <env-entry-type>java.lang.Integer</env-entry-type>
    </env-entry>
    <env-entry>
      <env-entry-name>foo/name4</env-entry-name>
      <env-entry-value>10</env-entry-value>
      <env-entry-type>java.lang.Integer</env-entry-type>
    </env-entry>

    <!-- EJB Reference -->
    <ejb-ref>
      <description>Example EJB Reference</description>
      <ejb-ref-name>ejb/Account</ejb-ref-name>
      <ejb-ref-type>Entity</ejb-ref-type>
      <home>com.mycompany.mypackage.AccountHome</home>
      <remote>com.mycompany.mypackage.Account</remote>
    </ejb-ref>

    <!-- Local EJB Reference -->
    <ejb-local-ref>
      <description>Example Local EJB Reference</description>
      <ejb-ref-name>ejb/ProcessOrder</ejb-ref-name>
      <ejb-ref-type>Session</ejb-ref-type>
      <local-home>com.mycompany.mypackage.ProcessOrderHome</local-home>
      <local>com.mycompany.mypackage.ProcessOrder</local>
    </ejb-local-ref>


</web-app>
0
 
steve_bagnallAuthor Commented:
Thanks that's done it!
0
 
bloodredsunCommented:
Great!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.