war:war - filtering context.xml

November 10, 2011

war:war - filtering context.xml

[ru] [en]

Small "how-to" implement filtering of container specific deployment descriptor in maven WAR plugin
Многие используют maven-war-plugin, но не у многих воникает необхоимость иметь разные деплоймент десктрипторы для разработки и для прдакшена. Проблема возникает когда, к примеру, сборка релизной версии полностию автоматизируется при помощи то же maven-release-plugin а полученные потом артефакты автоматом "собириаются" в deb-пакеты (при помощи jdeb плагина - кстати, единственного реально пригодного для подобных целей, но об этом отдельно - а сии deb-пакеты автоматом запихиваются в соответствующие репозитории, а потом продекшен-сервера просто обновляются из этих репозиториев и.. и все хорошо, админы счастливы и начинают не так сильно нелюбить Яву :) а так же они имеют возможность простым стандартным способом откатиться в случае проблем с новой версией ну и т.д.).

Так вот, разработчикам очень полезно деплоить war-ы под разными контекстами дабы убедиться в правильности ссылок, но вот на проде все стоит в "ROOT". Вот тут и возникает необходимость иметь два разных контейнерных делоймент дестриптора. Казалось бы - чего проще, ведь есть свойство filteringDeploymentDescriptors - оно то есть, но работает херово, только на фильтрацию web.xml его и хватает.

Совет: используйте containerConfigXML или webResources - проврено фильтрация в них работает.

Итого
Для того же tomcat его context.xml кладем сюда

|-- pom.xml
`-- src
    |-- main
    |   |-- java
    |   |   `-- ....
    |   |-- resources
    |   |   `-- ...
    |   |-- webapp
    |   |   `-- ....
    |   `-- web-resources
    |       `-- META-INF
    |           `-- context.xml
    `-- test
        `-- ... 

В "pom.xml" прописываем вот такие строчки

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <configuration>
                    <filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>
                    <containerConfigXML>src/main/web-resources/META-INF/context.xml</containerConfigXML>
<!--
                    <webResources>
                        <resource>
                            <directory>src/main/web-resources</directory>
                            <filtering>true</filtering>
                        </resource>
                    </webResources>
-->
                </configuration>
            </plugin>
        </plugins>
        .....
    </build>


соответствнно, испльзуйте любую из секций - или "containerConfigXML", как в примере, или "webResources", как тут же в блоке комментариев - обе секции работают.

Все это позволит вам написать в context.xml что-то типа

<Context antiJARLocking="false" antiResourceLocking="false" cacheMaxSize="10240" cacheObjectMaxSize="512"
         cacheTT="60000" cachingAllowed="true" cookies="true" crossContext="true" disableURLRewriting="false"
         override="true" path="${war.context}" reloadable="${war.reloadable}">
</Context>

и потом в соответствующих maven-профилях определить веденные выше переменные war.context, war.reloadable

Удачи, не скучайте, слушайте хорошую музыку

A lot of developers use the maven-war-plugin, but a few really need to has a different container specific deployment descriptors for development and for production environment. The problem appears when, for example, you will need to automate the build and release processes by maven-release-plugin and deploy the artifacts as deb-packages (with jdeb plugin - by the way, just one that can really be used now -and than the deb-package should be automatically deployed to some repository. After that your production servers just can be "updated" from such repo and.. and your admins becomes happy and stop to hate Java so much :) and now they has a fully documented and automated install- and rollback- procedure, etc....).

So, developers should use different deployment descriptors in WEB applications but in production the "ROOT" context is always used. So we need to have a different deployment descriptors for different runtime environments. You can say - it's so easy because we have a filteringDeploymentDescriptors property - it's true, but it's worked only with filtering of web.xml.

Advise: try to use containerConfigXML or webResources - each of they is worked.

At least
So, for tomcat его context.xml server the you can place the context.xml file to

|-- pom.xml
`-- src
    |-- main
    |   |-- java
    |   |   `-- ....
    |   |-- resources
    |   |   `-- ...
    |   |-- webapp
    |   |   `-- ....
    |   `-- web-resources
    |       `-- META-INF
    |           `-- context.xml
    `-- test
        `-- ... 

Than into the "pom.xml" you can put

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <configuration>
                    <filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>
                    <containerConfigXML>src/main/web-resources/META-INF/context.xml</containerConfigXML>
<!--
                    <webResources>
                        <resource>
                            <directory>src/main/web-resources</directory>
                            <filtering>true</filtering>
                        </resource>
                    </webResources>
-->
                </configuration>
            </plugin>
        </plugins>
        .....
    </build>


and now you can use any of listed section - or "containerConfigXML", as in example, or "webResources", as in comments - all worked, tested.

And than you can modify the context.xml like

<Context antiJARLocking="false" antiResourceLocking="false" cacheMaxSize="10240" cacheObjectMaxSize="512"
         cacheTT="60000" cachingAllowed="true" cookies="true" crossContext="true" disableURLRewriting="false"
         override="true" path="${war.context}" reloadable="${war.reloadable}">
</Context>

after that you can define parameters war.context, war.reloadable in your maven-profile

Regards, be happy and listen a good mumsic


4 comments:

shurik said...

А вот тут есть веселый момент с фильтраций дескрипторов: если сборку производить из-под OS Windows и в фильтруемом xml файле будет где-то стоять заглавная русская буква 'И', то в результате фильтрации она превратиться в "нереальный бред" и deploy приложения будет падать с невменяемой ошибкой. (Это помойму баг не war плагина, а плагина ресурсов..., т.к. баг проявляется не только на xml файлах дескрипторов)

s13o said...

Это невероятный эксклюзив - даже сложно представить в каком месте web.xml или context.xml может встретиться русская буква И, как, впрочем, и любая другая не русская буква :)

shurik said...

Ну допустим в комментарии, в слове "ВНИМАНИЕ" :)

s13o said...

ACHTUNG круче ! :)
Проблема проявляется и с UTF-8 ? Если да - то очень странно и... спасибо за ценное замечание.

Post a Comment