Ant Javac任务删除方法

时间:2013-04-17 23:00:48

标签: java eclipse compiler-errors javac

我在Java项目中遇到了一些奇怪的奇怪行为。情况是javac似乎在编译期间从类中删除了一个方法。

该课程看起来像这样:

public class MessedUp extends X {
    //a bunch of variables here
    //a bunch of methods here

    public void thisDisappears(String arg){

    }

    //a bunch more methods here

}

还有另一个实例化并调用此方法的类:

public class WontCompile {

    public void doSomething(){
        MessedUp mu = new MessedUp();
        mu.thisDisappears("something");
    }
}

第一个类编译得很好,但第二个类没有。 javac输出如下内容:

[javac] C:\mypath\WontCompile.java:251: error: cannot find symbol
[javac]                     mu.thisDisappears("something");
[javac]                       ^
[javac]   symbol:   method thisDisappears(String)
[javac]   location: variable mu of type MessedUp

我知道代码很好,因为我已经在Eclipse中使用了几年(我正在尝试使用Eclipse生成的ant文件时跟踪这个问题)。但是,Eclipse偶尔会突出显示对thisDisappears的调用,说它不存在,并提供创建它。如果接受要约,那么Eclipse会抱怨有两种方法具有相同的名称。经过一些显然导致重建的东西后,错误就消失了。

在被驱动了一段时间之后,我决定检查MessedUp.java的实际类文件。使用Java Decompiler GUI,我发现类文件中不存在thisDisappears

以下是我的蚂蚁档案:

<project basedir="." default="build" name="MyProject">
    <property name="LIB_HOME" value="C:\dev\LibSuite-9.3.1"/>
    <property environment="env"/>
    <property name="debuglevel" value="source,lines,vars"/>
    <property name="target" value="1.7"/>
    <property name="source" value="1.7"/>
    <path id="MyProject.classpath">
        <pathelement location="bin"/>
        <pathelement location="lib/edu.mit.jwi_2.1.4.jar"/>
        <pathelement location="lib/edu.sussex.nlp.jws.beta.11.jar"/>
        <pathelement location="lib/jaws-bin.jar"/>
        <pathelement location="lib/junit-4.11.jar"/>
        <!--External Jars-->
        <pathelement location="${LIB_HOME}/share/java/abc.jar"/>
        <pathelement location="${LIB_HOME}/share/java/def-9.3.1.jar"/>
    </path>
    <target name="init">
        <mkdir dir="bin"/>
        <copy includeemptydirs="false" todir="bin">
            <fileset dir="main/src">
                <exclude name="**/*.launch"/>
                <exclude name="**/*.java"/>
            </fileset>
        </copy>
        <copy includeemptydirs="false" todir="bin">
            <fileset dir="main/test">
                <exclude name="**/*.launch"/>
                <exclude name="**/*.java"/>
            </fileset>
        </copy>
    </target>
    <target name="clean">
        <delete dir="bin"/>
    </target>

    <target depends="init" name="build">
        <echo message="${ant.project.name}: ${ant.file}"/>
        <javac debug="true" debuglevel="${debuglevel}" destdir="bin" includeantruntime="false" source="${source}" target="${target}">
            <classpath refid="MyProject.classpath"/>
            <src path="main/src"/>
            <src path="main/test"/>
            <compilerarg value="-Xlint"/>
        </javac>
    </target>

    <!--Test the app-->
    <target depends="build" name="regression">
        <junit>
            <classpath refid="MyProject.classpath"/>
            <test name="uni.my.app.TestSuite"/>
        </junit>
    </target>

    <!--Run the app-->
    <target depends="build" name="run">
        <java classname="uni.my.app.Application">
            <classpath refid="MyProject.classpath"/>
            <arg value="sentences.txt"/>
        </java>
    </target>
</project>

不幸的是,我无法将最低限度的例子放在一起。我正在处理的代码尚未向公众发布,因此我还无法分享它。它引用了几个jar(没有冲突的命名空间),有些使用本机方法。我不知道类和jar的确切组合会导致错误。我使用jdk 1.6.0_25和1.7.21时遇到了同样的问题。

有没有人对如何解决这个问题有任何经验或想法?

2 个答案:

答案 0 :(得分:1)

这是猜测。

Ant在eclipse之外运行,因此它所做的任何更改都不会反映在eclipse的大规模缓存世界观中。据我所知,eclipse的变化也没有反映在蚂蚁使用的文件中。

我会做一个项目干净,然后是项目构建,然后是项目刷新。我会看到你是否在日食中遇到这个问题。然后我会运行ant(如果必须的话),再做一次刷新,看看问题是否存在。

在使用其他程序之前,无论何时在eclipse或ant中执行任何操作,都要刷新eclipse项目。

让我们知道它是怎么回事。

P.S。相信java编译器没有删除任何方法。我同意你有一些奇怪的事情发生,但事实并非如此。

答案 1 :(得分:0)

问题在于,无论出于何种原因,另一个用户已将项目转换为VCS,其中所有类文件与相应的源位于相同的文件夹中。在我的机器上,Eclipse将二进制文件放入bin文件夹中,因此我不知道为什么将它们放在另一个用户的计算机上。

Eclipse生成的init目标旨在复制代码使用的资源。它复制源目录中除javalaunch文件之外的任何文件。但是,由于类文件位于源目录中,因此它也会复制它们。然后,当执行build目标时,它没有编译任何东西,因为它似乎已经存在新的类文件(但它们实际上只是旧代码的新副本)。

解决方案是:1)从源文件夹中删除所有类文件,2)将**/*.class的排除规则添加到资源复制代码中,以便进行测量。