Running adb.exe command from maven 3.0.5 - maven

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.

Related

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.

Mvn compile before exec

I am trying to set up my POM such that when I do mvn exec:exec or mvn exec:java it will first compile the source and iff successful, execute it.
I have the following and have tried moving the <execution> part about but can't get it to work:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
<executions>
<execution>
<phase>exec</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>my.main.class</mainClass>
</configuration>
</plugin>
</plugins>
</build>
When I do either mvn exec:exec ... or mvn exec:java it doesn't first compile. I have tried putting the <execution> part in the exec plugin section but that didn't work either?
It's an old topic, but someone else might be interested in an alternative solution for this.
It's not exactly what you were looking for, but you can compile and execute using a single command:
mvn compile exec:exec
This way Maven will always compile the project before executing it.
You can bind the exec plugin to a phase following compile in build lifecycle (verify in the example below):
<profile>
<id>proxy</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<mainClass>my.main.class</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
and than run mvn verify.
I see the answer is very late and you may have found a solution.
I'm just leaving as a reference for others who may need it.
This will not quite answer the question but it will help us to accomplish the main objective you have.
Instead of executing a build goal when running the mvn exec:java we can execute the mvn exec:java when calling a 'post-build" phase/goal.
This will effectively make that phase unusable as it was because we will be substituting it by the execution but if we have a "post-build" goal that we are not using (like package or install) we can use it for the execution like so:
using package goal will end up like:
...
<properties>
...
<main.class>${project.groupId}.MainClass</main.class>
...
</properties>
...
<build>
<plugins>
...
<!-- region Forces the app to be executed when using mvn package -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<mainClass>${main.class}</mainClass>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- endregion -->
...
</plugins>
</build>
This way when we execute goal package with: mvn package the plugin will be executed and the application runned.

Executing cmd command using 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.

run java server from maven

I need to run a server(implemented in a Java class) from Maven but if I use the exec:java goal, it will block maven and it will not pass to next phases which connect to the server.
Is there any way to run the exec:java task asynchronously, without interrupting the maven execution?
Thanks!
You could use exec-maven-plugin to run shell script which would start your process and detach from it (letting process to run in background). Something like this:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<id>start-server</id>
<phase>pre-integration-test</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>src/test/scripts/run.sh</executable>
<arguments>
<argument>{server.home}/bin/server</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
Where run.sh could be like this (for U*nix platform):
#! /bin/sh
$* > /dev/null 2>&1 &
exit 0
That should do the trick.
It looks like you can do this with the antrun plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.3</version>
<configuration>
<tasks>
<java fork="true" spawn="true" classpathref="maven.runtime.classpath" className="fully.qualified.package.App"/>
</tasks>
</configuration>
</plugin>
If you're running this server class in order to run further integration testing steps in your Maven POM, then it's actually better to consider using a Continuous Integration tool such as Jenkins, it has a lot of Plugins that allows you to run your own classes, start and stop servers, deploy applications, and many other possibilities, and it's free.

Is it possible to run a Bash script from Maven?

For creating configuration of my application I need to run bash script.
Is it possible to integrate execution of Bash scripts in Maven, maybe there are some plugins?
Could the Bash Maven Plugin help you? (Disclaimer: I initiated it, so please send me feedback)
<build>
<plugins>
<plugin>
<!-- Run with:
mvn bash:run
mvn install
-->
<groupId>com.atlassian.maven.plugins</groupId>
<artifactId>bash-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<executions>
<execution>
<id>test</id>
<phase>integration-test</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<configuration>
<script>
# Here you can execute shell commands
echo "Tomcat will start"
/opt/apache-tomcat/bin/startup.sh
</script>
</configuration>
</plugin>
</plugins>
</build>
You will need to install this maven plugin in your own Maven repo.
Like Konstantin: When you execute a shell script, you're not portable anymore.
You can do this, see answer:
I want to execute shell commands from maven's pom.xml
But it is not advisable, as this produces not so portable builds. Why do you need this in first place? Using this plugin usually indicates some weird necessity in project build
Would look more like:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>generateSources</id>
<phase>generate-sources</phase>
<configuration>
<tasks>
<exec executable="/bin/bash">
<arg value="myFirst.sh" />
<arg value="inputOne" />
</exec>
<exec executable="/bin/bash">
<arg value="src/mySecond.sh" />
<arg value="inputTwo" />
</exec>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
With myFirst.sh:
echo "call to myFirst.sh, message ${1}"
Solved. The problem is, executable is working in a different way for bash. This code is working. Write it in pom.xml
<plugin>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<groupId>org.codehaus.mojo</groupId>
<executions>
<execution><!-- Run our version calculation script -->
<id>Renaming build artifacts</id>
<phase>package</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>bash</executable>
<commandlineArgs>handleResultJars.sh</commandlineArgs>
</configuration>
</execution>
</executions>
</plugin>
If at all possible, I'd recommend using a scripting language that runs inside the JVM with dependencies that are captured either in your project or in the maven repository. That way your builds are platform independent and your dependencies are captured (i.e. you don't loose the build machine and realize your bash script was specific to that box). I showed an example in this post of using jacl. There are also good examples of using javascript and groovy inside antrun (though there may be more straightforward ways of calling them directly).
Use the maven-antrun-plugin artifact. This way, you can execute several executables sequentially more easily than exec-maven-plugin. Example:
* The <exec> tag is the important one here.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>generate-sources</phase>
<configuration>
<tasks>
<exec executable="my1.sh">
<arg value="input1"/>
</exec>
<exec executable="my2.sh">
<arg value="input2"/>
</exec>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
To experiment with commands you can use exec:exec:
$ mvn exec:exec -q -Dexec.executable=echo -Dexec.args="your arguments"
your arguments
$ mvn exec:exec -q -Dexec.executable=echo -Dexec.args="'your arguments'"
your arguments
This demonstrates:
passing arguments: if you need to pass several arguments: just split them with space
if you need to pass an argument with spaces: enclose it in quotes, as you would do in bash script/terminal
-q to shut up the mvn log

Resources