Стратегии переноса кодовой базы среднего размера с Java 1.4.2 на Java 5 - PullRequest
3 голосов
/ 07 апреля 2009

Я нахожусь в процессе рассмотрения базы кода (~ 20K LOC) и пытаюсь определить, как перенести ее с 1.4.2 на 5. Очевидно, что это не ночной проект, и я получил предложение: написать новый код для Java 5 и перенести старый код по частям. Кроме того, я не специалист по новым функциям в Java 5 (то есть знаю о них, но никогда не писал ничего для производственного использования).

Мои вопросы:

  1. Какие функции Java 5 обычно используются в производственном коде? (т. е. дженерики, автобокс и т. д.) Есть ли какие-либо особенности, которых следует избегать / которые не считаются передовыми?

  2. Каковы наилучшие стратегии рефакторинга, которые я могу использовать для переноса базы кода такого размера? (то есть вносить изменения в классы по одному только тогда, когда класс редактируется и т. д.) Цель - снизить риск на основе кода. Ограничение - ресурсы для рефакторинга.

Любой совет приветствуется - заранее спасибо.

ОБНОВЛЕНИЕ - год слишком поздно, но лучше поздно, чем никогда? =)

Спасибо за все комментарии - множество отличных точек зрения. В жизни разработчика программного обеспечения всегда будут проекты, которые вы стремитесь завершить, но никогда не решаетесь из-за чего-то более «срочного».

Что касается использования Java 5 (в то время), это было то, что требовалось в производственной среде клиента, поэтому мы не использовали Java 6.

Я обнаружил, что более строгая типизация для коллекций, перечислений и распаковки примитивов - это те функции, которые я чаще всего применяю как к старому, так и к новому коду. Рефакторинг был довольно простым, но понимание кода значительно улучшилось, и стандарты стали легче применять. Больше всего у меня были проблемы с дженериками; Я думаю, что это концепция, которую у меня еще не было возможности полностью понять и оценить, поэтому мне было трудно найти предыдущие случаи, когда применение дженериков было уместным.

Еще раз спасибо всем, кто внес свой вклад в эту ветку, и приносим извинения за позднее продолжение.

Ответы [ 6 ]

6 голосов
/ 07 апреля 2009

Java 5 почти полностью обратно совместима с Java 4. Как правило, единственное изменение, которое вы должны внести при переносе, - это переименовать любое использование нового ключевого слова enum в коде Java 4.

Полный список потенциальных проблем совместимости приведен здесь:

http://java.sun.com/j2se/1.5.0/compatibility.html

Единственное, с чем я столкнулся на практике, связано с изменением в реализации JAXP. В нашем случае это просто означало удаление xerces.jar из пути к классам.

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

Еще одна функция, которую я люблю использовать при переносе кода, - аннотация @Override. Это помогает выявить проблемы наследования при рефакторинге кода.

http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Override.html

Новая библиотека параллелизма очень полезна, если ваш код использует многопоточность. Например, вы можете заменить доменные пулы потоков на ThreadPoolExecutor.

http://java.sun.com/j2se/1.5.0/docs/relnotes/features.html#concurrency

Я бы определенно применил подход к обновлению кода при его изменении во время обычного обслуживания. Кроме проблем с совместимостью, я не думаю, что есть веская причина использовать новые функции Java 5, если вы уже не меняете код по другим причинам.

2 голосов
/ 07 апреля 2009

Это действительно сложный вопрос, потому что он зависит от того, какой код будет затронут и насколько критичен этот код.

Прежде всего, когда миграция является нетривиальной задачей, сделайте себе одолжение и обновитесь до последней версии Java, которая будет Java 6, а не Java 5. Java 6 выпускается уже полтора года или более зрелый Нет причин не выбирать его из Java 5 (imho).

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

Другая вещь, которую нужно сделать, это просто попробовать запустить приложение под Java 6 и посмотреть, что ломается. Это может быть хуже, чем вы ожидали. Это может быть намного лучше.

Другая вещь, о которой вам, вероятно, нужно знать, это то, что по звукам у вас в вашем приложении будут фляги / библиотеки, которые с тех пор устарели. Некоторые могут даже не быть совместимыми с Java за 1.4.2. Возможно, вы захотите обновить все эти версии до последней версии.

Это, вероятно, будет означать больше взлома вещей, но использование старых / устаревших API просто выбивает банку из строя и вызывает другие проблемы.

Существуют исключения из этого, когда обновление может иметь далеко идущие последствия. От Оси1 до Оси2 приходит на ум. Эти ситуации требуют более тщательного обдумывания.

Что касается того, какие функции используются ... все они в значительной степени. Я не могу думать ни о чем, чего следует избегать на макушке.

Кроме того, я только что заметил размер вашего проекта: ~ 20K LOC. Это на самом деле довольно мало (например, я сам написал приложение об этом размере за последние 3 месяца).

Наконец, это также зависит от того, насколько легко вы найдете вещи, которые ломаются. Если у вас есть хорошее покрытие модульных тестов, то отлично. Это довольно редко, хотя. Если вы можете просто запустить приложение и надежно найти проблемы, это не так уж плохо.

Проблемные ситуации, когда сценарии сложно протестировать, и, скорее всего, вы не сможете сразу же обнаружить проблемы. Это требует большей осторожности.

2 голосов
/ 07 апреля 2009

Существует одна очень реальная проблема с «вирусной» природой дженериков; как только вы начнете вводить их на заданном уровне в архитектуре, вы, как правило, захотите представить их также на уровне выше и ниже. Я обнаружил, что введение дженериков, вероятно, лучше всего делать в полной «вертикали». Но вам не нужно делать все вертикали одновременно.

1 голос
/ 07 апреля 2009

Я думаю, вы поступаете неправильно. Ваш план не должен состоять в том, чтобы обновить весь текущий код до Java 1.5, ваш план должен быть таким, чтобы весь текущий код работал точно так же, как и в 1.4.2, в версии 1.5.2, а весь будущий написанный код будет работать нормально в 1.5 .

Я прошел через несколько переходов, таких как базы кода различного размера. Цель всегда состояла в том, чтобы убедиться, что у нас есть тонна модульных тестов, чтобы мы могли легко подключить 1.5 и выполнить наши тесты через нее. На самом деле мы столкнулись с 10 проблемами, в основном связанными с тем, что библиотеки регулярных выражений не поддерживают что-то или поддерживают что-то по-другому.

Тогда напишите весь новый код в 1.5, и если вы по какой-либо причине измените старый класс, потратьте минуту и ​​внедрите дженерики, но нет причин для реорганизации всего. Это звучит немного опасно для меня, если у вас нет тестов на месте.

1 голос
/ 07 апреля 2009

20 (без комментариев) kloc должен быть достаточно маленьким, чтобы вставлять дженерики с большим взрывом. Очевидно, сначала убедитесь, что ваш код компилируется и работает на Java SE 5. Относительно простая вещь в дженериках заключается в том, что их добавление вносит очень незначительные изменения в семантику (некоторые перегрузки могут измениться из-за неявных случаев - Iterator<char[]> iter; ... System.out.println(iter.next()); как плохой пример из головы).

В некоторых случаях добавление дженериков высветит концептуальные проблемы с кодом. Например, используя одну Map как две карты с непересекающимися наборами ключей. TreeMap - это пример в библиотеке Java, где один класс имеет два разных режима (используя Comparator<T> или Comparable<T>).

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

1 голос
/ 07 апреля 2009

Вы хотели бы перенести материал, который не работает при переходе с 1.4 на 5 (не уверен, что это будет), но я бы остерегался переноса материала для ради этого .

Если вы выберете этот маршрут, некоторые вопросы:

Есть ли у вас комплексное тестовое покрытие? Если нет, вам следует написать модульные тесты для кода, который вы собираетесь перенести.

У вас есть компоненты, которые широко используются в вашей кодовой базе? Если это так, то они, вероятно, являются кандидатами на миграцию с точки зрения их API (например, с использованием обобщений и т. Д.)

С точки зрения того, что широко используется в Java 5. Дженерики важны и делают вашу жизнь намного проще. Я не вижу autoboxing слишком слишком много, ни перечисления (это все относительно). Вараргс почти никогда. Аннотации полезны для фреймворков, но я их потребляю. Я не думаю, что когда-либо реализовывал это сам.

...