From 6ce33e28f4ba7097e38cafcf408cb9a84657d0c5 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Wed, 21 May 2003 16:48:19 +0000 Subject: [PATCH] Split Embedding page to Embedding and Servlets. Added some more content gathered from fop-user. Replaced InputHandler usage with JAXP patterns. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@196444 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/book.xml | 1 + src/documentation/content/xdocs/embedding.xml | 467 +++++++++--------- src/documentation/content/xdocs/faq.xml | 26 +- src/documentation/content/xdocs/servlets.xml | 240 +++++++++ 4 files changed, 483 insertions(+), 251 deletions(-) create mode 100644 src/documentation/content/xdocs/servlets.xml diff --git a/src/documentation/content/xdocs/book.xml b/src/documentation/content/xdocs/book.xml index afd087834..37fd32068 100644 --- a/src/documentation/content/xdocs/book.xml +++ b/src/documentation/content/xdocs/book.xml @@ -19,6 +19,7 @@ + diff --git a/src/documentation/content/xdocs/embedding.xml b/src/documentation/content/xdocs/embedding.xml index a71431e0c..035b37d70 100644 --- a/src/documentation/content/xdocs/embedding.xml +++ b/src/documentation/content/xdocs/embedding.xml @@ -36,231 +36,178 @@

Here is an example use of Driver which outputs PDF:

+Driver driver = new Driver(new InputSource(args[0]), + new FileOutputStream(args[1])); +driver.setRenderer(Driver.RENDER_PDF); +driver.run();]]>

In the example above, args[0] contains the path to an XSL-FO file, while args[1] contains a path for the target PDF file.

-

You also need to set up logging. Global logging for all FOP - processes is managed by MessageHandler. Per-instance logging - is handled by Driver. You want to set both using an implementation - of org.apache.avalon.framework.logger.Logger. See - below for more information. -

+
+ Logging +

+ You also need to set up logging. Global logging for all FOP + processes is managed by MessageHandler. Per-instance logging + is handled by Driver. You want to set both using an implementation + of org.apache.avalon.framework.logger.Logger. See + below for more information. +

+

+ Call setLogger(Logger) always immediately after + instantiating the Driver object. See here: +

+import org.apache.avalon.framework.logger.Logger; +import org.apache.avalon.framework.logger.ConsoleLogger; -

To setup the user config file you can do the following -

+/*..*/ + +Driver driver = new Driver(); +Logger logger = new ConsoleLogger(ConsoleLogger.LEVEL_INFO); +MessageHandler.setScreenLogger(logger); +driver.setLogger(logger);]]> +
+ +
+ Processing XSL-FO +

+ Once the Driver is set up, one of the render() methods + is called. Depending on whether DOM or an InputSource is being used, the + invocation of the method is either render(Document) or + render(Parser, InputSource) respectively. +

+

+ Another possibility may be used to build the FO Tree: You can + call getContentHandler() and fire the SAX events yourself. + + You don't have to call run() or render() on the + Driver object if you use getContentHandler(). +

+

Here is an example use of Driver:

- - This is all you need to do, it sets up a static configuration class. - +Driver driver = new Driver(); +//Setup logging here: driver.setLogger(... +driver.setRenderer(Driver.RENDER_PDF); +driver.setInputSource(new FileInputSource(args[0])); +driver.setOutputStream(new FileOutputStream(args[1])); +driver.run();]]> +
-

Once the Driver is set up, the render method - is called. Depending on whether DOM or SAX is being used, the - invocation of the method is either render(Document) or - render(Parser, InputSource) respectively. -

-

- Another possibility may be used to build the FO Tree. You can - call getContentHandler() and fire the SAX events yourself. - -

-

Once the FO Tree is built, the format() and render() methods may be - called in that order. -

-

Here is an example use of Driver:

- -

You can also specify an xml and xsl file for the input. -

-

Here is an example use of Driver with the XSLTInputHandler:

- -

Have a look at the classes CommandLineStarter or FopServlet for complete - examples. Also, have a look at the examples at the bottom of this page. -

+
+ Processing XSL-FO generated from XML+XSLT +

+ If you want to process XSL-FO generated from XML using XSLT we recommend + using standard JAXP to do the XSLT part and piping the generated SAX + events directly through to FOP. Here's how this would look like: +

+ If your XSL-FO files contain SVG then Batik will be used. When Batik is -initialised it uses certain classes in java.awt that -intialises the java AWT classes. This means that a daemon thread -is created by the JVM and on Unix it will need to connect to a -DISPLAY. -The thread means that the Java application will not automatically quit -when finished, you will need to call System.exit(). These -issues should be fixed in the upcoming JDK 1.4 +//Setup Transformer +Source xsltSrc = new StreamSource(xslFile); +TransformerFactory transformerFactory = TransformerFactory.newInstance(); +Transformer transformer = transformerFactory.newTransformer(xsltSrc); +//Start the transformation and rendering process +transformer.transform(src, res);]]> + There's no need to call run() or render(). +

+ This may look complicated at first, but it's really just the combination of an + XSL transformation and a FOP run. It's also easy to comment out the FOP part + for debugging purposes, for example when you're tracking down a bug in your + stylesheet. You can easily write the XSL-FO output from the XSL transformation + to a file to check if that part generates the expected output. +

+

+ For fully working examples of the above and hints to some interesting + possibilities, see the examples section below. +

+
Controlling logging -

FOP uses Jakarta Avalon's - Logger - interface to do logging. See the Jakarta Avalon project for more information.

-

Per default FOP uses the ConsoleLogger which logs to System.out. If you want to do logging using a - logging framework (such as LogKit, Log4J or JDK 1.4 Logging) you can set a - different Logger implementation on the Driver object. Here's an example how you would use LogKit:

+

+ FOP uses the + Logger package + from Apache Avalon Framework to do logging. See the + Apache Avalon Framework + for more information. +

+

+ Per default FOP uses the ConsoleLogger which logs to System.out. If you want to do logging using a + logging framework (such as LogKit, Log4J or JDK 1.4 Logging) you can set a + different Logger implementation on the Driver object. Here's an example how you would use LogKit: +

-

The LogKitLogger class implements the Logger interface so all logging calls are being redirected to LogKit. - More information on Jakarta LogKit can be found here.

-

Similar implementations exist for Log4J (org.apache.avalon.framework.logger.Log4JLogger) and - JDK 1.4 logging (org.apache.avalon.framework.logger.Jdk14Logger).

-

If you want FOP to be totally silent you can also set an org.apache.avalon.framework.logger.NullLogger instance.

-

If you want to use yet another logging facility you simply have to create a class that implements org.apache.avalon.framework.logging.Logger - and set it on the Driver object. See the existing implementations in Avalon Framework for examples.

-
-
- Input Sources -

The input XSL-FO document is always handled internally as SAX (see the Parsing Design Document for the rationale). -However, the input itself can be provided in a variety of ways to FOP, which normalizes the input (if necessary) into SAX events:

-
    -
  • SAX Events through SAX Handler: FOTreeBuilder is the SAX Handler which is obtained through getContentHandler on Driver.
  • -
  • DOM (which is converted into SAX Events): The conversion of a DOM tree is done via the render(Document) method on Driver.
  • -
  • Data Source (which is parsed and converted into SAX Events): The Driver can take an InputSource as input. -This can use a Stream, String etc.
  • -
  • XML+XSLT Transformation (which is transformed using an XSLT Processor and the result is fired as SAX Events: XSLTInputHandler is used as an InputSource in the render(XMLReader, InputSource) method on Driver.
  • -
-

There are a variety of upstream data manipulations possible. -For example, you may have a DOM and an XSL stylesheet; or you may want to -set variables in the stylesheet. -Interface documentation and some cookbook solutions to these situations are provided in Xalan Basic Usage Patterns.

-

-See the Examples for some variations on input. -

-
-
- Hints -
- Object reuse -

-If FOP is going to be used multiple times within your application -it may be useful to reuse certain objects to save time. -

-

-The renderers and the driver can both be reused. A renderer is reusable -once the previous render has been completed. The driver is reuseable -after the rendering is complete and the reset method is called. -You will need to setup the driver again with a new OutputStream, -IntputStream and renderer. -

-
-
- Getting information on the rendering process -

-To get the number of pages that were rendered by FOP you can call -Driver.getResults(). This returns a FormattingResults object -where you can lookup the number of pages produced. It also gives you the -page-sequences that were produced along with their id attribute and their -number of pages. This is particularly useful if you render multiple -documents (each enclosed by a page-sequence) and have to know the number of -pages of each document. -

-
-
-
- Using FOP in a Servlet -

- Here is a minimal code snippet to demonstrate the basics: -

- response.setContentType("application/pdf"); -Driver driver=new Driver( new InputSource("foo.fo"), - response.getOutputStream()); -driver.setRenderer(Driver.RENDER_PDF); -driver.run(); -

-There are numerous problems with the code snippet above. -Its purpose is only to demonstrate the basic concepts. -See xml-fop/examples/servlet for a working example of FOP used in a servlet. -After building the servlet, drop the fop.war into the webapps directory of Tomcat. -Then access a URL as follows: -

-

http://localhost:8080/fop/fop?fo=/home/path/to/fofile.fo

-

http://localhost:8080/fop/fop?xml=/home/path/to/xmlfile.xml&xsl=/home/path/to/xslfile.xsl

-

The source code for the servlet can be found under xml-fop/examples/servlet/src/FopServlet.java.

- - Some versions of Internet Explorer will not automatically show the PDF. -This is well-known to be a limitation of Internet Explorer, and is not a problem with the servlet. -However, Internet Explorer can still be used to download the PDF so that it can be viewed later. Also, appending ".pdf" to the end of the URL may help. - -
-
- Using FOP in a Servlet with an XSLT Transformation +driver.setLogger(new org.apache.avalon.framework.logger.LogKitLogger(log));]]>

- If both the source XML and XSL are read from files, use the TraxInputHandler: + The LogKitLogger class implements the Logger interface so all logging calls are being redirected to LogKit. + More information on Jakarta LogKit can be found here.

- response.setContentType("application/pdf"); -XSLTInputHandler input - =new XSLTInputHandler(new File("foo.xml"), new File("foo.xsl")); -Driver driver=new Driver(); -driver.setOutputStream(response.getOutputStream()); -driver.setRenderer(Driver.RENDER_PDF); -driver.render(input.getParser(), input.getInputSource());

- This code snippet has the same problems as the one from the section above. + Similar implementations exist for Log4J (org.apache.avalon.framework.logger.Log4JLogger) and + JDK 1.4 logging (org.apache.avalon.framework.logger.Jdk14Logger).

- If your source XML is generated on the fly (for example from a database, a web service, or another servlet), create a transformer object explicitly, and use a SAX event stream to feed the transformation result into FOP: + If you want FOP to be totally silent you can also set an org.apache.avalon.framework.logger.NullLogger instance.

- response.setContentType("application/pdf"); -Driver driver =new Driver(); -driver.setOutputStream(response.getOutputStream()); -driver.setRenderer(Driver.RENDER_PDF); -Transformer transformer=TransformerFactory.newInstance() - .newTransformer(new StreamSource("foo.xsl")); -transformer.transform(xmlsource, new SAXResult(driver.getContentHandler()));

- You don't have to call run() or render() on the driver object. + If you want to use yet another logging facility you simply have to create a class that + implements org.apache.avalon.framework.logging.Logger and set it on the Driver object. + See the existing implementations in Avalon Framework for examples.

+
+
+ Input Sources

- The xmlsource is a placeholder for your actual XML source. -If you have to read the XML from a string, supply a new StreamSource(new StringReader(xmlstring)). -Constructing and reparsing an XML string is generally less desirable than using a SAXSource if you generate your XML. -You can alternatively supply a DOMSource as well. -You may also use dynamically generated XSL if you like. + The input XSL-FO document is always handled internally as SAX (see the + Parsing Design Document for the rationale). + However, the input itself can be provided in a variety of ways to FOP, + which normalizes the input (if necessary) into SAX events:

+
    +
  • SAX Events through SAX Handler: FOTreeBuilder is the SAX Handler which is obtained through getContentHandler on Driver.
  • +
  • DOM (which is converted into SAX Events): The conversion of a DOM tree is done via the render(Document) method on Driver.
  • +
  • Data Source (which is parsed and converted into SAX Events): The Driver can take an InputSource as input. +This can use a Stream, String etc.
  • +
  • XML+XSLT Transformation (which is transformed using an XSLT Processor and the result is fired as SAX Events: XSLTInputHandler is used as an InputSource in the render(XMLReader, InputSource) method on Driver.
  • +

- Because you have an explicit transformer object, you can also use it to explicitly set parameters for the transformation run. + There are a variety of upstream data manipulations possible. + For example, you may have a DOM and an XSL stylesheet; or you may want to + set variables in the stylesheet. Interface documentation and some cookbook + solutions to these situations are provided in + Xalan Basic Usage Patterns. +

+

+ See the Examples for some variations on input.

@@ -268,9 +215,19 @@ You may also use dynamically generated XSL if you like.

To access an external configuration:

- org.apache.fop.apps.Options options = new Options(new File("userconfig.xml")); + + + This is all you need to do, it sets up a static configuration class. +

No further reference to the options variable is necessary. + The "options = " is actually not even necessary.

See Multithreading FOP for issues related to changing configuration in a multithreaded environment. @@ -290,6 +247,82 @@ You may also use dynamically generated XSL if you like. See Multithreading FOP for issues related to changing configuration in a multithreaded environment.

+
+ Hints +
+ Object reuse +

+If FOP is going to be used multiple times within your application +it may be useful to reuse certain objects to save time. +

+

+The renderers and the driver can both be reused. A renderer is reusable +once the previous render has been completed. The driver is reuseable +after the rendering is complete and the reset() method is called. +You will need to setup the driver again with a new OutputStream, +IntputStream and renderer. +

+
+
+ AWT issues +

+ If your XSL-FO files contain SVG then Batik will be used. When Batik is + initialised it uses certain classes in java.awt that + intialises the java AWT classes. This means that a daemon thread + is created by the JVM and on Unix it will need to connect to a + DISPLAY. +

+

+ The thread means that the Java application may not automatically quit + when finished, you will need to call System.exit(). These + issues should be fixed in the upcoming JDK 1.4. +

+

+ If you run into trouble running FOP on a head-less server, please see the + notes on Batik. +

+
+
+ Getting information on the rendering process +

+To get the number of pages that were rendered by FOP you can call +Driver.getResults(). This returns a FormattingResults object +where you can lookup the number of pages produced. It also gives you the +page-sequences that were produced along with their id attribute and their +number of pages. This is particularly useful if you render multiple +documents (each enclosed by a page-sequence) and have to know the number of +pages of each document. +

+
+
+
+ Improving performance +

+ There are several options to consider: +

+
    +
  • + Whenever possible, try to use SAX to couple the individual components involved + (parser, XSL transformer, SQL datasource etc.). +
  • +
  • + Depending on the target OutputStream (in case of an FileOutputStream, but not + for a ByteArrayOutputStream, for example) it may improve performance considerably + if you buffer the OutputStream using a BufferedOutputStream: + driver.setOutputStream(new java.io.BufferedOutputStream(out)); +
    + Make sure you properly close the OutputStream when FOP is finished. +
  • +
  • + Cache the stylesheet. If you use the same stylesheet multiple times + you can setup a JAXP Templates object and reuse it each time you do + the XSL transformation. +
  • +
  • + Use an XSLT compiler like XSLTC that comes with Xalan-J. +
  • +
+
Multithreading FOP

@@ -299,44 +332,24 @@ variables for configuration data and loading images. Here are some tips to mitigate these problems:

    -
  • To avoid having your threads blocked, create a Driver object for each thread.
  • -
  • If possible, do not change the configuration data while there is a Driver object rendering. -Setup the configuration only once, preferably in the init() method of the servlet. +
  • + To avoid having your threads blocked, create a Driver object for each thread.
  • -
  • If you must change the configuration data more often, or if you have multiple servlets within the same webapp using FOP, consider implementing a singleton class to encapsulate the configuration settings and to run FOP in synchronized methods. +
  • + If possible, do not change the configuration data while there is a Driver object rendering. + Setup the configuration only once, preferably in the init() method of the servlet. +
  • +
  • + If you must change the configuration data more often, or if you have multiple + servlets within the same webapp using FOP, consider implementing a singleton + class to encapsulate the configuration settings and to run FOP in synchronized methods.
-
- Servlet Engines -

- When using a servlet engine, there are potential CLASSPATH issues, and potential conflicts with existing XML/XSLT libraries. -Servlet containers also often use their own classloaders for loading webapps, which can cause bugs and security problems. -

-
- Tomcat -

- Check Tomcat's documentation for detailed instructions about installing FOP and Cocoon. -There are known bugs that must be addressed, particularly for Tomcat 4.0.3. -

-
-
- WebSphere 3.5 -

- Put a copy of a working parser in some directory where WebSphere can access it. -For example, if /usr/webapps/yourapp/servlets is the CLASSPATH for your servlets, copy the Xerces jar into it (any other directory would also be fine). -Do not add the jar to the servlet CLASSPATH, but add it to the CLASSPATH of the application server which contains your web application. -In the WebSphere administration console, click on the "environment" button in the "general" tab. -In the "variable name" box, enter "CLASSPATH". -In the "value" box, enter the correct path to the parser jar file (/usr/webapps/yourapp/servlets/Xerces.jar in our example here). -Press "OK", then apply the change and restart the application server. -

-
-
Examples

-The directory "xml-fop/examples/embedding" contains several working examples. +The directory "{fop-fir}/examples/embedding" contains several working examples. In contrast of the examples above the examples here primarily use JAXP for XML access. This may be easier to understand for people familiar with JAXP.

diff --git a/src/documentation/content/xdocs/faq.xml b/src/documentation/content/xdocs/faq.xml index 5559dda05..7664a763d 100644 --- a/src/documentation/content/xdocs/faq.xml +++ b/src/documentation/content/xdocs/faq.xml @@ -758,31 +758,9 @@ Can I control this?

This is a problem of Internet Explorer requesting the content several - times. Some suggestions: + times. Please see the notes on Internet Explorer + for more information.

-
    -
  • - Use an URL ending in .pdf, like - http://myserver/servlet/stuff.pdf. Yes, the servlet can - be configured to handle this. If the URL has to contain parameters, - try to have both the base URL as well as the last parameter end in - .pdf, if necessary append a dummy parameter, like - http://myserver/servlet/stuff.pdf?par1=a&par2=b&d=.pdf. The - effect may depend on IEx version. -
  • -
  • - Give IEx the opportunity to cache. In particular, ensure the server - does not set any headers causing IEx not to cache the content. This - may be a real problem if the document is sent over HTTPS. Consult - your server manual. -
  • -
  • - Cache in the server. Including a parameter in the URL which has a - timestamp as the value may help you to decide whether a request is - repeated. IEx is reported to retrieve a document up to three times, - but never more often. -
  • -
diff --git a/src/documentation/content/xdocs/servlets.xml b/src/documentation/content/xdocs/servlets.xml new file mode 100644 index 000000000..c3bbdf9d5 --- /dev/null +++ b/src/documentation/content/xdocs/servlets.xml @@ -0,0 +1,240 @@ + + + +
+ Servlets + How to use FOP in a Servlet +
+ +
+ Overview +

+ This page discusses topic all around using FOP in a servlet environment. +

+
+
+ Example Servlets in the FOP distribution +

+ In the directory {fop-dir}/examples/servlet, you'll find a working example + of a FOP-enabled servlet. +

+

+ You can build the servlet easily by using the supplied Ant script. After building + the servlet, drop fop.war into the webapps directory of Tomcat. Then, you can use + URLs like the following to generate PDF files: +

+
    +
  • http://localhost:8080/fop/fop?fo=/home/path/to/fofile.fo
  • +
  • http://localhost:8080/fop/fop?xml=/home/path/to/xmlfile.xml&xsl=/home/path/to/xslfile.xsl
  • +
+

+

The source code for the servlet can be found under xml-fop/examples/servlet/src/FopServlet.java.

+
+
+ Create your own Servlet + + This section assumes you are familiar with embedding FOP. + +
+ A minimal Servlet +

+ Here is a minimal code snippet to demonstrate the basics: +

+ public void doGet(HttpServletRequest request, + HttpServletResponse response) throws ServletException { + try { + response.setContentType("application/pdf"); + Driver driver = new Driver(new InputSource("foo.fo"), + response.getOutputStream()); + driver.setRenderer(Driver.RENDER_PDF); + driver.run(); + } catch (Exception ex) { + throw new ServletException(ex); + } +} + + There are numerous problems with the code snippet above. + Its purpose is only to demonstrate the basic concepts. + See below for details. + +
+
+ Adding XSL tranformation (XSLT) +

+ A common requirement is the ability to do an XSL transformation to transform some + XML source to XSL-FO. It is recommended that JAXP be used for this task. The following + snippet shows the basic code for doing this: +

+ +protected Logger log; +protected TransformerFactory transformerFactory; + +public void init() throws ServletException { + this.log = new ConsoleLogger(ConsoleLogger.LEVEL_WARN); + this.transformerFactory = TransformerFactory.newInstance(); +} + +[..] + + //Setup FOP + Driver driver = new Driver(); + driver.setLogger(this.log); + driver.setRenderer(Driver.RENDER_PDF); + + //Setup a buffer to obtain the content length + ByteArrayOutputStream out = new ByteArrayOutputStream(); + driver.setOutputStream(out); + + //Setup Transformer + Source xsltSrc = new StreamSource(new File("foo-xml2fo.xsl")); + Transformer transformer = this.transformerFactory.newTransformer(xsltSrc); + + //Make sure the XSL transformation's result is piped through to FOP + Result res = new SAXResult(driver.getContentHandler()); + + //Setup input + Source src = new StreamSource(new File("foo.xml")); + + //Start the transformation and rendering process + transformer.transform(src, res); + + //Prepare response + response.setContentType("application/pdf"); + response.setContentLength(out.size()); + + //Send content to Browser + response.getOutputStream().write(out.toByteArray()); + response.getOutputStream().flush(); + + Buffering the generated PDF in a ByteArrayOutputStream is done to avoid potential + problems with the Acrobat Reader Plug-in. + +

+ The Source instance used above is simply an example. + If you have to read the XML from a string, supply a + new StreamSource(new StringReader(xmlstring)). Constructing and reparsing + an XML string is generally less desirable than using a SAXSource if you generate your XML. + You can alternatively supply a DOMSource as well. + You may also use dynamically generated XSL if you like. +

+

+ Because you have an explicit Transformer object, you can also use it to + explicitly set parameters for the transformation run. +

+
+
+ Custom configuration +

+ If you need to supply a special configuration do this in the init() + method so it will only be done once and to avoid multithreading problems. +

+ public void init() throws ServletException { + [..] + new Options(new File("userconfig.xml")); + //or + Configuration.put("baseDir", "/my/base/dir"); +} +
+
+ Improving performance +

+ There are several options to consider: +

+
    +
  • + Instead of java.io.ByteArrayOutputStream consider using the ByteArrayOutputStream + implementation from the Jakarta Commons IO project which allocates less memory. +
  • +
  • + In certain cases it can help to write the generated PDF to a temporary file so + you can quickly reuse the file. This is especially useful, if Internet Explorer + calls the servlet multiple times with the same request or if you often generate + equal PDFs. +
  • +
+

+ Of course, the + performance hints from the Embedding page + apply here, too. +

+
+
+
+ Notes on Microsoft Internet Explorer +

+ Some versions of Internet Explorer will not automatically show the PDF or call the servlet multiple times. + These are well-known limitations of Internet Explorer and are not a problem of the servlet. + However, Internet Explorer can still be used to download the PDF so that it can be viewed later. + Here are some suggestions in this context: +

+
    +
  • + Use an URL ending in .pdf, like + http://myserver/servlet/stuff.pdf. Yes, the servlet can + be configured to handle this. If the URL has to contain parameters, + try to have both the base URL as well as the last parameter end in + .pdf, if necessary append a dummy parameter, like + http://myserver/servlet/stuff.pdf?par1=a&par2=b&d=.pdf. The + effect may depend on IEx version. +
  • +
  • + Give IEx the opportunity to cache. In particular, ensure the server + does not set any headers causing IEx not to cache the content. This + may be a real problem if the document is sent over HTTPS. Consult + your server manual. +
  • +
  • + Setting the Expires header entry may help: + response.setDateHeader("Expires", System.currentTimeMillis() + cacheExpiringDuration * 1000); +
  • +
  • + Cache in the server. Including a parameter in the URL which has a + timestamp as the value may help you to decide whether a request is + repeated. IEx is reported to retrieve a document up to three times, + but never more often. +
  • +
+
+
+ Servlet Engines +

+ When using a servlet engine, there are potential CLASSPATH issues, and potential conflicts + with existing XML/XSLT libraries. Servlet containers also often use their own classloaders + for loading webapps, which can cause bugs and security problems. +

+
+ Tomcat +

+ Check Tomcat's documentation for detailed instructions about installing FOP and Cocoon. + There are known bugs that must be addressed, particularly for Tomcat 4.0.3. +

+
+
+ WebSphere 3.5 +

+ Put a copy of a working parser in some directory where WebSphere can access it. + For example, if /usr/webapps/yourapp/servlets is the CLASSPATH for your servlets, + copy the Xerces jar into it (any other directory would also be fine). + Do not add the jar to the servlet CLASSPATH, but add it to the CLASSPATH of the + application server which contains your web application. + In the WebSphere administration console, click on the "environment" button in the + "general" tab. In the "variable name" box, enter "CLASSPATH". + In the "value" box, enter the correct path to the parser jar file + (/usr/webapps/yourapp/servlets/Xerces.jar in our example here). + Press "OK", then apply the change and restart the application server. +

+
+
+
+ Handling complex use cases +

+ Sometimes the requirements for a servlet get quite sophisticated: SQL data sources, + multiple XSL transformations, merging of several datasources etc. In such a case + consider using Apache Cocoon instead + of a custom servlet to accomplish your goal. +

+
+ +
+ -- 2.39.5