Hi Li,
The situation is that we are providing utilities for our customers. These are in the form of one or more jars. Some of these utilities rely on there only being one copy of those classes in the VM they are running in.
Whilst the problem is general, let me give you my specific situation. We provide the ability to run COBOL code as a Java stored procedure. The COBOL is translated to Java, and then wrapped up as a DB2 stored procedure. There is a runtime portion to this COBOL (written in Java) that provides COBOL language services. All this is fine. One of the things we also provide is the ability to do source level debugging of COBOL programs. This means that a client application connects to the server process using a TCP socket, and commands and responses flow down that socket. To do all this, our runtime starts a thread that reads and writes this debugging protocol and issues instructions to the normal DB2 threads. All this is done by there being a Singleton instance of a control class. The must only be one of these in the whole JVM. Since user classes are load separately into each class loader of each stored procedure thread, there are multiple copies of these classes, and this does not work. In 11.5, we were able to get rid of the problem using the extension classloader. Putting the jars in jre/lib/ext means there is only one copy of the the code in the JVM and all works fine. It is this jre/lib/ext mechanism that has been removed from Java.
Admittedly, the use of jre/lib/ext for this purpose was less than ideal, but was the only known way to do this in previous java versions. But with this gone, we are stuck.
In simple terms, there is the classloader with the DB2 code in it. Each Java stored procedure has its code loaded into a thread-local classloader whose parent is the DB2 classloader. We need the ability to either put our classes in the DB2 classloader, or for there to be another intermediary classloader (either the parent or child of the DB2 classloader) into which we can put classes.
Thank you Li for taking an interest in this issue.
The secondary issue is that our cobol runtime loads messages using ResourceBundle.getBundle().getString(). Our code has these resources in properties files inside our jar, as is the usual way with Java. These resource bundle operations now fail with Java21. It seems the internals of ResourceBundle have changed making things not work in the DB2 environment. I do suspect though, that this issue would go away for us if our code was actually loaded in a non-thread specific classloader.
Regards,
Steve
------------------------------
Steve Millington
------------------------------
Original Message:
Sent: Wed June 11, 2025 06:24 PM
From: Li Shao
Subject: Java Stored Procedures under 12.1 on Linux
Hi Steve,
I am trying to answer your question, but I think I need some clarification on the question.
Do you mean customer is using classloader to load other class in their java procedure code? by java 'extensions' classloader are you referring to loading class which are located at <JAVA_HOME>/jre/lib/ext? And this is gone in Java 21? Are you able to provide an example of the issue you are facing?
If more more detailed analysis and diagnosis is needed, I would suggest open a support case to Db2 about this issue.
Thank you.
------------------------------
Li Shao
Original Message:
Sent: Thu April 03, 2025 01:22 AM
From: Steve Millington
Subject: Java Stored Procedures under 12.1 on Linux
We have some Java classes used by our customers Java Stored Procedures running successfully on 11.5. We would love to support those customers moving to 12.1. However, there are problems.
When running on DB2 11.5, our classes need to be placed in the java 'extensions' classloader. DB2 loads user classes in to a separate classloader for each thread. This means that one cannot use a singleton pattern without placing classes in the extensions loader.
Now, in DB2 12.1, the default version of Java is 21. In that version of java, the 'extensions' classloader is no more, so using the same technique as for 11.5 is not possible.
Has anyone else hit this, and has anyone found a technique for overcoming the issue?
(We have a secondary issue with 'getResourceAsStream()' not working, but if we got the resolution to the above, it feels likely that that issue might go away)
TIA.
------------------------------
Steve Millington
------------------------------