Problems passing element from xquey to java method

<oXygen/> general issues.
jbeuree
Posts: 3
Joined: Thu Feb 08, 2007 10:06 pm

Problems passing element from xquey to java method

Post by jbeuree » Thu Feb 08, 2007 10:13 pm

Hi,

We have some xquery like the following which calls a static java method and passes in an element:

$javans:myfn(/blah)

Where blah would be an element that exists in the document being processed. The corresponding java method would be:

static public void myfn(Element myelement) {
...
}

This works in our usual environment, but fails when run from within the Oxygen debugger with the following:

Error in call to extension function {[Full path to my class].myfn(org.w3c.dom.Element) } Cannot convert supplied XPath value to the required type for the extension function

I'm using Saxon8 and have added the saxon8-dom.jar to the classpath when running Oxygen, but the problem persists.

Anyone run into this and know a fix or workaround?

sorin_ristache
Posts: 4144
Joined: Fri Mar 28, 2003 2:12 pm

Post by sorin_ristache » Mon Feb 12, 2007 6:53 pm

Hello,

I tested a Java extension with a method that takes an org.w3c.dom.Element parameter and it worked correctly. The only cases when it did not work was when I passed a sequence of nodes (for example //*) as parameter instead of a single node (for example (/*) to the Java function. The error message was similar with what you obtained. Can you post a sample of your XQuery file, your XML input file and your Java class used as extension for the XQuery transformation?


Regards,
Sorin

jbeuree
Posts: 3
Joined: Thu Feb 08, 2007 10:06 pm

Problems passing element from xquey to java method

Post by jbeuree » Mon Feb 12, 2007 9:39 pm

I think I've found the root cause of the problem, although I'm not yet sure how to fix it. Looks like the object my java code is being passed is loaded with a different classloader. I can pass it through as an object type and compare. Here' s what I get:

class name: net.sf.saxon.tinytree.TinyDocumentImpl (I'm passing '/')
Class loader: ro.sync.util.k@1e04cbf

My code verifies this object is not an instance of TinyDocumentImpl. When I check its class loader I get the following:

sun.misc.Launcher$AppClassLoader@1ff5ea7

Looks to me like the saxon objects are being loaded with a different class loader, and that why it can never figure out how to convert them to make the method call.

Now if I can just figure out how to fix it.

sorin_ristache
Posts: 4144
Joined: Fri Mar 28, 2003 2:12 pm

Re: Problems passing element from xquey to java method

Post by sorin_ristache » Tue Feb 13, 2007 11:31 am

jbeuree wrote:Looks to me like the saxon objects are being loaded with a different class loader, and that why it can never figure out how to convert them to make the method call.
I also tried an XQuery with a Java extension that receives an org.w3c.dom.Element parameter like the myfn static method that you posted and the error was caused by passing a sequence instead of a single element. There was no class loader conflict. It is true that your Java extension and the Saxon classes are loaded by different class loaders but I do not see why this would cause the error because the different class loader loads only your extension. The Saxon classes or the JAXP classes are all loaded by the same class loader.
jbeuree wrote:This works in our usual environment, but fails when run from within the Oxygen debugger
Please post a small sample of your XQuery, your XML input file and your Java extension that shows the problem.
jbeuree wrote:I'm using Saxon8 and have added the saxon8-dom.jar to the classpath when running Oxygen, but the problem persists.
saxon8-dom.jar comes with oXygen so you do not need to add it to any classpath. You can see it in the [oXygen-install-folder]/lib folder. Did you add it as Java extension for your XQuery together with your Java classes (the class with the static myfn method)?


Regards,
Sorin

jbeuree
Posts: 3
Joined: Thu Feb 08, 2007 10:06 pm

Post by jbeuree » Tue Feb 13, 2007 7:07 pm

I've completely given up trying to pass an Element through. It only ever works if I pass as an Object, and then it says the actual class type is TinyElementImpl, which is a private class that I can't use anyway.

I'm trying to pass the document through with the same problems. Its very trivial. Here's my xquery:
-----------------------------------------------------------------------------
declare namespace juQuery="java:myPackage.TestClass";

<blah>
{ juQuery:testCall(/) }
</blah>
-----------------------------------------------------------------------------

And the java:

-----------------------------------------------------------------------------
package myPackage;

import net.sf.saxon.tinytree.TinyDocumentImpl;

public class TestClass {
public static String testCall(Object blah) {
System.out.println("Object class: " + blah.getClass().getName());
System.out.println("Object loader: " + blah.getClass().getClassLoader());
System.out.println("TinyDocumentImpl loader: " + TinyDocumentImpl.class.getClassLoader());

return "returnedBlahText";
}
}
-----------------------------------------------------------------------------

This gives me the following result:

Object class: net.sf.saxon.tinytree.TinyDocumentImpl
Object loader: ro.sync.util.k@8fce95
java.lang.NoClassDefFoundError: net.sf.saxon.tinytree.TinyDocumentImpl

Note that I have to add the saxon jars to the classpath to load the saxon classes. I believe this is the reason I'm seeing them loaded with two class loaders. It looks like the calls out to java don't have access, for whatever reason, to the same classloader your debugger is using.

The classpath I'm using is:
"C:\Program Files\Oxygen XML Editor 8.1\;C:\Program Files\Oxygen XML Editor
8.1\lib\oxygen.jar;Z:/myCompileDir/classes"

sorin_ristache
Posts: 4144
Joined: Fri Mar 28, 2003 2:12 pm

Post by sorin_ristache » Wed Feb 14, 2007 6:11 pm

I executed your XQuery in oXygen 8.1 without adding any jar file to oXygen. I only configured the folder containing myPackage/TestClass.class as extension of the transformation in the transformation scenario dialog, the Extensions button. My result in oXygen:

Code: Select all

<blah>returnedBlahText</blah>
and in the console:

Code: Select all

Object class: net.sf.saxon.tinytree.TinyDocumentImpl
Object loader: ro.sync.util.k@16caf43
TinyDocumentImpl loader: ro.sync.util.k@16caf43
You will get the same result with previous versions of oXygen. Naturally I get the same result if I package myPackage/TestClass.class as a jar file and set this jar file as extension instead of the folder containing myPackage/TestClass.class. As I said before the Saxon classes are loaded by oXygen from the jar files that are installed by oXygen in the lib subfolder of the install folder. As you can see the loader of net.sf.saxon.tinytree.TinyDocumentImpl is the same. Did you add TestClass.class to the classpath as explained in the User Manual section linked above (the Extensions button)?


Regards,
Sorin

dvdsdirectus
Posts: 1
Joined: Sun Apr 01, 2007 5:14 am
Location: Mansfield, OH

Post by dvdsdirectus » Sun Apr 01, 2007 5:18 am

Hello:
I am getting the same error message. I am using Saxon 8 and debugging with Stylus Studio 2007. I did discover that when I pass in a node() to the Java function, it is coming is as an ArrayList. I need to investifate further.
Gary

sorin_ristache
Posts: 4144
Joined: Fri Mar 28, 2003 2:12 pm

Post by sorin_ristache » Mon Apr 02, 2007 11:00 am

Hello,
dvdsdirectus wrote:I am using Saxon 8 and debugging with Stylus Studio 2007.
This forum is about the <oXygen/> XML Editor. If you have a question about other product you should ask the team that develops that product.


Regards,
Sorin

Post Reply