Статьи

Автономное веб-приложение с исполняемым Tomcat

Когда дело доходит до развертывания вашего приложения, простота — самое большое преимущество. Вы поймете это, особенно когда проект развивается и нуждается в некоторых изменениях в среде. Упаковка всего приложения в один автономный JAR-файл кажется хорошей идеей, особенно по сравнению с установкой и обновлением Tomcat в целевой среде. В прошлом я обычно включал JAR-файлы Tomcat в свое веб-приложение и писал тонкую программу командной строки, используя Tomcat API. К счастью, есть tomcat7:exec-warглавная цель, которая делает именно это. Он берет ваш WAR-артефакт и упаковывает его вместе со всеми зависимостями Tomcat. В конце он также включает Tomcat7RunnerCliMain-класс для манифеста.

Любопытно попробовать? Возьмите ваш существующий проект WAR и добавьте следующее pom.xml:

<plugin>
    <groupId>org.apache.tomcat.maven</groupId>
    <artifactId>tomcat7-maven-plugin</artifactId>
    <version>2.0</version>
    <executions>
        <execution>
            <id>tomcat-run</id>
            <goals>
                <goal>exec-war-only</goal>
            </goals>
            <phase>package</phase>
            <configuration>
                <path>/standalone</path>
                <enableNaming>false</enableNaming>
                <finalName>standalone.jar</finalName>
                <charset>utf-8</charset>
            </configuration>
        </execution>
    </executions>
</plugin>

Запустите mvn packageи через несколько секунд вы найдете блестящие standalone.jarв вашем targetкаталоге. Запустить ваше веб-приложение никогда не было так просто:

$ java -jar target/standalone.jar

… и вы можете просматривать localhost:8080/standalone. Хотя в документации pathпараметра указано (выделено мое):


Путь к контексту веб-приложения, используемый для запускаемого веб-приложения.
Имя для хранения веб-приложения в exec jar.
Не используйте /

только между нами,
<path>/</path>кажется, работает в конце концов. Оказывается, встроенный
mainкласс на самом деле немного более гибок. Например, вы можете сказать (я надеюсь, это говорит само за себя):

$ java -jar standalone.jar -httpPort=7070

Этот исполняемый JAR-файл сначала распаковывает WAR-файл внутри него в некоторый каталог (
.extractпо умолчанию
1 ) и развертывает его в Tomcat — все необходимые JAR-файлы Tomcat также включены. Пустой
standalone.jar(с небольшим количеством KiB WAR) весит около 8,5 МБ — не так много, если вы утверждаете, что загрузка всего Tomcat с каждым выпуском вместе с вашим приложением расточительна.

Говоря о JAR-файлах Tomcat, вы должны задаться вопросом, как выбрать версию Tomcat, включенную в этот runnable? К сожалению, я не смог найти ни одной простой опции, поэтому мы должны вернуться к явному переопределению
зависимостей
плагина (версия 2.0 имеет жестко закодированный 7.0.30 Tomcat). Это довольно скучно, но не так сложно и может пригодиться для дальнейшего использования:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <tomcat7Version>7.0.33</tomcat7Version>
</properties>
 
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.0</version>
            <executions>
                <execution>
                    <id>tomcat-run</id>
                    <goals>
                        <goal>exec-war-only</goal>
                    </goals>
                    <phase>package</phase>
                    <configuration>
                        <path>/standalone</path>
                        <enableNaming>false</enableNaming>
                        <finalName>standalone.jar</finalName>
                        <charset>utf-8</charset>
                    </configuration>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                  <groupId>org.apache.tomcat.embed</groupId>
                  <artifactId>tomcat-embed-core</artifactId>
                  <version>${tomcat7Version}</version>
                </dependency>
                <dependency>
                  <groupId>org.apache.tomcat</groupId>
                  <artifactId>tomcat-util</artifactId>
                  <version>${tomcat7Version}</version>
                </dependency>
                <dependency>
                  <groupId>org.apache.tomcat</groupId>
                  <artifactId>tomcat-coyote</artifactId>
                  <version>${tomcat7Version}</version>
                </dependency>
                <dependency>
                  <groupId>org.apache.tomcat</groupId>
                  <artifactId>tomcat-api</artifactId>
                  <version>${tomcat7Version}</version>
                </dependency>
                <dependency>
                  <groupId>org.apache.tomcat</groupId>
                  <artifactId>tomcat-jdbc</artifactId>
                  <version>${tomcat7Version}</version>
                </dependency>
                <dependency>
                  <groupId>org.apache.tomcat</groupId>
                  <artifactId>tomcat-dbcp</artifactId>
                  <version>${tomcat7Version}</version>
                </dependency>
                <dependency>
                  <groupId>org.apache.tomcat</groupId>
                  <artifactId>tomcat-servlet-api</artifactId>
                  <version>${tomcat7Version}</version>
                </dependency>
                <dependency>
                  <groupId>org.apache.tomcat</groupId>
                  <artifactId>tomcat-jsp-api</artifactId>
                  <version>${tomcat7Version}</version>
                </dependency>
                <dependency>
                  <groupId>org.apache.tomcat</groupId>
                  <artifactId>tomcat-jasper</artifactId>
                  <version>${tomcat7Version}</version>
                </dependency>
                <dependency>
                  <groupId>org.apache.tomcat</groupId>
                  <artifactId>tomcat-jasper-el</artifactId>
                  <version>${tomcat7Version}</version>
                </dependency>
                <dependency>
                  <groupId>org.apache.tomcat</groupId>
                  <artifactId>tomcat-el-api</artifactId>
                  <version>${tomcat7Version}</version>
                </dependency>
                <dependency>
                  <groupId>org.apache.tomcat</groupId>
                  <artifactId>tomcat-catalina</artifactId>
                  <version>${tomcat7Version}</version>
                </dependency>
                <dependency>
                  <groupId>org.apache.tomcat</groupId>
                  <artifactId>tomcat-tribes</artifactId>
                  <version>${tomcat7Version}</version>
                </dependency>
                <dependency>
                  <groupId>org.apache.tomcat</groupId>
                  <artifactId>tomcat-catalina-ha</artifactId>
                  <version>${tomcat7Version}</version>
                </dependency>
                <dependency>
                  <groupId>org.apache.tomcat</groupId>
                  <artifactId>tomcat-annotations-api</artifactId>
                  <version>${tomcat7Version}</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

В следующей статье мы узнаем, как приручить эти надоедливые внутренние журналы Tomcat, появляющиеся в терминале (
java.util.logging…) Тем временем я обнаружил и сообщил, что
MTOMCAT-186 Закрытие исполняемого файла JAR не вызывает ServletContextListener.contextDestroyed () — посмотрите, если это является нарушителем сделки для вас.

1 — это может быть хорошей идеей , чтобы указать другой каталог , используя
-extractDirectoryи очистить его перед каждым перезапуском с
-resetExtract.