HotLog

суббота, 29 января 2011 г.

PropertyChangeSupport и AspectJ

Когда надо создать несколько java-beans с извещением об изменении свойств, обычно заводят общий класс-предок:


И тогда java-bean выглядит примерно так:


Налицо дублирование кода. Повторящийся шаблон ("XXX" - заменяет переменную часть):


Основная цель аспектов - убирать дублирующийся код, встречающийся во многих методах. Это как раз тот случай. Заодно можно будет убрать и надоедливый "extends PropertyChange".

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


Тогда bean можно будет писать в более простом виде:


И сам аспект:

Или в annotation-style:


Теперь по шагам:
  1. Все классы, аннотированные @Bean будут наследовать PropertyChange (в случае с аннотациями они будут наследовать только интерфейс IPropertyChange, а реализация методов будет браться из PropertyChange).

    Или в annotation-style:

  2. Все нужные нам сеттеры - это методы типа void, принимающие один параметр, находящиеся в классе, помеченные аннотацией @Bean.

    Или в annotation-style:

  3. Перед вызовом сеттера запоминаем текущее значение свойства в переменную oldValue(//1). Выполняем сеттер (//2) и публикуем сообщение (//3).

    Или в annotation-style:

вторник, 25 января 2011 г.

JavaWS и javassist

При использовании javassist из-под java-webstart возможны проблемы с поиском классов и/или с класслоадерами. В первом случае мы получим ошибку вроде javassist.NotFoundException, во втором что-нибудь вроде VerifyError.

От первого спасет ручное добавление классов в пул:


От второго: создание класса с указанием класс-лоадера:

воскресенье, 23 января 2011 г.

Debug и JavaWS

Запускаем из консоли так:
set JAVAWS_VM_ARGS="-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8200"
javaws http://xxx.xx/launch.jnlp
И аттачимся дебаггером.

суббота, 15 января 2011 г.

Type-safe Hibernate Criteria.

Пусть у нас есть класс User:


Обычно Criteria-api используют в таком стиле:


Мне кажется немного неправильным писать имена свойств в виде строк: могут возникнуть проблемы при рефакторинге.

На решение меня натолкнула библиотека jmock. В результате для getUser(*) получаем такой код:


Осталось реализовать (использую javassist и google-collections):

вторник, 4 января 2011 г.

Hibernate: org.hibernate.MappingException: Unknown entity ...

Если пользуетесь аннотациями для маппинга, и получаете ошибку Unknown entity, проверяйте в первую очередь, что импортируете @javax.persistence.Entity, а не @org.hibernate.annotations.Entity.