HotLog

вторник, 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.

среда, 29 декабря 2010 г.

Пара regexp'ов для чистки проекта

Удаление строки author из javadoc:
/\*\*(\n.*$)*?(\n.*author.*$)(\n.*$)*?\n.*\*\/

Удаление пустых многострочных комментов:
\/\*\*\s*(\*\s*)*\*\/

вторник, 16 ноября 2010 г.

Spinner с четырьмя кнопками.

Понадобилось сделать спиннер, но с четырьмя кнопками. Две - для изменения значения на единицу и еще две - для изменения на 10.


Рассматривал два решения: поместить в спиннер в качестве эдитора другой спиннер или переписать BasicSpinnerUI (именно оно отвечает за создание и размещение компонентов спиннера). Остановился на втором.
Если наследоваться от BasicSpinnerUI, то получается все довольно просто. В installUI() добавляем на спиннер еще пару кнопок, а в createLayout() возвращаем наш layout, способный правильно расположить на пару кнопок больше.

И вот так можно протестировать:

пятница, 1 октября 2010 г.

Double-check locking.

Идея довольна проста. Пусть у нас есть Singleton, который дорог в создании. Создавать его может потребоваться, а может и нет. Хорошая идея создавать в тот момент, когда он понадобился в первый раз. Получаем код вроде такого:



Обратите внимание на synchonized при декларации метода: каждый раз, когда понадобится ссылка на Singleton, потоку придется захватить монитор, а это весьма дорогостоящая операция.
Если обращение к Singleton'у происходит часто, хотелось бы отказаться от захвата монитора в том случае, если объект уже создан и требуется только чтение.

Неправильное, но интуитивное решение:



Почему же оно неправильное? Причина кроется в специфике Java Memory Model, а именно в том, что обычные (не-volatile) переменные не являются точкой синхронизации.

Пусть у Singletona есть важное для нас поле value:



В худшем случае может происходить следующее:


NNпервый потоквторой поток
1 - getSingleton()
2 - singleton = new Singleton() и value=42
3 - переменная singleton скидывается в основную память
4getSingleton() -
5так как переменная singleton не null, в synchronized блок не заходим
6singleton.value==0 (значение по умолчанию, так как новое значение не было записано еще в основную память)-

Все потому, что для не-volatile переменных не гарантируется, что "happens-before order". Нужна некая точка синхронизации. Так как мы хотим отказаться от использования мониторов, то решение: пометить как volatile переменную singleton.