Структура проекта

В качестве IDE будем использоваться Intellij IDEA версии 14 и выше, т.к. ее поддержка имеется в платформе изначально.

Создание нового проекта

В каталоге для проектов создадим новый проект, воспользовавшись для этого приложением jc:

jc create -t:web-app -o:sample-project1

В результате выполнения команды будет создан каталог с проектом sample-project1.

Перейдем в этот каталог и выполним генерацию файлов для IDE (Intellij IDEA):

jc gen-idea

Сгенерированный файл sample-project1-(project).ipr нужно открыть в IDE.

Проект готов к разработке.

Обзор проекта

Наш созданный каталог sample-project1 - это проект. Далее этот каталог будет называтся каталогом проекта, а его содержимое - проектом.

В каталоге проекта имеется (среди прочих) файл project.jc, в котором наш проект описан. Этот файл является текстом класса groovy и описан подробнее в разделе Основы jc.

Внутри каталога проекта имеется каталог sample-project1-main. Он является модулем проекта. Далее этот каталог будет называтся каталогом модуля проекта, а его содержимое - модулем проекта или модулем. И в нем так же имеется файл project.jc, который описывает модуль.

Модуль - это набор исходников на java (или groovy) и ресурсов, из которых при компиляции получается один jar-файл. Загляните в каталог модуля. В нем имеются каталог src - тут хранятся исходники модуля. В каталоге test - unit-тесты модуля.

Файл project.jc в каталоге модуля описывает модуль. Загляните в него. Не вдаваясь пока в подробности, рассмотрим ключевые места этого файла.

project.name = "sample-project1-main"

В свойстве project.name указано имя модуля. Желательно, что бы имя модуля совпадало с именем каталога модуля. Это, конечно, не обязательно, но позволяет меньше путаться и запоминать новые незнакомые слова.

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

При компиляции модуля будет создан jar-файл с именем, соответствующем имени модуля. В данном случае sample-project1-main.jar. Это очень важная информация. Именно модуль содержит исходники и именно из модуля собирается jar-файл. В самом проекте исходного текста нет. Все исходники содержатся в модуле (или модулях).

Рассматриваем project.jc далее:

include(JavaProject).with {
    moduleDef("sample.project1.main").with {
        depends.prod(
                "jandcode.core.web",
        )
        depends.dev(
        )
    }
}

Строка moduleDef("sample.project1.main") определяет модуль Jandcode. Под модулем подразумевается java-пакет. Все исходники модуля должны быть расположены в рамках одного пакета и его дочерних пакетов. И это имя мы и указываем. Имя пакета обычно совпадает с именем java-модуля, где вместо '-' имеем символ '.'(точка). Конечно, можно и тут проявить фантазию, но это создает дополнительные сложности и потерю унификации. Я бы не советовал.

Работа с командной строки

Перейдите в каталог проекта и введите команду:

jc

Вы увидите список команд jc, которые доступны в этом каталоге.

А теперь перейдите в каталог модуля и снова выполните эту же команду. Как видите, список доступных команд отличается. Состав этих команд определяется содержимым файлов project.jc. Этот набор можно расширять своими командами, но это мы рассмотрим позже.

В процессе разработки команды обычно выполняются в каталоге проекта, а не модуля. Хотя и там они прекрасно работают.

Например, скомпилируем проект, выполнив в каталоге проекта команду:

jc compile

Проект скомпилирован.

Библиотеки

Для начала скомпилируем модуль. Для этого в каталоге модуля выполним команду:

jc compile

После выполнения обратите внимание на каталог temp. В этом каталоге находится весь мусор и промежуточные результаты процесса разработки. И, в том числе, результат компиляции. Перейдем в каталог temp. Нам интересен подкаталог lib, в котором содержится результат компиляции модуля в виде jar-файла. Как видим, полученный jar-файл имеет имя, соответствующее имени модуля.

Любой jar-файл, которые используется в проекте, в том числе и полученный в результате компиляции модуля, называется библиотекой. А именем библиотеки является имя jar-файла, в котором отброшено расширение (и версия, но об этом позже).

Таким образом, имеем модуль с именем sample-project1-main, из которого мы получили библиотеку с таким же именем sample-project1-main. Что, собственно, и является целью модуля - получить из него библиотеку.

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

jc showlibs

Полученный результат достаточно большой, поэтому отфильтруем его немного, запросим только библиотеки с именами, содержащими подстроку ant:

jc showlibs -q:ant

Результат включает в себя имя библиотеки, ее версию, а так же местонахождение jar-файла библиотеки.

А теперь посмотрим, как выглядет библиотека, которая соответсвует нашему модулю:

jc showlibs -q:sample-project1

Результат несколько отличается. Так как нам доступны исходники модуля, то мы имеем путь до файла project.jc этого модуля.

Когда в проекте так или иначе используется библиотека, доступная только в виде jar-файла, он используется напрямую.

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

Как добавить библиотеку в проект? Очень просто. Нужно создать каталог lib в каталоге проекта и скопировать туда нужный файл. Имя файла без расширения и будет именем библиотеки, доступной проекту. Причем, если имя jar-файла содержит версию, то версия тоже будет отброшена из имени библиотеки.

К примеру, скачайте этот файл http://central.maven.org/maven2/org/apache/commons/commons-email/1.4/commons-email-1.4.jar и скопируйте его в каталог lib проекта. После этого выполните команду:

jc showlibs -l

Как видите, библиотека нам доступна по имени jar-файла, в котором отброшено расширение и версия.

Можно заметить, что для библиотеки commons-email есть только jar-файл, но нет исходников. А они иногда очень важны для процесса разработки. Добавить исходники тоже просто. Скопируейте файл c исходниками http://central.maven.org/maven2/org/apache/commons/commons-email/1.4/commons-email-1.4-sources.jar в каталог lib и переименуйте в commons-email-1.4-src.zip. Файл с исходниками должен иметь такое же имя, как и jar-файл, с суффиксом -src и расширением zip. После этого снова выполните команду:

jc showlibs -l

Как видите, теперь доступны и исходники.

Зависимости

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

Зависимости определяются для модуля и представляют собой список библиотек, от которых зависит этот модуль.

Для компиляции кода модуля должен быть доступен определенный classpath, который включает в себя все, что в этом модуле используется. Этот classpath как раз и формируется из списка зависимых библиотек.

Кроме того, этот classpath должен быть доступен и для выполнения кода модуля в run-time.

Перейдем в каталог модуля и посмотрим в файл project.jc. В нем определены зависимости модуля:

depends.prod(
        "jandcode.core.web",
)
depends.dev(
)

Свойство depends.prod является списком имен библиотек, от которых зависит модуль при компиляции и в run-time.

Свойство depends.dev является списком имен библиотек, от которых зависит модуль при компиляции и при выполнении тестов. Они не используются в prоduction-режиме.

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

M1 -> M2,M3
M3 -> M4,M2
M5 -> M1

Для модуля M5 указан в качестве зависимости M1, но он в свою очередь зависит от M2,M3. Тогда полный список зависимостей модуля M5 будет M1,M2,M3,M4.

Если для модуля указана зависимость, то она должна быть где-то доступна. Если это библиотека, то она должна быть либо в поставке платформы, либо в каталоге lib. Если это модуль, то он должен быть частью проекта. Что бы посмотреть, какие библиотеки вообще доступны, введите команду:

jc showlibs -a

Если нужен просто список библиотек, то:

jc showlibs -a -n

Модули в проекте

В нашем проекте сейчас только один модуль, но это не предел. Мы можем их сделать столько, сколько нужно.

Давайте передем в каталог проекта и посмотрим в файл project.jc. Нас интересует следующий код:

include(RootProject).with {
    modules(
            "sample-project1-main",
    )
}

Экземпляр класса jandcode.jc.std.RootProject имеет свойство modules, в котором перечислены модули, которые входят в этот корневой проект. Причем перечислены не имена модулей, а каталоги модулей относительно корня проекта. Например можно написать так:

include(RootProject).with {
    modules(
            "./sample-project1-main",
    )
}

Давайте добавим еще один модуль в проект. Для этого в каталоге проекта выполняем команду:

jc create -t:module -o:sample-project1-module2

Создан каталог с новым модулем. Что бы проект знал про него, включаем его в список модулей проекта:

include(RootProject).with {
    modules(
            "sample-project1-main",
            "sample-project1-module2",
    )
}

Теперь модуль в проекте. Однако он нигде не используется. Он будет просто компилироваться. Это почти эквивалентно копированию новой библиотеки в каталог lib. Она доступна, но неиспользуется.

Перейдем в каталог модуля sample-project1 и внесем в его завасимости наш новый модуль:

depends.prod(
        "jandcode-core-web",
        "sample-project1-module2",
)

Теперь модуль sample-project1-main зависит от модуля sample-project1-module2. Что кроме всего прочего означает, что модуль sample-project1-module2 будет компилироватся до модуля sample-project1-main, а компиляция модуля sample-project1-main будет пользоватся результатом компиляции модуля sample-project1-module2.

jc gen-idea

Изменение структуры проекта в файлах project.jc сразу же доступны в командной строке, но IDE про эти изменения не знает.

Что бы синхронизировать структуру проекта с IDE, необходимо выполнить команду в каталоге проекта:

jc gen-idea

После этого перезагрузить проект в IDE.

Это важно запомнить: любые модификации в файлах project.jc, так или иначе затрагивающих структур проекта, необходимо заканчивать этой командой.

Выполнение команды безопасно, так что ее можно использовать в любое время.