пятница, 13 апреля 2012 г.

BoneCP - производительный пул соединений для БД

BoneCP - библиотека управления соединениями с БД. Использую ее уже более 2-х лет в разных проектах, в том числе и в системах с нагрузкой. Автор позиционирует ее как более производительную замену библиотекам c3p0 и dbcp. Представленные им бенчмарки это только подтверждают.

Среди полезных возможностей можно отметить:

  • логирование всех sql-операций

  • доступ к статистике через JMX

  • кэширование PreparedStatement-ов

четверг, 12 января 2012 г.

Поддержка socket.io протокола на Java

Опубликовал свой первый проект на github - netty-socketio, реализующий серверную поддержку socket.io протокола на java. В основе использован легендарный фреймворк Netty.

Socket.io - библиотека предназначенная для создания постоянной связи браузера с сервером. Таким образом возможно организовывать доставку данных в реальном времени в обе стороны. Socket.io поддерживает несколько транспортных механизмов для организации такого взаимодействия - web-sockets, xhr-polling и т.д.

В моей реализации поддерживается socket.io-client версии 0.8.7+. Из поддерживаемых транспортов пока только xhr-polling и websocket.

среда, 2 марта 2011 г.

Smooks: парсим xml с помощью ... xml

Smooks - отличный инструмент, который решает задачу парсинга xml используя xml-маппинг тэгов и аттрибутов на объекты и их свойства. Вообще продукт позиционируется как инструмент для трансформации, биндинга, валидации и обработки данных в различных форматах (CSV, XML, EDI). Я рассматриваю этот продукт как достойную альтернативу других механизмов парсинга xml - JAXB, JAXP, Digester и пр.

Предположим нам надо распарсить такой вот xml:

Xml необходимо распарсить в List из объектов типа PlayerRole:

Для начала создадим xml-маппинг необходимый для преобразования данных в объекты:

В Smooks все метаданные, необходимые для парсинга участков xml, представляются в виде бинов с сылками друг на друга. Адресация в xml осуществляется с помощью xpath-выражений. Если при парсинге необходима какая-то пост-обработка данных можно воспользоваться возможностью выполнения groovy-скриптов (тэг g:groovy), при этом код работы с xml будет более лаконичн чем на java. Из groovy также возможны обращение к бинам smooks.

Ну и наконец пример запуска механизма парсинга данных с приведенным конфигом:

Чтобы получить результат парсинга надо выбрать бин, обрабатывающий root-овый тэг, в нашем случае это бин с id="roles-bean".

Я выбраю этот движок для разбора xml т.к. он почти не требует кода и интегрирован с groovy. Использую его когда в проекте требуется распарсить различные конфигурационные ресурсы на этапе запуска сервера.

пятница, 14 января 2011 г.

Использование Javassist для генерации прокси в Spring Framework

Известно, что проект cglib давно находится в заброшенном состоянии, также при работе с ним возникают некоторые проблемы, описанные здесь. Наиболее популярная альтернатива этому проекту - javassist. Он используется в таких проектах как JBoss AS, Hibernate, Weld ...

Только вот в Spring он еще не появился. Замена библиотеки cglib, используемой для генерации proxy-объектов, на javassist, судя по плану проекта, состоится в версии 3.1 проекта. Вот jira-таск. В этом же таске я прикрепил аттачи в виде трех классов и пары патчей, которые позволяют окончательно перейти на Javassist.

Для включения поддержки Javassist вам понадобится пристроить к себе в проект вот эти три класса - JavassistAopProxy, JavassistAopProxyFactory и JavassistApplicationContext. Затем вместо spring-овой реализации ApplicationContext-а задействовать org.springframework.aop.framework.JavassistApplicationContext. Если вы не создаете его напрямую, а используете org.springframework.web.context.ContextLoaderListener сконфигурированный в web.xml, то вам необоходимо будет добавить в этот же web.xml такие строки:

суббота, 6 ноября 2010 г.

"Хорошая" новость от Oracle...

Хотя это событие было предсказуемо, после коммерциализации MySQL и OpenOffice, верить в него не хотелось. Похоже oracle хочет разделить версии JVM на "free" и "premium", подробнее тут.

среда, 3 ноября 2010 г.

Поиск по ключу входящему в числовой диапазон.

Дана таблица по которой, в зависимости от опыта игрока, определяется его уровень:

  Диапазон опыта     Уровень

0 < exp <= 12 1
12 < exp <= 30 2
30 < exp <= 67 3
... ...
231 < exp <= 300 10

Задача: реализовать алгоритм поиска уровня.

Для решения задачи я задействую класс java.util.TreeMap. Почему этот класс? Все просто, он реализует важный интерфейс - java.util.NavigableMap, появившийся с версии Java 1.6. Его метод

Map.Entry<K,V> ceilingEntry(K key)

как раз позволяет найти запись в map-е удовлетворяющую условию K(n) < key <= K(n+1) и при этом будет содержать значение по ключу K(n+1). Таким образом, остается составить map-у из записей: ключ - макс. значение опыта на уровне, значение - уровень. Код решения:

Для наглядности я захардкодил map-у в коде, на деле же она создается из xml.

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

Обновление максимального значения без использования блокировок

При реализации грамотных многопоточных механизмов, порой используют только синхронизованные блоки кода. Но, не следует также забывать и о функции CAS (Compare and swap, представленной соответствующей процессорной командой). Данная функция присутствует во всех классах пакета java.util.concurrent.atomic.

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

До недавнего времени примение CAS-у в своей практике я не находил. Однако, когда потребовалось реализовать многопоточный алгоритм обновления максимального значения, он оказался весьма уместен: