Maven에 있는 Profile의 주 목적은 서로 다른 빌드 환경간의 portability입니다. 개발 환경, 테스트 환경, 성능 테스트 환경, 클라이언트 환경 등 상상할 수 있는 모든 환경에 단일 프로젝트를 이식할 수 있도록 합니다.

Portability 종류

Non-Portability

이런 프로젝트는 오직 특정한 환경에서만 빌드를 할 수 있습니다. 프로젝트를 다른 환경으로 이식할 계획이 없다면 그냥 이렇게 사용해도 상관없습니다.

Environmental Protability

테스트 환경에서는 테스트 데이터베에스를 참조하고, 배고 환경에서는 배포용 데이터베이스를 참조할 수 있는 프로젝트입니다. 하지만 프로파일이 만들어져이지 않은 환경으로 이식한다면, 해당 프로젝트는 동작하지 않을 것입니다. 따라서 오직 정의되어 있는 환경으로만 이식할 수 있습니다.

In-House Portability

특정한 도구나 연결 접근이 필요한 프로젝트를 말합니다.

Wide Portability

Maven에서는 wide portability 프로젝트 소스를 누구나 다운받을 수 있습니다. 프로젝트를 빌드하려는 사람이 어떠한 추가작업도 필요로하지 않을때 Wide Portablilty 프롤젝트라고 합니다. 예를 들어, MySQL을 사용한다면, 해당 프로젝트를 빌드 할 때 MySQL이 없는 사람은 설치를 해야합니다. 이런 프로젝트는 Wide Protability를 가졌다고 할 수 없습니다. 반면에, HSQLDB를 사용한다면, hsql.jar 종속성을 추가하면 되기떄문에 widely protable합니다.

가능하면 프로젝트를 최대한 이식성이 좋도록하는 것이 목적입니다. 이식성이 넓어질 수록 빌드 작업을 하는 사람의 수고를 덜 수 있습니다. Maven의 Profile은 특정 환경의 기본 값이 설정 값들을 대체할 수 있습니다. Maven을 사용하면, Non-portable 프로젝트를 Environmentally portable 프로젝트로 변경시킬 수 있습니다.

POM Profiles

project 엘리먼트 내부에 profiles 엘리먼트 안에 모든 가용한 설정들을 합니다. 그 안에서 설정할 수 있는 엘리먼트들은 project 엘리먼트 레벨에서 사용할 수 있는 것들과 동일합니다.

<project>
  ...
  <profiles>
    <profile>
      ...
      <reporting>...</reporting>
      <modules>...</modules>
      <dependencies>...</dependencies>
      <dependencyManagement>...</dependencyManagement>
      <distributionManagement>...</distributionManagement>
      <repositories>...</repositories>
      <pluginRepositories>...</pluginRepositories>
      <properties>...</properties>
    </profile>
  </profiles>
</project>

Activation

activation 엘리먼트는 오직 profile 엘리먼트 내부에서만 사용할 수 있으며, 이 엘리먼트에 정의한 환경과 실행 환경이 일치하면 profile에 설정한 값들이 project에 설정한 값들을 대체합니다.

<project>
  ...
  <profiles>
    <profile>
      <id>dev</id>
      <activation>
        <activeByDefault>false</activeByDefault>
        <jdk>1.5</jdk>
        <os>
          <name>Windows XP</name>
          <family>Windows</family>
          <arch>x86</arch>
          <version>5.1.2600</version>
        </os>
        <property>
          <name>mavenVersion</name>
          <value>2.0.5</value>
        </property>
        <file>
          <exists>file2.properties</exists>
          <missing>file1.properties</missing>
        </file>
      </activation>
      ...
    </profile>
  </profiles>
</project>

Build

profile의 build 엘리먼트는 POM의 build 엘리먼트의 서브셋에 해당하는 정보를 가지고 있습니다.

<project>
  ...
  <profiles>
    <profile>
      <build>
        <defaultGoal>install</defaultGoal>
        <directory>${basedir}/target</directory>
        <finalName>${artifactId}-${version}</finalName>
        <filters>
          <filter>filters/filter1.properties</filter>
        </filters>
        <resources>
          <resource>
            <targetPath>META-INF/plexus</targetPath>
            <filtering>false</filtering>
            <directory>${basedir}/src/main/plexus</directory>
            <includes>
              <include>configuration.xml</include>
            </includes>
            <excludes>
              <exclude>**/*.properties</exclude>
            </excludes>
          </resource>
        </resources>
        <testResources>
          <testResource>...</testResource>
        </testResources>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-antrun-plugin</artifactId>
            <version>1.1</version>
            <extensions>false</extensions>
            <inherited>true</inherited>
            <configuration>
              <sourceRoot>${project.build.directory}/generated-sources</sourceRoot>
            </configuration>
            <dependencies>
              <dependency>
                <groupId>ant</groupId>
                <artifactId>ant-optional</artifactId>
                <version>1.5.2</version>
              </dependency>
            </dependencies>
            <executions>
              <execution>
                <id>echodir</id>
                <goals>
                  <goal>run</goal>
                </goals>
                <phase>verify</phase>
                <inherited>false</inherited>
                <configuration>
                  <tasks>
                    <echo>Build Dir: ${project.build.directory}</echo>
                  </tasks>
                </configuration>
              </execution>
            </executions>
          </plugin>
        </plugins>
        <pluginManagement>
          <plugins>...</plugins>
        </pluginManagement>
      </build>
    </profile>
  </profiles>
</project>

External Profiles

proflie들을 POM에서 빼내고 싶을 수 있습니다. 이럴 때는 \${basedir}에 profilesxml을 생성하고 그 안에 profiles 엘리먼트를 넣어주면 됩니다.

Settings Profiles

settings.xml에서도 profile을 설정할 수 있는데, 이 것은 project의 profile과 기능은 같으나, project의 profile은 여러 시스템들 중에 특정한 설정 값을 overriding 할 때 사용하고, settings의 profile은 모든 시스템 통채를 대상으로 합니다.

activeProfiles 엘리먼트를 사용하여 모든 빌드에서 자동으로 동작시킬 profile을 지정할 수 있습니다. 물론 이때의 profile은 project의 profile이 아니라 settings의 profile입니다.

<settings>
  ...
  <activeProfiles>
    <activeProfile>dev</activeProfile>
  </activeProfiles>
</settings>

어렵네요. -_-;;