Серёжа Пономарёв aka stokito

I'm Java & Grails developer, coach and founder of IT community #kranonit in my native city.

Working with cookies in Grails

I’m become a maintainer of Cookie Plugin for Grails.
And today happy to make it first production release.

To install it add compile ":cookie:1.0.1" dependency to BuildConfig.groovy.

Then you can use it via CookieService:

// This sets a cookie with the name `username` to the value `admin` with a expiration set to a week, defined in seconds
cookieService.setCookie('username', 'admin', 7 * 24 * 60)
// Or you can use named parameters:

cookieService.setCookie([
    name: 'username', // Cookie name. Can't be blank or null and is case-sensitive
    value: 'admin', // Cookie value.
    maxAge: 30 * 60, // Age to store cookie in seconds; if negative, means the cookie is not stored; if zero, deletes the cookie.
    path: '/admin/', // A path to which the client should return the cookie. The cookie is visible to all the pages in the directory
    domain: '.example.com', // It begins with a dot (.example.com) and means that the cookie is visible to servers in a specified DNS zone
    secure: true, // Indicates to the browser whether the cookie should only be sent using a secure protocol, such as HTTPS or SSL.
    httpOnly: true // "HTTP Only" cookies are not supposed to be exposed to client-side JavaScript code, and may therefore help mitigate XSS attack.
])  

// To get the cookie value
cookieService.getCookie('username') // returns 'admin'

cookieService.deleteCookie('username', '/admin/')

I will be thankful for any feedback and bug reports
Cookie Plugin on Grails.org

Оставить комментарий »

Dr. Deprecator Prescriptions: important things that you should know about obsolete Java API

Did you ever asked yourself why Cloneable or, for example, Serializable interfaces are not deprecated?
OpenJDK team has a special man Stuart Marks who call himself as Dr. Deprecator. He is «Software Deconstructionist» and few days ago he made a great talk about API evolution and upcoming removing of some obsolete code in Java 9.
Doctor Deprecator
Thanks to Yoshio Terada for a photo.

The most important idea from presentation is that «Deprecated» code may be separated into four categories:
“Condemned” – will be removed or disabled in a future release (no moral connota, on). For example, from Java 9 already removed java.util.logging.LogManager.addPropertyChangeListener()
“Dangerous” – using this may introduce bugs or data loss. For example, String.getBytes() may loss for anything other than ASCII
“Superseded” – not dangerous, not going away, but new code should use something different. For example Vector, Date classes.
“Unimplemented” – some things unconditionally throw an exception at runtime (e.g. UnsupportedOperatioonException). This enables warnings at compile time. For example: class ImmutableList implements List, so should implement mutator methods add() and remove()

Video doesn’t uploaded yet, but hope you will enjoy this presentation:

Оставить комментарий »

Уроки из авиа и космостроения для разработчиков

Бьёрн Фриман-Бенсом, рукводитель разработки крутейшей системы мониторинга NewRelic, интересно рассказал о том с какими проблемами сталкивались авиаконструкторы и что их выручал итератиный подход к разработке.  Ну и естественно, без систем мониторинга они никуда, как и нам айтишникам ;)

Оставить комментарий »

Erlang Курсы в Киеве 29 и 30 ноября

Камрады, тут в конце ноября намечается курсы по Эрлангу. Я хоть и джавист, но Эрланг у меня вызывает очень тёплые чувства и это очень достойная технология.
Курс обещает быть толковым, стоит чисто символически, вообщем, рекомендую для расширения кругозора. Описашка:

Erlang Курсы 2014 Киев
Как известно Synrc Research Center всячески поддерживает и развивает Erlang сообщество не только в Украине, но и за ее пределами. Наши фреймворки работают и помогают многим людям по обе стороны Атлантики тратить минимум усилий на инженерные процессы. Год назад Synrc давала модуль по основам языка Erlang и веб-программированию на Erlang. Пришло время нового модуля — охватить новые горизонты применения языка Erlang в бизнесе и вебе.

Тренер:

Максим Сохацкий. Технический директор «Synrc Research Center». В сфере IT более 13 лет. Еrlang’ом занимается с 2010 года. Автор нескольких компиляторов, интерпретаторов для платформы .NET. Завсегдатай Erlang User Conference в Стокгольме и Калифорнии. Фаундер Erlang Girls, а также автор известного блога об Erlang в ЖЖ.

Для кого:

Этот курс разработан для технических специалистов, руководителей команд и отделов, которые хотят применить Erlang у себя в производстве, но еще раздумывают. Наша цель — показать всю легкость и лаконичность данной технологии. Если вы присматриваетесь к языку Erlang и его проектам, и хотели бы узнать о реальных практических задачах, которые мы решаем каждый день в Synrc Research Center, будьте уверены, мы вам расскажем о всех подводных камнях.

Программа:

На курсах вы познакомитесь с Full-Stack Erlang Applications, начиная с виртуальной машины Ling созданной в Украине, и DevOps стеком, осваивая все фреймворки прикладного уровня, и заканчивая бизнес приложениями на Erlang. Значительное внимание будет уделено флагманскому продукту Synrc — веб фреймворку N2O и абстрактному хранилищу данных KVS. Мы покажем вам насколько просто создавать Erlang веб приложения, и вы сами сможете оценить мощность этих подходов, сравнить их с технологиями, которые вы уже используете у себя сегодня на Python, Java и других языках.

Теория:

Основы веб фреймворков и их классификация
Ивент стриминг по вебсокетам
Автогенерируемые формы
Персонифицированные сессии для анонимов
Одностраничные приложения
Консистентность данных
CAP теорема
CoSQL и SQL
Хранение данных в Erlang
Версионирование схем
Практика:

Написание приложений с использованием библиотек N2O, KVS, MAD.

При себе необходимо иметь ноутбук с Windows, Linux или Mac, установленный Erlang, и знание хотя бы одного языка программирования. Git и другие штуки тоже не забудьте, будем вместе с вами писать программ.

Ключевая Информация

Дата и время: 29 и 30 ноября, 10:00-14:30
Место проведения: Киев, Бизнес-центр «FIM CENTER», ул. Линейная 17

Стоимость участия: 1000 гривен.

Форма он-лайн регистрации: РЕГИСТРАЦИЯ

Количество мест ограничено (~30).

Оставить комментарий »

[Grails] Ещё пару GORM gotchas

Короткая заметка-черновик где хочу зафиксировать некоторые подводные камни с ипользованием GORM. Чуть позже докидаю примеров кода.
Это продолжение заметок:

И напоследок, обязательно изучите руководство по GORM’у чтобы не плодить проблем. Именно запросы в БД чаще всего являются узким местом в вашем приложении из-за которого проседает производтельность.
К сожалению в GORM очень много ловушек многих из которых избежать вам помогут три статьи евангелиста Grails Питера Ледбрука (Peter Ledbrook):

  1. GORM GOTCHAS (PART 1) Перевод на русский
  2. GORM GOTCHAS (PART 2) Перевод на русский
  3. GORM GOTCHAS (PART 3) (перевода на русский нет)

Advanced GORM — Performance, Customization and Monitoring

Implementing Burt Beckwith’s GORM Performance – No Collections

1. Всегда указывайте максимальный размер строковых полей

Если вы явно не указали максимальный размер строкового поля то GORM создаст таблицу с полем VARCHAR(255):

class Book {
  String title
}

grails schema-export:

create table book (
  id bigint generated by default as identity, 
  version bigint not null,
  title varchar(255) not null,
  primary key (id)
);

Наверное каждая база данных поддерживает VARCHAR до 255 символов, как этого требует стандарт ANSI SQL.
Проблема возникает при валидации объекта: поскольку максимальный размер поля не указан, то Grails его и не валидирует, пропуская объект дальше пока он не вызовет исключение при сохранении в БД. И то, я не проверял, но например MySQL может молча обрезать значение поля если не включен строгий режим. Хотя может на уровне Hibernate это и не допустится, я не в курсе.
Поэтому указывайте явно максимальный размер поля в секции constraints:

class Book {
    String title
    static constraints = {
        title maxSize: 255
    }
}

Кстати если вам требуется больше 255 символов, то вам следует использовать мапинг на текстовый блоб (CLOB):

class Book {
    String title
    static mapping = {
        title type: 'text'
    }
}

Правда вы теряете при этом возможность строить индексы по этому полю.
Но и в этом случае нужно указывать максимальный размер строки для валидации.

Проверка уникальности происходит только при сохранении

Ещё одна похожая ошибка. Так же как и размер строки, уникальные поля проверяются только момент сохранения, так что вы можете получить исключения уровня БД вместо ошибки на этапе валидации.

Лучше явно прописывайте Long id

Ключевое поле id создаётся динамически, то наверное лучше всё таки прописать его явно

class Book {
    Long id
    String title
}

Во первых, просто так становится меньше неявных мест. Ведь у вас могут быть другие доменные объекты у который ключ составной а поля id нет вовсе.
Это точно придётся сделать если вы захотите использовать это поле в выводе метода toString() или equals. А ведь бывают такие доменные объекты которые можно проверить на равенство только по id.

Лучше явно указывать тип полей hasMany

Тут ситуация схожая с явным id — иногда лучше избегать невного поведения.
По умолчанию поля генерируемые через hasMany имеют тип Set (PersistentSet).
Т.е. вам не гарантируется порядок например и каждый раз при вставке записи будут выгружены все объекты из ассоциации чтобы проверить на уникальность.
Если вы укажите тип в List то хибернейт тоже выгребет все записи, потому что он вынужден будет сохранить порядок. Поэтому самый лёгкий вариант указывать просто как Collection.
Это фича хибернейта как такового.
Так что лучше явно указать тип который вы желаете, чтобы хотя бы знать отчего проседает скорость:

class Book {
    Long id
    String title
    Set<Author> authors
    static hasMany = [authors: Author]
}
Оставить комментарий »

«Comparing JVM Web Frameworks» by Matt Raible

It’s very cool talk about qestions that every Java developer must decide on new project. Overview of all popular Java frameworks from JSF and Struts to Play and Vaadin.

Оставить комментарий »

Функциональные тесты в Grails: Spock + Geb = Кайф

Вообщем если вы хотите знать почему я прусь по Груви и Греилс посмотрите это видео

Я сам хотел такой доклад сделать но Богдан всё отлично рассказал за меня.
Всем приятного просмотра и расширения сознания

1 комментарий »

Very special time indeed.

stokito:

It’s like an Evolution: we live here, because only we can live here

Originally posted on The Object Matrix:

Why Now?

This is the brief history of time. Showing Y — axis as density of matter as the universe is expanding and X — axis as the age of the universe, and it looks like energy density is constant as the universe is getting bigger. And we are living in a time where energy density of empty space is three time bigger than energy density of matter. This is the only time in the entire history of universe when this two lines intersects, we are living in a very special time.

[Source: Lecture from Lawrence Strauss]


View original

Оставить комментарий »

[Чтиво] Три очень классные практические статьи-инструкции для программистов

Периодически почитываю что накопилось в закладках. Вот отличные прагматичные статьи вкурив которые сразу получите +2 к экспе девелопера.
Экстремальное программирование: Pair Programming чёткая инструкция по делу что такое парное программирование как его делать на практике и самое главное как его НЕ делать.

Парное программирование в аутсорсинге: достижение взаимопонимания с техническими специалистами заказчика Классная статья которую обязан прочесть каждый программист-аутсорсер. Вывод: если у вас есть часть удалённой команды то парно педалить код вы просто обязаны.

Практика рефакторинга в больших проектах в сотый раз о вечном. Для тех кто ещё халтурит и не прочёл замечательную книгу Working Effectively with Legacy Code

Оставить комментарий »

[Grails] Пару последних граблей с GORM

В последнее время несколько раз получал ошибки из-за неопытности в некоторых аспектах GORM и Hibernate. В этом плане GORM постоянный источник неприятных сюрпризов.
И сегодня увидев отличную статью Advanced GORM Features: Inheritance, Embedded Data, Maps and Lists Storing решил записать пока не забыл.

1. Если вы используете наследование в доменых объектах, то не забывайте миграцию при изменении имён классов

GORM позволяет использовать наследование. Классы наследники могут сохранятся либо в разные таблицы table-per-subclass либо все в одну table-per-hierarchy (по умолчанию).
Обратите внимание, что если у вас в одной таблице (table-per-hierarchy) то у вас будет ещё одно поле discriminator с именем class по которому собственно GORM и будет понимать какого конкретно класса эта запись.
Например для такой иерархии классов

class Content {
    String title
    User author
}

class Blog extends Content {
    Date dateCreated
}

class Book extends Content {
    String isbn
}

Будет такая таблица

+---------------------------------------------------------------------------------------+
| content                                                                               |
+---------------------------------------------------------------------------------------+
|id | class            | title            | author_id | date_created | isbn             |
|1  | com.example.Blog | My post          | 1         | '2014-1-1'   | null             |
|2  | com.example.Book | Grails in action | 2         | null         | '978-1933988931' |
+---------------------------------------------------------------------------------------+

Как вы видите, в поле class сохраняется полное имя класса. В момент выборки GORM по этому полю пытается создать этот класс и гидрировать данные из записи.
И тут кроется опасность: если вы допустим поменяли у себя имя класса или его пакет, то все старые записи не смогут извлечься. И самое противное что об этом вы можете узнать только когда уже задеплоите новую версию на продакшен.
Поэтому, если вы поменяли имя доменного класса, не забудьте добавить в скрипт миграции с помощью migration plugin (надеюсь, вы профессионалы, и используете его).
Например, если вы поменяли пакет класса Content и его наследников с com.example на com.example.content то вам следует написать примерно такой скрипт миграции:

databaseChangeLog = {
    changeSet(author: 'John Doe', id: '033_change_content_class-1') {
        update(tableName: "content") {
            column(name: "class", type: "varchar(255)", value: 'com.example.content.Blog')
            where("class = 'com.example.Blog'")
        }
    }
    changeSet(author: 'John Doe', id: '033_change_content_class-2') {
        update(tableName: "content") {
            column(name: "class", type: "varchar(255)", value: 'com.example.content.Book')
            where("class = 'com.example.Book'")
        }
    }
}

2. Не помечайте абстрактные доменные классы модификатором abstract, глючит

Наткнулся на какой-то хитрый баг. Если допустим вы пометите Content как абстрактный, что так и есть, то биндинг подклассов перестаёт почему то работать. Уже забыл детали, забыл зафайлить багу. Grails 2.2.3, возможно поздние версии работают.

Оставить комментарий »

Отслеживать

Get every new post delivered to your Inbox.

Join 686 other followers