run java server from maven - 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.

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.

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.

Using sbt from maven

I have a maven project and an SBT project as a module of the maven project. I need to create a single command maven build, which executes SBT package task too.
Is there any plugin which I can use to integrate SBT with maven?
Thanks.
One option is using "Exec Maven Plugin", and here is an example to do a "play compile"
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>${path.to.play}</executable>
<workingDirectory>${path.to.project.root}</workingDirectory>
<arguments>
<argument>compile</argument>
</arguments>
</configuration>
</plugin>
Use the maven antrun plugin (my example is for building a Scala.js app).
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>pre-integration-test</phase>
<configuration>
<target>
<exec executable="cmd.exe"
spawn="true">
<arg value="/c"/>
<arg value="C:\Program Files (x86)\sbt\bin\sbt.bat"/>
<arg value="fullOptJS"/>
</exec>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
Credit due to #checat for suggesting this in his comment and the discussion at Launching a windows batch script using Maven exec plugin blocks the build even though the script uses "start"
Other thoughts; it might still be worth using mvn-exec on non Windows systems, perhaps using maven profiles. If I go this route, I'll try to remember to update the answer.

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.

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