DB2 Java 存储过程 NoSuchMethodError
Posted
技术标签:
【中文标题】DB2 Java 存储过程 NoSuchMethodError【英文标题】:DB2 Java Stored Procedure NoSuchMethodError 【发布时间】:2014-05-15 16:31:11 【问题描述】:我目前正在使用 IBM DB2 v10.1 企业版。我需要创建一个 Java 存储过程,它连接到远程 TCP 服务器(同样在 Java 中)。因此,我用Java编写了以下类(文件名为SystemClient.java):
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class SystemClient
public static void callSystemML(String serverIPAddress, Integer serverPort,
String script, String args) throws IOException, ClassNotFoundException
Socket socket = new Socket(serverIPAddress, serverPort);
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
writer.println(script + "|" + args);
String line = reader.readLine();
writer.close();
reader.close();
socket.close();
所以,我使用以下命令为上面的类创建一个 Jar 文件:
javac SystemClient.java
jar cvf SystemClient.jar SystemClient.class
然后我从 DB2 命令行调用以下命令:
db2 "call sqlj.install_jar('file:/path/to/jar/SystemClient.jar','SYSTEM_ML_CLIENT_JAR', 0)
之后,我通过执行以下命令验证我的 JAR 是否已正确注册:
db2 "select jar_id from sysibm.sysjarcontents"
并检查新 Jar 是否已注册。然后,我有以下脚本用于创建我的 SQL 存储过程(文件名:create-system-call.sql):
CREATE OR REPLACE PROCEDURE DB2INST1.ML_CLIENT_CALL(
IN serverIPAddress VARCHAR(255),
IN serverPort INTEGER,
IN script VARCHAR(255),
IN args VARCHAR(255))
LANGUAGE java
PARAMETER STYLE java
FENCED THREADSAFE
EXTERNAL NAME 'SYSTEM_ML_CLIENT_JAR:SystemClient.callSystemML(java.lang.String, java.lang.Integer, java.lang.String, java.lang.String)';
我再次执行以下脚本来验证我的过程是否已创建:
db2 "select routinename from syscat.routines where language='JAVA'"
我在那里看到了 ML_CLIENT_CALL 的名称。当我尝试使用以下命令从命令行调用新过程时出现问题:
db2 "call ml_client_call('localhost',4444,'sample.dml','someargs')"
那是我收到以下输出的时候:
SQL4306N Java stored procedure or user-defined function
"DB2INST1.ML_CLIENT_CAL", specific name "SQL140514162506200" could not call
Java method "callSystemML", signature "(Ljava/lang/Str". SQLSTATE=42724
我检查了 ~/sqllib/db2dump/db2diag.log 中的确切错误,我看到以下内容:
2014-05-15-09.17.23.080944-420 I944034E848 LEVEL: Warning
PID : 2987 TID : 139759180494592 PROC : db2fmp (
INSTANCE: db2inst1 NODE : 000
APPID : *LOCAL.db2inst1.140515154559
HOSTNAME: oxiro
FUNCTION: DB2 UDB, BSU Java support, sqlejCallJavaRoutine_dll, probe:130
MESSAGE : JNI GetMethodID failed. class:
DATA #1 : Hexdump, 81 bytes
0x00007F1C3AD73480 : 2F68 6F6D 652F 6462 3269 6E73 7431 2F73 /home/db2inst1/s
0x00007F1C3AD73490 : 716C 6C69 622F 6675 6E63 7469 6F6E 2F6A qllib/function/j
0x00007F1C3AD734A0 : 6172 2F44 4232 494E 5354 312F 5359 5354 ar/DB2INST1/SYST
0x00007F1C3AD734B0 : 454D 5F4D 4C5F 434C 4945 4E54 5F4A 4152 EM_ML_CLIENT_JAR
0x00007F1C3AD734C0 : 2E6A 6172 3A53 7973 7465 6D43 6C69 656E .jar:SystemClien
0x00007F1C3AD734D0 : 74 t
2014-05-15-09.17.23.081203-420 I944883E455 LEVEL: Warning
PID : 2987 TID : 139759180494592 PROC : db2fmp (
INSTANCE: db2inst1 NODE : 000
APPID : *LOCAL.db2inst1.140515154559
HOSTNAME: oxiro
FUNCTION: DB2 UDB, BSU Java support, sqlejCallJavaRoutine_dll, probe:140
MESSAGE : JNI GetMethodID failed. method:
DATA #1 : Hexdump, 12 bytes
0x00007F1C3AD734D2 : 6361 6C6C 5379 7374 656D 4D4C callSystemML
2014-05-15-09.17.23.081294-420 I945339E699 LEVEL: Warning
PID : 2987 TID : 139759180494592 PROC : db2fmp (
INSTANCE: db2inst1 NODE : 000
APPID : *LOCAL.db2inst1.140515154559
HOSTNAME: oxiro
FUNCTION: DB2 UDB, BSU Java support, sqlejCallJavaRoutine_dll, probe:150
MESSAGE : JNI GetMethodID failed. signature:
DATA #1 : Hexdump, 58 bytes
0x00007F1C3AD73560 : 284C 6A61 7661 2F6C 616E 672F 5374 7269 (Ljava/lang/Stri
0x00007F1C3AD73570 : 6E67 3B49 4C6A 6176 612F 6C61 6E67 2F53 ng;ILjava/lang/S
0x00007F1C3AD73580 : 7472 696E 673B 4C6A 6176 612F 6C61 6E67 tring;Ljava/lang
0x00007F1C3AD73590 : 2F53 7472 696E 673B 2956 /String;)V
2014-05-15-09.17.23.081575-420 E946039E433 LEVEL: Warning
PID : 2987 TID : 139759180494592 PROC : db2fmp (
INSTANCE: db2inst1 NODE : 000
APPID : *LOCAL.db2inst1.140515154559
HOSTNAME: oxiro
FUNCTION: DB2 UDB, BSU Java support, sqlejLogException, probe:10
MESSAGE : ADM10000W A Java exception has been caught. The Java stack
traceback has been written to the db2diag log file.
2014-05-15-09.17.23.081835-420 I946473E518 LEVEL: Warning
PID : 2987 TID : 139759180494592 PROC : db2fmp (
INSTANCE: db2inst1 NODE : 000
APPID : *LOCAL.db2inst1.140515154559
HOSTNAME: oxiro
FUNCTION: DB2 UDB, BSU Java support, sqlejLogException, probe:10
MESSAGE : java.lang.NoSuchMethodError: SystemClient.callSystemML(Ljava/lang /String;ILjava/lang/String;Ljava/lang/String;)V
DATA #1 : Hexdump, 4 bytes
0x00007F1C384E9B00 : 0000 0000 ....
2014-05-15-09.17.23.081961-420 I946992E445 LEVEL: Warning
PID : 2987 TID : 139759180494592 PROC : db2fmp (
INSTANCE: db2inst1 NODE : 000
APPID : *LOCAL.db2inst1.140515154559
HOSTNAME: oxiro
FUNCTION: DB2 UDB, routine_infrastructure, sqlerJavaCallRoutine, probe:30
MESSAGE : Error from DB2ER CallUDF. RC:
DATA #1 : Hexdump, 4 bytes
0x00007F1C384EA6A0 : 2EEF FFFF ....
现在,我不明白为什么我会收到 JNI GetMethodID failed 消息和 java.lang.NoSuchMethodError,因为我遵循了注册 JAR 的正确步骤。
我想检查我所遵循的步骤中是否有问题,所以我对一个更简单的 Java 类做了同样的事情:
public class TestUdf
public static void testMethod(String inStr1, String inStr2, String inStr3, int[] out)
String someString = inStr1 + inStr2 + inStr3;
out[0] = 1;
及其创建SQL脚本:
CREATE PROCEDURE DB2INST1.TESTMETHOD(IN str1 VARCHAR(255), IN str2
VARCHAR(255), IN str3 VARCHAR(255), OUT out1 INTEGER)
LANGUAGE java
PARAMETER STYLE java
FENCED THREADSAFE
EXTERNAL NAME
'TESTUDF:TestUdf.testMethod(java.lang.String, java.lang.String, java.lang.String, java.lang.Integer[])';
而且效果很好。
因此,我的问题是:在第一种情况下我做错了什么并且我的程序没有执行?它与我的 JDK 有什么关系吗?我使用的是 IBM 的 JDK,它安装在目录中:
/opt/ibm/java-x86_64-71/
此外,db2 配置管理器返回以下内容:
db2inst1@oxiro:~$ db2 get dbm cfg
Database Manager Configuration
Node type = Enterprise Server Edition with local and remote clients
Database manager configuration release level = 0x0f00
Java Development Kit installation path (JDK_PATH) = /opt/ibm/java-x86_64-71/
最后,我想说我正在使用 Ubuntu 12(64 位)机器。
谢谢你,很抱歉发了这么长的帖子。
【问题讨论】:
【参考方案1】:DB2 正在寻找带有签名(String, int, String, String)
的方法:
(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
注意“I”作为第二个参数类型,它不是“Ljava/lang/Integer”。
SQL INTEGER
数据类型映射到 Java int
,因此您需要更改方法签名。
【讨论】:
非常感谢。这实际上是问题所在。我认为 java.lang.Integer 和 int 在 DB2 中的工作方式相同。我猜他们没有。再次非常感谢您以上是关于DB2 Java 存储过程 NoSuchMethodError的主要内容,如果未能解决你的问题,请参考以下文章