简体   繁体   English

Ant Javac任务删除方法

[英]Ant Javac Task Deletes Method

I have run into some trully bizarre behavior in a Java project. 我在Java项目中遇到了一些非常奇怪的行为。 The situation is that javac seems to be removing a method from a class during compilation. 情况是javac似乎在编译期间从类中删除了一个方法。

The class looks something like this: 该类如下所示:

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

}

There is another class that instantiates and calls this method: 还有另一个实例化并调用此方法的类:

public class WontCompile {

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

The first class compiles just fine, but the second doesn't. 第一类编译的很好,但是第二类没有。 javac outputs something like the following: 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

I know that the code is fine because I have been using it in Eclipse for a couple of years (I'm tracking down this problem as I try to use the ant file Eclipse produced). 我知道代码很好,因为我已经在Eclipse中使用了两年了(当我尝试使用Eclipse生成的ant文件时,我正在追踪这个问题)。 However, once in a while Eclipse will highlight the call to thisDisappears , saying it doesn't exist, and offering to create it. 但是, thisDisappears Eclipse会突出显示对thisDisappears的调用,并说它不存在,并愿意创建它。 If accept the offer, then Eclipse complains that there are two methods with the same name. 如果接受报价,那么Eclipse会抱怨有两个名称相同的方法。 After a little bit of finagling which apparently causes a rebuild or something, the error goes away. 经过一点点整理后,显然会导致重建或其他原因,该错误消失了。

After being driven up the while for a while, I decided to check the actual class file for MessedUp.java. 经过一段时间的驱动后,我决定检查MessedUp.java的实际类文件。 Using the Java Decompiler GUI , I found that thisDisappears isn't present in the class file! 使用Java Decompiler GUI ,我发现在类文件中没有thisDisappears

Below is my ant file: 以下是我的ant文件:

<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>

Unfortunately, I was unable to put together a minimum breaking example. 不幸的是,我无法提出一个最低限度的例子。 The code I am working on is not yet released to the public, so I can't share it all yet. 我正在使用的代码尚未发布给公众,所以我还不能全部共享。 It references several jars (with no conflicting namespaces), some with native methods. 它引用了几个jar(没有冲突的名称空间),有些引用了本机方法。 I have no idea what exact combination of classes and jars causes the error. 我不知道是什么类和jar的确切组合导致错误。 I had the same problem using jdk 1.6.0_25 and 1.7.21. 我在使用jdk 1.6.0_25和1.7.21时遇到了相同的问题。

Does anyone have any experience or ideas on how to solve this problem? 是否有人对解决此问题有任何经验或想法?

This is a guess. 这是一个猜测。

Ant operates outside of eclipse, and therefore any changes it makes are not reflected in eclipse's massively cached view of the world. Ant在eclipse之外运行,因此它所做的任何更改都不会反映在eclipse大量缓存的世界视图中。 For all I know, eclipse's changes are not reflected in files that ant uses, either. 就我所知,eclipse的更改也没有反映在ant使用的文件中。

I would do a project clean, then a project build, then a project refresh. 我将清理项目,然后构建项目,然后刷新项目。 I would see if you have this problem from within eclipse. 我会在月食中看看您是否有这个问题。 Then I would run ant (if I must), do another refresh, and see if the problem exists then. 然后,我将运行ant(如果必须这样做),再次刷新,然后查看问题是否存在。

Any time you do anything in either eclipse or ant, before you use the other program, refresh the eclipse project. 每当您在eclipse或ant中执行任何操作时,在使用其他程序之前,请刷新eclipse项目。

Let us know how it goes. 让我们知道怎么回事。

ps trust that the java compiler is not removing any methods. ps相信Java编译器不会删除任何方法。 I agree you have something strange going on, but that isn't it. 我同意您正在做一些奇怪的事情,但是不是。

The problem was that, for whatever reason, another user had turned the project into the VCS with all of the class files in the same folders as their corresponding sources. 问题在于,无论出于何种原因,另一个用户都已将项目转换为VCS,并且所有类文件都位于与它们相应的源相同的文件夹中。 On my machine, Eclipse puts the binaries into the bin folder, so I don't know why they were placed with the source on the other user's machine. 在我的机器上,Eclipse将二进制文件放入bin文件夹,所以我不知道为什么将它们与源一起放置在另一位用户的机器上。

The init target generated by Eclipse is meant to copy over resources used by the code. Eclipse生成的init目标旨在复制代码使用的资源。 It copies over anything but java or launch files from the source directories. 它会复制java或源目录中的launch文件以外的任何内容。 However, since the class files were in the source directories, it copied them over, too. 但是,由于类文件位于源目录中,因此它也将它们复制了过来。 Then, when the build target was executed, it didn't bother compiling anything because it seemed that there were already fresh class files present (but they were actually just fresh copies of old code). 然后,在执行build目标时,它并不需要进行任何编译,因为似乎已经存在新的类文件(但它们实际上只是旧代码的新副本)。

The solution was to 1) remove all of the class files from the source folders and 2) add exclude rules for **/*.class to the resource copying code, for good measure. 解决方法是:1)从源文件夹中删除所有类文件,2)为资源复制代码添加**/*.class排除规则,以达到良好的效果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM