'Spring Integration MimeMessage gmail Folder is not Open exception

Whenever I try to read content of a MimeMessage I get the "java.lang.IllegalStateException: Folder is not Open" exception.

I have a very simple service handling the received message:

@Service
public class ReceiveMailService {

    private final Logger log = LoggerFactory.getLogger(ReceiveMailService.class);

    public void handleReceivedMail(MimeMessage receivedMessage) {
        try {
            log.debug("{}", receivedMessage.getContent());

            MimeMessageParser mimeMessageParser = new MimeMessageParser(receivedMessage).parse();  // it breaks here

            doMyStuff(mimeMessageParser);

        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }
}

Here's my configuration class:

@Configuration
@EnableIntegration
public class MailReceiverConfiguration {

    private static final Logger log = LoggerFactory.getLogger(MailReceiverConfiguration.class);

    @Value("${spring.mail.pop3.host}")
    private String host;
    @Value("${spring.mail.pop3.port}")
    private Integer port;
    @Value("${spring.mail.username}")
    private String username;
    @Value("${spring.mail.password}")
    private String password;

    private final ReceiveMailService receiveMailService;

    public MailReceiverConfiguration(ReceiveMailService receiveMailService) {
        this.receiveMailService = receiveMailService;
    }

    @Bean
    public IntegrationFlow mailListener() {
        return IntegrationFlows
            .from(Mail
                    .pop3InboundAdapter(host, port, username, password)
                    .javaMailProperties(p -> {
                        p.put("mail.debug", "false");
                        p.put("mail.pop3.socketFactory.fallback", "false");
                        p.put("mail.pop3.port", port);
                        p.put("mail.pop3.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
                        p.put("mail.pop3.socketFactory.port", port);
                    })
                    .maxFetchSize(10)
                    .shouldDeleteMessages(false),
                e -> e.poller(Pollers.fixedRate(5000).maxMessagesPerPoll(10))
            )
            .handle(message -> receiveMailService.handleReceivedMail((MimeMessage) message.getPayload()))
            .get();
    }

}

I have ran out of ideas why this wouldn't work.



Solution 1:[1]

See this option for use-cases like yours:

/**
 * When configured to {@code false}, the folder is not closed automatically after a fetch.
 * It is the target application's responsibility to close it using the
 * {@link org.springframework.integration.IntegrationMessageHeaderAccessor#CLOSEABLE_RESOURCE} header
 * from the message produced by this channel adapter.
 * @param autoCloseFolder set to {@code false} to keep folder opened.
 * @return the spec.
 * @since 5.2
 * @see AbstractMailReceiver#setAutoCloseFolder(boolean)
 */
public S autoCloseFolder(boolean autoCloseFolder) {

The docs is here: https://docs.spring.io/spring-integration/docs/current/reference/html/mail.html#mail-inbound

Starting with version 5.2, the autoCloseFolder option is provided on the mail receiver. Setting it to false doesn’t close the folder automatically after a fetch, but instead an IntegrationMessageHeaderAccessor.CLOSEABLE_RESOURCE header (see MessageHeaderAccessor API for more information) is populated into every message to producer from the channel adapter.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Artem Bilan