Author Archives: flash

Установка mod_jk для Apache 2.2 под CentOS 6

1. Загрузите исходники последней версии mod_jk и распакуйте:

2. Ставим компилятор, если его еще нет:

3. Собираем и ставим:

 

Received end packet from server, apparent master shutdown

Если в логах mysql слейв сервера вы видите массу ошибок вида:

Скорее всего, server-id из my.cnf не уникален и есть другой слейв с таким же ID

HP DL320e + Smart Array RAID B120i + CentOS 6.4 x64

По работе была необходимость поставить CentOS 6.4. x64 на новый сервер от HP – Proliant DL320e. Естественно, без проблем не обошлось, иначе не было бы этого поста. Началось с того, что Live DVD CentOS’а не загружался, выкидывая Kernel Panic. Также, не грузились и другие дистрибутивы, например Fedora 18. Решилось путем отключения в BIOS USB 3.0. Где-то в его недрах  есть пункт USB Routing по-умолчанию выставленный на 3.0. После того, как поменял на 2.0 установщик смог загрузиться.

Следующая проблема в том, что при инсталляции линукс не видит RAID контроллер. Чтобы это исправить, необходимо скачать соответствующий драйвер с сайта HP, закатать его на флешку в виде образа либо через DD:

Далее, вставляем DVD намбер ван с установкой CentOS, вставляем флешку и грузимся с DVD. Когда появится GRUB жмем ESC и пишем в строке boot:

Нажимаем Enter, ждем вопроса про диск с драйверами и отвечаем Yes. Дальше надо выбрать /dev/sdc (в моем случае туда замаунтилась флешка) и выбрать соответствующий образ с драйвером. Если установщик предложит указать, для чего этот драйвер, выдав приличный список девайсов, там надо найти Driver for HP Smart Array RAID (что-то в этом роде). После всего, продолжаем инсталляцию на успешно обнаруженный RAID массив.

 

Как примонтировать LVM разделы в режиме восстановления

1. Загрузиться с LiveCD
2. Выполнить сканирование:

3. Активировать разделы:

4. Проверить список логических дисков:

 

Теперь можно смело монтировать разделы командой mount:

Форматирование даты с помощью JSTL

Простой пример, как можно отформатировать дату на jsp странице с помощью fmt taglib.

Форматирование чисел с помощью JSTL

1. Форматирование чисел в денежных форматах:

2. Форматирование по шаблону


 

Cocoa / iPhone: отладка ошибки EXC_BAD_ACCESS

Если вы хоть раз занимались разработкой программного обеспечения под iPhone, то наверняка встречались с ошибкой EXC_BAD_ACCESS. Отловить ее достаточно непросто, т.к. встроенный дебагер не покажет вам нужный стектрейс и тем более не подскажет, как все исправить.

Что же такое EXC_BAD_ACCESS? Мне удобнее сравнивать эту ошибку с NullPointerException в Java, т.к. возникает она в ситуации, когда вы отправляете “сообщение” объекту, который уже был выгружен из памяти (released). Например, попробуйте создать объект с помощью alloc и затем два раза подряд его “отпустить” с помощью release.

Так как же быть, если у нас достаточно большой проект с массой кода и объектов? Как проще и быстрее отловить данную ошибку? На помощь придет директива NSZombiEnabled, установленная в переменных окружения проекта. Все, что она сделает – это заставит Objective C runtime оставлять объект-пустышку за каждым выгруженным реальным объектом и в следующий раз, когда вы попытаетесь обратиться к своему выгруженному объекту, вызов пойдет именно к пустышке, которая остановит выполнение кода и выведет короткое и ясное сообщение в дебагер о том, какой объект был вызван и что за сообщение ему было отправлено. Стектрейс при этом также не будет испорчен, и сможет дать дополнительную информацию о месте баги.

Чтобы установить данную переменную, откройте Xcode, меню Project –> Edit Active Executable. Далее выберите вкладку Arguments, во втором списке добавьте переменную NSZombieEnabled и поставьте ей значение YES в столбце Value. Убедитесь, что перед названием переменной стоит галка.

В моем примере помимо NSZombieEnabled установлены еще две переменные: NSAutoreleaseFreedObjectCheckEnabled и NSDebugEnabled. Первая предотвратит автоматическую выгрузку из памяти объектов, помеченных как autorelease в случае, когда они уже были выгружены ранее. Вторая переменная будет полезна скорее самому разработчику, т.к. ее можно будет использовать в своем коде, когда нужно, например, вывести дополнительную информацию в debug log:


После того, как проблема решена, не забудьте снять галки с этих переменных, т.к. нам не нужно, чтобы память в работающем приложении тратилась на дополнительные дебажные объекты.

Управление памятью в Objective C

При разработке софта под iPhone, столкнулся с проблемой непонимания механизма распределения памяти. Являясь java-разработчиком, привыкшим к чудесам Garbage Collector’а, тема памяти в Objective C поначалу доставляла мне массу неприятностей. Спустя некоторое время, написав свое первое приложение, я подумал, что полностью разобрался в этой непростой теме… и это было моей ошибкой. Все таки, сначала надо хорошо читать мануалы и желательно до конца :)

Назвал я данную тему непростой не из-за сложности механизмов управления памятью – они то как раз более-менее понятные и простые, а, скорее, из-за того, что не разобравшись до конца, как правильно “освободить” объект из памяти, можно получить массу сложноотлавливаемых ошибок типа EXC_BAD_ACCESS, причем необязательно именно в том месте, где была допущена ошибка распределения памяти.

Начну с того, что Objective C является основным языком программирования под Mac OS X и сама Apple рекомендует использовать для управления памятью механизм Garbage Collection. Однако, на данный момент, такой подход не доступен для разработки под iPhone. Что ж, придется заботится об удалении всех переменных из памяти вручную.

Итак, начну с базовых вещей. Управление памятью в Objective C базируется на принципе количества ссылок на объект. Когда мы создаем новый объект, его счетчик ссылок становится равным единице. Как только объект перестает быть нужным, мы говорим ему об этом и счетчик уменьшается на ту самую единицу. Как только счетчик становится равным нулю, объект автоматически удаляется из памяти. Приведу простой пример:

Первая строка данного примера вызывает поочередно alloc, который выделяет место в памяти под будущий объект и метод init, который, в свою очередь, инициализирует объект (аналог конструктора). Счетчик ссылок при этом устанавливается равным единице. Последней строкой мы говорим, что данный объект нам больше не нужен, тем самым заставляя счетчик ссылок уменьшится на 1, становясь равным нулю. Как я писал выше, нулевое кол-во ссылок незамедлительно удаляет объект из памяти, вызывая метод dealloc.

Существует также другой способ освобождения объекта – autorelease. Разница в том, что стандартный release удалит ссылку на объект незамедлительно (если счетчик стал = 0), в то время, как autorelease сделает это позже и ссылка на объект будет оставаться действительной до выхода из функции, где autorelease был вызван или до принудительной очистки NSAutoreleasePool.

Целесообразно использовать autorelease, например, в set методах, т.к. объекты str и name из примера выше могут ссылаться на один и тот же объект и если бы мы делали release, то это сразу бы удалило его из памяти (при условии, что на момент входа в setName, объект str/name имел кол-во ссылок = 1). Соответственно на строке [str retain] вылетела бы ошибка EXC_BAD_ACCESS.

Итак, базовое правило при работе с памятью, которое нужно запомнить:

Каждому alloc, new*, copy или retain должен соответствовать свой release или autorelease. Это значит, если вы создавали объект или становились его владельцем через copy/retain, то вам же необходимо его удалить из памяти. Во всех других случаях release или autorelease делать ни в коем случае нельзя.

Примерами случаев, когда вы не должны заботиться об удалении объекта из памяти может послужить любая ситуация, когда вы не вызывали вышеупомянутых alloc / copy / retain:

В данном примере мы явно не создавали новый инстанс NSDate, а следовательно нам и не надо думать о его дальнейшей судьбе. Единственное, что надо иметь в виду – объект помечен как autorelease, а значит, someObject setDate должен сделать на нем retain, т.к. он получил его в использование. Это произойдет автоматически, если вы в someObject будете использовать @property:

Другой пример:


 

Исходя из нашего базового правила мы освобождаем num1, который был явно создан, но не трогаем num2, созданием которого занимался фреймворк Foundation.

Подводя итог моего знакомства с управлением памятью в Objective C, еще раз повторю две основные вещи: всегда удаляйте из памяти объекты, которые сами создали и не забывайте делать copy или retain на получаемых в использование объектах, пока их владелец не успел освободить их.

Также, рекомендую почитать документ от Apple на эту тему:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html#//apple_ref/doc/uid/10000011-SW1

Cocoa / iPhone: форматирование даты

Простой пример для тех, кто ищет простой и быстрый путь отформатировать дату при разработке под iPhone. В моем примере будем форматировать дату по стандарту RFC2822.

Данный подход достаточно прост и эффективен, но у него есть один минус – куча строк, которые придется писать каждый раз, когда надо сделать преобразование. Чтобы этого избежать можно сделать так:

NSDate-RFC2822.h:

NSDate-RFC2822.m:

И теперь, чтобы конвертировать дату, нужно лишь: