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

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

[HOWTO] WYSIWYG with Grails + CKEditor + Spring Security

Add last version of Grails CKEditor plugin to BuildConfig.groovy

grails.project.dependency.resolution = {
    plugins {
        compile ":ckeditor:"

Plugin version corresponding to bundled CKEditor version, and may be outdated.
To update it, and you use assets pipeline plugin, download CKEditor and unpack to grails-app/assets/ckeditor.
Then you should add dependency to application.js like this

//= require jquery-1.11.1.min
//= require jquery-ui.min
//= require_tree plugins
//= require_tree globalize
//= require bootstrap
//= require ../ckeditor/ckeditor
//= require_self

If CKEditor version is good enough for you, just put ckeditor:resources tag into head of view:


Then you can insert CKEditor in form with tag ckeditor:editor. For example editor of article content:

<ckeditor:editor name="content" height="400px" width="80%" userSpace="${currentUser.id}">${article.content}</ckeditor:editor>

Here used attribute userSpace with value of current user's id. It makes all user images upload to server separated to their own folders.

But you should also restrict access to users spaces. If you use Spring Security (S2) plugin you can create custom filter with command grails create-filters OfmSecurity:

class OfmSecurityFilters {
 def springSecurityService
 def filters = {
 all(uri: '/ck/ofm/**') {
 before = {
 if (springSecurityService.currentUser?.id != params.space?.toLong()) {
 redirect(controller: "user", action: "login")
 return false

 after = { Map model ->

 afterView = { Exception e ->

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

Conditional Verbosity With Temporary Log Queues

I found a great advise in article Optimal Logging and it worth to mention separately:

When errors occur, the log should contain a lot of detail. Unfortunately, detail that led to an error is often unavailable once the error is encountered. Also, if you’ve followed advice about not logging too much, your log records prior to the error record may not provide adequate detail. A good way to solve this problem is to create temporary, in-memory log queues. Throughout processing of a transaction, append verbose details about each step to the queue. If the transaction completes successfully, discard the queue and log a summary. If an error is encountered, log the content of the entire queue and the error. This technique is especially useful for test logging of system interactions.

It’s cool idea, I’ll try in practice.
And Michael Würtinger created a SLF4J extension for doing it.

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

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:

    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 теорема
Хранение данных в 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.


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

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


Get every new post delivered to your Inbox.

Join 687 other followers