You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@xalan.apache.org by Bassi Suk <ba...@mellon.com> on 2000/12/15 17:21:42 UTC

RE: Xalan Extensions: using a single instance rather than new i nstantiation

Gary,

Thanks a lot for your assistance.

We have got it to work with your suggestion on making 'myMethod' static.

However, the second suggestion (still using the singleton approach) did not
seem to work - we got an exception when we passed the instance in as the
first parameter of any subsequent calls.

I think l was a bit too sketchy on the attributes of the java extension.
Here is more detail as to the java code:

public class MyDBFactory{
	private static MyDBFactory instance = null; 
	private static DataSourceImpl ds = null;

	private MyDBFactory(){
	}

	public static synchronized MyDBFactory getInstance() {
		if (instance == null) {
			instance = new myDBFactory();
			instance.init();
		}
		return instance;
	}

	private void init() {
		....
		// set data source from naming service lookup 
		ds = ....etc
		
	}

	public synchronized Connection getConnection() {
		...
		// returns a database connection from a pool of connections
managed by an external resource
	}


	public String getCustomer(String s1, String s2) {
		....
		uses getConnection to get DB connection, issues a sql select
statement
		and returns result
	}
}


When we put the following in the xslt:
...
<xsl:variable name="my-singleton" select="xyzExt:getInstance()"/>
<xsl:variable name="value"
select="xyzExt:getCustomer($my-singleton,$variable1,$variable2)"/>
...
....

we get the following error message:

....
...
Call to extension function failed: method call/new failed:
java.lang.reflect.InvocationTargetException target exception:
java.lang.Exception: MyDBFactory::Get connection, process, or close
statement exception: null: 
....
....

I think this may be because the inital getInstance call is a static method
but the subsequent call getCustomer is not statically declared.

To summarise, we have a solution that works based on your first suggestion,
but I just wondered if you had any ideas on how we could get the other
option to work as this method of calling fits the pattern we have used a lot
in our system.

regards,
Suk.




> -----Original Message-----
> From:	Gary L Peskin [SMTP:garyp@firstech.com]
> Sent:	Thursday, December 14, 2000 5:54 PM
> To:	Bassi Suk
> Cc:	'xalan-dev@xml.apache.org'
> Subject:	Re: Xalan Extensions: using a single instance rather than
> new   instantiation
> 
> Bassi Suk wrote:
> > Therefore, in the XSLT stylesheet we want to call the
> > mySingleton.getInstance() and get an instance of mySingleton and then be
> > able to use the mySingleton.myMethod().
> > 
> > The QUESTION is, what should the XSLT syntax be for the above to occur.
> 
> Suk --
> 
> This depends on whether you're using XalanJ1 or XalanJ2, as I'll explain
> below.  Let's start with XalanJ1 since that's the most stable version,
> for now.
> 
> First of all, I recommend not using the lxslt:component/script
> construct.  It's not needed for java language extensions.  Second, you
> don't need the extension-element-prefixes attribute.  That's only if you
> have extension -elements- and your example is limited to an extension
> -function-.
> 
> In XalanJ1, you should be able to prefix your namespace URI with
> "class:" to prevent instantiation of the class by Xalan.  This is not
> necessary in XalanJ2.
> 
> Finally, you might want to consider just making myMethod a static
> method.  That way you wouldn't need to instantiate any instances of
> mySingleton at all.
> 
> Assuming myMethod is static, your java would look like:
> 
> public class mySingleton {
>   private mySingleton() {}
>   public static String myMethod() {
>     return "We are humbled";
>   }
> }
> 
> You could invoke this method with a stylesheet that looks like this:
> 
> <?xml version="1.0" ?> 
> <xsl:stylesheet 
>         xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>         xmlns:xyzExt="class:mySingleton"
>         version="1.0">
> 
> <xsl:variable name="value" select="xyzExt:myMethod()"/>
>  ...
> </xsl:stylesheet>
> 
> If you wanted to stick with instantiating a singleton object, you java
> code would look like that in your email and the stylesheet could look
> like this:
> 
> 
> <?xml version="1.0" ?> 
> <xsl:stylesheet 
>         xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>         xmlns:xyzExt="class:mySingleton"
>         version="1.0">
> 
> <xsl:variable name="my-singleton" select="xyzExt:getInstance()"/>
> <xsl:variable name="value" select="xyzExt:myMethod($my-singleton)"/>
>  ...
> </xsl:stylesheet>
> 
> When calling an instance method, you need to supply the object as the
> first argument to the method call.  The extension mechanism uses the
> first argument to determine on what object the method is being invoked. 
> It then strips off that first argument and passes the remaining
> arguments to the actual java function.
> 
> HTH,
> Gary
*****************************************************************
DISCLAIMER:   The information contained in this e-mail may be confidential
and is intended solely for the use of the named addressee.  Access, copying
or re-use of the e-mail or any information contained therein by any other
person is not authorized.  If you are not the intended recipient please
notify us immediately by returning the e-mail to the originator.    

Re: Xalan Extensions: using a single instance rather than new instantiation

Posted by Gary L Peskin <ga...@firstech.com>.
Bassi Suk wrote:
> However, the second suggestion (still using the singleton approach) did not
> seem to work - we got an exception when we passed the instance in as the
> first parameter of any subsequent calls.
> 
> I think l was a bit too sketchy on the attributes of the java extension.
> Here is more detail as to the java code:
> 
> public class MyDBFactory{
>         private static MyDBFactory instance = null;
>         private static DataSourceImpl ds = null;
> 
>         private MyDBFactory(){
>         }
> 
>         public static synchronized MyDBFactory getInstance() {
>                 if (instance == null) {
>                         instance = new myDBFactory();
>                         instance.init();
>                 }
>                 return instance;
>         }
> 
>         private void init() {
>                 ....
>                 // set data source from naming service lookup
>                 ds = ....etc
> 
>         }
> 
>         public synchronized Connection getConnection() {
>                 ...
>                 // returns a database connection from a pool of connections
> managed by an external resource
>         }
> 
>         public String getCustomer(String s1, String s2) {
>                 ....
>                 uses getConnection to get DB connection, issues a sql select
> statement
>                 and returns result
>         }
> }
> 
> When we put the following in the xslt:
> ...
> <xsl:variable name="my-singleton" select="xyzExt:getInstance()"/>
> <xsl:variable name="value"
> select="xyzExt:getCustomer($my-singleton,$variable1,$variable2)"/>
> ...
> ....
> 
> we get the following error message:
> 
> ....
> ...
> Call to extension function failed: method call/new failed:
> java.lang.reflect.InvocationTargetException target exception:
> java.lang.Exception: MyDBFactory::Get connection, process, or close
> statement exception: null:

Bassi --

The diagnostics from the Xalan extension mechanism are not that great
for this version of XalanJ.  We really need to find out where this
message is being issued from as to whether its in the getInstance() call
or the getCustomer() call.  If it's in the getCustomer() call, then at
least we know that the mechanism is calling the correct method.

If you are able to run your code in a debugger, I would do that
first.    Also, if you're running Xalan from the command line, use the
"-edump" command line option which will produce a stack trace.

Failing both of those options, I'd place statements like:

  System.err.println("Entering getCustomer.");
-and-
  System.err.println("Existing getCustomer.");

at the beginning and end of the getCustomer, getConnection, init, and
constructor methods.  At least then we'll be able to see where the
exception is being thrown from and we can go from there.

The message that you're getting:

MyDBFactory::Get connection, process, or close statement exception:
null: 

is coming from somewhere in your code and these techniques should help
track it down.  Please come back with your results.

Gary