Kohei Nozaki's blog 

Entries tagged [maven]

Conditional inclusion of whole element for deployment descriptor with Maven


Posted on Wednesday Jan 21, 2015 at 11:26AM in Technology


Sometimes I need to tweak deployment descriptors (e.g. web.xml) for different environment (e.g. development/integration-test/production). I frequently see the case which tweaks only values of context-param, or choose appropriate one from separated files for each environment but I’m looking for a way to include or exclude whole an element using single template. I found a solution so I leave some note about that.

pom.xml

Specify <filteringDeploymentDescriptors>true</filteringDeploymentDescriptors> in plugin configuration.

<build>
    <plugins>
        <plugin>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>
            </configuration>
        </plugin>
    </plugins>
</build>

Define variables for each environment. in my case I need to include a context-param of JSF for development environment only. if I didn’t use profile named development when the time of build, then that context-param will be simply excluded from web.xml.

    <profiles>
        <profile>
            <id>development</id>
            <properties>
                <context-params><![CDATA[ -->
    <context-param>
        <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
        <param-value>0</param-value>
    </context-param>
    <!-- ]]></context-params>
            </properties>
        </profile>
        <profile>
            <id>default</id>
            <properties>
                <context-params></context-params>
            </properties>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
        </profile>
    </profiles>

web.xml

Just put an expression inside XML comment syntax. it’s intended to avoid that complaining XML editor of your IDE.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
    <!-- ${context-params} -->
    ...
</web-app>

Processed web.xml

If I build with mvn clean package -P development then web.xml will be:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
    <!-- -->
    <context-param>
        <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
        <param-value>0</param-value>
    </context-param>
    <!-- -->
    ...

If I use mvn clean package then web.xml will be:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
    <!--  -->
    ...


Switching environment specific configuration files


Posted on Tuesday Mar 04, 2014 at 08:18PM in Technology


  • In my last posting Treating environment specific configurations with Maven filtering, I said that I don't want to create separate files for each environment.
  • But it is still needed by some cases.
    • Such as web.xml, logback.xml is too long for treat with Maven properties at some cases.
  • So I'm going to find a way to achieve it.

Environment

  • Apache Maven 3.1.1
  • Jenkins 1.551
  • WildFly 8.0.0.Final
  • Eclipse Kepler SR1
  • Oracle JDK7u51
  • OS X 10.9.2

Preparation

~/.m2/settings.xml

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
    <profiles>
        <profile>
            <id>development</id>
            <properties>
                <hogeApp.environmentId>dev</hogeApp.environmentId>
            </properties>
        </profile>
    </profiles>
</settings>

Explicit selection of the Maven Profile is mandatory.

  1. Right-click the project - Maven - Select Maven Profiles

  2. Check “development” - OK

Sample project

Project structure

kyle-no-MacBook:switch kyle$ tree src
src
├── main
│   ├── java
│   │   └── org
│   │       └── nailedtothex
│   │           └── sw
│   │               └── MainServlet.java
│   ├── resources
│   │   ├── _dev
│   │   │   └── env-specific.properties
│   │   ├── _it
│   │   │   └── env-specific.properties
│   │   └── common.properties
│   └── webapp
│       ├── WEB-INF
│       │   ├── index.jsp
│       │   └── lib
│       ├── _dev
│       │   └── WEB-INF
│       │       └── web.xml
│       └── _it
│           └── WEB-INF
│               └── web.xml
└── test
    ├── java
    │   └── org
    │       └── nailedtothex
    │           └── sw
    │               └── MainServletIT.java
    └── resources
        ├── _dev
        │   └── test-env-specific.properties
        ├── _it
        │   └── test-env-specific.properties
        └── test-common.properties
  • We can place environment specific files in the folders named such as “_dev” or “_it”.
  • Common resources among environments are can be placed on the regular place.
    • /webapp/WEB-INF/index.jsp and /src/main/resources/common.properties are regarded as common resources.
    • So they will be included for every environment.
  • This mechanism supports both of /src/main/resources and /src/webapp, and /src/test/resources too.
  • MainServet acquires all of properties, then dispatch to /WEB-INF/index.jsp, and return variables to the client.

Produced artifact by standalone Maven

kyle-no-MacBook:switch kyle$ mvn clean package -P development >/dev/null; unzip -l target/switch.war
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
Archive:  target/switch.war
  Length     Date   Time    Name
 --------    ----   ----    ----
        0  03-05-14 11:12   META-INF/
      129  03-05-14 11:12   META-INF/MANIFEST.MF
        0  03-05-14 11:12   WEB-INF/
        0  03-05-14 11:12   WEB-INF/classes/
        0  03-05-14 11:12   WEB-INF/classes/org/
        0  03-05-14 11:12   WEB-INF/classes/org/nailedtothex/
        0  03-05-14 11:12   WEB-INF/classes/org/nailedtothex/sw/
       64  03-05-14 11:12   WEB-INF/classes/common.properties
       75  03-05-14 11:12   WEB-INF/classes/env-specific.properties
     2479  03-05-14 11:12   WEB-INF/classes/org/nailedtothex/sw/MainServlet.class
      158  03-04-14 22:41   WEB-INF/index.jsp
      470  03-04-14 22:31   WEB-INF/web.xml
     2433  03-05-14 10:15   META-INF/maven/org.nailedtothex/switch/pom.xml
      116  03-05-14 11:12   META-INF/maven/org.nailedtothex/switch/pom.properties
 --------                   -------
     5924                   14 files
kyle-no-MacBook:switch kyle$ 

Resources

Whole resources are available in GitHub.

Output of MainServlet on development environment

  • This is output of when I deployed the application to WildFly through Eclipse.
kyle-no-MacBook:switch kyle$ curl http://localhost:8080/switch/
This value came from context-param defined in /src/main/webapp/_dev/WEB-INF/web.xml
This value came from /src/main/resources/common.properties
This value came from /src/main/resources/_dev/env-specific.properties
kyle-no-MacBook:switch kyle$ 

Test execution from command-line

  • Ensure WildFly is stopped before execute the command.
kyle-no-MacBook:switch kyle$ mvn verify -P development,test-with-wildfly
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building switch 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- properties-maven-plugin:1.0-alpha-2:read-project-properties (default) @ switch ---
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ switch ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 1 resource
[INFO] 
[INFO] --- maven-compiler-plugin:2.5.1:compile (default-compile) @ switch ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ switch ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 1 resource
[INFO] 
[INFO] --- maven-compiler-plugin:2.5.1:testCompile (default-testCompile) @ switch ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-surefire-plugin:2.16:test (default-test) @ switch ---
[INFO] 
[INFO] --- maven-war-plugin:2.4:war (default-war) @ switch ---
[INFO] Packaging webapp
[INFO] Assembling webapp [switch] in [/Users/kyle/gits1/switch/switch/target/switch]
[INFO] Processing war project
[INFO] Copying webapp webResources [/Users/kyle/gits1/switch/switch/src/main/webapp/_dev] to [/Users/kyle/gits1/switch/switch/target/switch]
[INFO] Copying webapp resources [/Users/kyle/gits1/switch/switch/src/main/webapp]
[INFO] Webapp assembled in [36 msecs]
[INFO] Building war: /Users/kyle/gits1/switch/switch/target/switch.war
[INFO] 
[INFO] --- wildfly-maven-plugin:1.0.1.Final:start (wildfly-run) @ switch ---
[INFO] JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre
[INFO] JBOSS_HOME=/Users/kyle/apps/wildfly-8.0.0.Final

[INFO] Server is starting up.
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
3 05, 2014 12:01:24 午後 org.xnio.Xnio <clinit>
INFO: XNIO version 3.2.0.Final
3 05, 2014 12:01:25 午後 org.xnio.nio.NioXnio <clinit>
INFO: XNIO NIO Implementation Version 3.2.0.Final
3 05, 2014 12:01:25 午後 org.jboss.remoting3.EndpointImpl <clinit>
INFO: JBoss Remoting version 4.0.0.Final
12:01:25,334 INFO  [org.jboss.modules] (main) JBoss Modules version 1.3.0.Final
12:01:25,601 INFO  [org.jboss.msc] (main) JBoss MSC version 1.2.0.Final
12:01:25,689 INFO  [org.jboss.as] (MSC service thread 1-6) JBAS015899: WildFly 8.0.0.Final "WildFly" starting
12:01:25,696 DEBUG [org.jboss.as.config] (MSC service thread 1-6) Configured system properties:
    awt.toolkit = sun.lwawt.macosx.LWCToolkit
    file.encoding = UTF-8

*SNIP*

12:01:27,910 INFO  [org.jboss.as.server] (ServerService Thread Pool -- 29) JBAS018559: Deployed "switch.war" (runtime-name : "switch.war")
12:01:27,911 INFO  [org.jboss.as.server] (ServerService Thread Pool -- 29) JBAS018559: Deployed "mavenprops.war" (runtime-name : "mavenprops.war")
12:01:27,920 INFO  [org.jboss.as] (Controller Boot Thread) JBAS015961: Http management interface listening on http://127.0.0.1:9990/management
12:01:27,920 INFO  [org.jboss.as] (Controller Boot Thread) JBAS015951: Admin console listening on http://127.0.0.1:9990
12:01:27,921 INFO  [org.jboss.as] (Controller Boot Thread) JBAS015874: WildFly 8.0.0.Final "WildFly" started in 2929ms - Started 359 of 419 services (100 services are lazy, passive or on-demand)
[INFO] 
[INFO] >>> wildfly-maven-plugin:1.0.1.Final:deploy (wildfly-run) @ switch >>>
[INFO] 
[INFO] --- properties-maven-plugin:1.0-alpha-2:read-project-properties (default) @ switch ---
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ switch ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 1 resource
[INFO] 
[INFO] --- maven-compiler-plugin:2.5.1:compile (default-compile) @ switch ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ switch ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 1 resource
[INFO] 
[INFO] --- maven-compiler-plugin:2.5.1:testCompile (default-testCompile) @ switch ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-surefire-plugin:2.16:test (default-test) @ switch ---
[INFO] Skipping execution of surefire because it has already been run for this configuration
[INFO] 
[INFO] --- maven-war-plugin:2.4:war (default-war) @ switch ---
[INFO] Packaging webapp
[INFO] Assembling webapp [switch] in [/Users/kyle/gits1/switch/switch/target/switch]
[INFO] Processing war project
[INFO] Copying webapp webResources [/Users/kyle/gits1/switch/switch/src/main/webapp/_dev] to [/Users/kyle/gits1/switch/switch/target/switch]
[INFO] Copying webapp resources [/Users/kyle/gits1/switch/switch/src/main/webapp]
[INFO] Webapp assembled in [8 msecs]
[INFO] Building war: /Users/kyle/gits1/switch/switch/target/switch.war
[INFO] 
[INFO] <<< wildfly-maven-plugin:1.0.1.Final:deploy (wildfly-run) @ switch <<<
[INFO] 
[INFO] --- wildfly-maven-plugin:1.0.1.Final:deploy (wildfly-run) @ switch ---
12:01:30,671 INFO  [org.jboss.as.repository] (management-handler-thread - 3) JBAS014900: Content added at location /Users/kyle/apps/wildfly-8.0.0.Final/standalone/data/content/77/69a251de04b468b0d3afc81afe32b2c1b58a63/content
12:01:30,678 INFO  [org.wildfly.extension.undertow] (MSC service thread 1-9) JBAS017535: Unregistered web context: /switch
12:01:30,713 INFO  [org.hibernate.validator.internal.util.Version] (MSC service thread 1-9) HV000001: Hibernate Validator 5.0.3.Final
12:01:30,756 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-16) JBAS015877: Stopped deployment switch.war (runtime-name: switch.war) in 81ms
12:01:30,757 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-12) JBAS015876: Starting deployment of "switch.war" (runtime-name: "switch.war")
12:01:30,785 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-3) JBAS015877: Stopped deployment switch.war (runtime-name: switch.war) in 27ms
12:01:30,786 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-14) JBAS015876: Starting deployment of "switch.war" (runtime-name: "switch.war")
12:01:30,829 INFO  [org.wildfly.extension.undertow] (MSC service thread 1-14) JBAS017534: Registered web context: /switch
12:01:30,871 INFO  [org.jboss.as.server] (management-handler-thread - 3) JBAS018562: Redeployed "switch.war"
12:01:30,871 INFO  [org.jboss.as.server] (management-handler-thread - 3) JBAS018565: Replaced deployment "switch.war" with deployment "switch.war"
[INFO] 
[INFO] --- maven-failsafe-plugin:2.16:integration-test (default) @ switch ---
[INFO] Failsafe report directory: /Users/kyle/gits1/switch/switch/target/failsafe-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
Running org.nailedtothex.sw.MainServletIT
testEnvSpecific: {app.hostname=localhost, wildfly.port.offset=0, wildfly.port.mgmt=9990, wildfly.home=/Users/kyle/apps/wildfly-8.0.0.Final, value=This value came from /src/test/resources/_dev/test-env-specific.properties, app.port=8080}
testCommon: {app.environmentId=dev, app.path=/switch, value=This value came from /src/test/resources/test-common.properties}
test(): environment=dev, url=http://localhost:8080/switch/
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.568 sec - in org.nailedtothex.sw.MainServletIT

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] 
[INFO] --- wildfly-maven-plugin:1.0.1.Final:undeploy (wildfly-stop) @ switch ---
12:01:31,863 INFO  [org.wildfly.extension.undertow] (MSC service thread 1-3) JBAS017535: Unregistered web context: /switch
12:01:31,873 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-8) JBAS015877: Stopped deployment switch.war (runtime-name: switch.war) in 10ms
12:01:31,889 INFO  [org.jboss.as.repository] (management-handler-thread - 4) JBAS014901: Content removed from location /Users/kyle/apps/wildfly-8.0.0.Final/standalone/data/content/77/69a251de04b468b0d3afc81afe32b2c1b58a63/content
12:01:31,889 INFO  [org.jboss.as.server] (management-handler-thread - 4) JBAS018558: Undeployed "switch.war" (runtime-name: "switch.war")
[INFO] 
[INFO] --- wildfly-maven-plugin:1.0.1.Final:shutdown (wildfly-stop) @ switch ---
12:01:31,917 INFO  [org.jboss.as.connector.subsystems.datasources] (MSC service thread 1-16) JBAS010409: Unbound data source [java:jboss/jdbc/JBatchDS]

*SNIP*

12:01:31,950 INFO  [org.jboss.as] (MSC service thread 1-10) JBAS015950: WildFly 8.0.0.Final "WildFly" stopped in 28ms
[INFO] 
[INFO] --- maven-failsafe-plugin:2.16:verify (default) @ switch ---
[INFO] Failsafe report directory: /Users/kyle/gits1/switch/switch/target/failsafe-reports
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 9.541s
[INFO] Finished at: Wed Mar 05 12:01:32 JST 2014
[INFO] Final Memory: 14M/245M
[INFO] ------------------------------------------------------------------------
kyle-no-MacBook:switch kyle$ 

How to apply this method to Jenkins job which executes integration test?

  • We need to specify the profile named “test-with-wildfly”
  • And appropriate environmentId on MAVEN_OPTS.

Test run

  • integration-test phase executed expectedly.
[INFO] --- maven-failsafe-plugin:2.16:integration-test (default) @ switch ---
[INFO] Failsafe report directory: /Users/Shared/Jenkins/Home/jobs/Switch/workspace/switch/target/failsafe-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running org.nailedtothex.sw.MainServletIT
testEnvSpecific: {app.hostname=localhost, wildfly.port.offset=40000, wildfly.port.mgmt=49990, wildfly.home=/Users/Shared/Jenkins/wildfly-8.0.0.Final, value=This value came from /src/test/resources/_it/test-env-specific.properties, app.port=48080}
testCommon: {app.environmentId=it, app.path=/switch, value=This value came from /src/test/resources/test-common.properties}
test(): environment=it, url=http://localhost:48080/switch/
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.738 sec - in org.nailedtothex.sw.MainServletIT

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

Remarks

  • I don't know whether it is good idea for any cases because we easily misses to keep these platform specific files correctly.
    • Sometimes we forget about these files need to be edited or created.
  • So, I guess that we are better to apply this method for few numbers of resources that really required this way.

Unresolved issues

  • Eclipse produces the package contains unnecessary resources.
  • It seems to that exclusions are ignored.
  • I guess this is not a problem for most cases, because correct environment specific resources are included.
kyle-no-MacBook:switch kyle$ unzip -l ~/apps/wildfly-8.0.0.Final/standalone/deployments/switch.war
Archive:  /Users/kyle/apps/wildfly-8.0.0.Final/standalone/deployments/switch.war
  Length     Date   Time    Name
 --------    ----   ----    ----
      222  03-05-14 11:25   META-INF/maven/org.nailedtothex/switch/pom.properties
     4476  03-05-14 11:25   META-INF/maven/org.nailedtothex/switch/pom.xml
      470  03-05-14 11:25   WEB-INF/web.xml
      105  03-05-14 11:23   META-INF/MANIFEST.MF
     2186  03-05-14 10:15   WEB-INF/classes/org/nailedtothex/sw/MainServlet.class
       64  03-05-14 10:15   WEB-INF/classes/common.properties
       75  03-05-14 10:15   WEB-INF/classes/env-specific.properties
       75  03-05-14 09:46   WEB-INF/classes/_dev/env-specific.properties
      158  03-04-14 22:41   WEB-INF/index.jsp
       74  03-04-14 22:34   WEB-INF/classes/_it/env-specific.properties
      433  03-04-14 22:14   _dev/WEB-INF/web.xml
        0  03-04-14 22:04   META-INF/
        0  03-04-14 22:04   META-INF/maven/
        0  03-04-14 22:04   META-INF/maven/org.nailedtothex/
        0  03-04-14 22:04   META-INF/maven/org.nailedtothex/switch/
        0  03-05-14 09:48   WEB-INF/
        0  03-04-14 22:34   WEB-INF/classes/
        0  03-04-14 22:04   WEB-INF/classes/org/
        0  03-04-14 22:04   WEB-INF/classes/org/nailedtothex/
        0  03-04-14 22:04   WEB-INF/classes/org/nailedtothex/sw/
        0  03-04-14 22:34   WEB-INF/classes/_dev/
        0  03-04-14 22:13   _dev/
        0  03-04-14 22:13   _dev/WEB-INF/
        0  03-04-14 22:34   WEB-INF/classes/_it/
        0  03-05-14 09:48   WEB-INF/lib/
 --------                   -------
     8338                   25 files
kyle-no-MacBook:switch kyle$ 

References

  1. Maven War plugin - Adding and Filtering External Web Resources
  2. maven 2 - maven2: excluding directory from WAR - Stack Overflow
  3. maven-war-pluginでファイルの除外やweb.xmlの指定など:Javaってまだいけますか
  4. Configure a Maven project for multiple target environments | Vino.java
  5. maven - Eclipse and m2e: how to automatically exclude a resource folder from JAR? - Stack Overflow
  6. Bug 388683 – maven-surefire-plugin SystemPropertyVariables ignored
  7. Properties Maven Plugin - Introduction


Filtering environment specific configuration files


Posted on Tuesday Mar 04, 2014 at 04:45PM in Technology


Environment

  • Apache Maven 3.1.1
  • Jenkins 1.551
  • Eclipse Kepler SR1
  • Oracle JDK7u51
  • PostgreSQL 9.2.4
  • OS X 10.9.2

Requirement

  • I'm searching an appropriate way to define environment specific configuration.
  • I don't want to create separate files for each environment.
  • I don't want to define environment specific information on pom.xml.

Where to define?

  • There are some candidates for achieve it with Maven.
    • Maven Properties
      • Maven can reference it as ${name}.
    • Java System Properties
      • Maven can reference it as ${name}.
    • Environment Variables
      • Maven can reference it as ${env.name}.

Maven Properties

  • User-local properties are can be defined on ~/.m2/settings.xml
  • It's easy to define on Jenkins jobs through configuration of MAVEN_OPTS.
    • We can specify it like: “-Dname=value”
  • We have to take care on Eclipse to make sure select a profile explicitly.
    • activeByDefault won't work on some cases[8].
  • I go with this way at this time.

Java System Properties

  • We need to define it through arguments of java command.
  • It's annoying to define on Eclipse.
    • I can't found any way on define globally for Run Configuration.
    • Thus, I have to configure it for each programs. It's pretty annoying.
  • It's easy to define it on Jenkins jobs through configuration of MAVEN_OPTS.
    • We can specify it like: “-Dname=value”

Environment Variables

  • We need to define it through platform-specific way.
  • But any programs can reference it through cross-platform way.
  • I guess it's more cross-platform way than Java System Properties.
  • We need a plugin[2] for Jenkins to define environment variables in jobs.
  • I guess it's not bad to achieve it.
  • But it's might not a good idea to storing security informations such as password.

Sample

  • This sample executes simple SQL which acquires the name of connected database.
  • Assume PostgreSQL is running at localhost:5432 and database named “kyle”, “testdb”, “testdb001” are exists.

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.nailedtothex</groupId>
    <artifactId>mavenprops</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

    <dependencies>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>9.3-1100-jdbc41</version>
        </dependency>
    </dependencies>

</project>

~/.m2/settings.xml

  • This defines variables of the development environment with Eclipse.
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
    <profiles>
        <profile>
            <id>development</id>
            <properties>
                <hogeApp.jdbc.url>jdbc:postgresql://localhost:5432/kyle</hogeApp.jdbc.url>
                <hogeApp.jdbc.user>kyle</hogeApp.jdbc.user>
                <hogeApp.jdbc.password>***</hogeApp.jdbc.password>
            </properties>
        </profile>
    </profiles>
</settings>

Activate the profile on Eclipse explicitly

  1. Right-click the project - Maven - Select Maven Profiles

  2. Check “development” - OK

main/resources/jdbc.properties

url=${hogeApp.jdbc.url}
user=${hogeApp.jdbc.user}
password=${hogeApp.jdbc.password}

Main.java

package mavenprops;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;

public class Main {

    public static void main(String[] args) throws Exception {
        Properties info = new Properties();
        try (InputStream is = Main.class.getResourceAsStream("/jdbc.properties")) {
            info.load(is);
        }

        try (Connection cn = DriverManager.getConnection(info.getProperty("url"), info);
                Statement st = cn.createStatement();
                ResultSet rs = st.executeQuery("select current_database()")) {
            rs.next();
            System.out.println("current_database(): " + rs.getString(1));
        }
    }
}

Run

Run on Eclipse

current_database(): kyle
  • The database specified in ~/.m2/settings.xml is shown.

Run from command-line

kyle-no-MacBook:mavenprops kyle$ mvn clean compile exec:java -Dexec.mainClass="mavenprops.Main" -DhogeApp.jdbc.url=jdbc:postgresql://localhost:5432/testdb -DhogeApp.jdbc.user=kyle -DhogeApp.jdbc.password=***
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building mavenprops 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ mavenprops ---
[INFO] Deleting /Users/kyle/Documents/workspace/mavenprops/target
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ mavenprops ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] 
[INFO] --- maven-compiler-plugin:2.5.1:compile (default-compile) @ mavenprops ---
[INFO] Compiling 1 source file to /Users/kyle/Documents/workspace/mavenprops/target/classes
[INFO] 
[INFO] >>> exec-maven-plugin:1.2.1:java (default-cli) @ mavenprops >>>
[INFO] 
[INFO] <<< exec-maven-plugin:1.2.1:java (default-cli) @ mavenprops <<<
[INFO] 
[INFO] --- exec-maven-plugin:1.2.1:java (default-cli) @ mavenprops ---
current_database(): testdb
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.333s
[INFO] Finished at: Tue Mar 04 18:25:25 JST 2014
[INFO] Final Memory: 13M/245M
[INFO] ------------------------------------------------------------------------
kyle-no-MacBook:mavenprops kyle$ 
  • The database specified at the command-line arguments is shown.
kyle-no-MacBook:mavenprops kyle$ cat target/classes/jdbc.properties 
url=jdbc:postgresql://localhost:5432/testdb
user=kyle
password=***
  • Filter worked as expectedly.

How to apply this method on Jenkins job

  • We can specify the variables on the configure of the job like this:

Build log

<===[JENKINS REMOTING CAPACITY]===>channel started
log4j:WARN No appenders could be found for logger (org.apache.commons.beanutils.converters.BooleanConverter).
log4j:WARN Please initialize the log4j system properly.
Executing Maven:  -B -f /Users/Shared/Jenkins/Home/jobs/MavenProps/workspace/mavenprops/pom.xml clean compile exec:java
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building mavenprops 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ mavenprops ---
[INFO] Deleting /Users/Shared/Jenkins/Home/jobs/MavenProps/workspace/mavenprops/target
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ mavenprops ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] 
[INFO] --- maven-compiler-plugin:2.5.1:compile (default-compile) @ mavenprops ---
[INFO] Compiling 1 source file to /Users/Shared/Jenkins/Home/jobs/MavenProps/workspace/mavenprops/target/classes
[INFO] 
[INFO] >>> exec-maven-plugin:1.2.1:java (default-cli) @ mavenprops >>>
[WARNING] Failed to getClass for org.codehaus.mojo.exec.ExecJavaMojo
[INFO] 
[INFO] <<< exec-maven-plugin:1.2.1:java (default-cli) @ mavenprops <<<
[INFO] 
[INFO] --- exec-maven-plugin:1.2.1:java (default-cli) @ mavenprops ---
current_database(): testdb001
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.472s
[INFO] Finished at: Tue Mar 04 19:08:39 JST 2014
[INFO] Final Memory: 15M/245M
[INFO] ------------------------------------------------------------------------
[JENKINS] Archiving /Users/Shared/Jenkins/Home/jobs/MavenProps/workspace/mavenprops/pom.xml to org.nailedtothex/mavenprops/0.0.1-SNAPSHOT/mavenprops-0.0.1-SNAPSHOT.pom
channel stopped
Finished: SUCCESS
  • The database specified at configured in the job is shown.

jdbc.properties on the workspace of Jenkins

  • Filter worked expectedly.

References

  1. フィルタリング
  2. EnvInject Plugin - Jenkins - Jenkins Wiki
  3. Setting the system-wide PATH environment variable in Mavericks - Ask Different
  4. HowTo: Set an Environment Variable in Mac OS X - /etc/launchd.conf - Dowd and Associates
  5. Maven Settings Example - Users | Community
  6. maven-war-pluginで環境ごとの設定ファイルを管理してみた - Challenge Java EE !
  7. I can't get maven to use properties defined in ~/.m2/settings.xml? - Stack Overflow
  8. Happy Wide Grove: Eclipse+maven+m2e+JavaFX2


Memo of useful commands


Posted on Monday Feb 24, 2014 at 10:53AM in Technology


Environment

  • Apache Maven 3.1.1

Common goals

clean

  • Delete everything at target directory

compile

  • Compile sources to class files

test

  • Run JUnit test classes

package

  • Make the JAR file or WAR file

install

  • It does “package” goal and install the package to local repository so that other Maven project can reference it.

Execute Main class

mvn exec:java -Dexec.mainClass=org.sonatype.mavenbook.weather.Main -Dexec.args="70112"

Show dependencies

Command

mvn dependency:resolve

What will we got

[INFO] The following files have been resolved:
[INFO]    com.ibm.icu:icu4j:jar:2.6.1:compile
[INFO]    xml-apis:xml-apis:jar:1.0.b2:compile
[INFO]    xerces:xmlParserAPIs:jar:2.6.2:compile
[INFO]    oro:oro:jar:2.0.8:compile
[INFO]    log4j:log4j:jar:1.2.14:compile
[INFO]    velocity:velocity:jar:1.5:compile
[INFO]    dom4j:dom4j:jar:1.6.1:compile
[INFO]    commons-lang:commons-lang:jar:2.1:compile
[INFO]    xerces:xercesImpl:jar:2.6.2:compile
[INFO]    commons-collections:commons-collections:jar:3.1:compile
[INFO]    junit:junit:jar:3.8.1:test
[INFO]    jdom:jdom:jar:1.0:compile
[INFO]    xalan:xalan:jar:2.6.0:compile
[INFO]    jaxen:jaxen:jar:1.1.1:compile
[INFO]    commons-io:commons-io:jar:1.3.2:test
[INFO]    xom:xom:jar:1.0:compile

Show dependencies in tree style

Command

mvn dependency:tree

What will we got

[INFO] org.sonatype.mavenbook.custom:simple-weather:jar:0.8-SNAPSHOT
[INFO] +- log4j:log4j:jar:1.2.14:compile
[INFO] +- dom4j:dom4j:jar:1.6.1:compile
[INFO] |  \- xml-apis:xml-apis:jar:1.0.b2:compile
[INFO] +- jaxen:jaxen:jar:1.1.1:compile
[INFO] |  +- jdom:jdom:jar:1.0:compile
[INFO] |  +- xerces:xercesImpl:jar:2.6.2:compile
[INFO] |  \- xom:xom:jar:1.0:compile
[INFO] |     +- xerces:xmlParserAPIs:jar:2.6.2:compile
[INFO] |     +- xalan:xalan:jar:2.6.0:compile
[INFO] |     \- com.ibm.icu:icu4j:jar:2.6.1:compile
[INFO] +- velocity:velocity:jar:1.5:compile
[INFO] |  +- commons-collections:commons-collections:jar:3.1:compile
[INFO] |  +- commons-lang:commons-lang:jar:2.1:compile
[INFO] |  \- oro:oro:jar:2.0.8:compile
[INFO] +- commons-io:commons-io:jar:1.3.2:test
[INFO] \- junit:junit:jar:3.8.1:test

Verbose Output

Command

mvn install -X

What will we got

  • It outputs tons of verbose information, such as why each jars are included or excluded.

How to skipping unit tests

mvn install -Dmaven.test.skip=true

Show description of a plugin

mvn help:describe -Dplugin=exec -Dfull

Create a jar with dependencies

mvn assembly:attached
  • This might need additional configuration of the plugin in the pom.xml

Run Jetty and deploy the WAR

mvn jetty:run
  • This might be useful for some proto-typing of servlet or jsp.
  • This might need additional configuration of the plugin in the pom.xml

Project Hierarchy

  • Every Maven projects can have children or its parent.
  • It's useful for declare common dependencies (using dependencyManagement) or plugins (using pluginManagement).
    • Child pom.xml can omit “version” element in dependencies that are declared in dependencyManagement of the parent pom.xml

Analyze “used undeclared” or “unused declared” dependencies

mvn dependency:analyze


How to install a Eclipse project to local repository


Posted on Sunday Feb 23, 2014 at 04:51PM in Technology


Environment

  • Apache Maven 3.1.1
  • Eclipse Kepler SR1
  • Oracle JDK7u51
  • OS X 10.9.1

Why need to do it?

  • Many kind of dependency resolving work can take on Maven.
  • It is a better way than that take it on Eclipse or IDEs.
    • It is stable and it has some efficient mechanism like local repository.
    • We can just put in Jenkins job or shell scripts.
    • It makes automation of some annoying works (e.g. build, deploy, etc) much easier.
  • Thus, in this post, I'm going to try to resolve a dependency through local repository of Maven.

Create a project

  • I'm going to install this project to local repository.
  • After install, I will try to resolve a dependency to it from another project.

Create a project

  • Create a maven project named “hogeproject” in Eclipse.
    • Check “Create a simple project (skip archetype selection)”

Edit pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.nailedtothex</groupId>
    <artifactId>hogeproject</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <properties>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
</project>

Make a class

package hogeproject;

public class Hello {

    public String hello() {
        return "hello from hogeproject";
    }
}

Install the project to Maven repository

kyle-no-MacBook:hogeproject kyle$ pwd
/Users/kyle/Documents/workspace/hogeproject
kyle-no-MacBook:hogeproject kyle$ ls -l
total 8
-rw-r--r--+ 1 kyle  staff  566  2 23 17:07 pom.xml
drwxr-xr-x+ 4 kyle  staff  136  2 23 17:01 src
drwxr-xr-x+ 7 kyle  staff  238  2 23 17:12 target
kyle-no-MacBook:hogeproject kyle$ mvn install
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building hogeproject 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ hogeproject ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:2.5.1:compile (default-compile) @ hogeproject ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ hogeproject ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:2.5.1:testCompile (default-testCompile) @ hogeproject ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ hogeproject ---
[INFO] 
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ hogeproject ---
[INFO] 
[INFO] --- maven-install-plugin:2.4:install (default-install) @ hogeproject ---
Downloading: http://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/3.0.5/plexus-utils-3.0.5.pom
Downloaded: http://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/3.0.5/plexus-utils-3.0.5.pom (3 KB at 2.3 KB/sec)
Downloading: http://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/3.0.5/plexus-utils-3.0.5.jar
Downloaded: http://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/3.0.5/plexus-utils-3.0.5.jar (226 KB at 193.3 KB/sec)
[INFO] Installing /Users/kyle/Documents/workspace/hogeproject/target/hogeproject-0.0.1-SNAPSHOT.jar to /Users/kyle/.m2/repository/org/nailedtothex/hogeproject/0.0.1-SNAPSHOT/hogeproject-0.0.1-SNAPSHOT.jar
[INFO] Installing /Users/kyle/Documents/workspace/hogeproject/pom.xml to /Users/kyle/.m2/repository/org/nailedtothex/hogeproject/0.0.1-SNAPSHOT/hogeproject-0.0.1-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.438s
[INFO] Finished at: Sun Feb 23 17:19:25 JST 2014
[INFO] Final Memory: 11M/245M
[INFO] ------------------------------------------------------------------------
kyle-no-MacBook:hogeproject kyle$ 
  • It showed that the jar file and pom.xml were placed somewhere under $HOME/.m2/repository.

Create an another project

  • Create in Eclipse same way as above. Name is “higeproject”

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.nailedtothex</groupId>
    <artifactId>higeproject</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <properties>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.nailedtothex</groupId>
            <artifactId>hogeproject</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>
  • A dependency to hogeproject is specified.

Build the package by Maven

kyle-no-MacBook:higeproject kyle$ ls -l
total 8
-rw-r--r--+ 1 kyle  staff  825  2 23 17:27 pom.xml
drwxr-xr-x+ 4 kyle  staff  136  2 23 17:23 src
drwxr-xr-x+ 9 kyle  staff  306  2 23 17:27 target
kyle-no-MacBook:higeproject kyle$ pwd
/Users/kyle/Documents/workspace/higeproject
kyle-no-MacBook:higeproject kyle$ mvn clean package
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building higeproject 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ higeproject ---
[INFO] Deleting /Users/kyle/Documents/workspace/higeproject/target
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ higeproject ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:2.5.1:compile (default-compile) @ higeproject ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ higeproject ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:2.5.1:testCompile (default-testCompile) @ higeproject ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ higeproject ---
[INFO] 
[INFO] --- maven-war-plugin:2.2:war (default-war) @ higeproject ---
[INFO] Packaging webapp
[INFO] Assembling webapp [higeproject] in [/Users/kyle/Documents/workspace/higeproject/target/higeproject-0.0.1-SNAPSHOT]
[INFO] Processing war project
[INFO] Copying webapp resources [/Users/kyle/Documents/workspace/higeproject/src/main/webapp]
[INFO] Webapp assembled in [23 msecs]
[INFO] Building war: /Users/kyle/Documents/workspace/higeproject/target/higeproject-0.0.1-SNAPSHOT.war
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.106s
[INFO] Finished at: Sun Feb 23 17:31:39 JST 2014
[INFO] Final Memory: 9M/245M
[INFO] ------------------------------------------------------------------------
kyle-no-MacBook:higeproject kyle$ unzip -l target/
classes/                        higeproject-0.0.1-SNAPSHOT/     higeproject-0.0.1-SNAPSHOT.war  maven-archiver/                 test-classes/
kyle-no-MacBook:higeproject kyle$ unzip -l target/higeproject-0.0.1-SNAPSHOT.war 
Archive:  target/higeproject-0.0.1-SNAPSHOT.war
  Length     Date   Time    Name
 --------    ----   ----    ----
        0  02-23-14 17:31   META-INF/
      129  02-23-14 17:31   META-INF/MANIFEST.MF
        0  02-23-14 17:31   WEB-INF/
        0  02-23-14 17:31   WEB-INF/classes/
        0  02-23-14 17:31   WEB-INF/lib/
     1986  02-23-14 17:12   WEB-INF/lib/hogeproject-0.0.1-SNAPSHOT.jar
        0  02-23-14 17:31   META-INF/maven/
        0  02-23-14 17:31   META-INF/maven/org.nailedtothex/
        0  02-23-14 17:31   META-INF/maven/org.nailedtothex/higeproject/
      825  02-23-14 17:27   META-INF/maven/org.nailedtothex/higeproject/pom.xml
      121  02-23-14 17:31   META-INF/maven/org.nailedtothex/higeproject/pom.properties
 --------                   -------
     3061                   11 files
kyle-no-MacBook:higeproject kyle$ 
  • We can see that the WAR contains “hogeproject-0.0.1-SNAPSHOT.jar”.

References

  1. Maven - Running Maven