In a typical enterprise application environment, DB2 applications
often use the SQLJ tools db2sqljcustomize and db2sqljbind. These SQLJ
tools call Java programs that provide tooling necessary for customizing
and binding SQLJ applications. In the current design, these Java programs
then return to the shell with an exit code. This is
accomplished through the JVM-supported System.exit() call. A 0
(zero) indicates success, while a non-zero return code indicates failure of
the customization or bind process.
System.exit() means the JVM exits and is unsuitable for special build tools
like Ant or Maven, which need a continuous JVM. In the past, there was
no alternate way by which you could trap the System.exit or JVM exit after
customization and the bind process. In such cases, you had to run the
application again to continue with the rest of the business logic. This
would be fine when running the utilities in a shell script, but in a
special build tool like Ant, when a Java program calls System.exit(), it
can cause problems. For example, if the build tool, such as Ant, works
with a default security manager that does not trap System.exit
and executes in the same JVM as Ant, it may exit after the customization
or bind process.
In this article, you'll take a tour of the new JDBC Universal Driver global
property db2.jcc.sqljToolsExitJVMOnCompletion
and see how to use it.
To use the new global property, you need the following:
- A simple SQLJ application and SQLJ serialized profile — A Java application with embedded SQL statements. Translation of SQLJ applications produce .class files and one or more serialized profiles. It calls the Java compiler by default.
- A simple JDBC application — A simple Java application having SQLJ tools like db2sqljcustomize and db2sqljbind.
- IBM DB2 Universal Driver for SQLJ and JDBC — The Universal Driver is com.ibm.db2.jcc.DB2Driver and is contained in db2jcc.jar. The sqlj.zip contains the SQLJ translator.
- Global property file DB2JccConfiguration.properties
— This resource file is to set the property
db2.jcc.sqljToolsExitJVMOnCompletion. The property can be set in DB2Configuration.properties or passed via-Dto the Java command. There are also other ways in which you can set the property, refer to the Information Center section on Customization of IBM Data Server Driver for JDBC and SQLJ configuration properties.
Advantages of the new JCC property
The new global JCC property
db2.jcc.sqljToolsExitJVMOnCompletion has a
Boolean return type. The default value for this property is true, which
means that all SQLJ tools will call System.exit() upon completion. To
trap System.exit() after SQLJ tools execution, you need to set the
property value as false:
db2.jcc.sqljToolsExitJVMOnCompletion=false.
Whether there is an error or not, by default, the JVM will exit when
System.exit is called. The execution of SQLJ
tools call System.exit regardless of an error. When
the property is set to false, the shell gets a 0 return code even in
case of customization failure. You can use customizeMain programmatically
to get a return code from the method.
If you set the property value as
db2.jcc.sqljToolsExitJVMOnCompletion=false and
there is an error in the customize or bind process, the application
return code will be 0.
if you set the property value as
db2.jcc.sqljToolsExitJVMOnCompletion=true and
there is an error in the customize or bind process, application
return code will be non-zero.
Sample application use case and configuration
Make sure you have put the Universal Driver JAR files db2jcc.jar and sqlj.zip into the classpath.
Step 2: Writing a simple SQLJ application
This SQLJ application connects to a database with data source object ds and fetches the rows from existing table Employee with positioned iterator
ByPos.
Listing 1. SQLJ program fetching rows from an existing table
import java.sql.*;
// Create connection context class DB2Connect
#sql context DB2Connect;
// Declare positioned iterator ByPos
#sql iterator ByPos(String,int);
public class sqljapp {
public static void main(String[] args) throws Exception
{
// Create a DataSource object ds
javax.sql.DataSource ds =
new com.ibm.db2.jcc.DB2SimpleDataSource();
((com.ibm.db2.jcc.DB2BaseDataSource) ds).
setServerName("localhost");
((com.ibm.db2.jcc.DB2BaseDataSource) ds).
setPortNumber(50000);
((com.ibm.db2.jcc.DB2BaseDataSource) ds).
setDatabaseName("SAMPLE");
((com.ibm.db2.jcc.DB2BaseDataSource) ds).
setDriverType(4);
java.sql.Connection con =
ds.getConnection("administrator", "passwd");
// Creating connection context object db2con
DB2Connect db2con = new DB2Connect(con);
// Declare the object of ByPos class
ByPos positer;
// Use db2con for executing an SQL statement
#sql[db2con] positer= { select * from EMPLOYEE };
}
}
|
Step 3: Translating the SQLJ application
Translating the application generates a standard Java source file, plus an
SQLJ serialized profile
(sqljapp_SJProfile0.ser).
Listing 2. Translation of SQLJ program
C:\jcc_home3\jcc>sqlj sqljapp.sqlj |
Step 4: Executing the Java application
This is a simple Java application in which you are passing parameters to
the customization utility. You are executing the Java application in a
single JVM without a new property. The application should exit to the
caller with a return code using the System.exit(). The return code will be
0 if customization executes successfully. The application should not
call any code (the function fun_checkJVM) after completing the
db2sqljcustomize utility.
Listing 3. Java application without using property
db2.jcc.sqljToolsExitJVMOnCompletion
public class JVMexit {
public static void main(String a[]) throws Exception {
// Array of String as parameters to db2sqljcustomize
String[] cmd = { "-url", "jdbc:db2://localhost:50000/SAMPLE",
"-user","administrator", "-password", "passwd", "-onlinecheck",
"YES", "-rootPkgName", "BCB", "-collection", "COL18",
"-tracefile", "trace_cust.txt", "-tracelevel", "TRACE_ALL",
"sqljapp_SJProfile0.ser" };
// Create an object of db2sqljcustomize
com.ibm.db2.jcc.sqlj.Customizer cust = new
com.ibm.db2.jcc.sqlj.Customizer();
// Execute the db2sqljcustomize with arguements
cust.main(cmd);
/* Function to check if JVM exited or not,if exited it will not call
below function or else it will. */
fun_checkJVM();
}
private static void fun_checkJVM() {
System.out.println("JVM didn't exit");
}
}
|
So far, you have seen how to execute the Java application in a single JVM
without using the new global property. (The default value of the property
is true — db2.jcc.sqljToolsExitJVMOnCompletion=true). Now
let's look at a scenario where you can set the value of the property as
db2.jcc.sqljToolsExitJVMOnCompletion=false in
the global property file DB2JccConfiguration.properties to execute the
same Java application.
Step 5: Global file DB2JccConfiguration.properties
Create a resource file named DB2JccConfiguration.properties, put it in the classpath and add the property as shown below.
Listing 4. DB2JccConfiguration.properties
//Add the property value as false in file db2.jcc.sqljToolsExitJVMOnCompletion=false |
Step 6: Execute the Java application
The application will execute the code after the customization process
completes. The function fun_checkJVM() will be
called, which proves that the application did not call System.exit() after the customization process completion.
Now look at a scenario where you want to execute the whole Java application
with an error in the customization process. By setting the property value
as false
(db2.jcc.sqljToolsExitJVMOnCompletion=false),
you can achieve that as well.
Step 7: Execute the Java application including wrong parameters
In the example of execution of an application with wrong parameters, an
error exists in customizer/bind process even though the application calls
function fun_checkJVM(), which proves that
application did not call System.exit() after the customization process
completion.
Listing 5. Java application including wrong parameters
public class JVMexit {
public static void main(String a[]) throws Exception {
// Array of String with wrong port # as parameter to db2sqljcustomize
String[] cmd = { "-url", "jdbc:db2://localhost:5000/SAMPLE",
"-user","administrator", "-password", "passwd", "-onlinecheck",
"YES", "-rootPkgName", "BCB", "-collection", "COL18",
"-tracefile", "trace_cust.txt", "-tracelevel", "TRACE_ALL",
"sqljapp_SJProfile0.ser" };
// Create an object of db2sqljcustomize
com.ibm.db2.jcc.sqlj.Customizer cust = new
com.ibm.db2.jcc.sqlj.Customizer();
// Execute the db2sqljcustomize with arguments
cust.main(cmd);
/* Function to check if JVM exited or not,if exited it will not call
below function or else it will. */
fun_checkJVM();
}
private static void fun_checkJVM() {
System.out.println("JVM didn't exit");
}
}
|
In this article, we have shown how you can use the new property
db2.jcc.sqljToolsExitJVMOnCompletion to trap
System.exit() upon completion of SQLJ tools such as customization and
bind. Once you set the property value as false, the application will not
exit JVM even if there is an error in the execution of SQLJ tools, and you
can continue with execution of your application.
Learn
- Refer to the Information Center section
about db2sqljcustomize and db2sqljbind
for more information about these tools.
- Learn more about Customization of IBM Data Server Driver for JDBC and SQLJ
configuration properties in the Information Center.
- Learn more about DB2 in the DB2 for Linux, UNIX, and Windows on developerWorks.
- Learn more about Java
application development with DB2.
- Learn more about Information Management at the developerWorks Information Management
zone. Find technical documentation,
how-to articles, education, downloads, product information, and
more.
- Stay current with
developerWorks technical events and webcasts.
- Follow developerWorks on
Twitter.
Get products and technologies
- Build your next
development project with
IBM trial software,
available for download directly from developerWorks.
Discuss
- Participate in the discussion forum.
- Check out the
developerWorks
blogs and get involved in the
developerWorks community.

Sujan Ghosh has been a software engineer at the IBM lab in India for more than four years as a member of the DB2 Java common connectivity and pureQuery client optimization team. Most of his projects have been based on DB2 and Java technology. He is an IBM Certified Database Administrator for DB2 for Linux, UNIX, and Windows, and an IBM Certified Solution Developer for XML.




