🔴 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.