2017-02-24 18 views
0

我在运行调用我已加载的JAR文件的函数时遇到Postgres中的java.lang.ClassNotFoundException:错误。我已经在我的数据库中安装并配置了PL/JAVA(包括交付的示例),并可以运行示例以取得成功。我不是试图加载/安装我的第一个JAR,但我做错了什么。Postgres PL/JAVA:在数据库中加载JAR文件后出现java.lang.ClassNotFoundException错误

我的主机控制操作系统版本: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的提示符下运行。

    1. 在psql运行SQLJ.INSTALL_JAR:

      select sqlj.install_jar('file:/tmp/Doug.jar','Doug',false); 
      
    2. 设置内部Postgres的类路径(在psql提示的Postgres =#):

      select sqlj.set_classpath('public','Doug'); 
      
    3. 创建调用该函数罐。这个创建功能代码直接来自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

    非常抱歉,我没有及时看到您的问题。在所有的异常细节(PostgreSQL,PL/Java,模式,类路径...)下面,只是介绍一些基本的Java:如果jar文件在com.msmetric包中包含类Doug.class,它在jar中的路径必须反映:它必须是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 a -d目录选项,而不是只在其旁边编写类文件来源,它会将它们全部放在您指定的目录下的适当位置,然后您可以告诉jar更改为该目录,并将它们全部提起(不要忽略jar命令末尾的.) 。

    一旦你解决这个问题,如果你重试原来的步骤,你会看到,你现在得到一个不同的错误:

    ERROR: Unable to find static method com.msmetric.Doug.addOne with signature (Ljava/lang/Integer;)I 
    

    那是因为你宣布Doug.javaint addOne(int value)的功能(即,采用原始参数int),但是您在SQL中声明了它,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; 
    

    你就可以看到:

    # select addone(3); 
    addone 
    -------- 
         4 
    (1 row) 
    

    如果你碰巧看到这个迟来的答案,我会问PL/Java的你的是什么版本正在使用?这是你没有提到的一个细节。如果它大于1.5.0,则有更新的功能可以帮助您。首先,你可以只标注该功能:

    @Function 
    public static int addOne(int value) { 
        return value + 1; 
    } 
    

    ,并有javac吐出不仅Doug.class文件,但也有pljava.ddr文件,已经正确地写入您的SQL函数声明(没有混淆参数类型!)。有一种方法可将.ddr文件包含到您创建的jar文件中,以便您可以用最后一个参数true调用sqlj.install_jar,以便它运行.ddr中的命令,并且可以使用您的函数。有一个你好,世界的例子in the docs,更多地显示它是如何完成的。

    干杯,
    - 细节

    相关问题