Executing cmd command using Maven - maven

I want to execute this command:
zipalign [-f] [-v] <alignment> infile.apk outfile.apk
Using Maven. I have to execute this command in the Android SDK/ tools directory. Can anyone help me on how to do this? I think this can be done using batch file but I am not sure how to create a batch file. I need this command to be executed when I type "mvn clean install". Thanks

Executing commands using Maven
You can use the Maven Exec Plugin bound to the install phase.
In the snippet below, the commant ping with the argument 8.8.8.8 will be executed every time you do a mvn install:
<project>
...
<build>
<plugins>
<plugin>
<artifactId>exec-maven-plugin</artifactId>
<groupId>org.codehaus.mojo</groupId>
<version>1.2.1</version>
<executions>
<execution>
<id>My Command Runner</id>
<phase>install</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>ping</executable>
<arguments>
<argument>8.8.8.8</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
 
And that's it.
 
 
Update:
I see now what you really having trouble with is executing zipalign, not an arbitrary command. For that, there are two ways.
Using the built-in zipalign of the maven-android-plugin
As of release 2.5.0 of the Android Maven Plugin the zipalign goal is part of the plugin. To activate simply add the goal zipalign as an execution (e.g. to the package phase) and set the skip parameter in the plugin configuration to false:
<zipalign><skip>false</skip></zipalign>
Full <plugin> tag example:
<plugin>
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
<artifactId>maven-android-plugin</artifactId>
<inherited>true</inherited>
<configuration>
<sign>
<debug>false</debug>
</sign>
<zipalign>
<verbose>true</verbose>
<inputApk>${project.build.directory}/${project.artifactId}.apk</inputApk>
<outputApk>${project.build.directory}/${project.artifactId}-signed-aligned.apk
</outputApk>
</zipalign>
</configuration>
<executions>
<execution>
<id>alignApk</id>
<phase>package</phase>
<goals>
<goal>zipalign</goal>
</goals>
</execution>
</executions>
</plugin>
Sources:
Here you'll find an example using the an older version (still called android-maven-plugin);
ZipalignAPKBuiltByMAven: Describes how to automatically zipalign an APK that has been built by Maven.
Simpligility: Maven Android Plugin with zipalign and improved verification
Another example: A full pom.xml that uses the zipalign.
Zipalign using Exec-Maven Plugin
The code below will bind the functionality of zip aligning to the package phase, overwriting previous zip aligned file without asking.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1.1</version>
<executions>
<execution>
<id>zipalign</id>
<goals>
<goal>exec</goal>
</goals>
<phase>package</phase>
<configuration>
<executable>${ANDROID_HOME}/tools/zipalign</executable>
<arguments>
<argument>-f</argument>
<argument>4</argument>
<argument>target/${project.build.finalName}.apk</argument>
<argument>target/${project.build.finalName}-zipped.apk</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
Please note that this profile has to be added to the pom for the actual APK. You can't add it to a parent pom. The reason for this is that it uses the Maven property that defines the artefact name (project.build.finalName).

If you're building an Android project with Maven, you should be using the maven-android-plugn, which supports the zipalign tool directly.

Related

How to upload custom artifact after it was build using a windows bat command?

I have a windows batch file to create me a file myUser.aaa.
And I call this bat file using exec-maven-plugin
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<phase>pre-integration-test</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>scripts/MyBat.bat</executable>
</configuration>
</plugin>
</plugins>
What I want to know is how can I install the file to my repo after the MyBat.bat was executed?
I first wanted to use an mvn command from the bat file to upload it but this job gets executed from a Jenkins server and it has its own maven config. If I run mvn from the bat file it will refer to the maven on the local system.
I would suggest to use the build-helper-maven-plugin to add the supplemental artifact to your build and afterwards it will be deployed in one go with the rest which can be done like this:
<project>
...
<build>
<plugins>
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.9.1</version>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>some file</file>
<type>extension of your file </type>
<classifier>optional</classifier>
</artifact>
...
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
May be you should bind the exec-maven-plugin to an earlier phase or the build-helper-maven-plugin to a later phase. I would suggest to use prepare-package for the exec-maven-plugin. Furthermore i would suggest to use uptodate versions of the plugins.

Mule could not resolve placeholder with maven exec

I'm using maven exec plugin to run Mule 3. I have some properties that are correctly resolved when they are in my properties file, however if I try to provide them as a JVM option they do not get resolved/overridden. Below is my maven exec config:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>org.mule.MuleServer</mainClass>
<arguments>
<argument>-config</argument>
<argument>src/main/app/prioritisation-api.xml</argument>
<argument>-classpath</argument>
<argument>src/main/app</argument>
<argument>-Dmule3.http.root=http://localhost:8095</argument>
</arguments>
<classpathScope>compile</classpathScope>
</configuration>
</plugin>
I also tried using -M-Dmule3.http.root=http://localhost:8095 but that did not work.
The exec plugin has two goals java and exec. You are using the java which means:
(Excerpt from the docs):
exec:java Executes the supplied java class in the current VM with the
enclosing project's dependencies as classpath.
I would suggest to use the exec goals instead and start a separate JVM to which you can provided different parameters.

Building multiple Maven profiles for a single Jenkins job

I am trying to build multiple Maven profiles in a single Jenkins job. Each profile changes some code and then creates a jar by executing mvn -Pdev install then mvn -Pprod install in the command line (According to Maven using mvn -Pdev,prod install is supposed to work but it isn't working for me). Here are the two profiles in my project's pom.xml:
<profiles>
<!-- prod profile -->
<profile>
<id>prod</id>
<build>
<plugins>
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.2</version>
<executions>
<execution>
<phase>process-resources</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<file>src/main/java/com/IQzone/android/configuration/AbstractHoldingRefreshable.java</file>
<replacements>
<replacement>
<token>TrUe</token>
<value>TOAST_SWITCH</value>
</replacement>
</replacements>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>prod</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<!-- dev profile -->
<profile>
<id>dev</id>
<build>
<plugins>
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.2</version>
<executions>
<execution>
<phase>process-resources</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<file>src/main/java/com/IQzone/android/configuration/AbstractHoldingRefreshable.java</file>
<replacements>
<replacement>
<token>TOAST_SWITCH</token>
<value>TrUe</value>
</replacement>
</replacements>
</configuration>
</plugin>
<!-- build project with JAVA 1.6 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>dev</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
How would I setup Jenkins to automatically build both of these profiles for a single Jenkins job whenever the job is hit for a build? And put both of these jars in the Artifactory? I have very little Jenkins knowledge and there isn't much information on this on the web.
You could create a Jenkins matrix job. A matrix job allows the same job to run with changing settings (in your case: a string).
Each changing setting is called an axis. In your case you would create a string axis containing the two values: dev and prod.
That way your job would run twice, with both values.
However: your usage of profiles is dangerous. Since the profile used to run the build is not codified into your artifact, your break the "one source revision should always lead to exactly the same target artifact" contract of Maven (see: http://www.blackbuild.com/how-to-really-use-maven-profiles-without-endangering-your-karma/ for a more detailed explanation)
Consider creating either two different artifacts using classifier (-dev and -prod) or even better: create two separate modules of your build, each one creating only one of your target artifacts.
In Maven, if you use mvn -Pdev,prod, then you are activating both profiles simultaneously in one command.
It seems you want 2 distinct run of the command, i.e. something you would achieve on the command line by doing 2 builds:
mvn -Pdev install; mvn -Pprod install
In jenkins you can achieve this with either
one free style project job (with 2 shell builders running the mvn -P$PROFILE install tasks)
2 maven type jobs (that you can chain one after the other using "build after other projects are built").
In addition to Matrix job and multiple maven invocations in a free-style job, there's another way: Run top-level Maven targets as a pre-build step and run the other command via maven jenkins plugin.
Make sure that the pre-build step uses the same maven repo as the other command by supplying -Dmaven.repo.local=/${whatever-it-is}/${EXECUTOR_NUMBER}.
Please refer to other answers for details on matrix job, etc.
You can do it by setting different execution ids to each execution and then trigger the command
mvn -Pdev,prod clean package install

Running adb.exe command from maven 3.0.5

Is it possible to run adb.exe commands from maven. For example I want to run adb shell instrument -e classname#testcasename -w packagename/instrumenation. I need to run this command in maven is it possible?? Do i need to specify it in the pom.xml file or it can be run directly by specifying the command-line argument.
You can use the Maven Exec Plugin to execute cmd commands.
In the snippet below (add it to a pom.xml), the command ping with the argument 8.8.8.8 will be executed every time you do a mvn install:
<project>
...
<build>
<plugins>
<plugin>
<artifactId>exec-maven-plugin</artifactId>
<groupId>org.codehaus.mojo</groupId>
<version>1.2.1</version>
<executions>
<execution>
<id>My Command Runner</id>
<phase>install</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>ping</executable>
<arguments>
<argument>8.8.8.8</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
In your case, the inner configuration would be something around:
<configuration>
<executable>adb </executable>
<arguments>
<argument>shell</argument>
<argument>instrument</argument>
<argument>-e</argument>
<argument>classname#testcasename</argument>
<argument>-w</argument>
<argument>packagename/instrumenation</argument>
</arguments>
</configuration>
Make sure you bind it to the phase you really need. The example above, as said, is bound to the mvn install - meaning the command will be executed when someone runs that (install) phase.

Download source via maven with maven-dependency-plugin

I want to download a specific sources jar (guice-sources.jar) and I don't want it to download android sources. This would work on the terminal:
mvn dependency:sources -DincludeArtifactIds=android
and this works well too:
mvn dependency:sources -DincludeArtifactIds=guice
I config a plugin segment in the pom.xml as below,
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>default-cli</id>
<goals>
<goal>sources</goal>
</goals>
<configuration>
<includeArtifactIds>guice</includeArtifactIds>
<!--<excludeArtifactIds>android</excludeArtifactIds>-->
</configuration>
</execution>
</executions>
</plugin>
and run this,it still downloads the android jar for me
mvn dependency:sources
I have tried to move the plugin part in a pluginManagement, didn't work either.
What's wrong with it?

Resources