1

我真的有这个问题。

所以我有一个 jar 和一个用于处理数据库连接的类。在那个课程中,我提出了几种方法。在这个类中,我使用 Ant 创建了一个 jar。

昨天某个时候,我突然无法再访问该数据库类中的最新方法。我得到:

compile:
[javac] C:\cygwin\home\user\Dev\Java\avc_alarm\build.xml:22: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
[javac] Compiling 1 source file to C:\cygwin\home\user\Dev\Java\avc_alarm\build
[javac] C:\cygwin\home\user\Dev\Java\avc_alarm\src\se\gefa\avc_alarm\Main.java:9: error: cannot find symbol
[javac] symbolAliases = db.getAlarmSymbolAlias();
[javac]                   ^
[javac]   symbol:   method getAlarmSymbolAlias()
[javac]   location: variable db of type AvcDb
[javac] 1 error

尝试使用此类方法的代码:

package se.gefa.avc_alarm;

import se.gefa.avc_db.AvcDb;
import java.util.ArrayList;

public class Main {
    static AvcDb db  = new AvcDb();
    static ArrayList<String> symbolAliases;

    public static void main(String args[]) throws Exception {
        db.setupConnection("jdbc:h2:tcp://localhost/C:/XXXX/xyz", "sa", "");
        symbolAliases = db.getAlarmSymbolAlias();
    }
}

和 db 类(进入一个罐子):

package se.gefa.avc_db;

import java.sql.*;
import java.util.ArrayList;

public class AvcDb {

    // ---
    // Other methods that DO work
    // ---

    // The one that DO NOT work
    public ArrayList<String> getAlarmSymbolAlias() throws Exception {
        String query = "SELECT * FROM Alarm";
        Statement statement = conn.createStatement();
        ResultSet resultSet = statement.executeQuery(query);

        ArrayList<String> symbols = new ArrayList<String>();
        while (resultSet.next())
            symbols.add(resultSet.getString("symbol_alias"));

        return symbols;
    }
}

我正在使用 java 7、Ant 1.8.3 和 Vim。在 IntelliJ 中打开 db jar 时,我可以看到 getAlarmSymbolAlias 方法存在。正如我所说,我可以调用 db 类的任何其他方法,除了昨天添加的任何方法。IntelliJ 中的一个简单测试,它似乎可以工作(但是当我在 Vim、CL 和 Ant 中进行所有其他设置时,我不想学习新的编辑器。

编辑Ant 脚本:

<project name="AvcAlarm" default="dist" basedir=".">
  <description>
    Alarm program. 
  </description>

  <property name="src" location="src"/>
  <property name="build" location="build"/>
  <property name="dist" location="dist"/>
  <property name="lib" location="lib"/>

  <path id="classpath">
    <fileset dir="${lib}" includes="**/*.jar"/>
  </path>

  <target name="init">
    <tstamp/>
    <mkdir dir="${build}"/>
    <mkdir dir="${dist}"/>
  </target>

  <target name="compile" depends="init" description="compile the source " >
    <javac srcdir="${src}" destdir="${build}" classpathref="classpath"/>
  </target>

  <target name="dist" depends="compile" description="generate the distribution" >
    <jar destfile="${dist}/gefa_alarm.jar" basedir="${build}">
        <zipgroupfileset dir="lib" includes="*.jar" />
        <manifest>
            <attribute name="Main-Class" value="se/gefa/avc_alarm/Main"/>
        </manifest>
    </jar>
  </target>

  <target name="clean" description="clean up" >
    <delete dir="${build}"/>
    <delete dir="${dist}"/>
  </target>
</project>
4

3 回答 3

2

您的类路径一定是错误的,或者您使用了不包含此方法的无效 JAR 版本。

使用 OP 调查后更新:文件夹中的另一个 JARlib包含不同版本的 AvcDb,并且首先在类路径上加载,因此找不到所需的方法。

于 2012-06-12T06:48:13.713 回答
1

由于您已验证您的 JAR 包含新添加的方法,因此类路径中应该存在问题,并且加载了该类的其他一些旧版本。更改类路径的顺序,以便将此 jar 文件设置在顶部。

于 2012-06-12T07:36:18.803 回答
0

我怀疑当您编译 AvcDb.java 时,您的 JAR 文件不在您的类路径中,或者您的类路径中有旧版本的您的 JAR,但方法签名不同。

您还应该删除所有旧的 *.class 文件,这些文件可能是从以前的构建中创建的。您的 ANT build.xml 中是否有一个“准备”目标,可以在再次编译之前删除所有旧的构建工件?

于 2012-06-12T06:54:39.167 回答