Performing simple tasks with Maven and Java

Java

Sometimes I need a small tool to perform a simple task for me. One recent example is a simple test client that sends a SOAP request that in an integrated environment would be sent by an external party. The client needs to send an ID and the outcome (accepted/rejected) of a request that was sent in a previous stage.

Now, there are several ways to achieve this. You could write a full web-based GUI, or, on the other end of the spectrum, use a tool like Boomerang. But if you’re already using Maven, you should also consider using the Exec Maven plugin.

The Exec plugin is an easy way to execute some code; it is lot faster to set up than a standalone application, but you are still able to access normal Maven dependencies.

Setting it up

You can use this in an existing project or create a new project. Since my client is basically test code, I created a new project that depends on the project that contains the application code.

java
<project>
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>eu.luminis.mvnexec</groupId>
        <artifactId>parent</artifactId>
        <version>1.0.0</version>
    </parent>
    <artifactId>mvn-exec-example</artifactId>
    <name>Exec Maven plugin example</name>
    <dependencies>
        <dependency>
            <groupId>eu.luminis.mvnexec</groupId>
            <artifactId>services</artifactId>
            <version>1.0.0</version>
        </dependency>
    </dependencies>
</project>

Add an executable class to the project that performs the action you need. You can use the standard arguments array if you need paramaters. My class takes three parameters: a customer ID, the outcome, and the endpoint URL. It then performs a SOAP call and prints the results to the console.

java
package eu.luminis.mvnexec.client;

import eu.luminis.mvnexec.services.*;

import javax.xml.ws.BindingProvider;
import java.math.BigInteger;

public class SoapClient {

    private final LuminisService service;

    public static void main(final String[] args) {
        final String url = args[2];
        final SoapClient client = new SoapClient(url);
        final ServiceRequest request = new ServiceRequest();
        request.setCustomerId(BigInteger.valueOf(Long.parseLong(args[0])));
        request.setOutcome(Outcome.valueOf(args[1]));
        final ServiceResponse response = client.updateCustomer(request);
        System.out.println("Status: " + response.getStatus());
        System.out.println("Message: " + response.getMessage());
    }
    
    public SoapClient(final String endpointUrl) {
        service = new LumninisService();
        this.endpointUrl = endpointUrl;
    }
    
    public ServiceResponse updateCustomer(final ServiceRequest request) {
        return getPort().updateCustomer(request);
    }

    private LuminisPort getPort() {
        final LuminisPort port = service.getLuminisPort();
        final BindingProvider bp = (BindingProvider) port;
        bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointUrl);
        return port;
    }
}

Add the Exec plugin to your pom; if you want to use arguments, you must specify them in the configuration of the plugin. With the classpath tag you automatically add all project dependencies to the classpath.

java
<project>
  ...  
  <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.3.2</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>exec</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <executable>java</executable>
                    <arguments>
                        <argument>-classpath</argument>
                        <classpath />
                        <argument>eu.luminis.mvnexec.client.SoapClient</argument>
                        <argument>${customerId}</argument>
                        <argument>${outcome}</argument>
                        <argument>${serviceUrl}</argument>
                    </arguments>
                </configuration>
            </plugin>
        </plugins>
    </build>
    ...
</project>

Running your code

Run the code by calling the exec:exec goal and providing the parameters you defined in the pom. You must provide all parameters that you defined!

java
mvn exec:exec -DcustomerId=1234 -Doutcome=REJECTED -DserviceUrl=http://localhost:8080/services/soap

If one of the parameters is (almost) always the same for the user, you could define the value as a property in the user's Maven settings file (user_home/.m2/settings.xml) so you don't have to provide it every time you execute the code.

java
 <settings>
      <profiles>
        <profile>
          <id>inject-services-url</id>
          <properties>
            <serviceUrl>http://localhost:8080/services/soap</serviceUrl>
          </properties>
        </profile>
      </profiles>

      <activeProfiles>
        <activeProfile>inject-services-url</activeProfile>
      </activeProfiles>
    </settings>

You can still override the property by providing it to the Exec goal as before.

Java