Инструмент для поиска несовместимостей в сигнатурах / полях метода - PullRequest
8 голосов
/ 24 марта 2011

Я хотел бы иметь возможность сравнить две версии класса / библиотеки, чтобы определить, были ли какие-либо изменения, которые могли бы нарушить код, который его вызывает.Например, рассмотрим некоторый класс Foo, у которого есть метод в версии a:

public String readWidget(Object widget, Object helper);

и в версии b метод становится:

public String readWidget(Object widget); //removed unnecessary helper object

или что-то подобное в случае поля:

version a: public static Object sharedFoo;
version b: static Object sharedFoo; //moved to package private for version b

Я хотел бы инструмент, который пометит эти изменения как потенциальные несовместимости (но в идеале не наоборот, то есть увеличение видимости метода).Теперь я знаю, что могу сделать это с помощью отражений или анализа выходных данных из javap, однако кажется, что должен существовать инструмент (желательно некоммерческий).Поэтому я хотел узнать, может ли кто-нибудь что-нибудь порекомендовать, прежде чем я совершу ошибку, катясь самостоятельно / изобретая велосипед заново.

Ответы [ 3 ]

3 голосов
/ 24 марта 2011

Возможно, я не понимаю вопроса, но разве компилятор не является точным инструментом, который решит эту проблему?

Перекомпиляция классов, использующих Foo, для новой версии Fooзагорится очень быстро, если возникнут какие-либо несовместимости.

2 голосов
/ 24 марта 2011

Вот ответ, который вы не хотели, но я думаю, что это правильный ответ:

  1. Напишите набор модульных тестов, которые вызывают каждый метод вашего API (у вас это уже есть, верно?: -)).
  2. Когда вы вносите изменение в API, перекомпилируйте новую версию вашего API, но не юнит-тесты.
  3. Запустите «устаревший» набор юнит-тестов для «свежий "API.Этот устаревший набор тестов становится канарейкой, имитируя ситуацию, в которой будут находиться клиенты вашего API.

Проблема first , связанная с простой перекомпиляцией всего кода клиента это то, что это может быть невозможно.Код может не принадлежать вам;это может быть пользовательский код, написанный одним из ваших клиентов и недоступный для вас.

Проблема second в простой перекомпиляции клиентского кода заключается в том, что иногда вы даже не получитеошибка компиляции, потому что код вызова не нужно менять.Однажды я столкнулся с такой проблемой.У меня был такой метод API:

public void doSomething(){
}

с кодом, который связан с ним.Я хотел изменить это на это:

public boolean doSomething() {
}

Так я сделал это и перекомпилировал.Не было никаких ошибок, потому что код, который вызвал первую версию doSomething(), безоговорочно связывался с новой версией (отбрасывая возвращаемое значение, которое является допустимым в Java).Однако мало что я знал, что он изменил байт-код внешнего класса при перекомпиляции.Мы начали получать ошибки, когда API обновлялся, но код, использующий его, не перекомпилировался.

Поэтому вместо того, чтобы искать ошибки, мне следовало бы также посмотреть, какие внешние файлы в результате изменили свой байт-код.В этот момент я бы сказал, что вы должны просто использовать модульные тесты для этой цели, так как вы все равно должны их писать.

2 голосов
/ 24 марта 2011

Гуава использует JDiff , чтобы сообщить изменения версии , может быть, вы тоже найдете это полезным?

...