我在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时遇到了同样的问题。
有没有人对如何解决这个问题有任何经验或想法?
答案 0 :(得分:1)
这是猜测。
Ant在eclipse之外运行,因此它所做的任何更改都不会反映在eclipse的大规模缓存世界观中。据我所知,eclipse的变化也没有反映在蚂蚁使用的文件中。
我会做一个项目干净,然后是项目构建,然后是项目刷新。我会看到你是否在日食中遇到这个问题。然后我会运行ant(如果必须的话),再做一次刷新,看看问题是否存在。
在使用其他程序之前,无论何时在eclipse或ant中执行任何操作,都要刷新eclipse项目。
让我们知道它是怎么回事。
P.S。相信java编译器没有删除任何方法。我同意你有一些奇怪的事情发生,但事实并非如此。
答案 1 :(得分:0)
问题在于,无论出于何种原因,另一个用户已将项目转换为VCS,其中所有类文件与相应的源位于相同的文件夹中。在我的机器上,Eclipse将二进制文件放入bin
文件夹中,因此我不知道为什么将它们放在另一个用户的计算机上。
Eclipse生成的init
目标旨在复制代码使用的资源。它复制源目录中除java
或launch
文件之外的任何文件。但是,由于类文件位于源目录中,因此它也会复制它们。然后,当执行build
目标时,它没有编译任何东西,因为它似乎已经存在新的类文件(但它们实际上只是旧代码的新副本)。
解决方案是:1)从源文件夹中删除所有类文件,2)将**/*.class
的排除规则添加到资源复制代码中,以便进行测量。