Uploading files using scp and the Maven Wagon plugin

I’ve been struggling with a little Maven problem for a while but only just managed to find time to look into it in any detail. What I’ve been trying to do is copy an artifact to a remote server using scp. The artifact in question is a WAR which I want to copy to a server hosting Tomcat, so this is not a typical deploy-artifact-to-repository type of requirement.

(As an aside, I know all about the Cargo plugin for deploying web apps to servlet containers but in this instance I’m more interested in the more general issue of copying any artifact, be it a WAR or a JAR or something else, using scp)

In principle this sounds like a very simple thing to do. The Maven Wagon plugin is the tool for the job but the documentation is woefully inadequate and I just could not get it to do what I wanted.

Anyway, after a lot of Googling and, crucially, inspecting Maven debug output from failed attempts at using the plugin I’ve finally cracked it.

Everything I’d seen written about this involved the following aspects…

Configuring details about the server to be copied to (typically in your main Maven settings.xml configuration):

<server>
  <serverId>my-server-id</serverId>
  <user>my-user-name</user>
  <password>my-password</password>
</server>

Using the Wagon plugin to perform the actual copy:

<build>
  <extensions>
    <extension>
       <groupId>org.apache.maven.wagon</groupId>
       <artifactId>wagon-ssh</artifactId>
       <version>1.0-beta-6</version>
     </extension>
   </extensions>

   <plugins>
     <plugin>
       <groupId>org.codehaus.mojo</groupId>
       <artifactId>wagon-maven-plugin</artifactId>
       <version>1.0-beta-3</version>
       <configuration>
         <fromFile>${project.build.directory}/${project.build.finalName}.war</fromFile>
         <url>scp://my-server-id.fully.qualified.domain/path/to/destination</url>
       </configuration>
       <executions>
         <execution>
           <id>upload-war-to-server</id>
           <phase>deploy</phase>
           <goals>
             <goal>upload-single</goal>
           </goals>
         </execution>
       </executions>
     </plugin>
   </plugins>

 </build>

All looks logical… but it simply refused to work, complaining about authentication failures. I knew the corresponding <server> configuration block was using the correct username and password, so the symptoms suggested that it wasn’t finding the <server> configuration. I’d made sure the host part of the server domain in the scp:// URL matched the server id element but it just wouldn’t match them up.

And then I noticed something in the Wagon plugin’s debug output – mention of a serverId property in the configuration. I’d not seen this documented anywhere before, but I thought I’d try adding it to my Wagon plugin configuration all the same…

      <configuration>
        <serverId>my-server-id</serverId></pre>
        <fromFile>${project.build.directory}/${project.build.finalName}.war</fromFile>
        <url>scp://my-server-id.fully.qualified.domain/path/to/destination</url>
      </configuration>

…and all of a sudden it started working! So, in my situation that appears to have been the missing link between my Wagon plugin and the server configuration details.

  • Thanks Darren, that was useful.

  • Darren

    Thanks Ludovic – glad you found it useful.

    One of the main reasons I started keeping this blog was so I could pay back in some small way for all the useful bits of info I’ve gleaned from other people’s blogs over the years 🙂

  • Thank you Darren! 🙂 One more thing I had to do is bypass the artifact deployment setting up the maven-deploy-plugin with the “skip” option set to true.

  • That is a very good tip especially to those new to the blogosphere.
    Short but very accurate info… Appreciate your sharing this one.
    A must read article!