В первой статье этой серии из пяти частей я представил Shale и объяснил, в чем он отличается от своего предшественника Struts. Я рассмотрел концептуальную основу Shale и показал вам, как установить и настроить его в вашей среде разработки. Также я рассмотрел некоторые из возможных недостатков Shale (а именно то, что он находится на стадии развития), но сделал вывод, что для пытливых разработчиков, обучающихся по ходу работы, Shale является чрезвычайно многообещающей новой интегрированной средой разработки.
В данной статье я начну использовать этот принцип (проб и обучения) на практике и подробно рассмотрю анатомию Shale-приложения. Я начну с так называемого начального Shale-приложения (которое, как вы быстро поймете, является чем-то большим, нежели шаблон), для того чтобы вы четко видели, что именно эта технология дает разработчику Web-приложений. Вы будете использовать начальное приложение для создания своего собственного примера приложения, которое затем используете для исследования многочисленных файлов и каталогов, создаваемых даже для самых элементарных Shale-приложений. Попутно я покажу вам, куда помещаются ваши JSP-страницы и Java™-классы, а также объясню, как Shale упрощает процесс создания полнофункциональных и специализированных Web-приложений.
Большая часть материала данной статьи основана на знаниях, полученных вами в первой статье данной серии. Если вы не читали ее, то должны сделать это сейчас.
Как вы узнали из предыдущей статьи, самым простым способом начать создавать Shale-приложение является использование начального Shale-приложения в качестве шаблона и последующее его изменение. Поскольку данная статья сильно привязана к практике, первое, что вы должны сделать, - запустить начальное приложение прямо сейчас. Изучение различных компонентов начального приложения (через структуру каталогов приложения) и способов их совместного функционирования поможет в создании вашего собственного Shale-приложения.
Фактически, всегда не плохой идеей является начинать ваши проекты разработки Shale-приложений на основе начального приложения. Я рассмотрел в пошаговом режиме процесс настройки начального Shale-приложения в моей последней статье, поэтому предполагаю, что вы уже сделали эту подготовительную работу. Вы должны скопировать начальное Shale-приложение в каталог вашей среды разработки под названием "first-shale". Код в каталоге first-shale является вашим личным начальным приложением, которое вы будете использовать для изучения структуры Shale-приложения.
Предположив, что вы скопировали ваше собственное приложение (first-shale) из начального Shale-приложения, рассмотрим структуру его каталогов. Вы обнаружите массу файлов. Если вы не знаете точно, что делает каждый компонент, файл и каталог, приложение на первый взгляд может выглядеть немного устрашающим. На рисунке 1 показана структура каталогов; как вы можете увидеть, в начальном приложении есть много всего.
Рисунок 1. Структура каталогов начального Shale-приложения
Итак, я начну рассматривать структуру каталогов начального Shale-приложения.
Файлы, связанные с компоновкой
Первыми двумя файлами в корневом каталоге начального приложения являются build.xml и default.properties. Если вы когда-либо использовали среду компоновки Ant, то эти файлы вам знакомы. По существу, build.xml указывает Ant, что делать. Для случая начального Shale-приложения он дает Ant знать, какие файлы компилировать и как создать WAR-дистрибутив и файлы, используемые вашим контейнером сервлетов (который я рассмотрю более подробно чуть позже в данной статье).
Файл default.properties является шаблоном для указания месторасположения нескольких Shale-зависимостей. Да, это означает, что вы, по существу, имеете файл шаблона (default.properties) внутри приложения-шаблона (начальное Shale-приложение). Я не буду углубляться в детали default.properties, потому что рассматривал его в первой статье данной серии (см. раздел "Ресурсы"). Короче говоря, вы копируете этот файл в новый файл build.properties, настраиваете его под вашу среду и затем используете Ant для компоновки проекта. Во время своей работы Ant использует указанные вами в build.properties месторасположения для создания Shale-дистрибутива.
Далее вы видите два пустых каталога: ext/ и lib/. Они пусты преднамеренно, поэтому не думайте, что вам чего-то не хватает. При компоновке Shale Web-приложения и настройке файла build.properties вы должны указать, где среда Shale и ваш контейнер сервлетов должны искать зависимости. Фактически, вы можете указать два типа зависимостей:
- JAR-файлы, которые нужны для вашего приложения как во время компоновки, так и во время исполнения. Эти файлы должны быть частью WAR-файла для вашего приложения и размещаться в каталоге WEB-INF/lib/ вашего Web-приложения.
- JAR-файлы, которые нужны для вашего приложения во время компоновки, но не во время исполнения. Обычно это тот случай, когда ваш контейнер сервлетов предоставляет набор библиотек во время исполнения, но они вам нужны и для компилирования вашего приложения. Вам не нужно включать эти файлы в WAR-файл приложения, поскольку контейнер предоставляет их во время исполнения.
Файл build.properties предоставляет путь для указания зависимостей среды исполнения (используя свойство lib.dir) и зависимости среды компиляции, которые не нужны в WAR-конфигурации развертывания для среды исполнения (используя свойство ext.dir). Если хотите, можете просто разместить ваши зависимости в соответствующих каталогах:
- Зависимости среды исполнения в lib/
- Зависимости только среды компиляции в ext/
Эти два каталога предоставляются исключительно для этих целей.
LICENSE.TXT, NOTICE.txt и README.txt - это файлы документации. Они подробно описывают условия, при которых вы можете использовать Shale, и модификации, которые вы можете сделать в интегрированной среде. Они также предоставляют простые инструкции по настройке и компоновке Shale-приложения. Эти файлы стоит прочитать один раз, но, сделав это, вы сможете пользоваться их указаниями в дальнейшем.
Назначение последнего каталога под названием src/ должно быть довольно очевидно: он содержит исходный код начального Shale-приложения. В нем нет большого количества файлов, но он содержит массу подкаталогов. В результате этого его структура выглядит более сложной, чем она есть на самом деле. На рисунке 2 показана полная, развернутая структура каталога с исходными кодами.
Рисунок 2. Структура каталога с исходными кодами.
Рассмотрим эти подкаталоги более подробно:
- conf/ содержит один файл MANIFEST.MF, который настраивается в процессе компоновки и используется при генерировании WAR-файла для вашего приложения. Вы никогда не должны использовать или менять этот файл в обычном цикле разработки приложения.
- java/ фактически содержит один класс, используемый в начальном приложении.
org.apache.shale.blank.WelcomeBean- это простой JavaBean-компонент, демонстрирующий, как можно использовать компоненты с Shale. Более важно то, что он указывает, где вы можете разместить Java-файлы в начальном приложении. Любой Java-код, имеющийся в каталоге java/, автоматически компилируется программой Ant при компоновке начального приложения. Поэтому, если у вас есть код для добавления, вы можете просто поместить его в каталог java/, и Ant скомпилирует код и включит его в процесс компоновки вашего приложения. - test/ и systest/ просто содержат тесты для проверки корректности компоновки и функционирования начального приложения. Если вы не работаете над средой Shale или над начальным приложением, ни один из этих каталогов вам не понадобится.
- web/ содержит JSP-страницы, используемые в начальном приложении. Вы можете пополнить этот подкаталог любыми JSP-страницами для включения в приложение, и они будут добавлены в процессе компоновки.
Должно быть довольно очевидно, что большинство интересных компонентов начального Shale-приложения расположено в каталоге src/. По мере разработки все более сложных Shale-приложений ваши каталоги src/ будут все больше заполняться вашими собственными Java-классами и JSP-страницами. Поэтому освойте работу в структуре src/ начального Shale-приложения - вам это поможет во время разработки собственных приложений.
После более близкого знакомства с исходной структурой начального приложения вы готовы подробно узнать о том, как выглядят Shale-приложения после компоновки. В предыдущем разделе вы увидели, где размещается исходный код Shale-приложения. В данном разделе вы узнаете, как этот исходный код компонуется в Web-приложение, и где размещаются все скомпилированные Java-файлы, JSP-страницы и соответствующие зависимости.
Попутно вы должны понять, как развертываются Shale-приложения и где можно изменить стандартные параметры развертывания. Вы также узнаете, куда добавлять библиотеки для дополнительных подключаемых модулей или зависимостей, которые вы хотите использовать в вашем Shale-коде.
Компоновка начального приложения
Из обсуждения, приведенного в последней статье данной серии, вы должны помнить, как компонуется начальное приложение, но я, все же, приведу краткий обзор:
- Скопировать default.properties в новый файл и назвать его build.properties.
- Открыть файл build.properties в каталоге first-shale/ и отредактировать его для соответствия вашей системе.
- Использовать Ant для компоновки приложения путем ввода команды
antв командной строке.
Добавление к дереву исходных файлов
Ранее я упоминал, что вы легко можете добавить ваши собственные JSP-страницы в каталог src/web/ начального Shale-приложения. Затем все JSP-страницы в этом каталоге автоматически добавятся в процесс компоновки. Это же относится и к исходным Java-файлам. В каталоге src/ есть подкаталог java/. Просто поместите ваши исходные Java-файлы в этот каталог, и они будут скомпилированы как часть вашего процесса компоновки.
Если вы не совсем уверены относительно ценности использования начального Shale-приложения, процесс компоновки должен доказать вам, насколько это полезно. Редактируя единственный файл build.properties, вы можете скомпоновать ваше собственное приложение практически без усилий. Даже при работе с Ant (система компоновки, используемая для начального Shale-приложения) вы должны настраивать все каталоги, зависимости и правила, вовлеченные в компоновку Web-приложения. Но при использовании начального Shale-приложения вы можете потратить ваше время на написание JSP-страниц и Java-классов, поместить эти файлы в нужное место, выполнить команду ant и все.
Когда дело доходит до размещения ваших файлов Java-классов, общим правилом является использование структуры каталогов, соответствующей структуре пакетов ваших Java-классов. Например, если ваш класс называется Song, и он находится в пакете com.nathanson.music, вы должны поместить файл Song.java в структуру каталога src/java/com/nathanson/music. Это не меняет способ компилирования файла системой Java (javac просто просматривает директиву package в начале вашего файла Song.java), но это дает вам хорошую организационную структуру для вашего кода.
После выполнения команды ant и компоновки вашего приложения вы должны увидеть новый каталог target/. Этот каталог содержит все файлы, скомпонованные из исходного кода, находящегося в каталоге src/. Фактически, каталог target/ содержит "разбитый на части WAR". WAR-файлы представляют собой просто JAR-файлы с небольшой дополнительной конфигурационной информацией, скомпонованные таким образом, чтобы все контейнеры сервлетов могли развернуть в себе приложение. Если вы возьмете WAR-файл и развернете его (то есть разархивируете его), то получите структуру каталогов каталога target/ (скоро я объясню, как на самом деле создать WAR).
Лучший способ узнать, куда помещаются исходные файлы Shale-приложения, - посмотреть в каталог src/ начального приложения. Аналогично, лучший способ понять, как выглядит развернутое Shale-приложение, - проверить каталог target/. Сначала я рассмотрю, куда Shale помещает различные файлы во время процесса компоновки, а затем покажу вам, как они настраиваются для развертывания приложения.
Сразу после завершения работы программы Ant откройте новый каталог target/, который был создан. Содержимое этого каталога должно выглядеть аналогично изображенному на рисунке 3.
Рисунок 3. Каталог target/
Здесь много похожего на структуру, которую вы видели в каталоге src/, показанном на рисунке 2. Как и в каталоге src/, вы узнали стандартную структуру Web-приложения, включающую Java-классы и JSP-страницы. Хотя вы можете заметить несколько добавлений и то, что файлы немного перемешаны.
Почти все в каталоге target/ расположено в подкаталоге first-shale/. Название этого каталога может быть другим на вашей системе, если вы указали другой путь к проекту в вашем файле build.properties. Независимо от названия в листинге 1 приведено содержимое файла, используемого для компоновки приложения:
Листинг 1. Пример файла build.properties
# Основная информация о проекте project.copyright=My project, Copyright © 2006 project.name=My First Shale Application project.vendor=IBM DeveloperWorks project.vendor.id=com.ibm.dw # Java-пакет и путь к контексту для контейнера сервлетов project.package=com.ibm.dw.firstShale project.path=first-shale # Каталог для Shale-дистрибутива - измените его для вашей системы shale.dir=/usr/local/java/shale-framework-20060204 # Каталог для всех ваших библиотек - измените его для вашей системы lib.dir=/usr/local/java/shale-framework-20060204/lib |
Вы можете использовать любое имя в качестве пути вашего проекта. Сценарии компоновки в Shale (которые используют Ant) просто используют имя, указанное вами для каталога, создаваемого в target/.
Оставшаяся часть статьи в основном концентрируется на содержимом каталога target/, но перед дальнейшим его исследованием вы должны знать о содержимом каталога, созданного непосредственно в target/. Каталог META-INF/ содержит единственный файл, называемый MANIFEST.MF, содержимое которого приведено в листинге 2:
Листинг 2. Файл MANIFEST.MF
Extension-Name: com.ibm.dw.firstShale Specification-Vendor: The Apache Software Foundation Specification-Version: 1.0 Implementation-Vendor-Id: com.ibm.dw Implementation-Vendor: IBM DeveloperWorks Implementation-Version: 0.1 |
Сравните содержимое этого файла с листингом 1 и информацией, введенной в файл build.properties, и вы сразу должны заметить некоторые связи. MANIFEST.MF собирает название пакета, поставщика проекта и ID поставщика проекта из build.properties и вставляет их в содержимое данного файла.
При использовании процесса компоновки Shale для сборки WAR-файла для развертывания в вашем контейнере сервлетов этот манифест включается как часть WAR, идентифицируя его содержимое. Ели вы используете GUI-средства какого-либо рода для работы с вашим контейнером сервлетов, эти средства могут прочитать файл MANIFEST.MF и позволить вам (или другим администраторам) узнать, что находится в WAR.
В общем случае, вы никогда не должны вручную изменять MANIFEST.MF; вместо этого, если вам необходимо изменить его значения, обновите build.properties и просто повторно скомпонуйте приложение. Если бы вы изменили MANIFEST.MF самостоятельно (без изменения build.properties) и впоследствии повторно скомпоновали проект, все ваши изменения были бы утеряны. Управляя всем содержимым target/ при помощи build.properties и каталога src/, вы можете гарантировать, что развертываемое вами приложение всегда согласовано с разработанным вами кодом и авторской информацией об этом коде, указанной вами в build.properties.
Если вы программировали Web-приложение какого-нибудь рода (либо используя интегрированные среды, например Struts, либо кодируя JSP-страницы и сервлеты самостоятельно), то уже знакомы с основной структурой Web-приложения. Вы видели аналогичную структуру в каталоге target/first-shale/, где для вас не должно быть сюрпризом наличие каталогов META-INF/ и WEB-INF/.
Все JSP-файлы, которые вы включили в каталог src/web/, теперь размещаются в корневом каталоге Web-приложения. Вы видели файлы index.jsp, welcome.jsp и messages.jspf (три JSP и относящиеся к JSP файлы, находившиеся в каталоге src/web/) непосредственно в target/first-shale/.
Корневой каталог (first-shale/) - это каталог, в котором должны размещаться все ваши JSP-файлы; однако, если вам нужно добавить еще JSP-страницы к вашему приложению, не помещайте их просто в этот каталог. Вместо этого поместите дополнительные JSP-страницы в каталог src/web/ и повторно скомпонуйте приложение. Я говорил это раньше и скажу еще раз: одно из самых важных правил, которым вы должны следовать при программировании в Shale (как и при любом Web-программировании) - сохранять синхронизацию дерева исходных файлов и дерева развертывания. Если вы делаете все изменения в структуре каталога src/, у вас не будет никаких проблем.
Вы видели ваши Java-классы в структуре каталога target/first-shale/WEB-INF/classes/. Это стандартное размещение Java-классов в любом Web-приложении, поэтому оно не должно вызывать удивления. Вы обнаружите все скомпилированные Java .class-файлы в этой структуре вложенными в структуру каталога, соответствующую структуре пакета. То есть, класс WelcomeBean, находящийся в пакете org.apache.shale.blank, размещается в classes/org/apache/shale/blank в WelcomeBean.class.
Сохраняется разделение между исходным кодом и двоичным кодом: в структуре каталога classes/ нет .java-файлов. И не должно быть! Вместо этого здесь имеются только компилированные Java-файлы; вы должны (аналогично вашим JSP-страницам) помещать новые исходные Java-файлы в подкаталог java/ каталога src/ и давать возможность сценариям компоновки Shale компилировать ваш Java-код.
Сценарий компоновки также копирует все файлы свойств, находящиеся в вашей структуре каталога src/java/; например, в каталоге target/ вы видите файл Bundle.properties (вернитесь к рисунку 3), поскольку этот файл помещен в структуру каталога src/java/. Это позволяет вам помещать файлы, которые могут понадобиться вашим Java-классам, вместе с вашими исходными Java-файлами и знать, что они будут доступны в структуре компоновки приложения.
Каталог lib/, находящийся в каталоге target/first-shale/WEB-INF/, содержит все библиотеки, которые нужны для выполнения вашего приложения. Как упоминалось ранее, Shale имеет огромное количество зависимостей:
- Java Runtime Environment (JRE) и Java Development Kit (JDK) 1.4 или выше (включая Java 5.0)
- Java Servlet API 2.4 или выше
- JavaServer Pages (JSP) 2.0 или выше
- JavaServer Faces (JSF) 1.1 или выше
- JSTL (JSP Standard Tag Library) 1.1 или выше
- Jakarta Commons BeanUtils 1.7 или выше
- Jakarta Commons Chain 1.0 или выше
- Jakarta Commons Digester 1.7 или выше
- Apache Logging 1.0.4 или выше
- Apache Ant 1.6.3 или выше
Одной из ключевых функциональных возможностей начального Shale-приложения является то, что оно заботится об этих зависимостях вместо вас во время компоновки. Пока я не буду отвлекаться на рассмотрение того, что делают эти зависимости. Вы узнаете о них по мере использования в конкретных программных задачах или контекстах. Однако отмечу, что далее предполагается, что вы используете начальное приложение, и что у вас имеются все зависимости в нужном месте. Если вы хотите создать Shale-приложение действительно с нуля (без использования начального приложения в качестве шаблона), то должны добавить все зависимости самостоятельно. Это еще одна причина всегда начинать вашу разработку с начального Shale-приложения!
В вашем начальном приложении вы обнаружите зависимости в каталоге WEB-INF/lib/, все в виде JAR-файлов. Опять же, это стандартное расположение JAR-файлов в Web-приложениях, что не должно вызывать удивления. Вы также найдете настоящие Shale-библиотеки shale-core.jar, а также несколько дополнений к Shale add-ins, позволяющих Shale работать с другими интегрированными средами, например, Spring (shale-spring.jar), Clay (shale-core.jar), Tiles (shale-tiles.jar) и Java 5.0 Tiger (shale-tiger.jar). Другими словами, вы уже имеете практически все библиотеки, которые когда-либо могут вам понадобиться при разработке Web-приложений с использованием Shale. Это было легко, не правда ли?
Развертывание вашего приложения
Ваш исходный код расположен в нужном месте, и вы скомпоновали ваше приложение. Конечным результатом этих двух шагов является структура каталогов (в каталоге target/ вашего основного каталога first-shale/), которая содержит все файлы, необходимые вам для развертывания вашего приложения в контейнере сервлета. Однако хранение этих файлов вместе и копирование полных каталогов не слишком удобно и небезопасно. К счастью, Shale предоставляет более удобные инструментальные средства для развертывания вашего приложения.
Я показал вам, как создать WAR-файл, в предыдущей статье, но все же кратко напомню:
- Открыть ваш файл build.xml и изменить задачу "javadoc" так, как подробно описано в предыдущей статье.
- Выполнить команду
ant dist.
После выполнения этих шагов у вас появится еще один новый каталог, на этот раз называемый dist/. Содержимое данного каталога показано на рисунке 4.
Рисунок 4. Начальное Shale-приложение после компоновки.
Самым заметным файлом здесь является first-shale-0.1.war, который назван согласно значениям, указанным вами в build.properties (см. листинг 1). Каталог dist/ содержит также информацию о лицензии и файл readme о Shale, а также ваш исходный код. Это облегчает упаковку всего каталога dist/ в ZIP-файл, если вам понадобится перенести все приложение на другую машину, например, на другой сервер для разработки или на рабочую станцию. Во многих случаях вы просто будете разрабатывать ваши приложения на одной машине, поэтому для вас самым интересным будет WAR-файл.
После создания WAR-файла реальное развертывание приложения является очень простым делом. Просто возьмите файл и поместите его в каталог, который использует ваш контейнер сервлетов для Web-приложений. Этот каталог обычно имеет название похожее на webapps/. Контейнер сервлетов разархивирует WAR-файл (что приведет к созданию структуры каталогов, которую вы уже видели в target/) и развернет приложение. С этого момента все готово для использования вашего приложения.
В данной статье вы познакомились с анатомией Shale-приложения. Вы узнали назначение каждого каталога (и почти каждого файла в каждом каталоге) в контексте Shale-приложения, от компоновки приложения до его развертывания. Вы должны ясно понимать содержимое каталога исходных кодов Shale Web-приложения и получаемого развернутого WAR-файла.
Лучшее, что можно сделать до прочтения моей следующей статьи, - использовать полученную информацию на практике. Если у вас есть Web-приложение, которое вы хотели преобразовать для Shale, сделайте это. Начните с перемещения всех его JSP-страниц и Java-файлов в структуру каталогов Shale. Просто помните о том, что все ваши JSP-страницы нужно поместить в src/web/, а все Java-классы - в src/java/. Затем вы можете скомпоновать ваше приложение и развернуть его.
Да, игра с каталогами - это не то же самое, что использование Shale-компонентов, но вы уже работаете с инфраструктурой Shale-приложения, что является большим шагом в нужном направлении (достаточно большим, поскольку объяснение того, где Shale размешает все свои файлы в исходной и развертываемой форме, потребовало написания целой статьи). В следующей статье я сделаю еще один шаг, показав вам, как писать код, взаимодействующий с Shale. Я начну с JSP-страниц, а затем познакомлю вас с некоторыми относящимися к Shale тегами, которые вы можете использовать в ваших JSP-страницах. А пока поиграйте с начальным приложением. Измените его и протестируйте, но помните о необходимости сохранения синхронизации вашего дерева исходных кодов с деревом, предназначенным для развертывания!
Научиться
- Оригинал статьи "All Hail Shale: Anatomy of a Shale application".
- "Здравствуй, Shale!: Shale - это не Struts": Начало работы с новой интегрированной средой Struts.
- Домашняя страница Shale: Информация о Javadoc и дополнительная информация о Shale.
- Apache Struts: "Отец" Shale - широко используемая и расширяемая среда разработки Web-приложений собственной персоной.
- Apache Issue tracking Web site: Информация о состоянии конкретных ошибок или функциональных возможностях в Shale.
- Раздел Технология Java: десятки статей о каждом аспекте Java-программирования.
Получить продукты и технологии
- Apache Tomcat: Отличный контейнер сервлетов, прекрасно работающий с Shale, так же как и со Struts.
- Apache Ant: Java-программа компоновки, используемая для компоновки Shale-приложений.
Обсудить

Брэт Маклафлин работает с компьютерами со времен Logo (помните маленький треугольник?). За последние несколько лет он стал одним из наиболее известных авторов и программистов сообщества по технологиям Java и XML. Он работал в Nextel Communications над реализацией сложных корпоративных систем, в Lutris Technologies, фактически, над созданием сервера приложений, а с недавнего времени - в O'Reilly Media, Inc., где продолжает писать и редактировать книги по данной тематике. Его готовящаяся книга "Head Rush Ajax" рассматривает инновационный подход "Вперед головой" к изучению Ajax; она пишется совместно с известными соавторами Эриком и Бет Фримэн. Его недавняя книга "Java 5.0 Tiger: Заметки разработчика" является первой доступной книгой по новейшей технологии Java, а его классическая "Java и XML" остается одной из наиболее авторитетных работ по использованию технологий XML в языке программирования Java.