2013-03-28 38 views
0

我有一个简单的java项目,我使用ant来构建。它有以下两类:用ant重新编译会导致代码在运行时崩溃?

A.java:

public class A { 
    public static void main(String[] args) { 
     Integer i = 0; 
     B.f(i); 
    } 
} 

B.java:

public class B { 
    public static void f(int i) { 
     System.out.println("hello"); 
    } 
} 

工作正常:现在

,如果我改变了int参数B.fObject

public class B { 
    public static void f(Object i) { 
     System.out.println("hello"); 
    } 
} 

...代码重新编译罚款...

$ ant compile 
[...] 
$ java -cp bin A 
Exception in thread "main" java.lang.NoSuchMethodError: B.f(I)V 
    at A.main(Unknown Source) 

...但它崩溃在运行时。为什么?在编译之前


文件夹结构:

bin 
build.xml 
src 
├── A.java 
└── B.java 

的build.xml:

<project> 
    <target name="compile"> 
     <javac srcdir="src" destdir="bin"/> 
    </target> 
</project> 

回答

0

默认情况下,ant不会重新编译任何东西,除非文件的日期改变。解决方案是使用<depend>任务。这使得ant在其依赖关系发生变化时重新编译依赖项。

2

蚂蚁将只编译自上次编译(除非你干净)没有改变的文件。也就是说,只有其中一个文件发生了变化,另一个正在发送预期旧版本的电话。如果你在运行ant build之前删除所有的类文件,我会打赌它会工作。

它说的蚂蚁<javac>任务Apache文档中:

的源和目标目录将被递归扫描 Java源文件进行编译。只有没有 对应的.class文件或类文件比 .java文件更旧的Java文件才会被编译。

这些方法可能在源代码级兼容,但是当编译成字节码时,它们具有其他类正在寻找的特定签名。您更改了已编译的签名,因此无法找到正在查找的方法。

------------------编辑---------------------

一个简单的清洁任务可以被添加到您的构建:

<target name="clean" 
     description="clean up" > 
    <!-- Delete the ${build} and ${dist} directory trees --> 
    <delete dir="${build}"/> 
    <delete dir="${dist}"/> 
    </target> 

而且你可以添加一个完全重建:

<target name="fullReBuild" depends="clean compile"> 
    </target> 

然后在命令行根据需要发出ant fullReBuild

+0

这听起来很可疑。这意味着蚂蚁的重新编译策略几乎是无用的,你也可以在每次编译时删除所有的类。尽管如此,不应该使用新的'B',因为参数是兼容的吗? – Dog

+0

@Dog,我可能是错的,但你是否尝试删除类文件并运行你的ant构建? – Lucas

+1

@狗,这里是另一个参考:http://stackoverflow.com/a/2590705/516433 – Lucas

相关问题