Link to home
Start Free TrialLog in
Avatar of derekl
derekl

asked on

Servlets and JAXP

I need to do some XSLT processing in a servlet using the new TRaX functionality of JAXP 1.1.  Whenever I try to do a transform however, I get the following error:

java.lang.NoSuchMethodError
     at org.apache.xpath.DOM2Helper.getNamespaceOfNode(DOM2Helper.java:348)
     at org.apache.xml.utils.TreeWalker.startNode(TreeWalker.java:281)
     at org.apache.xml.utils.TreeWalker.traverse(TreeWalker.java:119)
     at org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:320)

In order to be sure it had nothing to do with the JARs in my WEB-INF\lib directory I wrote a simple class that I could call either from the JDK or from the doGet method of a servlet:


import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;  
import javax.xml.parsers.FactoryConfigurationError;  
import javax.xml.parsers.ParserConfigurationException;
 
import org.xml.sax.SAXException;  
import org.xml.sax.SAXParseException;  
import org.w3c.dom.Document;
import org.w3c.dom.DOMException;
import java.io.*;
import com.lhs.pim.util.XSLTUtil;

public class Test
{
    public static void main(String[] args) {
     Test.TestXSLT();
    }
   
    public static void TestXSLT() {
     System.out.println("javax.xml.parsers.SAXParserFactory: " + System.getProperty("javax.xml.parsers.SAXParserFactory"));
     System.out.println("javax.xml.parsers.DocumentBuilderFactory : " + System.getProperty("javax.xml.parsers.DocumentBuilderFactory"));
     Document document = null;
     
     DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
     try {
         File f = new File("C:\\ods\\bin\\test.xml");
         DocumentBuilder builder = factory.newDocumentBuilder();
         document = builder.parse(f);
     } catch (SAXException sxe) {
         // Error generated by this application
         // (or a parser-initialization error)
         Exception  x = sxe;
         if (sxe.getException() != null)
          x = sxe.getException();
         x.printStackTrace();
     } catch (ParserConfigurationException pce) {
         // Parser with specified options can't be built
         pce.printStackTrace();
     } catch (IOException ioe) {
         // I/O error
         ioe.printStackTrace();
     }

     System.out.println(XSLTUtil.toString(document));
    }
   
}

This works fine when run under JDK1.3 with the classpath containing all of the jars in my WEB-INF\lib directory, but it gives me the error show above when run during the doGet handler of a servlet.

Any ideas?
Avatar of black
black

which appserver are you using? it's quite possible that the appserver parses an xml file before you do and therefore it loads up and xml parser, when you do your call your load up the one that's already instantiated and now your parser.
Try replacing the xml parser that your appserver comes with, with the xml parser that your application wants to use.
try printing out in your servlet:
    System.out.println("javax.xml.parsers.SAXParserFactory: " + System.getProperty("javax.xml.parsers.SAXParserFactory"));
    System.out.println("javax.xml.parsers.DocumentBuilderFactory : " + System.getProperty("javax.xml.parsers.DocumentBuilderFactory"));
Avatar of derekl

ASKER

I'm using Tomcat version 3.2.  When I run the servlet under Tomcat both of the System Properties I printed out came up as null.  It's interesting that parsing the test.xml file worked correctly but the xslt portion failed.
ASKER CERTIFIED SOLUTION
Avatar of black
black

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
We have similar problem before when we are using xalan.  After we put xalan.jar & xerces.jar in the begin of classpath.  It solved the problem.
Avatar of derekl

ASKER

Yeah, I just moved xalan.jar, jaxp.jar, and crimson.jar to the %TOMCAT_HOME%\lib directory from my web apps WEB-INF\lib directory and it worked fine.  I am curious why it would not work with those three files in the WEB-INF\lib directory, because files in that directory are supposed to be added to the CLASSPATH.
Avatar of derekl

ASKER

Thanks, you got me on the right track.
They are added to the classpath but after the entries in the %TOMCAT_HOME%\lib directory which means that when a search happens through the classpath for a suitable parser the tomcat parser's are found first and your parsers are not uses. that's why changing the order of the entries in the classpath fixes your problem.
Future versions of servlet engines and application servers are required to host the webapps on a separate classpath so that this issue does not occur. I'm not sure which servers do this yet.