A Maven plugin that synchronises files and directories using Java NIO FileSystem providers. This allows you to sync local files to any destination supported by a Java NIO FileSystem implementation — FTP, SFTP, S3, SMB, and more.
- Sync local directories to remote filesystems (FTP, SFTP, S3, etc.)
- Incremental sync — only copies files that are newer than the destination
- Deletes files from the destination that no longer exist in the source
- Credentials managed via Maven's
settings.xml(including encrypted passwords) - Extensible — add any NIO FileSystem provider as a plugin dependency
Add the plugin to your pom.xml:
<plugin>
<groupId>uk.co.bithatch</groupId>
<artifactId>niosync-maven-plugin</artifactId>
<version>0.9.1</version>
<executions>
<execution>
<id>deploy-to-ftp</id>
<phase>deploy</phase>
<goals>
<goal>sync</goal>
</goals>
<configuration>
<source>target/site</source>
<target>ftp://ftp.example.com/public_html</target>
<serverId>ftp.example.com</serverId>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.github.robtimus</groupId>
<artifactId>ftp-fs</artifactId>
<version>4.0.1</version>
</dependency>
</dependencies>
</plugin>Synchronises one or more source paths to a destination path.
Default phase: deploy
| Parameter | Type | Default | Description |
|---|---|---|---|
source |
String |
— | A single source path or URI to sync from |
sources |
List<String> |
— | Multiple source paths or URIs to sync from |
target |
String |
— | The destination path or URI to sync to |
serverId |
String |
— | The id of a <server> entry in settings.xml for credentials |
recursive |
boolean |
true |
Whether to sync directories recursively |
preserveAttributes |
boolean |
true |
Whether to preserve file attributes (timestamps, etc.) |
deleteRemoved |
boolean |
true |
Whether to delete files from the destination that no longer exist in the source |
checker |
String |
auto | Strategy for deciding if a file needs updating: lastModified, size, or always |
skip |
boolean |
false |
Skip execution entirely |
Note: Set
preserveAttributestofalsewhen syncing to remote filesystems (FTP, SFTP, etc.) that may not support copying file attributes.
The checker parameter controls how the plugin decides whether a file needs to be copied:
| Strategy | Description |
|---|---|
lastModified |
Compares last modified timestamps. Only copies if the source is newer. Default for local filesystem targets. |
size |
Compares file sizes. Copies if sizes differ. Default for ftp, ftps, sftp, and smb targets. |
always |
Always copies every file regardless of existing content. |
If checker is not specified, the plugin auto-selects based on the target scheme:
- FTP, FTPS, SFTP, SMB →
size(these protocols typically don't support setting modification times) - Everything else →
lastModified
Both source/sources and target accept either:
- Local paths:
target/repository,/absolute/path,relative/path - URIs:
ftp://host/path,sftp://host/path,s3://bucket/prefix
The appropriate NIO FileSystem provider must be available as a plugin dependency for non-local URIs.
The plugin integrates with Maven's standard credential management. Add a server entry to your ~/.m2/settings.xml:
<settings>
<servers>
<server>
<id>ftp.example.com</id>
<username>myuser</username>
<password>mypassword</password>
</server>
</servers>
</settings>Then reference it in the plugin configuration:
<configuration>
<source>target/repository</source>
<target>ftp://ftp.example.com/uploads</target>
<serverId>ftp.example.com</serverId>
</configuration>- Embedded in URI — If the target URI contains
user:pass@host, those are used directly - Explicit
serverId— Looks up the specified server ID insettings.xml - Hostname fallback — If no
serverIdis set and the URI has no credentials, the hostname is used as the server ID lookup key
The plugin supports Maven's encrypted passwords. Encrypt a password with:
mvn --encrypt-passwordThen use the encrypted value in settings.xml:
<server>
<id>ftp.example.com</id>
<username>myuser</username>
<password>{encrypted+value+here}</password>
</server>Make sure you have a master password configured in ~/.m2/settings-security.xml. See the Maven Encryption Guide for details.
The plugin works with any Java NIO FileSystemProvider. Add the provider library as a <dependency> of the plugin (not of your project).
<dependencies>
<dependency>
<groupId>com.github.robtimus</groupId>
<artifactId>ftp-fs</artifactId>
<version>4.0</version>
</dependency>
</dependencies>Target URI format: ftp://hostname/path or ftps://hostname/path
<dependencies>
<dependency>
<groupId>com.github.robtimus</groupId>
<artifactId>sftp-fs</artifactId>
<version>3.0</version>
</dependency>
</dependencies>Target URI format: sftp://hostname/path
<dependencies>
<dependency>
<groupId>software.amazon.nio.s3</groupId>
<artifactId>aws-java-nio-spi-for-s3</artifactId>
<version>2.1.0</version>
</dependency>
</dependencies>Target URI format: s3://bucket-name/prefix
<plugin>
<groupId>uk.co.bithatch</groupId>
<artifactId>niosync-maven-plugin</artifactId>
<version>0.0.1-SNAPSHOT</version>
<executions>
<execution>
<id>sync-p2-repo</id>
<phase>deploy</phase>
<goals>
<goal>sync</goal>
</goals>
<configuration>
<source>target/repository</source>
<target>ftp://ftp.example.com/eclipse/updates</target>
<serverId>ftp.example.com</serverId>
<preserveAttributes>false</preserveAttributes>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.github.robtimus</groupId>
<artifactId>ftp-fs</artifactId>
<version>4.0</version>
</dependency>
</dependencies>
</plugin><configuration>
<sources>
<source>target/classes</source>
<source>target/resources</source>
</sources>
<target>ftp://ftp.example.com/deploy</target>
<serverId>my-ftp-server</serverId>
</configuration><configuration>
<source>target/site</source>
<target>ftp://ftp.example.com/docs</target>
<serverId>ftp.example.com</serverId>
<deleteRemoved>false</deleteRemoved>
</configuration><configuration>
<source>target/repository</source>
<target>ftp://ftp.example.com/repo</target>
<skip>${skipDeploy}</skip>
</configuration>Run with: mvn deploy -DskipDeploy=true
The sync goal can be invoked directly without a project:
mvn uk.co.bithatch:niosync-maven-plugin:0.0.1-SNAPSHOT:sync \
-Dsource=./local-dir \
-Dtarget=ftp://ftp.example.com/remote-dir \
-DserverId=ftp.example.com- Incremental: Only files newer than the destination are copied (based on last modified time)
- Recursive: Subdirectories are synced recursively by default
- Deletions: Files present on the destination but not in the source are removed (configurable)
- Cross-filesystem: Source and destination can be on different filesystems (e.g. local → FTP)
Some NIO FileSystem providers (e.g. ftp-fs 4.0) register only via module-info.java and lack META-INF/services registration. The plugin handles this transparently by:
- Trying
FileSystems.newFileSystem(URI, env, classLoader)with the plugin classloader - Falling back to
ServiceLoaderwith the plugin classloader - As a last resort, instantiating known provider classes directly via reflection
Apache License 2.0