[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2233
  • Last Modified:

"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);
}
0
steve_bagnall
Asked:
steve_bagnall
  • 3
  • 2
1 Solution
 
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
 
bloodredsunCommented:
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
 
steve_bagnallAuthor Commented:
Thanks that's done it!
0
 
bloodredsunCommented:
Great!
0

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now