Incomplete WAR automatically uploaded by Maven - maven

To ease up the deployment process of my Jave EE application, I instructed Maven to automatically copy the resulting WAR file to the application server.
pom.xml:
<plugin>
<artifactId>exec-maven-plugin</artifactId>
<groupId>org.codehaus.mojo</groupId>
<executions>
<execution><!-- Run our version calculation script -->
<id>Copy to Application Server</id>
<phase>generate-sources</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>${basedir}/copy-to-appserver.sh</executable>
</configuration>
</execution>
</executions>
</plugin>
copy-to-appserver.sh:
scp /home/user/.m2/repository/com/wolf/apix/1.0/apix-1.0.war user#srv-web:/opt/wildfly-8.2.0.Final/standalone/deployments/apix.war
Unfortunately, this fails! The WAR is successfully transmitted to the application server, but it's mixed with old and new code. My assumption is that Maven tries to send it while still being in the WAR creation process, because when I run the copy script copy-to-appserver.sh manually after the deployment, everything works fine with it on the application server.
My question is, what do I have to change, so that Maven only accesses the WAR file when its creation / manipulation is complete?

Your plugin is being executed prematurely in the generate-sources phase
Run it in the last phase by changing the phase to deploy
<phase>deploy</phase>

In addition running the plugin in the correct phase, as suggested by 6ton, you might also want to consider using the Maven WildFly plugin, which specifically designed to solve your problem. That way, you can get rid of that nasty, nasty script.

I would recommend to separate the build process and the deployment process cause the deploy life cycle phase is intended to upload the artifacts to a remote repository.

Related

Spark Maven and Jar Development Workflow with local and remote server

So I have a very basic question about how to most effectively work with a local spark environment along with a remote server deployment and despite all of the various pieces of info about this, I still don't find any of them very clear.
I have my IntelliJ environment and dependencies in need within my pom to be able to compile and run and test with my local within intellij. Then I want to test and run against a remote server by copying over my packaged jar file via scp to then run spark-submits.
But I don't need any of the dependencies from maven within my pom file since spark-submit will just use the software on the server anyway so really I just need a jar file with the classes and keeping it very lightweight for the scp would be best. Not sure if I'm mis-understanding this but now I just need to figure out how to exclude any dependency from being added to the jar during packaging. What is the right way to do that?
Update:
So I managed to create a jar with and without dependencies using the below and I could just upload the one without any dependencies to server after building but how can I build only one jar file without any dependencies rather than waiting for a larger jar with everything which I don't need anyway:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Two things here.
The provided dependency scope will allow you to work locally and prevent any server provided libraries from being packaged.
Maven doesn't package external libraries without creating an uber or shaded jar.
An example of a good Spark POM is provided by Databricks
Also worth mentioning, Maven copy local file to remote server using SSH
See Maven Wagon SSH plugin

What does "echo" mean when it comes to using Maven?

I'm currently learning how to use Maven and have encountered a term called "echo". I was just wondering what it actually means?
There are few important concepts related to Maven Lifecycles, which
are worth to mention:
1) When a phase is called via Maven command, for example mvn compile,
only phases up to and including that phase will execute.
2) Different maven goals will be bound to different phases of Maven
lifecycle depending upon the type of packaging (JAR / WAR / EAR).
In the following example, we will attach maven-antrun-plugin:run goal
to few of the phases of Build lifecycle. This will allow us to echo
text messages displaying the phases of the lifecycle.
echo is an ant task which allow to print messages to console (system.out)
This makes sense when using maven-antrun-plugin which allow to execute ant tasks in a maven build.
It can be used to print some maven properties during the build as there is no built-in way to output value to console in maven.
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>${maven.antrun.plugin.version}</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>Configuration properties :</echo>
<echo>service.endpoint=${service.endpoint}</echo>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
It means to use echo tag in ant script executed by maven-antrun-plugin:run. Nothing directly related to maven itself.

Automatically publish JavaDoc as a functioning website on remote machine

Is there a way of automatically publishing as live website javadocs after uploading it to Nexus Maven repository? I have some packages, which are under constant development and I'd like to have the docs for them available for browsing by other team members straight after uploading updated code to our remote repository.
Is there any ready solution for doing that or would I have to write say a shell script (executed by Maven after successfull deployment of the code to the remote repo), which would copy the docs to a remote location on a web server?
I know that Nexus Professional allows to view javadocs out of the box, but even for 10 users it is a bit pricey, so I'd appreciate a different solution :-)
I'm using Eclipse#Windows + Maven 2.
Thanks!
If your project is open-source and is released to Maven Central then your javadoc will be available at javadoc.io automatically.
The url is of the form: http://www.javadoc.io/doc/[groupId]/[artifactId]. For example, I have my javadoc for my project at www.javadoc.io/doc/me.ramswaroop.jbot/jbot
Nexus Open Source as well as Nexus Professional support the site repository format, which allows you to host Maven produced sites. If you set up publishing a Maven site that includes Javadoc as part of your build you can have them accessible there.
The other thing you can do is just publish javadoc and source artifacts as part of you build and then Eclipse will be able to automatically download them from Nexus and you therefore wont even need a website with the javadoc on it for you developers.
Of course other people might want the site though.
Documentation on all that is available in the Nexus book as usual.
A bit late for reply, but someone else might need it in future. I didn't try the solution you proposed instead using one utilizing Maven Wagon plugin. Basically I first upload the jar with javadoc to webserver using sftp protocol and then unzip it using ssh command.
So parts of my parent POM, which configure the plugin look as follows:
<pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>wagon-maven-plugin</artifactId>
<executions>
<execution>
<id>upload-javadoc</id>
<phase>deploy</phase>
<goals>
<goal>upload</goal>
</goals>
<configuration>
<serverId>my_id</serverId>
<fromDir>${local.dir}</fromDir>
<includes>${javaDoc.file}</includes>
<excludes>pom.xml</excludes>
<url>${remote.url}</url>
<toDir>${remote.dir}</toDir>
</configuration>
</execution>
<execution>
<id>execute-test-commands</id>
<phase>deploy</phase>
<goals>
<goal>sshexec</goal>
</goals>
<configuration>
<serverId>my_id</serverId>
<url>${remote.url}</url>
<commands>
<command>mkdir -p ${www.dir}</command>
<command>unzip -o ${remote.dir}/${javaDoc.file} -d ${www.dir} > latest_unzip_log.txt</command>
</commands>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
And then just call the plugin in child pom:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
</plugins>
So that's my solution, but I guess Manfred's is much simpler.
Ps.
Having the Javadoc available only in Ecplise (which I do anyways) was not the goal as the purpose was for the Javadoc to be available for other project members through a website.
Another option to host javadocs is https://docshoster.org/. It can automatically pickup from maven. There is an api to upload directly as well.

run calabash-android tests during Maven build

First off, I suspect this isn't going to be easy, because there isn't an entry for calabash-android in the Maven central repository and the calabash-android project doesn't provide one.
That being said, does anyone know how to manage calabash-android tests during a Maven build? Are there any plugins for this? I can't find any, but in the off chance my google-fu has failed me or there's a workaround... I'd love to hear about it.
[edit] I'm using the maven-android plugin for the apk build.
I am assuming you are familiar with the Android Maven plugin? If not, you should check it out. Here is a method that is not bulletproof, but should work:
1- Start by writing a shell script that launches the Calabash tests. This shell script, say calabash.sh, wouldn't be too complicated, just something along the lines of:
calabash-android run ../target/<app>.apk /path/to/calabash/tests
2- Launch this script once maven has finished its integration-test phase (if you are using Android Maven, that's when you run your unit tests). This is taken from this SO question:
<plugin>
<artifactId>exec-maven-plugin</artifactId>
<groupId>org.codehaus.mojo</groupId>
<executions>
<execution>
<id>Version Calculation</id>
<phase>validate</phase> //This occurs [after integration-test][3]
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>${basedir}/scripts/calabash.sh</executable>
</configuration>
</execution>
</executions>
</plugin>
This is not a bulletproof solution because I suspect that Maven cannot report any calabash test failures. Also, you might need to add some bash magic to make the script run until completion before Maven finishes building.

How should I get Maven to deploy artifacts for all supported architectures at the same time?

I have a question that's probably pretty similar to this. I need to solve what I have to imagine to be a pretty common problem -- how to configure Maven to produce multiple variations on the same artifact -- but I have yet to find a good solution.
I have a multi-module project, that eventually results in the assembly plugin generating an artifact. However, part of the assembly includes libraries that have changed substantially in the recent past, with the result that some consumers of the project need library version N, while others need version N+1. Ideally, we'd just automatically generate multiple artifacts, e.g. theproject-1.2.3.thelib-1.0.tar.gz, theproject-1.2.3.thelib-1.1.tar.gz, etc. (where that's release 1.2.3 of our project, running against either library version 1.0 or 1.1).
Right now, I have a bunch of default properties, which build against the latest version of the library in question, plus a profile to build against the older version. I can deploy one or the other this way, but cannot deploy both in one build. Here's the key wrinkle that differs from the above question: I can't automate build-one-clean-build-the-other inside of the release plugin.
Normally, we'd mvn release:prepare release:perform from the root of the multi-module project to take care of deploying everything to our internal Nexus. However, in that case, we have to pick one -- either run the old-library profile, or run without and get the new one. I need the release plugin to deploy both. Is this just impossible? I have to imagine we're not the first people who want to have our automated builds generate support for different platforms....
You may install additional artifacts with differrent types/classifiers. Use attach-artifact goal of the build-helper-maven-plugin to achieve this. Here is a small example - we are deploying a Windows and a Unix installers of the product as windows/exe and unix/sh files. These files will be installed to the local repo and deploy to the distribution management.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>install-installation</id>
<phase>install</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${basedir}/target/${project.artifactId}-${project.version}-windows.exe</file>
<classifier>windows</classifier>
<type>exe</type>
</artifact>
<artifact>
<file>${basedir}/target/${project.artifactId}-${project.version}-unix.sh</file>
<classifier>unix</classifier>
<type>sh</type>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
Hope this helps.

Resources