我在运行调用我已加载的JAR文件的函数时在Postgres中获取java.lang.ClassNotFoundException:error。我已经在我的数据库中安装并配置了PL / JAVA(包括交付的示例),并且可以运行示例以获得成功。我没有尝试加载/安装我的第一个JAR,但我做错了。
我的主机控制操作系统版本:CentOS 6.8。 Postgres是版本8.4。
我正在尝试安装我自己非常简单的java类,它是传递的示例Parameters.addOne类的衍生物。我的所有代码都在/ tmp中。以下是我遵循的步骤:
Doug.java:
package com.msmetric;
import java.math.BigDecimal;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
import java.util.logging.Logger;
public class Doug {
public static int addOne(int value) {
return value + 1;
}
}
使用'javac Doug.java'编译Doug.java成功。
使用'jar -cvf Doug.jar Doug.class创建包含Doug.class文件的JAR文件。这很好。
现在我将JAR文件加载到Postgres(公共模式),更改类路径,创建调用JAR的函数,然后尝试在psql提示符下运行。
从psql运行sqlj.install_jar:
select sqlj.install_jar('file:/tmp/Doug.jar','Doug',false);
在Postgres中设置类路径(来自psql提示符postgres =#):
select sqlj.set_classpath('public','Doug');
创建调用JAR的函数。此创建函数代码直接取自PL / JAVA附带的examples.ddr文件。我只是将org.postgres更改为com.msmetric。
create or replace function addone(int) returns int as 'com.msmetric.Doug.addOne(java.lang.Integer)' language java;
现在加载了JAR并创建了函数,我尝试运行它。此功能只需在提供的数字上加1即可。
select addone(3);
结果: 错误:java.lang.ClassNotFoundException:com.msmetric.Doug
思想?
答案 0 :(得分:0)
我很抱歉我没有及早看到你的问题。在所有异国情调的细节(PostgreSQL,PL / Java,模式,类路径......)下面,这里只是一些基本的Java:如果一个jar文件在包Doug.class
中包含{ {1}},它在jar中的路径必须反映:它必须是com.msmetric
。否则,它就不会被发现。
您可以逐步设置整个结构:
com/msmetric/Doug.class
或者,您可以让
javac Doug.java
mkdir com
mkdir com/msmetric
mv Doug.class com/msmetric/
jar -cvf Doug.jar com/msmetric/Doug.class
为您完成更多工作:
javac
当您提供
mkdir classes
javac -d classes Doug.java
jar -cvf Doug.jar -C classes .
javac
目录选项时,不会只在其-d
来源旁边编写类文件,而是将它们全部放入其中在您命名的目录下的适当位置,然后您可以告诉.java
更改到该目录并将它们全部搞砸(不要忽略jar
在.
的末尾命令)。
修复后,如果您重试原始步骤,则会发现您现在遇到了其他错误:
jar
这是因为您在ERROR: Unable to find static method com.msmetric.Doug.addOne with signature (Ljava/lang/Integer;)I
中使用Doug.java
声明了该函数(即采用原始int addOne(int value)
参数),但是您在SQL中使用int
进行了声明一个returns int as 'com.msmetric.Doug.addOne(java.lang.Integer)'
对象。
一旦你纠正了:
Integer
您将能够看到:
create or replace function addone(int) returns int as 'com.msmetric.Doug.addOne(int)' language java;
如果您碰巧看到这个迟来的答案,请问您使用的是什么版本的PL / Java?这是你没有提到的一个细节。如果它早于1.5.0,则有更新的功能可以帮助您。首先,您可以注释该功能:
# select addone(3);
addone
--------
4
(1 row)
并让@Function
public static int addOne(int value) {
return value + 1;
}
不仅吐出javac
文件,还吐出Doug.class
文件,并且已经正确编写了SQL函数声明(没有混合参数类型!)。有一种方法可以将pljava.ddr
文件包含到您创建的jar中,以便您可以使用最后一个参数.ddr
调用sqlj.install_jar
,以便它运行true
中的命令并且您的功能随时可用。这是一个Hello,世界范例in the docs,它展示了它的完成方式。
干杯,
-chap