How to do Base64 Encoding in Java

Hey fellow coders! Let’s talk about a common pitfall I’ve seen in Java projects: using internal APIs like sun.misc.BASE64Encoder and sun.misc.BASE64Decoder for Base64 encoding. You might have inherited legacy code that relies on these classes, or maybe you stumbled onto an old tutorial that recommended them. But here’s the problem they’re ticking time bombs. Let me explain why, and then I’ll show you safer, modern alternatives.

What’s Wrong with the Original Code?

If you’ve ever encountered errors like “Access restriction: The type BASE64Encoder is not accessible” in Eclipse or warnings about internal APIs in IntelliJ, this section is for you.

The sun.misc package contains classes that are part of Sun/Oracle’s internal implementation of the JDK. These classes:

  1. Are not part of the public Java API, meaning they can change or disappear in future JDK updates.
  2. Won’t work reliably across environments (e.g., different JDK vendors like OpenJDK vs. Oracle JDK).
  3. Make your code brittle. For example, if you upgrade to Java 9+, you’ll likely face runtime errors because these APIs were deprecated or removed.

In short: Internal APIs are not your friends. They’re undocumented, unsupported, and unsafe for production code.

Better Alternatives

Luckily, there are robust, future-proof solutions for Base64 encoding. Let’s explore two options based on your Java version.

Java 8’s Built-In java.util.Base64

Java 8 introduced a standardized Base64 API in java.util.Base64. It’s efficient, well-documented, and guaranteed to work across JDK versions.

Example Code:

import java.util.Base64;

public class Base64Example {
    public static void main(String[] args) {
        String originalInput = "Hello, World!";
        
        // Encoding
        String encodedString = Base64.getEncoder().encodeToString(originalInput.getBytes());
        System.out.println("Encoded: " + encodedString); // SGVsbG8sIFdvcmxkIQ==
        
        // Decoding
        byte[] decodedBytes = Base64.getDecoder().decode(encodedString);
        String decodedString = new String(decodedBytes);
        System.out.println("Decoded: " + decodedString); // Hello, World!
    }
}

How It Works:

  • Base64.getEncoder() and Base64.getDecoder() provide thread-safe instances.
  • encodeToString() converts bytes to a Base64 string in one line.
  • No external dependencies—just pure, modern Java.

Apache Commons Codec (For Java 7 or Legacy Projects)

If you’re stuck on Java 7, the Apache Commons Codec library is a battle-tested alternative.

Step 1: Add the Dependency
Grab the Apache Commons Codec JAR or add it via Maven:

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.16.0</version>
</dependency>

Run HTML

Example Code:

import org.apache.commons.codec.binary.Base64;

public class Base64Example {
    public static void main(String[] args) {
        String originalInput = "Hello, World!";
        
        // Encoding
        byte[] encodedBytes = Base64.encodeBase64(originalInput.getBytes());
        String encodedString = new String(encodedBytes);
        System.out.println("Encoded: " + encodedString);
        
        // Decoding
        byte[] decodedBytes = Base64.decodeBase64(encodedString.getBytes());
        String decodedString = new String(decodedBytes);
        System.out.println("Decoded: " + decodedString);
    }
}

Why Apache Commons?

  • Works on older Java versions.
  • Offers additional flags (e.g., encodeBase64URLSafe for URL-safe strings).
  • Actively maintained and widely used.

Going Further: Encoding Files

Need to encode a file’s content? Here’s a Java 8 example that reads a file, encodes it, and writes the result:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;

public class FileBase64Encoder {
    public static void main(String[] args) {
        String inputFilePath = "input.dat";
        String outputFilePath = "encoded.txt";
        
        try {
            byte[] fileContent = Files.readAllBytes(Paths.get(inputFilePath));
            String encodedContent = Base64.getEncoder().encodeToString(fileContent);
            Files.write(Paths.get(outputFilePath), encodedContent.getBytes());
            System.out.println("File encoded successfully!");
        } catch (IOException e) {
            System.err.println("Error: " + e.getMessage());
        }
    }
}

Use Cases:

  • Encoding images or documents for email attachments.
  • Storing binary data in JSON or XML.

Final Thoughts

Using internal APIs like sun.misc.BASE64Encoder is like building a house on sand—it might work today, but it’ll collapse tomorrow. Instead:

  • Upgrade to Java 8+ and use java.util.Base64 for a zero-dependency solution.
  • Use Apache Commons Codec if you’re constrained to Java 7.

By adopting these practices, you’ll write code that’s resilient, maintainable, and free from hidden surprises.

Related blog posts