2013-03-28 2 views
0

У меня есть простой проект java, который я использую для сборки. Она имеет следующие два класса:Перекомпиляция с кодом муравьев вызывает сбой во время выполнения?

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.f до Object:

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>. Это позволяет муравьям перекомпилировать иждивенцы, когда их зависимости меняются.

2

Ant будет только компилировать файлы, которые не изменялись с момента последней компиляции (если вы чистый). Тем не менее, только один из ваших файлов изменился, а другой вызывает ожидание старой версии. Если вы удалите все файлы классов перед запуском муравьиной сборки, я бы поставил, что это сработает.

Это говорит в документации апача для муравьев <javac> задачи:

Источник и целевой каталог будет рекурсивно сканируются для исходных Java-файлов для компиляции. Будут скомпилированы только файлы Java, у которых нет соответствующего файла .class или где файл класса старше файла .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

Это звучит довольно сомнительно. Это означало бы, что стратегия перекомпиляции муравьев почти бесполезна, и вы можете просто удалить все классы каждый раз, когда собираетесь собирать. Тем не менее, не следует ли «A» работать с новым «B», поскольку аргумент совместим в любом случае? – Dog

+0

@Dog, я могу ошибаться, но попытался ли вы удалить файлы классов и запустить сборку муравьев? – Lucas

+1

@Dog, вот еще одна ссылка: http://stackoverflow.com/a/2590705/516433 – Lucas

Смежные вопросы