Troubleshooting

Bug report

Please ensure before reporting a bug that the classpath has been set correctly, as shown in the running section.

Please have a look at the limitations in the status and the ToDo list.

Tracking

The best way to report a bug is to supply an XUnit test that show what fails : once corrected, the test will be added to the test suite. Please refer to the XUnit cookbook.

Main issues

Issues running RefleX on JDK 1.4.0

I get an Internal Error from the JVM like this one :

#
# HotSpot Virtual Machine Error, Internal Error
# Please report this error at
# http://java.sun.com/cgi-bin/bugreport.cgi
#
# Java VM: Java HotSpot(TM) Client VM (1.4.0-b92 mixed mode)
#
# Error ID: 43113F32554E54494D45110E435050034A
#
# Problematic Thread: prio=1 tid=0x0x83f5100 nid=0x4ca9 runnable
#

Solution : upgrade your JVM to v1.4.2.

Issues running RefleX on JDK 1.4.2

I get a SAX parse error like this one :

org.xml.sax.SAXParseException: Attribute "failures" already appeared in this tag.
        at org.apache.crimson.parser.Parser2.fatal(Parser2.java:3339)
        at org.apache.crimson.parser.Parser2.fatal(Parser2.java:3333)
        at org.apache.crimson.parser.Parser2.maybeElement(Parser2.java:1534)
        at org.apache.crimson.parser.Parser2.parseInternal(Parser2.java:634)
        at org.apache.crimson.parser.Parser2.parse(Parser2.java:333)
        at org.apache.crimson.parser.XMLReaderImpl.parse(XMLReaderImpl.java:448)

Solution : do not use Crimson, use Xerces instead :

  • use the Endorsed Standards Override Mechanism. Place the xercesImpl.jar AND xmlParserAPIs.jar in the $JAVA_HOME/lib/endorsed directory, where $JAVA_HOME is where the runtime software is installed.

The following methods do not work :

  • Using the CLASSPATH environment variable or using -classpath to place the new classes in the classpath.
  • Using the -jar option to explicitly execute the classes inside the new jar files.

Issues running RefleX on OpenJDK

I get an error when converting SVG to JPEG like this:

Exception in thread "main" java.lang.IncompatibleClassChangeError: Found class com.sun.image.codec.j
peg.JPEGImageEncoder, but interface was expected
        at org.apache.batik.ext.awt.image.codec.jpeg.JPEGImageWriter.writeImage(Unknown Source)
        at org.apache.batik.transcoder.image.JPEGTranscoder.writeImage(Unknown Source)
        at org.apache.batik.transcoder.image.ImageTranscoder.transcode(Unknown Source)
        [etc...]

Solution : do not use OpenJDK, use un JDK instead.

Also, take a look at issues 46513 and 38183 if you intend to use Batik's current development versions - there is some effort into moving out from those proprietary classes into standard ones.

The Web applications of the tutorial doesn't work

Please check the prerequisites.

Issues running XSLT on Tomcat 5.5 or Tomcat 6

I get a Servlet Exception like this one :

[www]
Apache Tomcat/5.5 - Error report - Web Navigator
HTTP Status 500 -

type Status report

message

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

exception

javax.servlet.ServletException: javax.xml.transform.TransformerFactoryConfigurationError
    javax.xml.transform.TransformerFactoryConfigurationError: Provider org.apache.xalan.processor.TransformerFactoryImpl not found
    at javax.xml.transform.TransformerFactory.newInstance(Unknown Source)
    at org.inria.ns.reflex.processor.xcl.TransformAction.doTransform(TransformAction.java:427)
.../...
    at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:577)
    at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683)
    at java.lang.Thread.run(Thread.java:595)

note The full stack trace of the root cause is available in the Apache Tomcat/5.5 logs.


Apache Tomcat/5.5

This is not specific to RefleX, but as that can make your Web applications stall, I give you the solution when such error is encountered :

This is due to the XSLT compiler which is supplied with Java 1.5.0 and that is used by default in Tomcat ; the generated classes contains things that are too big for Xalan.

You just have to put newer jar files in the $TOMCAT_HOME/shared/lib directory (Tomcat 5.5) or the $TOMCAT_HOME/lib directory (Tomcat 6.x), where $TOMCAT_HOME is where Tomcat is installed. The files are xalan.jar, serialize.jar, and xsltc.jar. If you prefer using Saxon, try it and please let me know.

Please read also the next tip if the actions above didn't fix this issue (just consider that you have to deal with Xalan, not Xerces).

Issues running Xerces on Tomcat 5.5

I get a Servlet Exception like this one :

[www]
Apache Tomcat/5.5 - Error report - Web Navigator
HTTP Status 500 -

type Status report

message

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

exception

javax.servlet.ServletException: org.inria.ns.reflex.structures.InitializationException: java.net.MalformedURLException: no protocol: entity.dtd
file:///path/to/tomcat/webapp/WEB-INF/active-sheet.xml
        org.inria.ns.reflex.ReflexServlet.init(ReflexServlet.java:195)
        javax.servlet.GenericServlet.init(GenericServlet.java:212)
.../...

root cause

java.net.MalformedURLException: no protocol: entity.dtd
        java.net.URL<init>(URL.java:567)
        java.net.URL<init>(URL.java:464)
        java.net.URL<init>(URL.java:413)
        org.apache.xerces.impl.XMLEntityManager.startEntity(Unknown Source)
.../...

note The full stack trace of the root cause is available in the Apache Tomcat/6.0 logs.


Apache Tomcat/6.0

Once again, this is not specific to RefleX, it is a similar issue that may occur according to the version of Xerces in use.

To fix it, you just have to put newer jar files of Xerces in the $TOMCAT_HOME/common/lib directory or the $TOMCAT_HOME/shared/lib directory, where $TOMCAT_HOME is where Tomcat is installed.

If you don't find xercesImpl.jar installed inside Tomcat, perhaps you have to change it inside your own Web application inside your WEB-INF/lib directory.

Other Web issues running with Tomcat

If you get another issue that doesn't look like one of the previous traces, please check the logs in the $TOMCAT_HOME/logs directory (or the directory where the logs are written) where $TOMCAT_HOME is where Tomcat is installed.

Troubles that involve XML or XSLT errors should come either from Xerces and Xalan and can be fixed as explained before, or are simple real XML or XSLT errors and must be fixed according to the relevant specifications (W3C's XML, namespaces, XSLT...)

I can't get the value of a system property (environment variable)

If you use some code like this :

  <xcl:set name="fee" value="{ $sys:env/fee * price }"/>

...your XML active sheet will be well formed, and nothing wrong will be reported ; simply ensure that the root element contains the right xmlns declaration for the SYS module, otherwise the right property won't be found :

xmlns:sys="http://ns.inria.org/active-tags/sys"

Don't forget to launch Java with the expected property : java -Dfee=0.15

More generally, RefleX won't complain for any property referenced that is not in the data set (an error will be reported only if a prefix is not bound to a namespace URI). According to the context, a property that doesn't exist is simply processed as null, or 0, or the empty String, or an empty collection... However an action that do need a reference may fail.

Hence : check your namespace URIs.

My active sheet cause an XML parsing error

There's nothing that RefleX can do for you : as it relies on XML standards, you must follow them carefully and correct yourself such errors. Particularly, your active sheets (and XSLT stylesheets) MUST BE well-formed and conform to XML namespaces. Moreover, XPath expressions within must be syntactically correct.

Please refer to the relevant specifications, or lookup for some tutorials available on the Web.

However, there is a convenient feature available in RefleX : you can explicitely ask for a lax parsing. If the XML document to parse is a well-formed XML fragment (with no DTD, several root elements and/or non-blank text nodes under the document root), you can get it anyway. Please refer to the documentation of the <xcl:parse> element and its @mode attribute.

I have some troubles with XML attribute values

Unlike XSLT, XPath expressions in Active Tags allow to handle objects. Thus, when you refer to an attribute :

  <xcl:set name="birth-date" value="{ $myXML/doc/author/@birth-date }"/>

...you get the attribute as an object, not its value. Attempting to print such attribute object may vary according to the underlying XML parser, but usually the result might be something like this birth-date="1969/06/10" instead of 1969/06/10. If you need to deal with the string value of the attribute, you have to extract it explicitely :

  <xcl:set name="birth-date" value="{ string( $myXML/doc/author/@birth-date ) }"/>

Notice that Active Tags also allows to handle with XPath some non-XML objects that behaves like if they were XML objects ; as such objects can store objects in their attribute values that can be other than strings, there is an additional XPath function that allows to extract their values. This is the value() function. For example :

  <xcl:transform output="{ value( $web:response/@web:output ) }" source="{ $myXML }"/>

...allow to copy an XML parsed document to the output stream of a Web response in a Web application (the @web:output attribute value is not a string but a reference to the output flow of the HTTP response).

Handling XML nodes

For the same reasons, other XML nodes are NOT transformed automatically to strings. It is sometime useful to use the string() function for text nodes, like this : string( text() ).

Selecting an attribute with XPath doesn't work on an active tag

This is likely a misunderstanding of one of the core concepts of Active Tags. Be aware that in Active Tags one can encounter 2 kinds of XML elements :

  • active tags, that are operations written with XML elements and that appear like this :
      <io:file encoding="iso-8859-1" name="myFile" uri="file:///path/to/file.txt"/>
  • XOperable objects, that are like XML elements (but internally are not necessary real XML elements) and accessible with XPath :
      { $myFile/@io:encoding }

Although they both look like the same, an XML element that is an active tag and an XML element that is backed by an XOperable objects are not the same, are not used for the same purpose, and their attributes are not interchangeable.

In one hand, the <io:file> element creates an object with the help of some attributes and specifically the @encoding attribute. On the other hand the $myFile that has been created is of the type #io:x-file and exposes some of its properties as attributes and specifically the @io:encoding attribute.

You can't use the @io:encoding attribute in the active tag nor the @encoding attribute in the XOperable object, they are not interchangeable and if you look at the documentation of the active tag and at the documentation of the type, you'll see which attributes are supported and which are not.

  { $myFile/@encoding }

...won't raise an error : in XPath, when one try to access an attribute that doesn't exist, an empty result is returned.

Notice that XOperable objects do define their own attributes with a name bound to the namespace URI of the module they belong unlike active tags that define their own attributes without a namespace URI. This is just a design choice that was taken because some XOperable objects can host custom attributes that are not reflecting their own internal properties ; those additional attributes are not bound to a namespace URI. This is the case for example of the #web:x-session data type that defines its own attributes (@web:XXX), and that allow to add custom unbound attributes that represent the objects stored in the session (for example : @shopping-cart).

An active tag doesn't produce the expected result

There are some main reasons that can cause that trouble :

  • Ensure that you didn't miss the curly braces...

      <acme:foo bar-object="$myBar/myFoo"/>

    You'd probably better have to write it like this :

      <acme:foo bar-object="{ $myBar/myFoo }"/>
  • Ensure that you are using the right attributes, and the right allowed values for them. RefleX doesn't check automatically the validity of the Active Sheets. It is planned for a future release.

    You can check them by looking at the XML material reference or in the Javadoc.

    For XSLT users

    Active Tags is not XSLT : XSLT instructions often use the @select attribute whereas Active Tags instructions often use the @value attribute. Take care of what you write !

  • Ensure that the attribute values have the right content. This is particularly important for XPath expressions : for example, if you have to give an object reference to a tag thanks to an attribute, you should write it like this :

      <acme:foo bar-object="{ $myBar }"/>
      <!--the object can be handled correctly by the tag implementation-->

    It is important to trim the spaces before "{" and after "}" (within the curly braces, any whitespace is allowed), otherwise the value of the attribute will be automatically evaluated to a String which is certainly not whished, like shown below.

      <acme:foo bar-object=" { $myBar } "/>
      <!--this certainly won't produce the expected result
          because the object handled is definitively a String-->
  • Ensure that the reference is not empty. It might be a normal case but the more often it is not. A simple trace can show if you have a value or not :

      <xcl:echo value="The string value of $myBar is : { $myBar }"/>
      <acme:foo bar-object="{ $myBar }"/>
  • Ensure that you don't have to unwrap the value of an object with the value() function, as explained here. If you're not sure, use it anyway as this function return the input object as-is if it is not a wrapped object.

<xcl:for-each> doesn't work

Possible reasons :

  • Unlike most of the other elements, <xcl:for-each> doesn't use the @value attribute, but the @select attribute.
  • I'm sure having several nodes, why <xcl:for-each> select only the first string ?
      <xcl:for-each name="str" select="{ string( $myBar/foo ) }">
          <!--do something-->
      </xcl:for-each>

    With XPath, the rule with the string() function is to cast to a string the FIRST item of a collection. Thus, if you have several nodes, the code above won't iterate on each string value of the nodes, but on the first one only. You'd rather write :

      <xcl:for-each name="foo" select="{ $myBar/foo }">
          <xcl:set name="str" value="{ string( $foo) }"/>
          <!--do something-->
      </xcl:for-each>

My active sheet fails on parsing an XML document...

...but it is a normal case that might occur in my application. How can I avoid crashing my application ?

Use the <xcl:fallback> element to catch errors :

<?xml version="1.0" encoding="iso-8859-1"?>
<xcl:active-sheet xmlns:io="http://ns.inria.org/active-tags/io" xmlns:xcl="http://ns.inria.org/active-tags/xcl"> <xcl:parse-stylesheet name="xslt" source="file:///path/to/stylesheet.xsl"/> <xcl:for-each name="file"
select="{ io:file('file:///path/to/dir')//*[@io:is-file][@io:extension='xml'] }"> <xcl:parse name="xml" source="{ $file }"> <xcl:fallback> <xcl:echo value="Warning : { $file } is not well formed"/> <xcl:continue/> </xcl:fallback> </xcl:parse> <xcl:transform output="{ $file/.. }/{ $file/@io:short-name }.html" source="{ $xml }"
stylesheet="{ $xslt }"/> </xcl:for-each> </xcl:active-sheet>

There is a runnable example in the basic tutorial.

I designed my own module but my custom tags seems to be inactive

If the engine encounters inactive tags, it won't report errors because it will process such tags as litterals, even if these litteral tags are not relevant in some using context (in this case they would be somewhat ineffective). To force the engine to understand a tag family as active tags, you have to specify on the root element of your Active Sheet or Active Document the list of modules that must be active thanks to the @exp:enable-prefixes foreign attribute which belongs to the EXP module (which is always active) :

<?xml version="1.0" encoding="iso-8859-1"?>
<xcl:active-sheet exp:enable-prefixes="xcl sys acme" xmlns:exp="http://ns.inria.org/active-tags/exp" xmlns:sys="http://ns.inria.org/active-tags/sys" xmlns:xcl="http://ns.inria.org/active-tags/xcl" xmlns:acme="urn:acme-business-model:purchase-orders"> <acme:xml-order db-url="..." name="purchase-order" order-id="..."/> <xcl:transform output="{ $sys:out }" source="{ $purchase-order }"/> </xcl:active-sheet>

Now, the engine will report errors if it doesn't know one of the modules specified by the @exp:enable-prefixes foreign attribute. As RefleX comes with built-in modules (XCL, ASL, I/O, etc) you should have troubles only with custom modules. If so, it means that the engine doesn't have the knowledge of your custom modules.

Notice that "sys" is also a prefix forced to be active : thus, the $sys:out property is really bound to the underlying module. If the "sys" prefix wasn't active, $sys:out wouldn't be the predefined property $sys:out.

To tell the engine where are your own module definitions, you must register them to RefleX thanks to an Active Catalog, as shown in this tutorial. You can also read "how to plug a module to the engine with a catalog".

The string value displayed is not those expected

RefleX handles objects. The string value of an object is not necessary the XPath value of that object. When you refer to an object and let display its intrinsic string value, you might get an ugly Java reference or a smartest string if the Java toString() method is implemented, but it is certainly not the value expected :

  <xcl:echo value="{ $myObject }"/>
org.acme.foo.Bar@189c036

If you do want the XPath string value, ask for it explicitely by using the XPath function string() :

  <xcl:echo value="{ string( $myObject ) }"/>
Hello world !

But you will get the XPath string value only for XML objects and X-operable objects. Don't complain about other objects ! Their Java string value will be get in any case.

The engine fails to resolve a relative URL

You might have to supply a relative URL that will be resolved correctly by the engine in some cases :

  <do:something source="../../some-file.xml"/>

...and that fails on some other cases :

  <do:something-else source="../../some-file.xml"/>

What happens ?

That depends on how the underlying active tag is implemented : in the case where a Java class is beyond the tag, usually everything will work fine, but in the case where the tag is implemented like a macro-tag, it might fail. In this last case, the module that defines the macro-tag is an XML file that has its own base URI that can be located in another place than the caller active sheet (the active sheet that uses that tag) : the relative URL will be then resolved upon the base of the module.

There is no obvious solution that the engine can resolve for you, because if a relative URL could be resolved according to the base URI of the caller, in many cases it is not what one really expect : it is impossible to distinguish a relative URI that was specified inside that module from a relative URI that was specified outside because both are represented by strings. The solution must be find outside the engine.

In many cases, the place where an URI is expected is also suitable for a file reference ; the most simple thing to realize is to transform the relative URI (as a string) to a file object, which cause its resolution regarding the current base URI :

  <do:something source="{ io:file( '../../some-file.xml' ) }"/>
  <do:something-else source="{ io:file( '../../some-file.xml' ) }"/>

In both examples above, the URL is absolutized before passing them to the module that supply the tags implementation.

If a string would be really needed as the argument, the string() function can also wrap the given expressions.

I don't try to connect to a server, but I receive an error...

...such as "Could not connect to HTTP server on "www.acme.org"".

RefleX relies on VFS for resolving URIs and retrieving resources. Unfortunately, when a resolver have to map "http://www.acme.org/path" to another URL (for example a local file), VFS tries to connect to the server, even if it is not expected. If you work on a network that can't reach internet, you can get an error.

No solution except :

  • allowing RefleX to have access to internet,
  • making a dummy mapping at the lowest level of your system (DNS resolution).

A patch to VFS is included in this release of RefleX and should fix the issue for HTTP, but others scheme might fail... A replacement of VFS is under consideration.

I can't connect to my database (SQL)

Did you read this and this ?

Other issues

[TODO: More helpers...]