The Reactive Manifesto

Натолкнулся тут на интересный манифест по принципам разработки больших систем. Потрудился его перевести и представляю его здесь. Если вы владеете английским языком – то лучше почитайте его в оригинале. Для всех остальных, перевод ниже.

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

Это происходит потому, что требования к приложениям радикально изменились в последние годы. Всего лишь несколько лет назад большое приложение могло состоять из пары десятков серверов, время ответа измерялось в секундах, время технических работ могло измеряться часами а данные умещались в несколько гигабайт. Сегодня приложения развернуты везде, где только можно – от мобильных устройств до облачных кластеров с тысячами многоядерных процессоров. Пользователи же ожидают мгновенного ответа от сервера и 100% аптайма. Данные теперь измеряются в петабайтах. Запросы сегодняшнего дня просто не могут быть удовлетворены вчерашними архитектурами.

Мы верим, что требуется сбалансированный подход к архитектуре систем, и мы верим, что все необходимые аспекты уже открыты порознь: нам требуются системы, которые обладают качествами отзывчивости (Responsive), живучи (Resilient), гибкие (Elastic) и основываются на сообщения (Message Driven). Мы называем такие системы «Реактивными» (Reactive Systems).

Такие системы более гибкие, менее связные и масштабируемые. Это упрощает их разработку и развитие. Они более устойчивы к нештатным ситуациям, а когда что-то непредвиденное все-таки случаются, они легко восстанавливаются а не приводят к катастрофе. Реактивные системы обеспечивают пользователю эффективную интерактивную обратную связь.

Реактивные системы:

Отзывчивы (Responsive): Система отвечает настолько быстро, насколько это возможно. Отзывчивость – это краеугольный камень удобных и полезных в использовании систем, но кроме этого, отзывчивость также означает то, что проблемы могут быть быстро диагностированы и эффективно устранены. Отзывчивые системы сфокусированы на обеспечении быстрого и логичного ответа, тем самым формируя верхнюю границу для качества обслуживания. Согласованное ответ в свою очередь упрощает обработку ошибок, сборку и интерфейс пользователя, поощряет дальнейшее взаимодействие.

Живучи (Resilient): Система остается отзывчивой даже в случае отказа. Это правило применяется не только для высокодоступных критичных систем, любая «неживучая» система при сбое станет неотзывчивой. Живучесть обеспечивается репликацией, включением (containment), изоляцией и делегированием. Сбои могут случиться в любом компоненте системы, поэтому изоляция компонентов друг от друга позволяет всей системе оставаться в работоспособном состоянии, даже в случае когда произошел сбой в отдельном компоненте и происходит операция восстановления. Восстановление компонента делегируется другому (внешнему) компоненту, а высокая доступность обеспечевается через резервирование там, где необходимо. Клиент компонента не должен задумываться о том, как действовать в случае его отказа.

Гибки (Elastic): Система должна оставаться отзывчивой под различными нагрузками. Реактивные системы должны реагировать на изменение нагрузки увеличением или уменьшением задействованных ресурсов. Это в свою очередь требует отсутствия ключевых точек или «бутылочных горлышек», что позволяет распределять (shard) или реплицировать (replicate) компоненты, и распределять нагрузку между ними. Реактивные системы должны быть предсказуемыми, алгоритмы масштабирования должны предоставлять все необходимые показатели работоспособности. Такие системы обеспечивают экономию при работе на обычном (не специальном) оборудовании и программных платформах.

Основываются на сообщениях (Message Driven): Реактивные системы основываются на асинхронном обмене сообщениями для обеспечения слабой связности между программными компонентами, изоляции, прозрачности местоположения и дают инструменты для делегирования обработки ошибок через ошибочные сообщения. Благодаря явному обмену сообщениями становится возможным организация балансировки нагрузки, эластичности и управления потоком путем мониторинга и управления потоком очередей сообщений. Прозрачность местоположения сообщений как параметр коммуникации позволяет управлять сбоями одними и теми же методами, вне зависимости от того, работает система на кластере или на отдельном хосте. Неблокирующее взаимодействие позволяет потреблять ресурсы только в периоды активности, что в свою очередь ведет к меньшей перегрузке системы.


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

Подписать манифест можно тут.

Об RAII замолвите слово

Давненько я сюда не писал ничего технического, настало время заполнить сий пробел. Считаю важным зафиксировать здесь несколько заметок о технологии RAII (Resource Acquisition Is Initialization, получение ресурса есть инициализация). Еще информацию об этой технологии на просторах англоязычного интернета можно найти по названию Scoped-Based Resource Management (SBRM), по русски это будет звучать как-то так – управление ресурсами на основе области видимости.

Технология RAII достаточно часто используется и является важной технологией управления временем жизни ресурсов. Управление осуществляется с использованием вспомогательного объекта, в котором ресурс выделяется в конструкторе, а освобождается в деструкторе.

Давайте проиллюстрируем важность и удобство техники на примере.

Например, у нас есть функция, которая получает мьютекс в начале и освобождает его в конце:

1
2
3
4
5
6
7
8
void foo( Mutex& mutex)
{
    mutex.acquire( );
 
    // выполняем какой-нибудь код
 
    mutex.release( );
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void foo( Mutex& mutex )
{
    mutex.acquire( );
 
    // выполняем какой-нибудь код
 
    if ( shoudExit )
    {
        // неплохо бы сделать следующее
        mutex.release( );
        return;
    }
 
    // выполняем какой-нибудь код
 
    mutex.release( );
}

По прошествии длительного времени (год, например) функция разрастается и начинает занимать много строк кода. В процессе роста было добавлено много досрочных выходов, но освобождение мьютекса всегда добавлялось. Однажды, над кодом начинает работать новый человек, он решает добавить очередной досрочный выход… Из-за больших размеров функции мьютекса он может и не увидеть:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void foo( Mutex& mutex )
{
    mutex.acquire( );
 
    // очень много строк кода
 
    if ( newShouldExit )
    {
        // опаньки ...
        return;
    }
 
    // очень много строк кода
 
    mutex.release( );
}

Из примера видно, что такая техника управления ресурсами очень чувствительна к человеческой ошибке. Поэтому в таких случаях целесообразно применять RAII. Согласно стандарту С++ если мы определяем объект на стеке, его конструктор всегда будет выполнен в процессе инициализации, а деструктор в момент выхода из зоны видимости, то есть при return. Поэтому давайте использовать это соглашение в своих целях для управления ресурсами. Для начала напишем вспомогательный класс для автоматического получения и освобождения мьютекса:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class MutexLock
{
public:
 
    MutexLock( Mutex& mutex )
        :    _mutex( mutex )
    {
        _mutex.acquire( );
    }
 
    ~MutexLock( )
    {
        _mutex.release( );
    }
 
private:
 
    Mutex& _mutex;
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void foo( Mutex& mutex )
{
    MutexLock lock( mutex );
 
    // очень много строк кода
 
    if ( newShouldExit )
    {
        // теперь нет необходимости освобождать мьютекс здесь
        return;
    }
 
    // очень много строк кода
 
    if ( shouldExit )
    {
        // и здесь тоже не надо
        return;
    }
 
    // очень много строка кода
 
    // и в конце также не надо
}

Эту технику можно использовать в разных сценариях. Например, если в начале функции выделяется память из кучи, и требуется, чтобы память освобождалась в момент выхода из функции, можно использовать умные указатели STL. Ниже приведен скелет реализации умного указателя с использованием обозначенной техники:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
template < typename T >
class SmartPointer
{
public:
 
    SmartPointer( T* ptr )
        :    _ptr( ptr )
    { 
    }
 
    ~SmartPointer( )
    {
        delete _ptr;
    }
 
    T& operator * ( )
    {
        return *_ptr;
    }
 
    T* operator -> ( )
    {
        return _ptr;
    }
 
private:
 
    T* _ptr;
}

Наша функция в свою очередь будет выглядеть так:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void foo( )
{
    // выделяем память
    SmartPointer ptr( new MyClass( ) );
 
    // очень много строк кода
 
    // это работает правильно, т.к. мы переопределили оператор ->
    ptr->DoSomething( );
 
    if ( shouldExit )
    {
        // память автоматически очищается в деструкторе
        return;
    }
 
    // очень много строк кода
 
    // память автоматически очищается здесь тоже
}

С памятью есть еще один интересный пример. Иногда требуется неким образом занять всю доступную память при запуске. Далее мы будем использовать эту память по своему усмотрению с помощью технологии placement new. Соответственно куски такой «сырой» превыделенной памяти мы назовем контекстами памяти. Соответственно мы имеем глобальный набор таких контекстов, после чего мы решаем, из какого контекста будет возвращен указатель на «выделенную» память.

Если дальше необходимо использовать какой-то контекст в рамках области видимости функции, то опять наблюдается уже знакомый паттерн:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class MemoryChunkUse
{
public:
 
    MemoryChunkUse( MemoryChunk& chunk )
        :    _chunk( chunk )
    {
        UseMemoryChunk( chunk );
    }
 
    ~MemoryChunkUse( )
    {
        ReleaseMemoryChunk( chunk );
    }
 
private:
 
    MemoryChunk& _chunk;
}

Функция будет выглядеть так:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void foo( )
{
    // используем контекст
    MemoryChunkUse useChunk( GRAPHICS_MEMORY_CHUNK );
 
    // очень много строк кода
 
    if ( shouldExit )
    {
        // здесь контекст памяти будет автоматически освобожден
        return;
    }
 
    // очень много строк кода
 
    // здесь контекст памяти также будет освобожден
}

С помощью технологии RAII вы заставляете компилятор освобождать ресурсы за вас, причем практически бесплатно. Круто, не так ли?

Навеяно (англ.)

Наткнулся вот тут на такую мысль. Считаю важной. Цитата
«The ability to take data – to be able to understand it, to process it, to extract value from it, to visualize it, to communicate it is going to be a hugely important skill in the next decades.»
Автор: Hal Varian, Chief Economist, Google

Eclipse RCP (4.3) приложение с использованием maven. Продукт

Сегодня как и обещал, расскажу про то, как сделать готовый продукт. В следующих статьях, если они будут – расскажу про то, как подключить в Eclipse RCP обычные maven’овские зависимости.

Итак, открываем наши проекты в eclipse и делаем вот что. В проекте ru.mrdekk.ercp.gui есть файлик ru.mrdekk.ercp.gui.product. Так вот – этот файлик надо перенести в проект ru.mrdekk.ercp.repository:

Необходимо сконфигурировать уровни запуска и параметры автостарта. Открываем файл продукта, который мы только что перенесли. Переходим на вкладку Configuration. В Start Levels … нажимаем кнопку Add …

Далее в появившемся окне необходимо выбрать бандлы org.eclipse.equinox.common и org.eclipse.equinox.ds и нажать ОК

Для обоих бандлов установить start level = 2 и auto start = true, далее таким же способом необходимо добавить бандл org.eclipse.core.runtime:

Для этого бандла необходимо установить только auto start = true. В итоге получим что-то вроде:

На вкладке Overview в поле ID введите ru.mrdekk.ercp.product:

Измените «The product configuration is base on…» на features:

На вкладке Dependencies нажмите кнопку Add …

И выберите org.eclipse.rcp:

Также нажмите кнопку Add Required … eclipse добавить требуемые зависимости:

И конечно добавить нашу фичу:

Теперь запустим сборку проекта через maven, мы должны получить как обычно успешный результат:

[INFO] Reactor Summary:
[INFO]
[INFO] mrdekk.ru eclipse rcp demo - parent ............... SUCCESS [0.109s]
[INFO] mrdekk.ru eclipse rcp demo - gui .................. SUCCESS [2.875s]
[INFO] mrdekk.ru eclipse rcp demo - feature .............. SUCCESS [0.125s]
[INFO] mrdekk.ru eclipse rcp demo - update site .......... SUCCESS [5.531s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 16.734s
[INFO] Finished at: Thu Oct 03 11:12:56 NOVST 2013
[INFO] Final Memory: 16M/38M
[INFO] ------------------------------------------------------------------------

В папке target/repository мы должны увидеть метаданные и файлы для продукта:

Теперь заставим maven собирать для нас пакет инсталляции продукта, и архивный файл. Для этого в pom.xml проекта ru.mrdekk.ercp.repository необходимо написать следующее:

    <build>
        <plugins>
            <plugin>
                <groupId>org.eclipse.tycho</groupId>
                <artifactId>tycho-p2-director-plugin</artifactId>
                <version>${tycho-version}</version>
                <executions>
                    <execution>
                        <!-- install the product using the p2 director -->
                        <id>materialize-products</id>
                        <goals>
                            <goal>materialize-products</goal>
                        </goals>
                    </execution>
                    <execution>
                        <!-- create zip file with the installed product -->
                        <id>archive-products</id>
                        <goals>
                            <goal>archive-products</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

И запустите сборку снова, вы должны будете увидеть каталог продукта и архивный файл в папке target:

[INFO] Reactor Summary:
[INFO]
[INFO] mrdekk.ru eclipse rcp demo - parent ............... SUCCESS [0.094s]
[INFO] mrdekk.ru eclipse rcp demo - gui .................. SUCCESS [2.766s]
[INFO] mrdekk.ru eclipse rcp demo - feature .............. SUCCESS [0.109s]
[INFO] mrdekk.ru eclipse rcp demo - update site .......... SUCCESS [12.953s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 24.250s
[INFO] Finished at: Thu Oct 03 11:17:54 NOVST 2013
[INFO] Final Memory: 17M/42M
[INFO] ------------------------------------------------------------------------

Вы можете запустить полученный продукт, и увидите примерно следующее:

На этом основные статьи по Eclipse RCP закончены. Вы можете добавить этот проект например в Hudson и автоматически собирать его там. Я постараюсь сделать еще несколько статей, в которых расскажу про то, как подключать в Eclipse RCP проекты обычные maven’овские зависимости.

P.S. Исходники как всегда доступны в github

Eclipse RCP (4.3) приложение с использованием maven. Сайт обновлений

Продолжаю повествование о том, как собрать Eclipse RCP проект с помощью maven’а. Сегодня поговорим о том, как сделать Update Site для нашего проекта. Update Site нужен для распространения компонентов Eclipse RCP и готовых приложений. Когда Вы устанавливаете что-то себе в Eclipse вы пользуетесь одним или несколькими Update Site’ами.

Итак, открываем наш проект.

Для начала создадим проект Update Site’а через стандартные функции Eclipse, для этого File > New > Other … > Plug-In Development > Update Site Project:

Eclipse создаст нам проект. Далее необходимо site.xml переименовать в category.xml. Для этого нужно кликнуть правой кнопкой мыши на этом файле и выбрать Refactor > Rename:

Далее необходимо открыть полученный файл в Manifest Editor. В Eclipse есть бага, которая не позволяет сделать это простым двойным щелчком, поэтому нужно по правой кнопке выбрать Open With > Category Manifest Editor.

Далее создадим и отредактируем некоторые параметры в нашей категории:

Добавим ссылку на новую фичу (надо нажать на кнопку Add Feature). Выберем нашу фичу:

После этого, как обычно преобразуем полученный проект в проект maven. Для этого по правой кнопке Configure > Convert to Maven Project. Не забываем о том, что в настройках maven’а необходимо повторять те же идентификаторы. Тип проекта – eclipse-repository

После преобразования проекта в проект maven’а необходимо в pom.xml указать ссылку на родительский проект, после чего полученный pom.xml примет примерно следующий вид:

<project
        xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                            http://maven.apache.org/xsd/maven-4.0.0.xsd" >

    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>ru.mrdekk.ercp</groupId>
        <artifactId>ru.mrdekk.ercp.parent</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>..</relativePath>
    </parent>

    <artifactId>ru.mrdekk.ercp.repository</artifactId>
    <packaging>eclipse-repository</packaging>

    <name>mrdekk.ru eclipse rcp demo - update site</name>

</project>

И добавим полученный проект в качестве модуля в родительский pom.xml. Секция modules будет выглядеть следующим образом:

    <modules>
        <module>gui</module>
        <module>feature</module>
        <module>repository</module>
    </modules>

После чего все это дело надо сохранить и попробовать собрать через родительский проект maven’ом. Должно получится примерно следующее:

[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] mrdekk.ru eclipse rcp demo - parent ............... SUCCESS [0.094s]
[INFO] mrdekk.ru eclipse rcp demo - gui .................. SUCCESS [2.984s]
[INFO] mrdekk.ru eclipse rcp demo - feature .............. SUCCESS [0.109s]
[INFO] mrdekk.ru eclipse rcp demo - update site .......... SUCCESS [1.157s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 12.266s
[INFO] Finished at: Fri Sep 27 10:38:27 NOVST 2013
[INFO] Final Memory: 15M/37M
[INFO] ------------------------------------------------------------------------

Теперь протестируем полученный репозиторий, для этого надо через правую кнопку мыши зайти в свойства проекта папки target/repository проекта repository (Properties).

Затем выделить и сохранить в буфер обмена путь к полученному репозиторию:

Теперь выберем в главном меню Help > Install New Software … Добавим новый Update Site (надо нажать кнопку Add):

Мы должны увидеть содержимое этого репозитория, т.е. нашу фичу:

Нажмите Cancel, ведь мы пока не собираемся устанавливать нашу фичу в Eclipse. Как обычно исходники доступны на github тут

Eclipse RCP (4.3) приложение с использованием maven. Часть 2. Фича!

Добрый день, читатели!

Сегодня продолжил создавать приложение на основе Eclipse RCP. Сегодня сделаем фичу (feature). Фича – это компонент rcp который может быть отдельно установлен в Eclipse, в том числе в тот, под которым вы его разрабатываете. В дальнейшем нам этот компонент понадобится чтобы создать пакет приложения и сайт апдейтов.

Работу будем продолжать в уже созданном нами проекте. Создадим проект фичи, для этого File > New > Other … > Plug-in Development > Feature Project.

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

Выберем созданный нами в предыдущей статье плагин:

Далее преобразуем полученный проект в проект Maven’а. Правой кнопкой мыши на проекте, Configure > Convert to Maven Project. Далее не забываем, что настройки артефакта maven’а должны совпадать с настройками в билде эклипса. Кроме того, обратите внимание на packaging type, он должен быть eclipse-feature.

pom.xml проекта должен выглядеть примерно следующим образом. Ссылку на родительский проект необходимо вписать руками.

<project
        xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                            http://maven.apache.org/xsd/maven-4.0.0.xsd" >

    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>ru.mrdekk.ercp</groupId>
        <artifactId>ru.mrdekk.ercp.parent</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>..</relativePath>
    </parent>

    <artifactId>ru.mrdekk.ercp.feature</artifactId>
    <packaging>eclipse-feature</packaging>

    <name>mrdekk.ru eclipse rcp demo - feature</name>
</project>

Теперь пропишем в родительском проекте этот проект в качестве модуля для того, чтобы он собирался при сборке всего проекта. Секция modules в родительском проекте должна выглядеть примерно следующим образом:

    <modules>
        <module>gui</module>
        <module>feature</module>
    </modules>

После этого попробуем собрать проект. Должно получится примерно следующее:

[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] mrdekk.ru eclipse rcp demo - parent ............... SUCCESS [0.109s]
[INFO] mrdekk.ru eclipse rcp demo - gui .................. SUCCESS [2.953s]
[INFO] mrdekk.ru eclipse rcp demo - feature .............. SUCCESS [0.109s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 11.171s
[INFO] Finished at: Wed Sep 25 10:47:53 NOVST 2013
[INFO] Final Memory: 14M/35M
[INFO] ------------------------------------------------------------------------

В следующий раз настроим сборку продукта и сайта апдейтов.

Eclipse RCP (4.3) приложение с использованием maven

Итак. Намедни потребовалось создать eclipse rcp приложение на платформе Kepler. Положение осложнялось тем, что сборку надо было проводить с использованием maven’а. Ввиду того, что платформа kepler (4.3) достаточно новая и в ней было много всего переделано, информации по ней – кот наплакал. Поэтому пришлось подключать лом и чью-то матерь. Но в итоге все получилось. Методику этого получилось я и постараюсь описать тут.

Начнем с того, что у Вас должен быть установлен eclipse последней версии, в нем должен быть настроен maven и инструменты для разработки eclipse rcp. Я использовал для этого Spring ToolSuite, в котором мавен уже есть из коробки, а eclipse rcp tools легко ставятся через Install New Software. Методику этого всего я тут описывать не буду – материала навалом даже на русском языке.

Для начала создадим родительский проект для мавена – File > New > Maven Project.

Затем настроим основные вещи

pom.xml будет выглядеть следующим образом

<project
    xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                        http://maven.apache.org/xsd/maven-4.0.0.xsd" >

    <modelVersion>4.0.0</modelVersion>
    <groupId>ru.mrdekk.ercp</groupId>
    <artifactId>ru.mrdekk.ercp.parent</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <name>mrdekk.ru eclipse rcp demo - parent</name>

</project>

Для дальнейшего прогресса необходимо добавить некоторые вещи. Для начала – настройки, пока только версия tycho – инструмента для сборки rcp проектов maven’ом. Все это добавляем в pom.xml:

    <properties>
        <tycho-version>0.18.1>/tycho-version<
    </properties>

Теперь добавим репозиторий eclipse rcp который нужен будет maven’у и tycho для получения артефактов:

    <repositories>
        <repository>
            <id>eclipse-platform</id>
            <layout>p2</layout>
            <url>http://download.eclipse.org/eclipse/updates/4.3/R-4.3-201306052000</url>
        </repository>
    </repositories>

Добавляем maven’овский плагин tycho в сборку:

    <build>
        <plugins>

            <plugin>
                <groupId>org.eclipse.tycho</groupId>
                <artifactId>tycho-maven-plugin</artifactId>
                <version>${tycho-version}</version>
                <extensions>true</extensions>
            </plugin>

        </plugins>
    </build>

C родительским проектом пока все, теперь создаем непосредственно проект eclipse rcp – File > New > Project … > Eclipse 4 > Eclipse 4 Application Project:

Запустим приложение для проверки работоспособности, для этого:

  • 1. Открываем файл определения продукта – ru.mrdekk.ercp.gui.product
  • 2. На вкладке «Overview» нажмите «Launch an Eclipse application».

Вы должны увидеть примерно следующее:

Теперь преобразуем проект в maven’овский проект. Для этого нажимаем правой кнопкой мыши на проекте и выбираем Configure > Convert to Maven Project. Появится следующее окошко, в нем вбиваем нужные данные. Внимание! Важно чтобы эти данные совпадали с тем, что Вы ввели когда создавали проект, т.е. MANIFEST/Bundle-SymbolicName == POM/artifactId и MANIFEST/.qualifier == POM/-SNAPSHOT!

Eclipse будет ругаться на полученный pom, т.к. он не увидит tycho. Чтобы все получилось, необходимо указать ссылку на созданный нами родительский проект, Ваш pom.xml должен выглядеть примерно следующим образом:

<project
        xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                            http://maven.apache.org/xsd/maven-4.0.0.xsd" >

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>ru.mrdekk.ercp</groupId>
        <artifactId>ru.mrdekk.ercp.parent</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>..</relativePath>
    </parent>

    <artifactId>ru.mrdekk.ercp.gui</artifactId>

    <packaging>eclipse-plugin</packaging>
    <name>mrdekk.ru eclipse rcp demo - gui</name>

</project>

Дальше на проекте ru.mrdekk.ercp.gui нажимаем правой кнопкой и Maven > Update Project …

Надо кроме того добавить проект ru.mrdekk.ercp.gui как модуль основного (родительского проекта), для этого в pom.xml родительского проекта добавляем:

    <modules>
        <module>gui</module>
    </modules>

Далее на проекте ru.mrdekk.ercp.parent нажимаем правой кнопкой и Run As > Maven build … Указываем цели «clean package» и нажимаем Apply, затем Run.

Все должно нормально собраться:

[INFO] Reactor Summary:
[INFO]
[INFO] mrdekk.ru eclipse rcp demo - parent ............... SUCCESS [0.109s]
[INFO] mrdekk.ru eclipse rcp demo - gui .................. SUCCESS [2.860s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 9.797s
[INFO] Finished at: Mon Sep 23 11:02:05 NOVST 2013
[INFO] Final Memory: 14M/34M
[INFO] ------------------------------------------------------------------------

В следующих статьях расскажу что делать дальше. Мы соберем feature и update site, что позволит нам публиковать приложения для установки в eclipse и распространять бинарные билды.

Для референсов исходники проекта доступны на github’е вот тут.

Мысли вслух

Давно я сюда уже ничего постоянно не писал, видимо стоит возобновить практику. В последнее время по долгу службы приходится работать с языком Java в области Enterprise приложений. Можно говорить много слов об этом, но я сейчас не об этом. Для Java есть замечательный Spring Framework, который позволяет сосредоточиться на проблеме, а не на вспомогательных вещах, которые кочуют из проекта в проект.

Так как я сам лично люблю С++, то попытался я поискать чего нибудь подобного для этого языка. И не нашел. Причем по отдельности, по разной функциональности есть готовые разработки и библиотеки, есть даже в Open Source, однако чего-то целостного я не нашел. Может быть кто в курсе? Или С++ настолько непопулярен для разработки такого рода приложений?…

Впрочем, увидим…

Устанавливаем C++ драйвер для MongoDB на Mac OS X Mountain Lion

Потребовался мне вдруг С++ драйвер для MongoDB на Mac OS X, так как писать для FreeBSD софт на С++ лучше всего под Mac OS X в xCode, вот такой уж винегрет.

Поэтому, первое что делаем, качаем вот отсюдова вот файлик с названием cxx-driver/mongodb-linux-x86_64-latest.tgz пофигу что linux – скомпиляем и так, ведь для Mac OS X специально нету :( а жаль.

Распаковываем, и идем в распакованную папку, пытаемся сделать

1
# scons

Но вот блин, scons’а нет на маке, увы :(

Ладно, качаем его отсюдова вот

и дальше

1
# python setup.py install

Возвращаемся в папку с распакованным драйвером MongoDB, и пытаемся снова сделать

1
# scons

Веселье продолжается – на маке не установлен Boost, отлично идем и качаем исходники отсюдова вот

Как скачалось распаковываем и идем в распакованную папку и делаем

1
2
3
# ./bootstrap.sh
# ./b2
# sudo ./b2 install

Алилуйя! Возвращаемся в папку с распакованным драйвером и снова делаем

1
2
# scons
# sudo scons install

И вуаля – теперь у нас есть MongoDB C++ драйвер для Mac OS X Mountain Lion