View Single Post

   
  #4 (permalink)  
Old 02-27-2008, 06:56 AM
Knut Stolze
 
Posts: n/a
Default Re: UnsatisfiedLinkError in Java UDF

Rhino wrote:

>
> "Knut Stolze" <stolze@de.ibm.com> wrote in message
> news:e2t9qi$v2u$1@lc03.rz.uni-jena.de...
>> Rhino wrote:
>>
>>> I'm trying to debug a simple Java UDF written in the DB2General style
>>> within Eclipse.
>>>
>>> I'm getting a java.lang.UnsatisfiedLinkError when I execute the set()
>>> method in the UDF. I know that the UnsatisfiedLinkError has something to
>>> do with a DLL that is not visible but I'm not sure why I'm having the
>>> problem given that both db2java.zip and db2jcc.jar are visible on my
>>> classpath and each of them contain the COM.ibm.db2.app.UDF class with a
>>> variety of set() methods, including the one that I am trying to execute.
>>> I've also tried removing db2java.zip from the classpath to see if that
>>> would help prevent the error but it didn't.
>>>
>>> Does anyone have any idea how I can solve this problem?
>>>
>>> This is the UDF. By the way, I'm pretty sure there are no errors in it
>>> and
>>> I know the code is trivial; I'm just trying to debug it with Eclipse to
>>> prove that I can. Another UDF I wrote that also grabs the leftmost
>>> characaters of a String works fine but it is written in style "Java" and
>>> is therefore missing the set() method.
>>>
>>>

>>

---------------------------------------------------------------------------------------------------------------------
>>> public void leftmost(String input, int size, String output) throws
>>> Exception {
>>>
>>> String trimmedInput = input.trim();
>>> if (trimmedInput.length() < size) size = trimmedInput.length();
>>> String leftmost = trimmedInput.substring(0, size);
>>>
>>> set(3, leftmost);
>>> }
>>>

>>

---------------------------------------------------------------------------------------------------------------------
>>
>> How did you register the function in your database, i.e. what's the exact
>> CREATE FUNCTION statement?
>>

> Sorry for the delay in replying; I spent most of yesterday trying things
> that were implied by your note....
>
> This is the definition of the leftmost() UDF function that was in effect
> when I posted my question:
>
> --------------------------------------------------------------------
> CREATE FUNCTION leftmost (varchar(4000), int)
>
> RETURNS varchar(4000)
>
> SPECIFIC leftmost
>
> EXTERNAL NAME 'TextUDFs_Java:com.foo.java.TextUDFs.leftmost'
>
> LANGUAGE JAVA
>
> PARAMETER STYLE JAVA
>
> DETERMINISTIC
>
> NO EXTERNAL ACTION
>
> FENCED
>
> RETURNS NULL ON NULL INPUT
>
> ALLOW PARALLEL
>
> NO DBINFO
>
> NO SQL
>
> NO SCRATCHPAD
>
> NO FINAL CALL;
>
> --------------------------------------------------------------------
>
> The leftmost() function works just fine from the command line when defined
> this way and I can debug it in Eclipse too; I can step through every
> statement of the UDF and the driver. Naturally, the method is defined
> somewhat differently than shown in my original post though; this is the
> source code for leftmost(), as written for parameter style Java, stripped
> to its bare bones:
>
>

---------------------------------------------------------------------------------------------------------------------
> public static String leftmost(String input, int size) throws
> SQLException {
>
> try {
> String trimmedInput = input.trim();
> if (trimmedInput.length() < size) size =
> trimmedInput.length(); String output =
> trimmedInput.substring(0, size); return (output);
> } catch (Exception excp) {
> throw new SQLException("leftmost() - " + excp.getMessage(),
> "38600");
> }
>

---------------------------------------------------------------------------------------------------------------------
>
>
> However, when I use the code shown in the first post of this thread and I
> replace the definition of the leftmost() function with this:
>
> --------------------------------------------------------------------
>
> CREATE FUNCTION leftmost (varchar(4000), int)
> RETURNS varchar(4000)
> SPECIFIC leftmost
> EXTERNAL NAME 'TextUDFs_DB2General:com.foo.db2general.TextUDFs.l eftmost'


You're using a JAR file here. Have you packaged your Java code into such a
JAR file and used the SQLJ.INSTALL_JAR procedure to load it into the
database?

> LANGUAGE JAVA
> PARAMETER STYLE DB2GENERAL
> DETERMINISTIC
> NO EXTERNAL ACTION
> FENCED
> RETURNS NULL ON NULL INPUT
> ALLOW PARALLEL
> NO DBINFO
> NO SQL
> NO SCRATCHPAD
> NO FINAL CALL;
>
> --------------------------------------------------------------------
>
> I get an UnsatisfiedLinkError when I reach the set() statement at the end
> of the method during debugging in Eclipse. The function still works just
> fine from the command line.


You mean that you can call the SQL function in a SQL statement executed on
the command line? And it fails if you debug it through Eclipse?

> Do you have any idea what I need to change in order to be able to debug my
> function in Eclipse and step through all of the statements, _including_
> the set()?


I don't know for sure. One guess might be that you don't have all the
necessary files/directories in the CLASSPATH.

> I can always write diagnostic lines to a logging file if I have to for
> debugging purposes but I'd rather just use Eclipse if that is possible. It
> is considerably less cumbersome to simply step through the real code with
> a good debugger than it is to add diagnostic code to my program.


Debugging UDFs and procedures is, unfortunately, not a straight forward task
due to the complex environments. I've done this quite often for C/C++ code
but not yet for Java.

What you could also do is to write a "main" function wrapper in Java that
calls your routine directly, taking DB2 out of the picture.

--
Knut Stolze
DB2 Information Integration Development
IBM Germany
Reply With Quote