Используя Maven для динамического запуска WAR в Tomcat, как добавить записи пути к классам, чтобы их видел только Tomcat? - PullRequest
2 голосов
/ 17 декабря 2009

Сценарий таков: у меня есть веб-приложение, которое я хочу динамически запускать с помощью tomcat: run target tomcat-maven-plugin. Проблема состоит в том, что у меня есть многочисленные ресурсы пути к классам, которые должны различаться между упакованным артефактом и тем, который запускается с локальной рабочей станции.

Неудачные попытки:

1.) Моей первой попыткой было использование builder-helper-maven-plugin, но он не сработает, поскольку целевые файлы конфигурации (непоследовательно!) Попадут в упакованный архив WAR.

<plugin>    
 <groupId>org.codehaus.mojo</groupId>
 <artifactId>build-helper-maven-plugin</artifactId>
 <version>1.3</version>
 <executions>

  <execution>     
   <id>add-resource</id>
   <phase>generate-resources</phase>
   <goals>
    <goal>add-resource</goal>
   </goals>
   <configuration>
    <resources>
     <resource>
      <directory>${basedir}/src/main/resources-env/${testEnv}</directory>
      <targetPath>${basedir}/target/classes</targetPath>
     </resource>
    </resources>
   </configuration>
  </execution>
 </executions>
</plugin>

2.) Моя вторая попытка состояла в том, чтобы добавить папку (так как файлы, которые должны быть развернуты, еще не присутствуют в classpath Tomcat) в -Djava.ext.dirs, но это не имеет никакого эффекта (я на самом деле подозревать, что этот элемент systemProperties неправильно настроен или вообще не работает). См:

<plugin>
 <groupId>org.codehaus.mojo</groupId>
 <artifactId>tomcat-maven-plugin</artifactId>
 <version>1.0-beta-1</version>
 <configuration>
  <tomcatWebXml>${basedir}/src/main/mock/web.xml</tomcatWebXml>

  <systemProperties>
   <property>
    <name>java.ext.dirs</name>
    <value>${basedir}/src/main/resources-env/${testEnv}</value>
   </property>      
  </systemProperties>      
  <path>/licensing</path>
 </configuration>
</plugin>

Я не уверен, что делать дальше. Суть проблемы заключается в том, что в этом плагине отсутствует элемент Surefire <additionalClasspathElement>.

Следующим шагом будет создание пользовательских catalina.properties и добавление его в <configurationDir>? Если да, то как должна выглядеть catalina.properties?

Редактировать: более подробное объяснение следует

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

My POM использует функциональность webResources плагина WAR для копирования некоторых конфигурационных файлов, специфичных для среды, и без использования профиля для этого путем копирования в ресурс с именем /src/main/resources-env/${env}, например, так:

...
<plugin>    
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
        ...
    <configuration>
            ...
        <webResources>
            <!-- Copy Environment-specific resources to classes -->
            <resource>
                <directory>${basedir}/src/main/resources-env/${env}</directory>
                <targetPath>WEB-INF/classes</targetPath>
            </resource>
        </webResources>
    </configuration>
</plugin>

Это скопирует ресурсы среды (по умолчанию, DEV) в пакет и в настоящее время работает нормально. Также обратите внимание, что, поскольку они происходят как часть упаковки, цель tomcat:run никогда не предназначена для них (что желательно, поскольку среда различается).

Таким образом, проблема заключается в следующем: при выполнении динамического tomcat:run приложение завершится сбоем, поскольку его пути к классам (он смотрит на target/classes) будет не хватать необходимых локальных файлов конфигурации среды рабочей станции. Все, что мне нужно сделать, это получить их по пути для tomcat, но я хотел бы сделать это, не добавляя ничего в командную строку и определенно , не нарушая целостность сборки, если кто-то последует с mvn package и не clean первый.

Надеюсь, это более понятно.

Ответы [ 4 ]

4 голосов
/ 17 декабря 2009

Я могу что-то упустить, но почему бы вам не объявить требуемые зависимости в профиле и не использовать этот профиль при запуске Tomcat? Я не понимаю, почему вам нужно разместить эти ресурсы на уровне classpath Tomcat.

ОБНОВЛЕНИЕ: Я редактирую свой ответ, чтобы покрыть комментарий от самого ОП, отвечая на мой вопрос выше.

Вы правы, файлы действительно должны быть в classpath веб-приложения, а не в tomcat. Итак, как я могу создать профиль, который автоматически активируется для tomcat: run, но без дополнительных аргументов строки cmd?

Я не знаю, как это сделать без объявления профиля как <activeByDefault> или перечисления его под <activeProfiles> (но это не то, что я имел в виду, я бы предпочел использовать активацию свойства и вызвать что-то вроде mvn tomcat:run -Denv=test, не уверен, что понимаю, почему это проблема).

И как мне «объявить зависимости» в профиле, гарантируя, что последующие вызовы никогда не позволят им войти в пакет WAR через пакет vanilla mvn

Если ранее упомянутый профиль активен по умолчанию, то вам нужно будет исключить его, если он вам не нужен, вызвав что-то вроде mvn package -P !profile-1. Профиль не может быть магически деактивирован для одной конкретной цели (по крайней мере, насколько мне известно).

На самом деле, я понимаю, что у вас действительно есть два разных контекста: контекст «тестирования» (где вы хотите включить больше вещей в WAR) и «нормальный» контекст (где вы не хотите, чтобы эти вещи быть включенным). Честно говоря, я не знаю, как вы могли бы различить эти две ситуации без указания какого-либо дополнительного параметра (либо активировать профиль, либо деактивировать его в зависимости от контекста). У вас должны быть веские причины, но, как я уже сказал, я не совсем понимаю, почему это проблема. Поэтому, возможно, профили не являются решением для вашей ситуации. Но я бы очень хотел понять почему, потому что это типичный вариант использования профилей:)

ОБНОВЛЕНИЕ2: Прочитав ваш комментарий к другому ответу и ваше обновление, я понимаю, что мое первоначальное понимание было неверным (хотя я говорил о зависимостях в смысле maven). Но я все еще думаю, что профили могут помочь вам, например, настроить <resources>, как в этом сообщении в блоге (это всего лишь один из способов сделать это, используя свойство типа src/main/resources/${env} в пути другой путь). Но это не решит всех ваших проблем (например, не указание дополнительных параметров командной строки или автоматическая очистка целевого каталога). У меня нет никаких решений для этого.

1 голос
/ 19 апреля 2011

Проголосуйте за http://jira.codehaus.org/browse/MTOMCAT-77, который удовлетворяет эту потребность.

1 голос
/ 17 декабря 2009

Добавить элемент зависимостей непосредственно в элемент плагина.

Вот пример того же действия с плагином Jetty из (до сих пор в разработке) Maven Handbook: http://www.sonatype.com/books/mhandbook-stage/reference/ch06s03.html

0 голосов
/ 19 декабря 2009

Вот решение, которое у меня есть на данный момент.

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

Я удалил файлы конфигурации из <webResources> из плагина WAR, а тестовый конфигурацию из <testResources> и теперь вручную управляю копированием ресурсов с помощью плагина maven-resources-plugin, чтобы скопировать их непосредственно в target/classes в цель, в которой они нуждаются. Таким образом Tomcat может видеть конфигурацию, но тесты не нарушаются, если в пути присутствуют дубликаты или отличающиеся файлы конфигурации.

Это определенно беспорядок, но это работает. Листинг:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-resources-plugin</artifactId>
    <version>2.4.1</version>
    <executions>
        <execution>
            <id>copy-env-resources</id>
            <phase>process-resources</phase>
            <goals>
                <goal>copy-resources</goal>
            </goals>
            <configuration>
                <resources>
                    <resource>
                        <directory>${basedir}/src/main/resources-env/${env}</directory>                                 
                        <filtering>true</filtering>
                    </resource>
                </resources>
                <outputDirectory>${basedir}/target/classes</outputDirectory>
            </configuration>
        </execution>
        <execution>
            <id>copy-testEnv-resources</id>
            <phase>process-test-resources</phase>
            <goals>
                <goal>copy-resources</goal>
            </goals>
            <configuration>
                <resources>
                    <resource>
                        <directory>${basedir}/src/main/resources-env/${testEnv}</directory>
                        <filtering>true</filtering>
                    </resource>
                </resources>
                <outputDirectory>${basedir}/target/classes</outputDirectory>
            </configuration>
        </execution>
        <execution>
            <id>copy-env-resources-again</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>copy-resources</goal>
            </goals>
            <configuration>
                <resources>
                    <resource>
                        <directory>${basedir}/src/main/resources-env/${env}</directory>
                        <filtering>true</filtering>
                    </resource>
                </resources>
                <outputDirectory>${basedir}/target/classes</outputDirectory>
            </configuration>
        </execution>                            
    </executions>
</plugin>

Таким образом, mvn clean install будет собирать и тестировать с $ {env} и $ {testEnv} соответственно. mvn -Denv=someLocalConfig tomcat:run (который в моем случае идентичен моему стандартному $ {testEnv}, обеспечит загрузку src/main/resources-env/someLocalConfig для динамического выполнения Tomcat, но не требует выполнения очистки перед успешной перестройкой.

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

...