0

我在 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 中使用它几年了(当我尝试使用antEclipse 生成的文件时,我正在追踪这个问题)。但是,有时 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>

不幸的是,我无法整理出一个最小的破坏示例。我正在编写的代码还没有向公众发布,所以我还不能全部分享。它引用了几个 jars(没有冲突的命名空间),其中一些带有本地方法。我不知道类和罐子的确切组合会导致错误。我在使用 jdk 1.6.0_25 和 1.7.21 时遇到了同样的问题。

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

4

2 回答 2

1

这是一个猜测。

Ant 在 eclipse 之外运行,因此它所做的任何更改都不会反映在 eclipse 的大量缓存的世界视图中。据我所知,eclipse 的更改也不会反映在 ant 使用的文件中。

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

每当您在 eclipse 或 ant 中执行任何操作时,在使用其他程序之前,请刷新 eclipse 项目。

让我们知道怎么回事。

ps 相信 java 编译器不会删除任何方法。我同意你发生了一些奇怪的事情,但事实并非如此。

于 2013-04-17T23:54:36.680 回答
0

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

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

解决方案是 1) 从源文件夹中删除所有类文件,以及 2) 为**/*.class资源复制代码添加排除规则,这是一个很好的衡量标准。

于 2013-04-18T03:20:10.370 回答