The Java
ClassNotFoundException for an SMTP server usually occurs because the required mail library is missing from your classpath or not included in your build configuration. This error prevents the application from loading classes like
javax.mail.Session, causing immediate failure when attempting to send emails. You can resolve this by explicitly adding the correct dependency to your project’s build file, such as Maven’s
pom.xml or Gradle’s
build.gradle, ensuring the artifact is downloaded and available at runtime.
Understanding the Root Cause
In modern Java development, particularly with versions 9 and above, the Jakarta EE APIs (formerly Java EE) were moved out of the standard JDK distribution. The
javax.mail package is no longer bundled with the Java Runtime Environment. Consequently, any attempt to instantiate an SMTP client without manually including the external library will result in a
ClassNotFoundException. This is distinct from a
NoClassDefFoundError, which typically indicates that the class was present at compile time but missing at runtime due to packaging issues.
When you see an exception trace pointing to
javax.mail.internet.MimeMessage or
com.sun.mail.smtp.SMTPTransport, it confirms that the JVM cannot locate the implementation classes in the loaded classpath. This often happens during rapid prototyping where developers assume standard libraries are always available, or after migrating a legacy application to a newer Java version.
Fixing the Issue in Maven Projects
If you are using Maven, the most reliable fix is to declare the Mail API dependency in your
pom.xml. While older tutorials might suggest
javax.mail:javax.mail, this is outdated. The current standard maintained by Eclipse is the
jakarta.mail API.
Add the following snippet inside your
<dependencies> block:
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId>
<version>1.6.7</version>
</dependency>
After adding this, ensure you run
mvn clean install to force Maven to download the JAR files into your local repository. If you are using an IDE like Eclipse or IntelliJ, you may need to refresh your project dependencies to recognize the new JARs. Note that if you are still using very old code relying on
javax.mail packages directly, you might need to use the legacy
javax.mail:mail artifact, but migrating to
jakarta.mail is recommended for future compatibility.
For more information on managing email configurations across different clients, you might find
Thunderbird: Two email accounts using the same SMTP server useful for understanding how SMTP settings interact with various environments.
Resolving Dependencies in Gradle
Gradle users should add the equivalent dependency to their
build.gradle file. Ensure you are using the correct syntax for your Groovy or Kotlin DSL.
For Groovy:
implementation 'com.sun.mail:jakarta.mail:1.6.7'
For Kotlin DSL (
build.gradle.kts):
implementation("com.sun.mail:jakarta.mail:1.6.7")
Sync your project after making these changes. If you encounter errors regarding conflicting versions, check your
gradle dependencies task to identify transitive dependencies that might be pulling in older, incompatible versions of the mail library. Sometimes, Spring Boot starters include their own mail dependencies, which can lead to version conflicts. In such cases, you may need to exclude the default mail dependency from the starter and include the specific version you require.
Verifying Classpath in Standalone Applications
If you are running a standalone Java application outside of a build tool, you must manually manage the classpath. Download the
jakarta.mail.jar and its dependencies (such as
activation or
jaf) from the official Eclipse website. When launching your application, use the
-cp or
-classpath flag to include these JARs.
java -cp ".:./lib/jakarta.mail-1.6.7.jar" com.example.MyApp
On Windows, use semicolons instead of colons for path separation. It is critical to verify that the JAR files are actually present in the specified directory. A common mistake is specifying the directory containing the JAR rather than the JAR itself, or vice versa. Always test with a simple
System.out.println or a basic try-catch block around the class loading to isolate whether the issue is purely classpath-related.
Frequently Asked Questions
Why do I get ClassNotFoundException even though I added the dependency?
This usually happens if you did not refresh your project after modifying the build file, or if the IDE is using a cached classpath. Ensure you have executed a clean build command to regenerate the compiled output with the new libraries included.
What is the difference between javax.mail and jakarta.mail?
javax.mail is the legacy namespace used in Java EE 8 and earlier.
jakarta.mail is the successor under the Jakarta EE namespace, starting from Java EE 9. Code written for
javax will not compile against
jakarta without package name refactoring, so consistency in imports is vital.
Can I use Spring Boot Starter Mail to avoid this error?
Yes, adding
spring-boot-starter-mail automatically includes the necessary mail dependencies managed by Spring Boot. This is often easier than manual configuration, but you must ensure the version aligns with your Spring Boot release to avoid conflicts.
How do I check which classes are in my classpath?
You can use the
javap command on the JAR file or inspect the dependency tree in Maven (
mvn dependency:tree) or Gradle (
./gradlew dependencies). This helps verify that the specific JAR containing the SMTP classes is actually being resolved by the build tool.