|
 |  |  |  | I'm getting a NoClassDefFound error. What has to be on the classpath? |  |  |  |  |
| |
- xalan.jar, xml-apis.jar, and xerces.jar (or the XML parser you are using) must always be on the classpath.
- To run the samples in the samples subdirectories, xalansamples.jar must be on the classpath. To run the servlet (in
samples/servlet), xalanservlet.jar must be on the classpath along with the javax.servlet and javax.servlet.http packages. Sun distributes
the javax.servlet packages in the JSWDK servlet.jar file.
- To run extensions (including the samples in samples/extensions), bsf.jar, and bsfengines.jar must be on the
classpath. To run extensions implemented in JavaScript, js.jar must also be on the classpath. For information on what
you need to run extensions implemented in other scripting languages, see Supported languages.
- To run applications that use the Xalan-Java version 1 API, you must put xalanj1compat.jar on the classpath, recompile the application,
and be sure xalanj1compat.jar is on the classpath at run time (see Using the Xalan-Java version 1
API).
For more information, see Setting up the system classpath.
Using the EnvironmentCheck utility: To help diagnose classpath problems, try running Xalan's environment checking utility, checked in at
xml-xalan/java/src/org/apache/xalan/xslt/EnvironmentCheck.
You can run this utility from the command line as follows:
java org.apache.xalan.xslt.EnvironmentCheck [-out outFile]
You can also call this utility from within your application. For example,
boolean environmentOK = (new EnvironmentCheck()).checkEnvironment (yourPrintWriter);
Be sure to run EnvironmentCheck in the environment where you are experiencing the problem. For example, if you get a
NoClassDefFound error from a command-line application, run EnvironmentCheck on the command line with exactly the same
classpath. If the error occurs inside your Java application (or in a servlet, etc.), be sure to call the
EnvironmentCheck checkEnvironment(...) method from within your running application.
|
 |  |  |  | How do I get line numbers for errors in the XML or XSL input when I am performing a transformation? |  |  |  |  |
| |
Use or mimic the command-line processor (org.apache.xalan.xslt.Process).
A TransformerException generally wraps another exception, often a SAXParseException. The command-line processor uses the static org.apache.xml.utils.DefaultErrorHandler printLocation() method to chase down the exception cause and get a SourceLocator that can usually report line and column number.
Suppose you wanted to modify the ValidateXMLInput sample in the samples/Validate subdirectory to include line and column numbers . All you
need to do is call DefaultErrorHandler.printLocation() in the the Handler internal class error() and warning() methods. For example, replace
 |  |  |  | public void error (SAXParseException spe)
throws SAXException
{
System.out.println("SAXParseException error: " + spe.getMessage());
} |  |  |  |  |
with
 |  |  |  | public void error (SAXParseException spe)
throws SAXException
{
PrintWriter pw = new PrintWriter(System.out, true);
org.apache.xml.utils.DefaultErrorHandler.printLocation(pw, spe);
pw.println("SAXParseException error: " + spe.getMessage());
} |  |  |  |  |
You can also replicate code from the printLocation() method to obtain a SourceLocator, and then use the SourceLocator getLineNumber() and getColumnNumber() methods. The getRootSourceLocator() method below returns a SourceLocator.
 |  |  |  |
import javax.xml.transform.SourceLocator;
import javax.xml.transform.TransformerException;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.apache.xml.utils.SAXSourceLocator;
import org.apache.xml.utils.WrappedRuntimeException;
....
public static SourceLocator getRootSourceLocator(Throwable exception)
{
SourceLocator locator = null;
Throwable cause = exception;
// Try to find the locator closest to the cause.
do
{
if(cause instanceof SAXParseException)
{
locator = new SAXSourceLocator((SAXParseException)cause);
}
else if (cause instanceof TransformerException)
{
SourceLocator causeLocator =
((TransformerException)cause).getLocator();
if(null != causeLocator)
locator = causeLocator;
}
if(cause instanceof TransformerException)
cause = ((TransformerException)cause).getCause();
else if(cause instanceof WrappedRuntimeException)
cause = ((WrappedRuntimeException)cause).getException();
else if(cause instanceof SAXException)
cause = ((SAXException)cause).getException();
else
cause = null;
}
while(null != cause);
return locator;
} |  |  |  |  |
 | Xalan exception handling: The exception architecture in Xalan and with transforms in general is tricky because of multiple layers of exception handling, involving movement back and forth between SAX and Transformer exceptions and across pipes. Xalan often uses a WrappedRuntimeException to throw over many layers of checked exceptions, in order not to have every possible checked exception be declared for every function in the stack, which means it has to catch this exception at the upper levels and unwrap the exception to pass it on as a TransformerException.
A JAXP 1.1 TransformerException often wraps another exception. Two of the TransformerException structures that are frequently used to construct contained exceptions in JAXP 1.1 do not set the locator. The locator is not set because we don't know the type of exception that the Throwable argument represents. The solution is to chase up the contained exceptions to find the root cause, which will usually have a location set for you. This can be somewhat tricky, as not all the exceptions may be TransformerExceptions. A good sample is in the DefaultHandler static printLocation() method, which the Xalan command-line processor uses to report errors. You can also roll your own functions along the lines of the getRootSourceLocator() example above. |
|
|