Of course! The Java ecosystem has several excellent options for creating an FTP server. The choice depends on your specific needs: simplicity, features, performance, or compliance with modern standards.
Here's a breakdown of the most popular and robust Java FTP server libraries, along with a practical code example.
Top Java FTP Server Libraries
Apache Mina FTP Server (Most Popular & Recommended)
This is arguably the most well-known, feature-rich, and actively maintained FTP server implementation in Java. It's part of the larger Apache MINA project, which is a high-performance networking framework.
-
Pros:
- Full-Featured: Supports FTP, FTPS (FTP over SSL/TLS), SFTP (via SSH, but often confused with FTPS), and FTPES (Explicit FTPS).
- High Performance: Built on the non-blocking I/O model of Apache MINA, making it very scalable and efficient for handling many concurrent connections.
- Highly Configurable: You can configure it extensively via Spring or programmatically.
- Active Community: Backed by the Apache Software Foundation with a large user base.
-
Cons:
- Can be more complex to set up than simpler libraries due to its many features.
- The dependency on Apache MINA might be heavier than needed for a simple, embedded server.
-
Maven Dependency:
<dependency> <groupId>org.apache.ftpserver</groupId> <artifactId>ftpserver-core</artifactId> <version>1.2.0</version> <!-- Check for the latest version --> </dependency>
FtpServer (Legacy, but still used)
This is the predecessor to the Apache Mina FTP Server. It was the original standalone FTP server project before it was donated to the Apache foundation and integrated with MINA. You might still find it in older projects.
-
Pros:
- Mature and stable.
- Simpler to configure for basic use cases than the MINA version.
-
Cons:
- No Longer Actively Developed. The Apache Mina version is the official continuation.
- Lacks the high-performance, non-blocking I/O of its successor.
-
Maven Dependency:
<dependency> <groupId>org.apache.ftpserver</groupId> <artifactId>ftplet-api</artifactId> <version>1.2.0</version> </dependency> <dependency> <groupId>org.apache.ftpserver</groupId> <artifactId>ftpserver-core</artifactId> <version>1.2.0</version> </dependency>
Simple Ftp Server (Good for Simplicity)
A lightweight and easy-to-use FTP server, perfect for unit testing, simple file sharing, or embedded applications where you don't need all the bells and whistles.
-
Pros:
- Extremely Easy to Use: The API is very straightforward.
- Lightweight with minimal dependencies.
- Good for testing and quick prototypes.
-
Cons:
- Not as performant or feature-rich as Apache Mina.
- Less active development compared to Apache Mina.
-
Maven Dependency:
<dependency> <groupId>com.github.dblock</groupId> <artifactId>ftpserver</artifactId> <version>3.0.0</version> <!-- Check for the latest version --> </dependency>
NanoFTPd (For Minimalist Needs)
A very small and simple FTP server implementation. It's designed to be embedded and have a minimal footprint.
- Pros:
- Tiny codebase and dependencies.
- Easy to embed.
- Cons:
- Very basic functionality. Not suitable for production or complex scenarios.
- Not actively maintained.
Practical Example: Apache Mina FTP Server
This example shows how to create a simple, embedded FTP server using the recommended library.
Step 1: Set up your Maven Project
Create a new Maven project and add the ftpserver-core dependency to your pom.xml.
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>java-ftpserver-example</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- Apache Mina FTP Server -->
<dependency>
<groupId>org.apache.ftpserver</groupId>
<artifactId>ftpserver-core</artifactId>
<version>1.2.0</version>
</dependency>
</dependencies>
</project>
Step 2: Write the Java Code
Create a Java class to configure and start the server. This server will:
- Listen on port
2221. - Use a simple in-memory user factory.
- Have one user:
adminwith passwordpassword. - Serve files from a directory named
ftp_rooton your local filesystem.
import org.apache.ftpserver.FtpServer;
import org.apache.ftpserver.FtpServerFactory;
import org.apache.ftpserver.ftplet.Authority;
import org.apache.ftpserver.ftplet.UserManager;
import org.apache.ftpserver.listener.ListenerFactory;
import org.apache.ftpserver.usermanager.ClearTextPasswordEncryptor;
import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
import org.apache.ftpserver.usermanager.impl.BaseUser;
import org.apache.ftpserver.usermanager.impl.WritePermission;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class EmbeddedFtpServer {
public static void main(String[] args) throws Exception {
// 1. Create a FtpServerFactory
FtpServerFactory serverFactory = new FtpServerFactory();
// 2. Configure the Listener
ListenerFactory listenerFactory = new ListenerFactory();
// Set the port number
listenerFactory.setPort(2221);
// Replace the default listener
serverFactory.addListener("default", listenerFactory.createListener());
// 3. Configure the User Manager
// For simplicity, we'll create a user programmatically.
// For production, you would use a file-based or database-backed user manager.
BaseUser user = new BaseUser();
user.setName("admin");
user.setPassword("password");
user.setHomeDirectory(new File("ftp_root").getAbsolutePath()); // IMPORTANT: Create this directory!
// Grant write permission
List<Authority> authorities = new ArrayList<>();
authorities.add(new WritePermission());
user.setAuthorities(authorities);
UserManager userManager = serverFactory.getUserManager();
userManager.save(user);
// 4. Start the server
FtpServer server = serverFactory.createServer();
server.start();
System.out.println("FTP Server started on port 2221.");
System.out.println("User: admin, Password: password");
System.out.println("Serving files from: " + new File("ftp_root").getAbsolutePath());
System.out.println("Press Enter to stop the server...");
System.in.read(); // Wait for user input to stop
server.stop();
}
}
Step 3: Run and Test
- Create the directory: Before running, create a directory named
ftp_rootin the root of your project (or wherever you want your files to be served). - Place some files: Put a few files (e.g.,
test.txt,image.png) inside theftp_rootdirectory. - Run the code: Execute the
EmbeddedFtpServerclass. - Connect with a client: Use any FTP client (like FileZilla, WinSCP, or even the command line) to connect to your server.
- Host:
localhost(or0.0.1) - Port:
2221 - Username:
admin - Password:
password
- Host:
You should now be able to browse, download, and upload files to the ftp_root directory.
Important Considerations for Production
- Security: Never use plain-text passwords in production code. Use encrypted password storage.
- FTPS (FTP Secure): For any real-world application, you must use FTPS (FTP over SSL/TLS) to encrypt both the commands and the data transfers. Apache Mina makes this relatively straightforward by configuring an SSL/TLS listener.
- User Management: For a real application, you'll want a persistent user manager. The
PropertiesUserManagerFactory(which loads users from a.propertiesfile) is a good starting point. - Logging: Configure logging (e.g., with SLF4J and Logback) to monitor server activity and debug issues. Apache FTP Server is very verbose in its logging, which is helpful for troubleshooting.
