in geronimo-javamail_1.3.1/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/transport/smtp/SMTPTransport.java [1182:1303]
protected void getConnectedSSLSocket() throws IOException {
if (debug) {
debugOut("Attempting SSL socket connection to server " + host + ":" + port);
}
// the socket factory can be specified via a protocol property, a
// session property, and if all else
// fails (which it usually does), we fall back to the standard factory
// class.
String socketFactory = getProtocolProperty(MAIL_SMTP_FACTORY_CLASS, getSessionProperty(MAIL_SSLFACTORY_CLASS,
"javax.net.ssl.SSLSocketFactory"));
// there are several protocol properties that can be set to tune the
// created socket. We need to
// retrieve those bits before creating the socket.
int timeout = getIntProtocolProperty(MAIL_SMTP_TIMEOUT, -1);
InetAddress localAddress = null;
// see if we have a local address override.
String localAddrProp = getProtocolProperty(MAIL_SMTP_LOCALADDRESS);
if (localAddrProp != null) {
localAddress = InetAddress.getByName(localAddrProp);
}
// check for a local port...default is to allow socket to choose.
int localPort = getIntProtocolProperty(MAIL_SMTP_LOCALPORT, 0);
socket = null;
// if there is no socket factory defined (normal), we just create a
// socket directly.
if (socketFactory == null) {
socket = new Socket(host, port, localAddress, localPort);
}
else {
// we'll try this with potentially two different factories if we're
// allowed to fall back.
boolean fallback = isProtocolPropertyTrue(MAIL_SMTP_FACTORY_FALLBACK);
while (true) {
try {
if (debug) {
debugOut("Creating SSL socket using factory " + socketFactory);
}
int socketFactoryPort = getIntProtocolProperty(MAIL_SMTP_FACTORY_PORT, -1);
// we choose the port used by the socket based on overrides.
Integer portArg = new Integer(socketFactoryPort == -1 ? port : socketFactoryPort);
// use the current context loader to resolve this.
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class factoryClass = loader.loadClass(socketFactory);
// done indirectly, we need to invoke the method using
// reflection.
// This retrieves a factory instance.
Method getDefault = factoryClass.getMethod("getDefault", new Class[0]);
Object defFactory = getDefault.invoke(new Object(), new Object[0]);
// now that we have the factory, there are two different
// createSocket() calls we use,
// depending on whether we have a localAddress override.
if (localAddress != null) {
// retrieve the createSocket(String, int, InetAddress,
// int) method.
Class[] createSocketSig = new Class[] { String.class, Integer.TYPE, InetAddress.class,
Integer.TYPE };
Method createSocket = factoryClass.getMethod("createSocket", createSocketSig);
Object[] createSocketArgs = new Object[] { host, portArg, localAddress, new Integer(localPort) };
socket = (Socket) createSocket.invoke(defFactory, createSocketArgs);
} else {
// retrieve the createSocket(String, int) method.
Class[] createSocketSig = new Class[] { String.class, Integer.TYPE };
Method createSocket = factoryClass.getMethod("createSocket", createSocketSig);
Object[] createSocketArgs = new Object[] { host, portArg };
socket = (Socket) createSocket.invoke(defFactory, createSocketArgs);
}
// now break out and configure the socket.
break;
} catch (Throwable e) {
// if we're allowed to fallback, then use the default
// factory and try this again. We only
// allow this to happen once.
if (fallback) {
if (debug) {
debugOut("First attempt at creating SSL socket failed, falling back to default factory");
}
socketFactory = "javax.net.ssl.SSLSocketFactory";
fallback = false;
continue;
}
// we have an exception. We're going to throw an
// IOException, which may require unwrapping
// or rewrapping the exception.
else {
// we have an exception from the reflection, so unwrap
// the base exception
if (e instanceof InvocationTargetException) {
e = ((InvocationTargetException) e).getTargetException();
}
if (debug) {
debugOut("Failure creating SSL socket", e);
}
// throw this as an IOException, with the original
// exception attached.
IOException ioe = new IOException("Error connecting to " + host + ", " + port);
ioe.initCause(e);
throw ioe;
}
}
}
}
if (timeout >= 0) {
socket.setSoTimeout(timeout);
}
}