473,386 Members | 1,791 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Unable to Debug Java SP in Stored Procedure Builder

Running DB2 v7 UDB ("DB2 v7.1.0.93", "n031208" and "WR21333") on Windows XP,
I am unable to find out why the "Build for Debug" option within Stored
Procedure Builder is not enabled on Java stored procedures. It is enabled
for SQL stored procedures.

It is possible to "Build" and "Run" the Java SPs, it just isn't possible to
click on the "Build for Debug" option. Thanks for any help in advance.

Michael
Dec 5 '05 #1
2 3124

"Michael" <in*************@nowhere.com> wrote in message
news:WH******************@news20.bellglobal.com...
Running DB2 v7 UDB ("DB2 v7.1.0.93", "n031208" and "WR21333") on Windows
XP, I am unable to find out why the "Build for Debug" option within Stored
Procedure Builder is not enabled on Java stored procedures. It is enabled
for SQL stored procedures.

It is possible to "Build" and "Run" the Java SPs, it just isn't possible
to click on the "Build for Debug" option. Thanks for any help in advance.

I was never able to get the Debugger to work for Java SPs either, despite
carefully following all instructions that were supposed to work; they worked
for many others but never for me. Mind you, I've never been great with
installing and configuring!

Let me suggest that you search the archives via Google Groups for the
technique of getting the debugger to work with Java SPs in Version 7 of UDB:
they may well work for you. Or consider upgrading to Version 8.

If an upgrade to Version 8 isn't possible and you can't get the debugger to
work, you can always resort to more old-fashioned techniques. I debugged
several Java SPs by writing System.out.println() statements to a simple log.

In fact, I even wrote a class called DB2RoutineLogger which I call from my
Java stored procs and UDFs. Here is the code for that class, followed by an
illustration of the technique for invoking it. It's not as nice as a full
screen interactive debugger but it does the job....

------------------------------------------------------------------------------------------------
package com.mydomain.udf.java;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

/**
* @author Rhino
*
*/
public class DB2RoutineLogger {

/*
*
* Variables and constants needed to support logging of this UDF.
*
*/

/**
* The path identifying the directory where the log will be written if
the
* program is running on a Windows operating system, e.g. Windows 2000,
* Windows XP. NOTE: The file separator character for Windows, '\',
needs to
* be written TWICE each time it occurs; the first backslash in each
pair is
* the Java escape character and the second backslash in each pair is
the
* actual file separator. Example: "C:\\RDS\\logs"
*/
private String logPathWindows = "C:\\RDS\\logs";

/**
* The path identifying the directory where the log will be written if
the
* program is running on a Unix operating system, e.g. AIX/6000, Linux.
* Example: "/home/rds/logs"
*/
private String logPathUnix = "/home/rds/logs";

/**
* The text that will begin all logging-related error messages to the
user,
* assuring them that they did nothing wrong and telling them (and
reminding
* support staff) that further information is available in DB2's
db2diag.log
* file, which is usually situated in SQLLIB\DB2.
*
* DB2 is only capable of showing around 40 characters worth of
* programmer-supplied text in the SQL4302N message that is displayed
when
* the program throws an exception. Since the following text is the most
* important information for the *USER* to see, this is made the leading
* part of the information that is displayed. Additional information is
* normally written to the db2diag.log for the use of systems personnel
in
* diagnosing the problem.
*/
private static final String USER_MESSAGE = "Internal error. Support: See
db2diag.log. ";

/** The desired format of the timestamp used in the log. */
private static final String TIMESTAMP_PATTERN = "yyyy-MM-dd
HH.mm.ss.SSS";

/**
* The Simple Date Format that will be used for creating the current
* timestamp.
*/
private static final SimpleDateFormat TIMESTAMP_FORMAT = new
SimpleDateFormat(
TIMESTAMP_PATTERN, Locale.getDefault());

/** The log file which is written by this class. */
private File outputFile = null;

/** A String concatenation that identifies which class has called this
class. */
private String sourceCodeLocation = null;
/**
* This constructor establishes a reference to an instance of the class
and creates
* the String concatenation which identifies the class which invoked the
constructor,
* which is the class that needs diagnostics generated.
*
* @param incomingPackageName the name of the package containing the
class which invoked this class
* @param incomingClassName the name of the class which invoked this
class
* @param incomingMethodName the name of the method which invoked this
class
*/
public DB2RoutineLogger(String incomingPackageName, String
incomingClassName, String incomingMethodName) {

this.sourceCodeLocation = incomingPackageName + "." +
incomingClassName + "." + incomingMethodName;
}
/*
*
* Utility methods used primarily to support logging.
*
*/

/**
* Set the log path for a Unix environment.
*
* @param String the desired log path in a Unix environment
*/
public void setLogPathUnix(String logPathUnix) {

this.logPathUnix = logPathUnix;
}

/**
* Get the log path for a Unix environment.
*
* @return String the log path currently set for a Unix environment
*/
public String getLogPathUnix() {

return logPathUnix;
}

/**
* Set the log path for a Windows environment.
*
* @param String logPathWindows the desired log path in a Windows
environment
*/
public void setLogPathWindows(String logPathWindows) {

this.logPathWindows = logPathWindows;
}

/**
* Get the log path for a Windows environment.
*
* @return String the log path currently set for a Windows environment
*/
public String getLogPathWindows() {

return logPathWindows;
}

/**
* Method getLogPath() chooses the log path based on the operating
system name.
*
* @version 1.0
* @since 2005-03-03
*
* @return String log path
*/
public String getLogPath() {

/*
* Determine the directory in which the log file will be written
based on the
* current operating system.
*/
if (System.getProperty("os.name").startsWith("Windows ")) {
return logPathWindows;
}
else {
return logPathUnix;
}
}

/**
* Method createFile() creates an output file.
*
* <p>
* If the log file cannot be created for some reason, carry on
regardless with the
* "main mission" of the UDF. Don't inform the user. [The
System.err.println()
* statements in the catch blocks are just placeholders; they won't
actually
* be written when running in a UDF.] The developer who wanted to
activate logging
* will realize that logging failed when the log isn't where it was
intended to be.
* </p>
*
* @version 1.0
* @since 2005-03-03
*
* @see #writeToFile(BufferedWriter, String)
* @see #closeFile(BufferedWriter)
*
* @param path the directory path into which the file will be written
* @param fileName the name of the file which will be written
* @return BufferedWriter
*/
public BufferedWriter createFile(String path, String fileName) {

String METHOD_NAME = "createFile()";

/*
* See if the output directory exists; if it doesn't, create it and
any
* needed parent directories.
*/
File outputPath = new File(path);
if (!outputPath.exists()) {
try {
outputPath.mkdirs();
} catch (SecurityException s_excp) {
System.err.println(USER_MESSAGE + "Problem:
SecurityException ("
+ s_excp.getMessage() + "). Code location: "
+ sourceCodeLocation
+ ". Programmer message: Could not create output
path, "
+ outputPath + ".");
}
}

/* See if the output file exists; if it doesn't, create it. */
outputFile = new File(outputPath, fileName);
if (!outputFile.exists()) {
try {
outputFile.createNewFile();
} catch (IOException io_excp) {
System.err.println(USER_MESSAGE + "Problem: IOException ("
+ io_excp.getMessage() + "). Code location: "
+ sourceCodeLocation
+ ". Programmer message: Could not create log file,
" + outputFile + ".");
} catch (SecurityException s_excp) {
System.err.println(USER_MESSAGE + "Problem:
SecurityException ("
+ s_excp.getMessage() + "). Code location: "
+ sourceCodeLocation
+ ". Programmer message: Could not create log file,
" + outputFile + ".");
}
}

BufferedWriter bufferedWriter = null;
/* Ensure that the FileWriter is opened in such a way that each
write appends to the file. */
try {
FileWriter fileWriter = new FileWriter(path + File.separator +
fileName, true);
bufferedWriter = new BufferedWriter(fileWriter);
} catch (IOException io_excp) {
System.err.println(USER_MESSAGE + "Problem: IOException ("
+ io_excp.getMessage() + "). Code location: "
+ sourceCodeLocation
+ ". Programmer message: Could not create FileWriter or
BufferedWriter.");
}

return (bufferedWriter);
}

/**
* Method writeToFile() writes a single line a file.
*
* <p>
* If the log file cannot be written for some reason, carry on
regardless with the
* "main mission" of the UDF. Don't inform the user. [The
System.err.println()
* statement in the catch block is just a placeholder; it won't actually
* be written when running in a UDF.] The developer who wanted to write
to the
* log will presumably realize that there was a problem when the log is
empty
* or when some of the expected lines are missing.
* </p>
*
* @version 1.0
* @since 2005-03-03
*
* @see #createFile(String, String)
*
* @param outputFile
* the BufferedWriter for the file
* @param oneLine
* the line which is to be written to the file
*/
public void writeToFile(BufferedWriter outputFile, String oneLine) {

String METHOD_NAME = "writeToFile()";

/* Get the current timestamp from the system. */
Date currentDateTime = new Date(System.currentTimeMillis());

/* Format the timestamp. */
String formattedDateTime = TIMESTAMP_FORMAT.format(currentDateTime);

/*
* Create the locator, which concatenates the formatted current
timestamp
* and the source code location to identify exactly when a given
event took
* place and what source code initiated that event.
*/
String locator = formattedDateTime + " - " + sourceCodeLocation +
" - ";

/*
* Write the incoming line of information after the locator, write a
newline,
* and then flush to ensure that all output is written to the file,
not left
* behind in the buffer.
*/
try {
outputFile.write(locator + oneLine);
outputFile.newLine();
outputFile.flush();
} catch (IOException io_excp) {
System.err.println(USER_MESSAGE + "Problem: IOException ("
+ io_excp.getMessage() + "). Code location: "
+ sourceCodeLocation
+ ". Programmer message: Could not create write line, '"
+ oneLine + "', to log.");
}

}
/**
* Method closeFile() closes the file.
*
* <p>
* If the log file cannot be closed for some reason, carry on regardless
with the
* "main mission" of the UDF. Don't inform the user. [The
System.err.println()
* statement in the catch block is just a placeholder; it won't actually
* be written when running in a UDF.] The developer who wanted to close
the log
* probably won't care if the log isn't closed and will rely on the
operating
* system to close it eventually.
* </p>
*
* @version 1.0
* @since 2005-03-03
*
* @see #createFile(String, String)
*
* @param outputFile
* the BufferedWriter for the file which is to be closed
*/
public void closeFile(BufferedWriter outputFile) {

String METHOD_NAME = "closeFile()";

try {
outputFile.close();
} catch (IOException io_excp) {
System.err.println(USER_MESSAGE + "Problem: IOException ("
+ io_excp.getMessage() + "). Code location: "
+ sourceCodeLocation
+ ". Programmer message: Could not close log.");
}
}
/**
* Method getStack() writes a stackTrace to a String, given a Throwable.
*
* <p>This is a utility method that will appear in every UDF that needs
to return
* a stackTrace.</p>
*
* @version 1.0
* @since 2004
*
* @param Throwable an Error or Exception
* @return String containing the stackTrace for the Throwable in String
format
*/
public String getStack (Throwable throwable) {

StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
throwable.printStackTrace(printWriter);
printWriter.close();

return (stringWriter.toString());
}
}
------------------------------------------------------------------------------------------------

To invoke the DB2RoutineLogger class from my UDF or stored procedure, I
include the following class variables in the SP or UDF:

-----------------------------------------------------------------------------------------------
/**
* If true, file logging of this UDF will be attempted. If successful,
the log output
* will be written to a file with the name specified in the 'LOG_FILE'
constant. The
* path to that file is operating system dependent; see the code in the
getLogPath()
* method.
*/
private static final boolean DO_LOGGING = true;
/**
* The name of the package. This need not be the actual package name;
instead it is used
* primarily to distinguish between UDFs that are written using
parameter style DB2GENERAL
* from UDFs written with parameter style DB2JAVA on the theory that
UDFs written for one
* parameter style will be in a different package than UDFs written in
the other parameter
* style.
*/
private static final String PACKAGE_NAME = "DB2JAVA";

/** The name of this class. */
private static final String CLASS_NAME = "Counter";

/** The name of the log file. */
private static final String LOG_FILE = "myUDFandSP.log"; //replace the
constant with a name you like better

/** The buffered writer which is used to write the log. */
private static BufferedWriter log = null;

/** The class used to write log information. */
private static DB2RoutineLogger logger = null;
------------------------------------------------------------------------------------------------

Then, in the constructor for my SP or UDF, I include this code to create the
log file and to close it when the UDF/SP is finished:
------------------------------------------------------------------------------------------------

String METHOD_NAME = "myMethod()"; //replace the constant with the
actual method name

/*
* Create the log file and write the input parameters to the log. If
the log file
* cannot be created for some reason, this will be obvious to the
developer by the
* absence of the log file. Proceed with the "main mission" of the
UDF.
*/
if (DO_LOGGING) {
logger = new DB2RoutineLogger(PACKAGE_NAME, CLASS_NAME,
METHOD_NAME);
log = logger.createFile(logger.getLogPath(), LOG_FILE);
}

// DO THE NORMAL WORK OF THE UDF or SP.

if (DO_LOGGING) {
logger.closeFile(log);
}
------------------------------------------------------------------------------------------------

Then, every time I want to display a variable value from the SP or UDF, I
execute code like this:

------------------------------------------------------------------------------------------------
if (DO_LOGGING) {
logger.writeToFile(log, "count: " + count); //replace 'count'
with your variable name
}

------------------------------------------------------------------------------------------------

I hope this helps.

Rhino
Dec 6 '05 #2
Hi Rhino,

Thanks for the debugging class. Despite going over various web pages,
newsgroup messages (including yours), and software documentation (DB2 and
Distributed Debugger) I haven't been able to debug the Java stored
procedures. It seems the best approach is to develop the Java code outside
of the Stored Procedure Builder (SPB) in something like Eclipse. Once it
works well the code can be pasted into SPB and DriverManager connection
calls can be updated to use the default connection established by the SP
call.

Michael

"Rhino" <no***********************@nospam.com> wrote in message
news:_g*******************@news20.bellglobal.com.. .

"Michael" <in*************@nowhere.com> wrote in message
news:WH******************@news20.bellglobal.com...
Running DB2 v7 UDB ("DB2 v7.1.0.93", "n031208" and "WR21333") on Windows
XP, I am unable to find out why the "Build for Debug" option within
Stored Procedure Builder is not enabled on Java stored procedures. It is
enabled for SQL stored procedures.

It is possible to "Build" and "Run" the Java SPs, it just isn't possible
to click on the "Build for Debug" option. Thanks for any help in
advance.

I was never able to get the Debugger to work for Java SPs either, despite
carefully following all instructions that were supposed to work; they
worked for many others but never for me. Mind you, I've never been great
with installing and configuring!

Let me suggest that you search the archives via Google Groups for the
technique of getting the debugger to work with Java SPs in Version 7 of
UDB: they may well work for you. Or consider upgrading to Version 8.

If an upgrade to Version 8 isn't possible and you can't get the debugger
to work, you can always resort to more old-fashioned techniques. I
debugged several Java SPs by writing System.out.println() statements to a
simple log.

In fact, I even wrote a class called DB2RoutineLogger which I call from my
Java stored procs and UDFs. Here is the code for that class, followed by
an illustration of the technique for invoking it. It's not as nice as a
full screen interactive debugger but it does the job....

Dec 11 '05 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: dinesh prasad | last post by:
I'm trying to use a servlet to process a form, then send that data to an SQL server stored procedure. I'm using the WebLogic 8 App. server. I am able to retrieve database information, so I know my...
4
by: richardshen | last post by:
DB2 V8 FP4 on W2K. After a long long time waiting.. SQL1131N DARI (Stored Procedure) process has been terminated abnormally. SQLSTATE=38503 And in DB2Diag.log
4
by: Rhino | last post by:
Is it possible for a Java Stored Procedure in DB2 V7.2 (Windows) to pass a Throwable back to the calling program as an OUT parameter? If yes, what datatype should I use when registering the...
1
by: Raquel | last post by:
Have a question on the Stored procedure method code generated by DB2 development center for Java stored procedures. Suppose I have a requirement to return the resultset consisting of FIRSTNME,...
4
by: Abram Friesen | last post by:
Hi all, I'm a newbie at DB2 and trying to create a simple java UDF. When I call my function, I'm receiving SQL4306N. Could someone please tell me what I'm doing wrong here? Here is my java...
2
by: Kent Lewandowski | last post by:
hi all, Recently I wrote some stored procedures using java jdbc code (admittedly my first stab) and then tried to implement the same within java packages (for code reuse). I encountered...
0
by: JollyK | last post by:
Hello folks, Previously I have debugged stored procedures with VS.NET 2002 on Windows 2000 successfully. I know that in order to debug a stored procedure, I need to enable SQLServer debugging...
0
by: DR | last post by:
Unable to start TSQL Debugging. Could not attach to SQL Server Process on 'srvname'. The RPC server is unavailable. I get this error when I try to run a SQL Server Project with a CLR stored...
1
by: okonita | last post by:
Hello all, I have a Java problem that I hope can be answered here. Very new to DB2 UDB and UDF (we are on DB2v9.5, Linux and Windows), I have managed to get the UDF registered but having problem...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.