Hi list, I'm using xalan-j 2.4.0 on Java 1.4.2 to execute some XPath expressions.
I wish to use some custom functions in these expressions, so I have created the appropriate org.apache.xpath.functions.Function class: my.pack.FuncDictionary My code is inspired by xalan, and compiles and instanciates fine. The code I am using to execute the XPath expression is the following: <code> 1: XPathContext xpathSupport = new XPathContext(); 2: PrefixResolverDefault prefixResolver = new PrefixResolverDefault( (contextNode.getNodeType() == Node.DOCUMENT_NODE) ? ((Document) contextNode).getDocumentElement() : contextNode); //Install hook functions 3: FunctionTable.installFunction("dictionary", new FuncDictionary()); 4: Class c = Class.forName(new FuncDictionary().getClass().getName()); 5: System.out.println(c); // Create the XPath object. 6: XPath xpath = new XPath(expr, null, prefixResolver, XPath.SELECT, null); // Execute the XPath, and have it return the result 7: int ctxtNode = xpathSupport.getDTMHandleFromNode(contextNode); 8: return xpath.execute(xpathSupport, ctxtNode, prefixResolver).str(); </code> It is called with: expr == "dictionary('a','b','a','c')" Symptoms are as follow: All works well until the new XPath() call on line 6, where a ClassNotFoundException occurs, wrapped by a TransformerException. Traceback: javax.xml.transform.TransformerException: java.lang.ClassNotFoundException: my/pack/FuncDictionary at org.apache.xpath.compiler.FuncLoader.getFunction(FuncLoader.java:154) at org.apache.xpath.compiler.FunctionTable.getFunction(FunctionTable.java:2 84) at org.apache.xpath.compiler.Compiler.compileFunction(Compiler.java:1055) at org.apache.xpath.compiler.Compiler.compile(Compiler.java:208) at org.apache.xpath.compiler.Compiler.compile(Compiler.java:156) at org.apache.xpath.XPath.<init>(XPath.java:209) at my.pack.CustomPDFBuilderHook.processXPath(CustomPDFBuilderHook.java:155) at my.pack.CustomPDFBuilderHook.main(CustomPDFBuilderHook.java:184) Caused by: java.lang.ClassNotFoundException: my/pack/FuncDictionary at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:141) at org.apache.xpath.compiler.FuncLoader.getFunction(FuncLoader.java:146) at org.apache.xpath.compiler.FunctionTable.getFunction(FunctionTable.java:2 84) at org.apache.xpath.compiler.Compiler.compileFunction(Compiler.java:1055) at org.apache.xpath.compiler.Compiler.compile(Compiler.java:208) at org.apache.xpath.compiler.Compiler.compile(Compiler.java:156) at org.apache.xpath.XPath.<init>(XPath.java:209) at my.pack.CustomPDFBuilderHook.processXPath(CustomPDFBuilderHook.java:155) at my.pack.CustomPDFBuilderHook.main(CustomPDFBuilderHook.java:184) Apparently, xalan-j cannot re-instantiate my FuncDictionary from the class name. What I figured out from the source & debugging: FunctionTable.installFunction("dictionary", new FuncDictionary()) assigns an id to this function, and stores a FunctionLoader for "my.pack.FuncDictionary" for this id. It also registers the Id with "dictionary" in Keywords.m_functions When the XPath expression is lexed, "dictionary('a','b','a','c')" transforms to a function call to that id (37 as happens) Then the expression is compiled, and the compiler retrieves the FuncLoader for id 37, and tries to create the function. The function is created with Class.forName(m_funcName), followed by newInstance() The Class.forName() is where the exception occurs, and it is called with "my.pack.FuncDictionary" It seems that the ClassLoader for the class FuncLoader is null when this is called. In my research I have managed to create a more minimal example: FunctionTable.getFunction(FunctionTable.FUNC_CURRENT); //OK int i = FunctionTable.installFunction("test", new FuncCurrent()); //i = 37 FunctionTable.getFunction(i); //OK int j = FunctionTable.installFunction("dictionary", new FuncDictionary()); //j = 38 FunctionTable.getFunction(j); //exception! Is there something I'm missing, is this a known bug with a work-around? Please ask for any clarification you might need. TIA, Jonathan Winterflood This message contains information that may be privileged or confidential and is the property of the Capgemini Group. It is intended only for the person to whom it is addressed. If you are not the intended recipient, you are not authorized to read, print, retain, copy, disseminate, distribute, or use this message or any part thereof. If you receive this message in error, please notify the sender immediately and delete all copies of this message.