Maven copy local file to remote server using SSH - maven-2

Can Maven copy local file to a remote server using SSH?
I want to specify location in maven configuration file and to copy that file (or files) to server each time deploy phase is executed.

The maven-deploy-plugin allows you to configure the deploy phase to deploy to a server using scp. There is a page in the documentation that describes how it can be done.
I believe this will replace the normal deployment instead of add to it, so it may not be what you're after.
If you need to deploy to a traditional Maven repository as well as deliver the file to the remote server, you will need to use the scp task as the other answers suggest.
In this answer I've described how to configure the ftp task, the scp task is almost identical except you may need to add the keyfile and passphrase attributes (and change the task name from ftp to scp obviously).

Have a look at Maven Wagon plugin
To try it manually with a simple command line: mvn org.codehaus.mojo:wagon-maven-plugin:1.0:upload -Dwagon.url=scp://username:userpassword#myserver -Dwagon.fromDir=target -Dwagon.includes=*.ear -Dwagon.toDir=/home/elisabetta
In both cases, be sure to add the SSH extension for Wagon to your pom.xml:
<extensions>
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ssh</artifactId>
<version>2.8</version>
</extension>
</extensions>

Why not use the Ant SCP task, which you can run within Maven?

Same idea as PaoloC, using Maven Wagon plugin with the wagon-ssh extension, but configuration in pom file and run it on specified phase, this examples copies the war file to a remote server with SSH:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>wagon-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<id>upload-to-myserver</id>
<phase>deploy</phase>
<goals>
<goal>upload-single</goal>
</goals>
<configuration>
<fromFile>${project.build.directory}/${project.build.finalName}.war</fromFile>
<url>scp://username#myserver/path</url>
</configuration>
</execution>
</executions>
</plugin>
<!-- other plugins ... -->
</plugins>
<extensions>
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ssh</artifactId>
<version>2.8</version>
</extension>
</extensions>
</build>
The <phase> tag is optional. You can run just the upload execution with the command:
mvn wagon:upload-single#upload-to-myserver

Maven is not a generic tool, it's a tool to make your build process reusable. I suggest to use an embedded antrun build step. In this step, you can do anything using the normal ant syntax which you'd use in build.xml.

Although this question is not exactly new, I found myself in a similar situation today. My goal is to upload files and run commands on a remote server to which I have to tunnel (through another server). I managed to forge a solution for that with ant (which again can be triggered from maven as mentioned here).
Ants sshsession task only creates a tunnel that you can use for the tasks within. The tasks within are not automatically run on the remote server but you can use the sshexec task together with the tunnel to achieve that. Also the scp task can now upload through the tunnel to the remote server. Here is an example:
<sshsession host="${jumphost}" port="22" username="${user}" password="${password}" trust="true">
<localtunnel lport="${localTunnelPort}" rhost="${targethost}" rport="22"/>
<sequential>
<!-- run a command on the remote server (here mkdir) -->
<sshexec host="localhost" port="${localTunnelPort}" username="${user.param}" password="${password.param}" command="mkdir ${home}/foobar" trust="true" />
<!-- upload a file to the remote server -->
<scp port="${localTunnelPort}" file="test_file.txt" todir="${user.param}:${password.param}#localhost:${home}/foobar/" trust="true" />
</sequential>
</sshsession>

Related

Arquillian and Open Liberty requires existing installation?

I'm familiar with Tomcat/TomEE and testing applications using Arquillian. Now were are switching to Open Liberty. I see there is a module for Arquillian using embedded Open Liberty but it seems to require an existing Open Liberty installation whose path is provided in the configuration. This makes it non-portable and therefore unsuitable for automated testing since the installation has to be present at the exact same path. Arquillian and TomEE are self-contained, no installation required. Therefore my question is why this isn't also possible with Open Liberty? And is this planned for the future?
For reference this is how you use Arquillian with TomEE/Tomcat:
<arquillian xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://jboss.org/schema/arquillian"
xsi:schemaLocation="http://jboss.org/schema/arquillian http://www.jboss.org/schema/arquillian/arquillian_1_0.xsd">
<container qualifier="tomee" default="true">
<configuration>
<property name="httpPort">-1</property>
<property name="stopPort">-1</property>
<property name="users">user=pass</property>
</configuration>
</container>
</arquillian>
As you can see, there is no path to a local installation required to run the tests. The only thing you need to do is a add a couple of Maven dependencies in test scope that pull in TomEE (embedded). If the same would work for Open Liberty that would be great.
Going further..so the above is how we do automated testing
but it still uses the location.
I see, regarding not needing any location specified at all, you say:
"The only thing you need to do is a add a couple of Maven dependencies in test scope that pull in TomEE (embedded). If the same would work for Open Liberty that would be great."
So, thinking, maven will put a bunch of classes on the classpath due to the TomEE
dependancies and then the test run will find the appropriate container to
run the tests on.
I will raise an issue over on
https://github.com/OpenLiberty/liberty-arquillian/issues/39
to cover the requirement please feel free to add remarks etc.
If you have a look at https://github.com/OpenLiberty/open-liberty/blob/integration/dev/com.ibm.ws.microprofile.config.1.2_fat_tck/publish/tckRunner/tck/src/test/resources/arquillian.xml
you will see an example arquillian.xml that sets $wlpHome
<property name="wlpHome">${wlp}</property>
from an environment variable $wlp.
('wlp' is short for Websphere Liberty Profile)
The wlpHome variable is used in the managed/local container here:
https://github.com/OpenLiberty/liberty-arquillian/blob/42cb523b8ae6596a00f2e1793e460a910d863625/liberty-managed/src/main/java/io/openliberty/arquillian/managed/WLPManagedContainer.java#L224
An example that does this dynamically is the setting of the
system property ${wlp} here:
https://github.com/OpenLiberty/open-liberty/blob/95c266d4d6aa57cf32b589e7c9d8b39888176e91/dev/fattest.simplicity/src/componenttest/topology/utils/MvnUtils.java#L161
If you have any more queries please post them...
and hope you love OpenLiberty - it rocks!
Gordon
The result you seem to be trying to achieve is a embedded runtime for liberty using arquillian. However, all as far as I can see, the openliberty team only provides a remote container adapter and a managed container adapter at the moment.
With us having a similar need, wanting to run automated integration tests where we wouldnt necessarily have a Openliberty server in-place. We managed to work-around this using liberty-maven-plugin.
The build/testing process would then be:
Running mvn verify, liberty-maven-plugin would generate the specified openliberty which we want to run our tests against.
<plugin>
<groupId>net.wasdev.wlp.maven.plugins</groupId>
<artifactId>liberty-maven-plugin</artifactId>
<version>${version.liberty-maven-plugin}</version> <!-- plugin version -->
<configuration>
<assemblyArtifact> <!-- Liberty server to run test against -->
<groupId>io.openliberty</groupId>
<artifactId>openliberty-runtime</artifactId>
<version>18.0.0.4</version>
<type>zip</type>
</assemblyArtifact>
<configDirectory>src/liberty/${env}/</configDirectory>
<configFile>src/liberty/server.xml</configFile>
<serverName>defaultServer</serverName>
</configuration>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>create-server</goal>
</goals>
</execution>
</executions>
</plugin>
As liberty-maven-plugin per default adds the Liberty server to the target/folder
<arquillian xmlns="http://jboss.org/schema/arquillian">
<container qualifier="liberty-managed" default="true">
<configuration>
<property name="wlpHome">target/liberty/wlp</property>
<property name="serverName">defaultServer</property>
</configuration>
</container>
</arquillian>
This way we can assure that a runnable liberty server according to our liking is always existant in our local environment or e.g. our Jenkins CI/CD Server, essentially getting the same effect as having a embedded container.

Apache ServiceMix 5.x full version

I need to run Apache ServiceMix on servers with no direct connection to the internet. I am unable to find a "full" assembly for Apache ServiceMix 5.1.4. An older version of ServiceMix (4.5.3) has a full version available for download.
Is a full version of 5.1.4 is available and if so where?
http://servicemix.apache.org/downloads/servicemix-5.1.4.html
http://servicemix.apache.org/downloads/servicemix-4.5.3.html
Starting with ServiceMix 5.0.0 we have removed the full and minimal assemblies and we provide only the default assembly which only includes bundles used by default boot features (please see discussion under http://servicemix.396122.n5.nabble.com/DISCUSS-Which-assemblies-to-keep-around-td5719173.html)
If you have a project you want to deploy on the ServiceMix, you can add a new module to your project that runs the add-features-to-repo goal of the features-maven-plugin and zips everything up. Next you can deliver the zip file with all the bundles for
all the features you need to install on ServiceMix.
Thanks to KSobkowiak's answer which pointed me in the right direction. I am posting the steps I used to get a custom ServiceMix 5.x up and running in case anyone else needs to do the same. The instructions assume Linux, but windows steps should be similar.
1) Download and unzip ServiceMix and Maven
cd /opt
unzip apache-servicemix-5.1.4.zip
unzip apache-maven-3.0.3.zip
2) Configure maven proxy, if needed:
3) Create a maven project directory
mkdir serviceMix_features
cd serviceMix_features
4) Create a maven pom file with the following xml. I got the list of descriptors by running features:listurl command in the servicemix console. The features would be whatever you need in your custom servicemix distro, in this case I am adding the webconsole and several camel components.
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>my.group</groupId>
<artifactId>custom-servicemix</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<name>My custom service mix repository</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.karaf.tooling</groupId>
<artifactId>features-maven-plugin</artifactId>
<version>2.3.9</version>
<executions>
<execution>
<id>add-features-to-repo</id>
<phase>generate-resources</phase>
<goals>
<goal>add-features-to-repo</goal>
</goals>
<configuration>
<descriptors>
<descriptor>mvn:org.apache.camel.karaf/apache-camel/2.13.3/xml/features</descriptor>
<descriptor>mvn:org.apache.servicemix/apache-servicemix/5.1.4/xml/internal</descriptor>
<descriptor>mvn:org.apache.activemq/activemq-karaf/5.10.0/xml/features</descriptor>
<descriptor>mvn:org.apache.karaf.assemblies.features/standard/2.3.9/xml/features</descriptor>
<descriptor>mvn:org.apache.karaf.assemblies.features/enterprise/2.3.9/xml/features</descriptor>
<descriptor>mvn:org.apache.jclouds.karaf/jclouds-karaf/1.7.2/xml/features</descriptor>
<descriptor>mvn:org.apache.cxf.karaf/apache-cxf/2.7.13/xml/features</descriptor>
<descriptor>mvn:org.apache.servicemix/apache-servicemix/5.1.4/xml/features</descriptor>
<descriptor>mvn:org.apache.servicemix/apache-servicemix/5.1.4/xml/examples</descriptor>
<descriptor>mvn:org.ops4j.pax.cdi/pax-cdi-features/0.8.0/xml/features</descriptor>
<descriptor>mvn:org.apache.activemq/activemq-karaf/5.10.0/xml/features-core</descriptor>
</descriptors>
<features>
<feature>webconsole</feature>
<feature>camel-restlet</feature>
<feature>camel-jackson</feature>
</features>
<repository>target/features-repo</repository>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
5) Execute the maven project. I noticed that sometimes maven would get part way through and fail. After retrying, I noticed that it pulled in additional jars each run, and finnally succeeded on the fourth try.
/opt/apache-maven-3.0.3/bin/mvn install
6) Overlay the maven files on the default service mix distro.
cp -Rvn target/features_repo/* /opt/apache-servicemix-5.1.4/system/
7) zip or tar your custom service mix distro and move it where you need to. If you were using a proxy, you can deconfigure the maven proxy and clear your maven repo to verify service mix was correctly updated from the service mix console.
features:install webconsole
You can find all releases from ASF from the Apache archive. For ServiceMix it is here: http://archive.apache.org/dist/servicemix/

Unable to Deploy to Tomcat using Maven3 with Mail API

I am working on an application where we need to use java mail functionality. We have started using maven 3.x as out build tool.
Everything was working fine till Java Mail API has not been introduced. We are using Eclipse with M2Eclipse plugin but most of our deployment work is being done by maven Command line.
We have introduced following dependency in our pom.xml and I have verify that both mail.jar and activation.jar are in there respected folder structure.
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4</version>
</dependency>
We tried the following command
> mvn clean
and then
>mvn tomcat:deploy
Though maven is showing that it has successfully deployed war on the tomcat but tomcat console showing that it is failing to deploy application and in other successful cases we are facing a strange issue, as we are using hibernate for persistance layer so on examing the folder structure it came out that the mapping file .hbm files are missing due to which Session factory is not creating and server is not able to startup.
Here is the snap shot of plugin entry
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<packagingExcludes>WEB-INF/web.xml</packagingExcludes>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<configuration>
<warFile>${project.build.directory}/${project.build.finalName}.war</warFile>
<url>http://localhost:8080/manager/html</url>
<server>localhost</server>
<path>/blood_donor</path>
</configuration>
</plugin>
From you procedure I see:
mvn clean - that deletes target directory with your build
mvn tomcat:deploy - should take the build (which was deleted with mvn clean) and deploy it on tomcat
There is no build phase. So use instead mvn clean package tomcat:deploy. If your application is already deployed in tomcat try mvn clean package tomcat:redeploy. For details check plugin documentation.
Which Tomcat version do you use?
According to http://repo1.maven.org/maven2/org/codehaus/mojo/tomcat-maven-plugin/ you use the version 1.1. In the plugin documentation you can find there that Tomcat 7 is not supported in this version. For that you must upgrade to version 2.0. See http://tomcat.apache.org/maven-plugin-2.0-SNAPSHOT/
Probably yo

Maven2: Cargo plugin hot deployment & Jonas support

I am trying to get the Cargo plugin works on my maven project in order to benefit from war hot-deployment targetting the Jonas server.
The official documentation is not that clear on what is supported and what is not (for example you can find this: http://cargo.codehaus.org/Hot+Deployment but also this http://cargo.codehaus.org/JOnAS+4.x).
Anyway I have the following coniguration in for my war's POM:
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.0</version>
<configuration>
<container>
<containerId>jonas4x</containerId>
<home>C:\JOnAS-4.8.4\nt\bin</home>
</container>
<configuration>
<type>existing</type>
<home>C:\JOnAS-4.8.4</home>
</configuration>
</configuration>
</plugin>
And when I run
mvn cargo:deploy
on my project, the war is copied to the Jonas webapps folder but there is no hot deployment. The file is only copied but the hot deploy Jonas command is not called so that my modifications are not available immediatly.
EDIT: I also tried to add a deployer configuration as suggested on the answers but the behaviour is the same (ie: war is copied but the Jonas hot deploy command is not called so that the war is not reloaded in Jonas).
Am I missing something or am I right saying the Cargo Maven plugin does not support Jonas Hot Deployement?
Thanks in advance!
The cargo page on deploying to a running container links to a table listing the version where hot deployment was introduced for that container. According to the table, JOnAS 4.x is supported from version 1.0 (which you are using), so it should work.
On that page it also has some guidelines for configuring the plugin for deployment, I've attempted to interpret them below.
From the home element in your configuration I assume you are attempting a local deployment. The configuration in the running container page implies that the hot-deployment should be automatic in this line at the end:
Just type mvn cargo:deploy. Notice that we haven't specified a element nor a one. This is because the plugin is smart enough to create default instances for you. Cool, isn't it?
However the earlier configuration block indicates you should configure the deployer section to make the cargo plugin aware of the war to be deployed. The configuration for the deployer would be something like this:
<deployer>
<type>local</type>
<deployables>
<deployable>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<type>war</type>
<properties>
<context>optional root context</context>
</properties>
<pingURL>optional url to ping to know if deployable is done or not</pingURL>
<pingTimeout>optional timeout to ping (default 20000 milliseconds)</pingTimeout>
</deployable>
</deployables>
</deployer>
If the automatic option isn't working for you, consider declaring the configuration for your war.

How do I deploy multiple peer webapps from a parent pom

I have a set of web apps that I manage that I am trying to move to maven.
/pom.xml // parent pom
webapp1/pom.xml // configured to point to parent
webapp2/pom.xml // peer of webapp1 and points to parent.
each of the webapps refers to the parent pom, and they both currently have a jetty maven plugin that works.
My question is how do I mount each of the webapps from the parent pom such that mvn jetty:run works in the parent directory?
edit to anwer: Pascal T
The issue is not so much that I'm getting an error when I try and run the command from the root pom, but that I'm not sure how to configure it.
for example the webapp1/pom.xml
looks like:
<project>
...
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
</plugin>
</plugins>
...
</project>
changing to this directory and typing mvn jetty:run works just fine and affords me the ability to hit: http://localhost:8080/webapp1.
However, what I would like would be to be in the parent of webapp1, and run all 'n' webapps from the parent directory. Thus having http://localhost:8080/webapp1, and http://localhost:8080/webapp2 available with one command line parameter.
btw, if the answer involved a tomcat plugin, that would be fine.
EDIT: I've totally edited my first answer now that I have a better understanding of the OP's expectations.
Check out Cargo, a thin wrapper that allows you to manipulate Java EE containers in a standard way.
Actually, there is a tutorial on Cargo's website that demonstrates how to use the Cargo Maven2 plugin to automatically start/stop a container (possibly deploying some deployables to it as it starts), which is what you're looking for from what I've understood.
I'm just not sure that doing this from the parent directory is feasible and if it's a requirement or if it would be ok to do it from another directory. I'll come back on this later. Lets first take a look at the Cargo Maven2 plugin setup.
In your case, you can start with the minimal configuration (that uses Jetty 5.x which is Cargo's default container):
[...]
<build>
<plugins>
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
</plugin>
</plugins>
</build>
[...]
If you want to use Jetty 6.x, you'll have to specify <containerId> and <type> in the <container> element:
[...]
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<configuration>
<container>
<containerId>jetty6x</containerId>
<type>embedded</type>
</container>
</configuration>
</plugin>
[...]
Then, add the modules you want to deploy by defining deployables explicitly inside the plugin configuration (refer to the Maven2 Plugin Reference Guide for the details of the configuration) :
<deployables>
<deployable>
<groupId>com.mycompany.myproject</groupId>
<artifactId>myproject-alpha</artifactId>
<type>war</type>
<properties>
<context>optional alpha root context</context>
</properties>
</deployable>
<deployable>
<groupId>com.mycompany.myproject</groupId>
<artifactId>myproject-beta</artifactId>
<type>war</type>
<properties>
<context>optional beta root context</context>
</properties>
</deployable>
[...]
</deployables>
With this, you should be able to start Jetty and have your webapps deployed on it with a simple (to run from the project containing the cargo plugin configuration):
$ mvn cargo:start
I'm just not sure that this can work with the parent pom (I wonder if this can lead to cyclic dependencies issues) and I didn't test it. But personally, I'd put all this stuff in the pom of a dedicated project, e.g. in a sibling project of your webapps, and not in the parent pom. I don't think it's a really a big deal and this is IMHO a better setup, especially if you plan to use cargo for integration testing.