【问题标题】:Websphere 7 javax.mail.MessagingException: SSLSocketFactory is nullWebsphere 7 javax.mail.MessagingException:SSLSocketFactory 为空
【发布时间】:2014-06-25 08:27:19
【问题描述】:

我正在尝试使用 SSL 连接到在 Websphere 7 上运行的邮件服务器。我将代码作为独立的测试主方法运行没有问题,一切正常。 我在 Websphere 上运行代码也没有问题 - 连接到邮件服务器(例如 imap.seznam.cz),但是当我不使用 SSL 时。如果我想使用 SSL,会抛出如下异常:

javax.mail.MessagingException: SSLSocketFactory 为空。如果调用 javax.net.ssl.SSLSocketFactory.getDefault() 创建一个套接字并且没有设置 javax.net.ssl.* 属性。嵌套的 例外是:

javax.net.ssl.SSLException: SSLSocketFactory 为空。如果调用 javax.net.ssl.SSLSocketFactory.getDefault() 来创建一个 未设置 socket 和 javax.net.ssl.* 属性。

在 com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:571)

在 javax.mail.Service.connect(Service.java:288)

这是一段代码:

Properties imapProps = new Properties();
System.out.println(imapProps);
imapProps.setProperty("mail.imap.ssl.enable", ssl ? "true" : "false");
if(ssl) {
    imapProps.setProperty("mail.imap.starttls.enable", "true");
}

imapProps.setProperty("javax.net.ssl.trustStore", "c:/Program Files/IBM/WebSphere/AppServer/profiles/AppSrv01/config/cells/T431sNode03Cell/nodes/T431sNode03/trust.p12");
imapProps.setProperty("javax.net.ssl.trustStorePassword", "WebAS");
imapProps.setProperty("javax.net.ssl.trustStoreType", "PKCS12");
imapProps.setProperty("javax.net.ssl.keyStore", "c:/Program Files/IBM/WebSphere/AppServer/profiles/AppSrv01/config/cells/T431sNode03Cell/nodes/T431sNode03/key.p12");
imapProps.setProperty("javax.net.ssl.keyStorePassword", "WebAS");

imapProps.setProperty("mail.debug", "true");
Session session = Session.getInstance(imapProps, null);
session.setDebug(true);

System.out.println("--------------------------------------------------------------------------------------------");
System.out.println(imapProps.toString());
System.out.println("--------------------------------------------------------------------------------------------");

SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
System.out.println(sslsocketfactory);

// connect
try {
    store = session.getStore(ssl ? "imaps" : "imap");
    store.connect(imapServer, imapPort, login, password);
    return true;
} catch(NoSuchProviderException ex) {
    ex.printStackTrace();
    return false;
} catch (MessagingException e) {
    e.printStackTrace();
    return false;
} 

参数取自属性文件...

ssl true,imapServer imap.seznam.cz,imapPort 993

这只是检查SSLSocketFactory是否为空,代码中不需要

SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault(); System.out.println(sslsocketfactory);

我可以看到 sslsocketfactory 不为空,并且类型为:com.ibm.websphere.ssl.protocol.SSLSocketFactory

我尝试的是:

  • 我有来自邮件服务器的证书存储在 Websphere 上的受信任存储中(使用管理控制台,从服务器的端口读取,我可以在那里看到它)
  • 我在 Websphere 服务器的属性和代码中设置了一些 javax.net.ssl.* 属性,如您所见 - 但我认为没有必要
  • 我假设 Websphere 正在从管理控制台中看到的信任存储位置读取证书:${CONFIG_ROOT}/cells/T431sNode03Cell/nodes/T431sNode03/trust.p12

任何 Websphere 专家可以帮助我解决这个问题吗?我试图修复它几天但没有成功:-(

正如我所提到的,它在不使用 SSL 时可以在 Websphere 上运行,但在为同一邮件服务器使用 SSL 时无法运行(例如 imap.seznam.cz,还有 imap.gmail.com),并且可以正常使用在 Websphere 外部作为独立 java 应用程序运行时的 SSL。

谢谢大家!

更新:

感谢 Gas 为我指出了如何在 Websphere 中配置邮件的正确方法。所以我做到了,我使用的是内置邮件提供程序,并且只创建了 2 个邮件会话

  • 使用“imap”提供程序支持 SSL 的一种
  • 另一个不支持 SSL,使用“imap”提供程序

两个会话都定义了相同的服务器并启用了调试。

在java代码中我这样做:

Context context = new InitialContext();
Session session = null;
if(ssl) {
    session = (Session) context.lookup("mail/exchangeSSL");
} else {
    session = (Session) context.lookup("mail/exchange");
}

store = session.getStore();
store.connect(login, password);

和有趣的想法,结果是完全一样的。当我使用非 SSL 会话时,一切正常,但是当我使用 SSL 会话时,出现此异常:

[25.6.14 16:35:19:615 SELČ] 00000023 SystemOut     O *** In SessionFactory.getObjectInstance, session properties:
[25.6.14 16:35:19:615 SELČ] 00000023 SystemOut     O    mail.store.protocol=imaps
[25.6.14 16:35:19:615 SELČ] 00000023 SystemOut     O    mail.imaps.class=com.sun.mail.imap.IMAPSSLStore
[25.6.14 16:35:19:615 SELČ] 00000023 SystemOut     O    mail.debug=true
[25.6.14 16:35:19:615 SELČ] 00000023 SystemOut     O    mail.pop3s.class=com.sun.mail.pop3.POP3SSLStore
[25.6.14 16:35:19:615 SELČ] 00000023 SystemOut     O    mail.smtp.class=com.sun.mail.smtp.SMTPTransport
[25.6.14 16:35:19:615 SELČ] 00000023 SystemOut     O    mail.imaps.host=imap.seznam.cz
[25.6.14 16:35:19:616 SELČ] 00000023 SystemOut     O    mail.smtps.class=com.sun.mail.smtp.SMTPSSLTransport
[25.6.14 16:35:19:616 SELČ] 00000023 SystemOut     O    mail.imap.class=com.sun.mail.imap.IMAPStore
[25.6.14 16:35:19:616 SELČ] 00000023 SystemOut     O    mail.mime.address.strict=false
[25.6.14 16:35:19:616 SELČ] 00000023 SystemOut     O    mail.pop3.class=com.sun.mail.pop3.POP3Store
[25.6.14 16:35:19:616 SELČ] 00000023 SystemOut     O DEBUG: mail.imaps.class property exists and points to com.sun.mail.imap.IMAPSSLStore
[25.6.14 16:35:19:617 SELČ] 00000023 SystemOut     O DEBUG: mail.imap.fetchsize: 16384
[25.6.14 16:35:19:618 SELČ] 00000023 SystemErr     R javax.mail.MessagingException: SSLSocketFactory is null. This can occur if javax.net.ssl.SSLSocketFactory.getDefault() is called to create a socket and javax.net.ssl.* properties are not set.;
nested exception is: 
javax.net.ssl.SSLException: SSLSocketFactory is null. This can occur if javax.net.ssl.SSLSocketFactory.getDefault() is called to create a socket and javax.net.ssl.* properties are not set.
[25.6.14 16:35:19:618 SELČ] 00000023 SystemErr     R    at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:479)
[25.6.14 16:35:19:618 SELČ] 00000023 SystemErr     R    at javax.mail.Service.connect(Service.java:275)

更新2:

我从这个例子中创建了一个新的项目:

http://www.mkyong.com/maven/how-to-create-a-web-application-project-with-maven/

我只是在控制器中添加了邮件会话相关的代码:

try {
    Context context = new InitialContext();
    Session session = (Session) context.lookup("mail/exchangeSSL");

    Store store = session.getStore();
    store.connect("<user>", "<password>");
} catch (NamingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (NoSuchProviderException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (MessagingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

当我部署这个新的网络应用程序并调用它时,同样的错误。在 WEB-INF/lib 中只有与 spring 和 commons 日志相关的 jar:

aopalliance-1.0.jar
commons-logging-1.1.1.jar
spring-aop-3.0.5.RELEASE.jar
spring-asm-3.0.5.RELEASE.jar
spring-beans-3.0.5.RELEASE.jar
spring-context-3.0.5.RELEASE.jar
spring-context-support-3.0.5.RELEASE.jar
spring-core-3.0.5.RELEASE.jar
spring-expression-3.0.5.RELEASE.jar
spring-web-3.0.5.RELEASE.jar
spring-webmvc-3.0.5.RELEASE.jar

所以我认为这与服务器设置有关?我使用 Websphere 7.0.0.31。我在管理控制台(从端口读取)中将邮件服务器证书添加到 NodeDefaultTrustStore,我可以在那里看到它。

这是我们在项目中使用的 jar 列表:

ant-1.7.1.jar
ant-launcher-1.7.1.jar
antlr-2.7.7.jar
aopalliance-1.0.jar
asm-3.3.1.jar
aspectjrt-1.7.4.jar
aspectjweaver-1.7.4.jar
avalon-framework-api-4.3.1.jar
avalon-framework-impl-4.2.0.jar
avalon-framework-impl-4.3.1.jar
barcode4j-2.1.jar
batik-anim-1.7.jar
batik-awt-util-1.7.jar
batik-bridge-1.7.jar
batik-css-1.7.jar
batik-dom-1.7.jar
batik-ext-1.7.jar
batik-extension-1.7.jar
batik-gvt-1.7.jar
batik-js-1.7.jar
batik-parser-1.7.jar
batik-script-1.7.jar
batik-svg-dom-1.7.jar
batik-svggen-1.7.jar
batik-transcoder-1.7.jar
batik-util-1.7.jar
batik-xml-1.7.jar
bcmail-jdk16-1.45.jar
bcprov-jdk16-1.45.jar
bctsp-jdk16-1.45.jar
bsh-2.0b4.jar
c3p0-0.9.1.1.jar
cglib-2.2.2.jar
commons-beanutils-1.9.1.jar
commons-cli-1.0.jar
commons-codec-1.9.jar
commons-collections-3.2.1.jar
commons-io-1.4.jar
commons-lang-2.6.jar
commons-logging-1.1.3.jar
core-1.0-SNAPSHOT.jar
core-interface-1.0-SNAPSHOT.jar
cxf-api-2.7.5.jar
cxf-rt-bindings-soap-2.7.5.jar
cxf-rt-core-2.7.5.jar
cxf-rt-databinding-jaxb-2.7.5.jar
cxf-rt-frontend-jaxws-2.7.5.jar
cxf-rt-frontend-simple-2.7.5.jar
cxf-rt-transports-http-2.7.5.jar
cxf-rt-ws-security-2.7.5.jar
cz.dalvi.commons.common-0.1.jar
cz.dalvi.commons.crypto-0.1.jar
cz.dalvi.commons.xml-0.1.jar
dom4j-1.6.1.jar
ehcache-core-2.5.1.jar
filenet-client-1.0-SNAPSHOT.jar
flexjson-2.0.jar
fontbox-1.8.5.jar
fop-1.1.jar
hibernate-commons-annotations-4.0.4.Final.jar
hibernate-core-4.3.5.Final.jar
hibernate-entitymanager-4.3.5.Final.jar
hibernate-jpa-2.1-api-1.0.0.Final.jar
iba-commons-core-1.5.jar
iba-commons-util-1.5.jar
ibm.filenet-stax-api-1.0.jar
ini4j-0.5.1.jar
ISDSClient-1.0-SNAPSHOT.jar
isds-client-1.0-SNAPSHOT.jar
Jace-1.0.jar
jackson-annotations-2.0.5.jar
jackson-core-2.0.5.jar
jackson-databind-2.0.5.jar
jandex-1.1.0.Final.jar
javassist-3.18.1-GA.jar
javax.xml.stream-stax-api-1.0.jar
jaxb-api-2.1.jar
jaxb-impl-2.1.11.jar
jaxws-api-2.1.jar
jaxws-rt-2.1.7.jar
jboss-logging-3.1.3.GA.jar
jboss-logging-annotations-1.2.0.Beta1.jar
jboss-transaction-api_1.2_spec-1.0.0.Final.jar
jcl-over-slf4j-1.7.1.jar
jcommander-1.27.jar
jempbox-1.8.5.jar
joda-time-2.3.jar
jstl-1.2.jar
log4j-1.2.17.jar
mimepull-1.3.jar
mimepull-1.7.jar
opensaml-2.5.1-1.jar
openws-1.4.2-1.jar
pdfbox-1.8.5.jar
quartz-2.2.1.jar
resolver-20050927.jar
saaj-impl-1.3.18.jar
slf4j-api-1.7.1.jar
slf4j-log4j12-1.7.6.jar
spring-aop-4.0.3.RELEASE.jar
spring-beans-4.0.3.RELEASE.jar
spring-context-4.0.3.RELEASE.jar
spring-context-support-4.0.3.RELEASE.jar
spring-core-4.0.3.RELEASE.jar
spring-expression-4.0.3.RELEASE.jar
spring-jdbc-4.0.3.RELEASE.jar
spring-ldap-core-1.3.2.RELEASE.jar
spring-orm-4.0.3.RELEASE.jar
spring-security-config-3.2.4.RELEASE.jar
spring-security-core-3.2.4.RELEASE.jar
spring-security-ldap-3.2.4.RELEASE.jar
spring-security-web-3.2.4.RELEASE.jar
spring-tx-4.0.3.RELEASE.jar
spring-web-4.0.3.RELEASE.jar
spring-webmvc-4.0.3.RELEASE.jar
sta-client-1.0-SNAPSHOT.jar
stax2-api-3.1.1.jar
stax-api-1.0.1.jar
stax-ex-1.2.jar
streambuffer-0.9.jar
testng-6.8.8.jar
usertype.core-3.1.0.GA.jar
usertype.spi-3.1.0.GA.jar
velocity-1.7.jar
woodstox-core-asl-4.2.0.jar
ws-api-1.0-SNAPSHOT.jar
wsdl4j-1.6.3.jar
wss4j-1.6.10.jar
wstx-asl-3.2.3.jar
xalan-2.6.0.jar
xercesImpl-2.11.0.jar
xlxpScanner-1.0.jar
xlxpScannerUtils-1.0.jar
xml-apis-1.4.01.jar
xml-apis-ext-1.3.04.jar
xmlgraphics-commons-1.5.jar
xmlsec-1.5.4.jar
xmlschema-core-2.0.3.jar
xmltooling-1.3.2-1.jar
xpp3_min-1.1.4c.jar
xstream-1.3.1.jar

我认为这也可能会有所帮助,来自我 WAS 上的 java.security 设置:

# Default JSSE socket factories
#ssl.SocketFactory.provider=com.ibm.jsse2.SSLSocketFactoryImpl
#ssl.ServerSocketFactory.provider=com.ibm.jsse2.SSLServerSocketFactoryImpl
# WebSphere socket factories (in cryptosf.jar)
ssl.SocketFactory.provider=com.ibm.websphere.ssl.protocol.SSLSocketFactory
ssl.ServerSocketFactory.provider=com.ibm.websphere.ssl.protocol.SSLServerSocketFactory

【问题讨论】:

    标签: websphere jakarta-mail sslsocketfactory


    【解决方案1】:

    这不是在应用服务器环境中使用邮件会话的正确方法。

    您应该通过 Resources > Mail 定义您的邮件会话,在此处指定所有必需的属性并选择是否要使用 SSL(imaps)。在您的应用程序中,您应该通过 JNDI 或注释获取邮件会话,而不是使用 getInstance()。

    您需要将 SSL 证书从您的邮件服务器添加到 NodeDeafaultTrustStore。

    一般来说,在 WebSphere 中,您应该避免更改任何 javax.net.ssl 系统属性。

    答案更新

    Marek 这是我的测试代码(片段)。我能够成功连接(我使用的是 WAS v8.5.5)。看看下面的日志。

    您的应用程序中是否还有其他 jars?请删除任何第三方 jar,例如 mail.jar、activation.jar 等...

    public class IMapTest extends HttpServlet {
    private static final long serialVersionUID = 1L;
    @Resource(name="mail", lookup="mail/test")
    Session mailSession;
    
    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        System.out.println("Accessing session");
        try {
            Store store = mailSession.getStore();
            System.out.println("gotStore");
            store.connect("user", "pass");
            System.out.println("connected!");
        } catch (NoSuchProviderException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (MessagingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }   
    
    }
    

    }

    日志(片段):

    [6/25/14 22:25:26:615 CEST] 0000007e SystemOut     O DEBUG: JavaMail version 1.4.2
    [6/25/14 22:25:26:615 CEST] 0000007e SystemOut     O DEBUG: successfully loaded resource: /META-INF/javamail.default.providers
    [6/25/14 22:25:26:615 CEST] 0000007e SystemOut     O DEBUG: Tables of loaded providers
    ...    
    [6/25/14 22:25:26:615 CEST] 0000007e SystemOut     O DEBUG: successfully loaded resource: /META-INF/javamail.default.address.map
    [6/25/14 22:25:26:615 CEST] 0000007e SystemOut     O *** In SessionFactory.getObjectInstance, session properties:
    [6/25/14 22:25:26:615 CEST] 0000007e SystemOut     O    mail.store.protocol=imaps
    [6/25/14 22:25:26:615 CEST] 0000007e SystemOut     O    mail.imaps.class=com.sun.mail.imap.IMAPSSLStore
    [6/25/14 22:25:26:615 CEST] 0000007e SystemOut     O    mail.debug=true
    [6/25/14 22:25:26:615 CEST] 0000007e SystemOut     O    mail.pop3s.class=com.sun.mail.pop3.POP3SSLStore
    [6/25/14 22:25:26:615 CEST] 0000007e SystemOut     O    mail.smtp.class=com.sun.mail.smtp.SMTPTransport
    [6/25/14 22:25:26:615 CEST] 0000007e SystemOut     O    mail.imaps.host=imap.gmail.com
    [6/25/14 22:25:26:615 CEST] 0000007e SystemOut     O    mail.smtps.class=com.sun.mail.smtp.SMTPSSLTransport
    [6/25/14 22:25:26:615 CEST] 0000007e SystemOut     O    mail.imap.class=com.sun.mail.imap.IMAPStore
    [6/25/14 22:25:26:615 CEST] 0000007e SystemOut     O    mail.mime.address.strict=true
    [6/25/14 22:25:26:615 CEST] 0000007e SystemOut     O    mail.pop3.class=com.sun.mail.pop3.POP3Store
    [6/25/14 22:25:26:630 CEST] 0000007e ServletWrappe I com.ibm.ws.webcontainer.servlet.ServletWrapper init SRVE0242I:  [servlet.IMapTest]: Initialization successful.
    [6/25/14 22:25:26:630 CEST] 0000007e SystemOut     O Accessing session
    [6/25/14 22:25:26:630 CEST] 0000007e SystemOut     O DEBUG: mail.imaps.class property exists and points to com.sun.mail.imap.IMAPSSLStore
    [6/25/14 22:25:26:646 CEST] 0000007e SystemOut     O DEBUG: mail.imap.fetchsize: 16384
    [6/25/14 22:25:26:646 CEST] 0000007e SystemOut     O DEBUG: mail.imap.statuscachetimeout: 1000
    [6/25/14 22:25:26:646 CEST] 0000007e SystemOut     O DEBUG: mail.imap.appendbuffersize: -1
    [6/25/14 22:25:26:646 CEST] 0000007e SystemOut     O DEBUG: mail.imap.minidletime: 10
    [6/25/14 22:25:26:646 CEST] 0000007e SystemOut     O gotStore
    [6/25/14 22:25:26:646 CEST] 0000007e SystemOut     O **DEBUG: trying to connect to host "imap.gmail.com", port 993, isSSL true**
    [6/25/14 22:25:27:380 CEST] 0000007e SystemOut     O * OK Gimap ready for requests from 
    ...
    [6/25/14 22:25:27:474 CEST] 0000007e SystemOut     O DEBUG: protocolConnect login, host=imap.gmail.com, user=uuuu, password=pass
    [6/25/14 22:25:28:599 CEST] 0000007e SystemOut     O connected!
    

    【讨论】:

    • 感谢您的回复。目标是在属性的某处定义邮件服务器。然后,我们有几个邮件帐户,对于每个帐户(不同的用户),我们希望从邮件服务器的收件箱中读取邮件并将它们存储在数据库中。如何使用 Websphere 7 实现这一目标?
    • 如果我不使用 SSL (imaps),我发布的示例代码可以正常工作。我的想法是我的方法是对的,只是忘记设置一些东西,我不知道。我在 NodeDefaultTrustStore 中有我的邮件服务器的 SSL 证书,我使用管理控制台“从端口读取”。
    • 这是一个复杂的项目,我们在 WEB-INF/lib 目录中有很多第三方 jars。我找到了geronimo 邮件、邮件和激活并删除了它们。但问题仍然存在。我试图在 findjar.com 中查找哪些 jar 包含 javax.mail,但看起来我的项目中没有这样的 jar。奇怪的问题...
    • 使用我的代码创建新项目进行测试,看看它是否有效,那么您现在将知道它是服务器配置还是您的应用程序。还要检查您是否有任何与 jsse 相关的库(或粘贴您的 WEB-INF/lib 的列表)。
    • 我现在手头没有 v7。稍后我将检查它在 v7 上的工作方式。这很奇怪。除了导入证书之外,您是否更改了任何其他与 SSL 相关的设置?或者设置任何会改变默认安全提供者的环境变量?
    【解决方案2】:

    需要将 javax.net.ssl.* 属性设置为系统属性,而不是 JavaMail 会话属性。虽然我希望如果根本没有设置它们,将使用一些合理的默认值。

    【讨论】:

      猜你喜欢
      • 2015-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-13
      • 1970-01-01
      • 2017-12-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多