๐Ÿ”ด The Error You're Seeing

Confirm this matches your console output. If it does, you're in the right place.

ERROR LOGorg.springframework.core.convert.ConversionNotSupportedException: Failed to convert property value of type 'java.lang.String' to required type 'javax.mail.Session' for property 'mailSession'; nested exception is java.lang.IllegalStateException: No converter found for type [javax.mail.Session]

โšก Quick Fix Works 80% of the time

Do not try to inject complex objects via @Value. Use @ConfigurationProperties and build the object manually.

@ConfigurationProperties(prefix = "app.mail") public class MailProps { private String host; // Build the Session in a @Bean method, not as a property.

๐Ÿง  Why this Happens

Tap to expand the deep technical explanation

Spring tried to take a String value from `application.properties` and inject it into a field that expects a complex Java object (like a `javax.mail.Session` or a custom class). Spring's default converters only handle primitives, Dates, and Collections. It doesn't know how to turn a String into a `Session` object.

The HITEC City Parking Spot Analogy:

It's like giving a chef a recipe card (String) when they asked for a baked cake (Session). The chef cannot magically turn the card into the cake without baking it first.

๐Ÿ” How to Reproduce Confirm this is your error

Create a `@Configuration` bean with a field `private Session mailSession;`. Add `app.mailSession=localhost` to `application.properties`. Spring will crash trying to convert the string.

๐Ÿ› ๏ธ Solutions (5 Ways to Fix)

Solution 1โœ“ Most common cause

Use primitives in properties, build objects in @Bean

๐Ÿ‘‰ Use this as the standard pattern for complex objects.

Read the simple properties (host, port) using @ConfigurationProperties, then construct the complex object manually inside a @Bean method.

@Configuration public class MailConfig { @Value("${mail.host}") private String host; @Bean public Session mailSession() { Properties props = new Properties(); props.put("mail.smtp.host", host); return Session.getInstance(props); } }
Solution 2

Register a Custom Converter

๐Ÿ‘‰ Use this if you frequently need to convert a String to a specific custom object.

Tell Spring how to perform the conversion by implementing the Converter interface.

@Component public class StringToSessionConverter implements Converter<String, Session> { @Override public Session convert(String source) { // Parse the string and build the Session return Session.getInstance(new Properties()); } }
Solution 3

Use SpEL (Spring Expression Language)

๐Ÿ‘‰ Use this if you need to inject a bean using @Value.

Instead of injecting a String, use SpEL to reference a Bean by its name.

// Instead of @Value("${mail.session}") @Value("#{@mailSession}") // SpEL referencing the bean named 'mailSession' private Session mailSession;
Solution 4

Fix typo in @Value placeholder

๐Ÿ‘‰ Use this if the property is actually a String, but the target field is also a String.

Sometimes you accidentally point @Value to a complex object instead of a String property.

// Bad // @Value("#{mailSession}") // Good @Value("${app.mail.host}") // Note the $ instead of # private String host;
Solution 5

Ensure Jackson is on the classpath

๐Ÿ‘‰ Use this if you are trying to bind a JSON string to a Map or Object via @ConfigurationProperties.

Spring Boot uses Jackson to convert JSON strings from properties files into Objects. If Jackson is missing, it fails.

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>

๐Ÿ“‹ Version Notes

Spring Boot 2.x

Standard ConversionService.

Spring Boot 3.x

Stricter binding, fails fast on unconvertible types.

๐Ÿ›ก๏ธ How to Prevent This Next Time

Never attempt to inject complex, stateful Java objects directly via `@Value`. Use the `@Bean` approach to construct them from simple primitive properties.

Course Search
Search across all chapters & stages
๐Ÿ“–

Search the course

Type any topic โ€” branching, stash, rebase, hooks โ€” and jump straight to that chapter.

merge branchesgit stashundo commitrebase