【问题标题】:JavaMail-Folder AutoClosable exceptionJavaMail-Folder AutoClosable 异常
【发布时间】:2021-09-01 09:23:04
【问题描述】:

Since JavaMail version 1.6.0 类 Store 和 Folder(在 Transport 中)应该实现 AutoClosable 接口。

我没有找到任何使用具有自动关闭功能的 JavaMail API 的示例。

经过几次测试,我不确定如何准确使用此功能,因为我发现了一个奇怪的(?)行为。

我正在使用依赖com.sun.mail:javax.mail:1.6.0

@Test
public static void test() {
  Session session = ...;
  Intger countOfMessages;
  try(Store store = session.getStore("imap");) {
    store.connect("<host>", "<user>", "<password>");
    try(Folder folder = store.getFolder("inbox");) {
      folder.open(Folder.READ_ONLY);
      count = folder.getMessages().
    }
  }
  Assert.assertEquals(0, count);
}

到目前为止一切正常。

但是,如果我将文件夹的名称更改为一些不正确的值 (store.getFolder("_no_folder_with_this_name_")),那么我会得到一个

javax.mail.FolderNotFoundException: _no_folder_with_this_name_ not found

这很好但是这个异常有一个被抑制的异常

Suppressed: java.lang.IllegalStateException: This operation is not allowed on a closed folder

我明白为什么会抛出这个异常。 try(Folder folder = store.getFolder(...) 抛出 FolderNotFoundException,因此文件夹的打开永远不会发生,并且在 close 方法中文件夹未打开。但就我个人而言,我不希望这个被压制的例外。作为第二个测试,我尝试将内部 try 块留空 (try(Folder folder = store.getFolder("inbox");) {}),以便不会打开该文件夹。即使在这种情况下,也会抛出 IllegalStateException。

在 1.6.0 版本之前,我使用 finally 语句自行关闭文件夹。

finally {
  if(folder != null) {
    try {
      if(folder.isOpen()) {
        folder.close(false);
      }
    }
    catch(MessagingException me) { LOG.warn(...); }
  if(store != null) {
    try {
      store.close();
    }
    catch(MessagingException me) { LOG.warn(...); }
  }
}

是我做错了什么还是这种行为是一个错误?

【问题讨论】:

    标签: jakarta-mail autocloseable


    【解决方案1】:

    尝试将代码重构为:

    @Test
    public static void test() {
       Session session = ...;
       Intger countOfMessages;
       Store store = session.getStore("imap");
       store.connect("<host>", "<user>", "<password>");
       try (store) {   
       //try(Store s = store) //For pre JDK9
           Folder folder = store.getFolder("inbox");
           folder.open(Folder.READ_ONLY);
           try (folder) {
              count = folder.getMessages();
           }
       }
       Assert.assertEquals(0, count);
    }
    

    close 方法与 connect 和 open 平衡。调用 getStore/getFolder 并不意味着存在活动连接。 如果我们让可自动关闭的调用不那么敌对的话会更干净。

    【讨论】:

    • 我希望在未来的版本中减少这种敌意。您的解决方案似乎合理,但由于 JDK-8 不支持 try-with-resource 中的变量,我目前无法使用它。
    • @Filou 可以引入new local 使其编译。还要确保你的 JavaMail 是 1.6+
    猜你喜欢
    • 2019-08-22
    • 2017-01-17
    • 1970-01-01
    • 2016-03-22
    • 1970-01-01
    • 1970-01-01
    • 2012-07-19
    • 1970-01-01
    • 2016-06-12
    相关资源
    最近更新 更多