Comet на Embedded Jetty. Первый блин)

комом. Мой первый эксперимент с COMET и с Embedded Jetty. “Пощупать” COMET хотелось уже давно. Во-первых сама по себе технология достаточно интересная, а во-вторых — хотелось попробовать что-то новенькое. Jetty был выбран в качестве сервера для экспериментов как наиболее легковесный (особенно в embedded-варианте) из известных мне Java-серверов.

В качестве примера напишем простенький чат. Будем использовать технику long polling. Допустим у нас запущен Jetty-сервер с приложением-чатом, к которому подключились два клиента Саша и Маша. На диаграмме все их мучения будут выглядеть так:

comet

Теперь попробуем объяснить увиденное с небольшими вставками кода (полный исходный код можно скачать в конце статьи).

Continue reading

Визуализируем репозиторий #2

Продолжаем эксперименты с Code Swarm. В связи со сменой работы решил натравить визуализацию на текущий проект) Вот что получилось:

P.S.: хорошая пошаговая инструкция по этой утилите.

Reorder JQuery event handlers

I was little bit suprised when I didn’t find in JQuery an ability to bind event’s handler before than already binded event’s handlers list. Yes, it is possible to first attach our handler rather than others, but this may be very difficult sometimes. So I spent some time looking through JQuery sources and found what I need:

/*
 * A number of helper functions used for managing events.
 * Many of the ideas behind this code originated from
 * Dean Edwards' addEvent library.
 */
jQuery.event = {
 
    // Bind an event to an element
    // Original by Dean Edwards
    add: function( elem, types, handler, data ) {
        ...
 
        // Init the element's event structure
        var elemData = jQuery.data( elem );
 
        // If no elemData is found then we must be trying to bind to one of the
        // banned noData elements
        if ( !elemData ) {
            return;
        }
 
        // Use a key less likely to result in collisions for plain JS objects.
        // Fixes bug #7150.
        var eventKey = elem.nodeType ? "events" : "__events__",
            events = elemData[ eventKey ],
            eventHandle = elemData.handle;
 
        ...
 
        while ( (type = types[ i++ ]) ) {
            ...
 
            // Get the current list of functions bound to this event
            var handlers = events[ type ],
                special = jQuery.event.special[ type ] || {};
 
            ...
 
            // Add the function to the element's handler list
            handlers.push( handleObj );
 
            ...
        }
 
        // Nullify elem to prevent memory leaks in IE
        elem = null;
    }
 
    ...
}

As we can see from this code all we need to do is get “handlers” array (for “click” event in this example) from target element. Then we can do anything we need with event’s handlers. Code to do this is quite simple:

var
elementData = jQuery.data(targetElementDom),
events = (elementData.events ? elementData.events : elementData.__events__),
handlers = events['click'];
 
// Only one handler. Nothing to change.
if (handlers.length == 1) {
    return;
}
 
// Insert last handler at first index.
handlers.splice(0, 0, handlers.pop());

I used previous code to attach confirm window to elements which already have (or not) “click” event handlers.

Little demo.

Jersey: how to get temporary file

I use Jersey with flash uploader and the problem I met is that I need to determine “file partialy uploaded” situation ’cause user has an opportunity to cancel it at any time. All solutions that I found for this problem were on PHP (look for The uploaded file was only partially uploaded text). I didn’t find any standart technics how to get size of uploaded file (uploaded file’s input stream doesn’t has such information) to compare it with actual file size. So I used a “little reflection magic” to get it. ’cause classes that we’ll use to get information is private for org.jvnet.mimepull package we need to create out util class in exactly the same package. Then we can use reflection to get any infomation that we need.

Continue reading

Fix for Jersey’s russian files names bug

In our project we use Sun/Oracle implementation of JAX-RS — Jersey ’cause it’s greate framework for build REST-services. But there are some troubles with uploading files feature. When you uploading file with latin chars in file name everything is fine, you read this file name on server and it’s exactly the same as on client computer. But when you trying to upload file with russian chars in file name you get “abracadabra” instead of them. For example:

Original file name Received file name
Test123.txt Test123.txt
Тест123.txt Тест123.txt

Continue reading

JRebel: хватит тратить своё время

Небольшой обзор по установке и использованию JRebel. Штука действительно очень клёвая. Предназначена для java-разработчиков. В основном для тех, которые занимаются enterprise-решениями, так как они достаточно громоздкие и пересборка/перезапуск всего проекта занимает значительное время (несколько минут), что сказывается как на скорости, так и на желании работать) JRebel позволяет увидеть результат от внесённых изменений практически мгновенно. Обзор проводился в следующем окружении:

  • Maven 2
  • JBoss 4.3.2
  • Seam 2.2.0.GA
  • IntelliJ IDEA 9

Однако, как будет видно из ролика, настройка должна пройти без проблем и для других вариантов окружения.

Continue reading

Чё за музяка?

Бывает порой слышишь какую-нить клёвую песню/музыку, но не знаешь/не можешь вспомнить кто исполнитель/что за песня. В нелёгком деле распознавания музыки призвана помочь программка shazam. Так как чудо это ставится только на мобильные устройства с нормальными ОС типа Symbian, Windows Mobile и т.д., то испробовать на деле у меня её не получилось, но отзывы довольно лестные, например:

Суть данной программы проста — вы даете ей секунд 15 послушать некую музыку, а она определяет, что это за композиция и кто исполнитель. Даже обложку из интернета закачивает и ссылки на Amazon и Youtube даёт.

И главное, она определила практически все треки, которые я ей подсунул. Удобно, когда играет что-то по радио, или музыка в каком-то фильме или сериале, или что-то на фоне играет в кафе, а ты хочешь понять, что же это.

Gluek’s blog

Вот тут ещё небольшое описалово. Но, к сожалению, на моём чуде китайской промышленности эту прогу не поставить, поэтому нашёл аналог — Tunatic. Она бесплатная, есть версия для Windows и Mac. У меня успешно распознала песни исполнителей:

  • Кипелов;
  • Yngwie J. Malmsteen;
  • Van Halen;
  • Lacuna Coil;
  • Rammstein.

Интерфейс очень минималистичный:

tunatic

По-моему круто) Так же было бы интересно услышать мнение по поводу shazam, если кто-то себе установит. Также существует бесплатный отечественный сервис по распознаванию музыки — AudioTag.info.

Sharing JSESSIONID cookie across subdomains on JBoss

The problem with sharing cookie with JSESSIONID value arises when we start use subdomains system in our application. For example: images.portal.com, security.portal.com, etc.

Respectively a cookie with unique JSESSIONID value will be created for each domain address and you can get some problems. For example, with autorization if it stores credentials in session. So for our example we will have three diffrent cookies with three different session ids.

# Domain Value
1 portal.com JSESSIONID1
2 images.portal.com JSESSIONID2
3 security.portal.com JSESSIONID3

Not very good, really?) Our cookie must have “.portal.com” domain to starts sharing across all subdomains (and there also will be only one session cookie instead of three). I didn’t find any standart solution for this problem. Possible solutions are:

  1. hardcode domain name in TomCat source files and recompile them (heh, I think this is the most popular solution for this problem over the Internet, but it isn’t our way);
  2. use custom valve to set domain name (very flexible solution, so we will used it);
  3. write cookie with true domain from application. But this will make your application logic more complicated and you will have two cookie with identical JSESSIONID value and different domains. “.portal.com” — from your application, “portal.com” — from TomCat.

Valve is the great software development company and it is also a filter that can do some transformation with request. In our case the valve must takes session cookie from request and rewrites its’ domain to some that we setup in config file. It’s very easy, ’cause problem is already solved. From previous link we saw how to work with valve and now we can go here.

Step-by-step guide (for JBoss 4.2.3):

  1. download customvalve2.zip file;
  2. put customvalve.jar file from archive to “JBOSS_HOME/server/YOUR_CONFIGURATION/lib” folder;
  3. add string “<Valve className=”com.redhat.jboss.support.ConfigureSessionCookieValve” cookieDomain=”.portal.com” />” to your host in “JBOSS_HOME/server/YOUR_CONFIGURATION/jboss-web.deployer/server.xml” file. Looks like:
    <Host name="localhost"
        autoDeploy="false" deployOnStartup="false" deployXML="false"
        configClass="org.jboss.web.tomcat.security.config.JBossContextConfig"
        >
        ...
        <Valve className="com.redhat.jboss.support.ConfigureSessionCookieValve"
            cookieDomain=".portal.com" />
        ...
    </Host>

And at last let us see the method that does all work (located in ResponseWrapper.java):

// Called from addCookie() and addCookieInternal() methods.
protected void configureSessionCookie(Cookie cookie) {
    if (Globals.SESSION_COOKIE_NAME.equals(cookie.getName())) {
        if (cookiePath != null) {
            cookie.setPath(cookiePath);
        }
        if (cookieDomain != null) {
            cookie.setDomain(cookieDomain);
        }
        if (cookieSecure != null) {
            if (cookieSecure.equalsIgnoreCase("true")) {
                cookie.setSecure(true);
            } else if (cookieSecure.equalsIgnoreCase("false")) {
                cookie.setSecure(false);
            }
        }
    }
}

That’s all!) Valve sources lie in downloaded archive so they can be easily modificated for your purposes.

Яблоко из Гонконга (M002L)

Вступление

Данный девайс был куплен мною около 4 месяцев назад. И вот, наконец-то собравшись с силами, я решил написать небольшой обзор про это чудо устройство)

Захотелось)

Идея прикупить себе iPhone появилась у меня довольно давно, но немного смущала цена данного девайса) Ибо отдавать около 20 000 рублей за телефон я пока не готов. Оставалось только ждать улучшения материального положения… но всё сложилось иначе)

Во время пребывания в гостях у одного моего друга он показал мне забавный китайский интернет-магазин Focal Price. Собственно вся забавность заключалась в том, что там продавались самые невероятные устройства за самые невероятные деньги. Одной из групп таких устройств являются подделки под iPhone. Среди которых были обнаружены два интересных экземпляра F003+ и M002L. Оба телефона обладают примерно одинаковыми характеристиками. Выбор был сделан в пользу последнего исключительно на основе отзывов с форумов) Время покупать!

Continue reading