среда, 13 апреля 2011 г.

Перевод xdoclet-based ejb-2.0 проекта на платформу ejb-3.0

Зачем?
Есть ещё такие проекты. Но нет уже таких application server-ов. Приходит долгожданное время, когда в организации появляются новые сервера, админы ставят на них новенький софт, все счастливы... И тут выясняется что технологически наш успешный и всё ещё развивающийся проект находится глубоко в прошлом веке. А ведь для него собственно и покупались сервера. А ставить раритетный resin 3.0 на новую систему ой как не хочется, да и неправильно. Очевидное решение - переписать проект - сталкивается с непониманием руководства. На старом сервере работало? Новый сервер лучше? Так почему не работает? И времени на "переезд" обычно даётся минимум. В таких условиях мне пришлось портировать уже третий проект, когда я решил всё-таки описать процедуру. Может быть, пригодится кому-то. Может даже мне :)

Что должно быть в наличии перед началом процедуры
Во-первых, конечно же, исходники проекта. Во-вторых xdoclet-библиотеки, ant, build.xml - короче всё, что нужно для его сборки. Достаточно даже не полной сборки а хотя бы исполнения target-а xdoclet-а.

Что получим
Проект совместимый с ejb-3.0 application server (resin 4, glassfish 3 ...), который нормально собирается в среде NetBeans или просто с коммадной строки.

Задача №1: Бины
В нашем старом проекте бины реализовывали интерфейс javax.ejb.SessionBean, в новом - будут реализовавать свои Local интерфейсы. Поэтому первое что нужно сделать - сгенерировать исходники Local-интерфейсов с помощью xdoclet. Выполняем соответствующий target нашего build.xml и получаем в нашей build-директории дерево каталогов с Local, Session, Util и LocalHome - классами. Local-интерфейсы переносим в каталоги с исходниками (подкаталоги src) и раскладываем рядом с исходниками бинов. Не забудем на этом этапе поменять библиотеку ejb-20.jar на ejb-30.jar. Проект перестал собираться. Теперь можно начать правку кода.
В local-интерфейсах добавляем перед объявлением класса аннотацию @Local, соответственно добавляем и импорт javax.ejb.Local. Удаляем из объявления класса "extends javax.ejb.EJBLocalObject". Больше интерфейсы трогать не будем.
В бине меняем обьявление класса с "public class MySuperBean implements SessionBean" на "public class MySuperBean implements MySuperLocal", добавляем аннотацию @Stateless с соответствующим импортом javax.ejb.Stateless и убираем метод ejbCreate(). Настройки транзакционности для методов бина, которые выносились в конфиг инструкцией для xdoclet вида @ejb.transaction type="NotSupported" теперь прописываем аннотациями: @TransactionAttribute(TransactionAttributeType.NOTSUPPORTED). Выполняем все эти операции для каждого бина в проекте. Надеюсь у вас их не слишком много :). Понятно, что если у вас конфигурация методов или типы бинов другие, аннотации ставите свои.

Задача №2: Сервлеты
Тут всё проще. Раньше получали обьект бина в сервлете мы в переопределённом методе public void init(ServletConfig conf) такой конструкцией:
InitialContext = new InitialContext();
Object objref = ic.lookup("java:comp/env/ejb/MyCoolBean");
MyCoolLocal cool = ((MyCoolLocalHome) PortableRemoteObject.narrow(objref, MyCoolLocalHome.class)).create();
Теперь метод init нам больше не нужен. Бины подключаем аннотацией:
@EJB MyCoolLocal cool;

Что не трогаем
Пока оставим использование xdoclet, это позволит нам получить web.xml автоматически. Остальные конфиги, сгенерированные им, уже не нужны. Поэтому задачу по генерации ejb-jar.xml выключаем. Также убираем в сервлетах  инструкции для xdoclet вида @web.ejb-local-ref.
Скорее всего ещё прийдётся поправить скрипт сборки, но это уже мелочи зависящие от конкретного проекта.
При такой схеме работы, по моим оценкам, адаптация небольшого проекта (300 - 400 классов) потребует не более 4 часов.

Комментариев нет:

Отправить комментарий