FileDocCategorySizeDatePackage
Session.javaAPI DocJavaMail 1.4.344521Tue Nov 17 10:38:12 GMT 2009javax.mail

Session

public final class Session extends Object
The Session class represents a mail session and is not subclassed. It collects together properties and defaults used by the mail API's. A single default session can be shared by multiple applications on the desktop. Unshared sessions can also be created.

The Session class provides access to the protocol providers that implement the Store, Transport, and related classes. The protocol providers are configured using the following files:

  • javamail.providers and javamail.default.providers
  • javamail.address.map and javamail.default.address.map

Each javamail.X resource file is searched for using three methods in the following order:

  1. java.home/lib/javamail.X
  2. META-INF/javamail.X
  3. META-INF/javamail.default.X

The first method allows the user to include their own version of the resource file by placing it in the lib directory where the java.home property points. The second method allows an application that uses the JavaMail APIs to include their own resource files in their application's or jar file's META-INF directory. The javamail.default.X default files are part of the JavaMail mail.jar file.

File location depends upon how the ClassLoader method getResource is implemented. Usually, the getResource method searches through CLASSPATH until it finds the requested file and then stops. JDK 1.1 has a limitation that the number of files of each name that will be found in the CLASSPATH is limited to one. However, this only affects method two, above; method one is loaded from a specific location (if allowed by the SecurityManager) and method three uses a different name to ensure that the default resource file is always loaded successfully. J2SE 1.2 and later are not limited to one file of a given name.

The ordering of entries in the resource files matters. If multiple entries exist, the first entries take precedence over the later entries. For example, the first IMAP provider found will be set as the default IMAP implementation until explicitly changed by the application. The user- or system-supplied resource files augment, they do not override, the default files included with the JavaMail APIs. This means that all entries in all files loaded will be available.

javamail.providers and javamail.default.providers

These resource files specify the stores and transports that are available on the system, allowing an application to "discover" what store and transport implementations are available. The protocol implementations are listed one per line. The file format defines four attributes that describe a protocol implementation. Each attribute is an "="-separated name-value pair with the name in lowercase. Each name-value pair is semi-colon (";") separated. The following names are defined.

Attribute Names in Providers Files
NameDescription
protocol Name assigned to protocol. For example, smtp for Transport.
type Valid entries are store and transport.
class Class name that implements this protocol.
vendor Optional string identifying the vendor.
version Optional string identifying the version.

Here's an example of META-INF/javamail.default.providers file contents:

protocol=imap; type=store; class=com.sun.mail.imap.IMAPStore; vendor=Sun Microsystems, Inc.;
protocol=smtp; type=transport; class=com.sun.mail.smtp.SMTPTransport; vendor=Sun Microsystems, Inc.;

javamail.address.map and javamail.default.address.map

These resource files map transport address types to the transport protocol. The getType method of javax.mail.Address returns the address type. The javamail.address.map file maps the transport type to the protocol. The file format is a series of name-value pairs. Each key name should correspond to an address type that is currently installed on the system; there should also be an entry for each javax.mail.Address implementation that is present if it is to be used. For example, the javax.mail.internet.InternetAddress method getType returns "rfc822". Each referenced protocol should be installed on the system. For the case of news, below, the client should install a Transport provider supporting the nntp protocol.

Here are the typical contents of a javamail.address.map file:

rfc822=smtp
news=nntp
author
John Mani
author
Bill Shannon
author
Max Spivak

Fields Summary
private final Properties
props
private final Authenticator
authenticator
private final Hashtable
authTable
private boolean
debug
private PrintStream
out
private final Vector
providers
private final Hashtable
providersByProtocol
private final Hashtable
providersByClassName
private final Properties
addressMap
private static Session
defaultSession
Constructors Summary
private Session(Properties props, Authenticator authenticator)


    // Constructor is not public
         
	this.props = props;
	this.authenticator = authenticator;

	if (Boolean.valueOf(props.getProperty("mail.debug")).booleanValue())
	    debug = true;

	if (debug)
	    pr("DEBUG: JavaMail version " + Version.version);

	// get the Class associated with the Authenticator
	Class cl;
	if (authenticator != null)
	    cl = authenticator.getClass();
	else
	    cl = this.getClass();
	// load the resources
	loadProviders(cl);
	loadAddressMap(cl);
    
Methods Summary
public synchronized voidaddProvider(javax.mail.Provider provider)
Add a provider to the session.

param
provider the provider to add
since
JavaMail 1.4

	providers.addElement(provider);
	providersByClassName.put(provider.getClassName(), provider);
	if (!providersByProtocol.containsKey(provider.getProtocol()))
	    providersByProtocol.put(provider.getProtocol(), provider);
    
private static java.lang.ClassLoadergetContextClassLoader()

	return (ClassLoader)
		AccessController.doPrivileged(new PrivilegedAction() {
	    public Object run() {
		ClassLoader cl = null;
		try {
		    cl = Thread.currentThread().getContextClassLoader();
		} catch (SecurityException ex) { }
		return cl;
	    }
	});
    
public synchronized booleangetDebug()
Get the debug setting for this Session.

return
current debug setting

	return debug;
    
public synchronized java.io.PrintStreamgetDebugOut()
Returns the stream to be used for debugging output. If no stream has been set, System.out is returned.

return
the PrintStream to use for debugging output
since
JavaMail 1.3

	if (out == null)
	    return System.out;
	else
	    return out;
    
public static synchronized javax.mail.SessiongetDefaultInstance(java.util.Properties props, javax.mail.Authenticator authenticator)
Get the default Session object. If a default has not yet been setup, a new Session object is created and installed as the default.

Since the default session is potentially available to all code executing in the same Java virtual machine, and the session can contain security sensitive information such as user names and passwords, access to the default session is restricted. The Authenticator object, which must be created by the caller, is used indirectly to check access permission. The Authenticator object passed in when the session is created is compared with the Authenticator object passed in to subsequent requests to get the default session. If both objects are the same, or are from the same ClassLoader, the request is allowed. Otherwise, it is denied.

Note that if the Authenticator object used to create the session is null, anyone can get the default session by passing in null.

Note also that the Properties object is used only the first time this method is called, when a new Session object is created. Subsequent calls return the Session object that was created by the first call, and ignore the passed Properties object. Use the getInstance method to get a new Session object every time the method is called.

In JDK 1.2, additional security Permission objects may be used to control access to the default session.

param
props Properties object. Used only if a new Session object is created.
It is expected that the client supplies values for the properties listed in Appendix A of the JavaMail spec (particularly mail.store.protocol, mail.transport.protocol, mail.host, mail.user, and mail.from) as the defaults are unlikely to work in all cases.
param
authenticator Authenticator object. Used only if a new Session object is created. Otherwise, it must match the Authenticator used to create the Session.
return
the default Session object

	if (defaultSession == null)
	    defaultSession = new Session(props, authenticator);
	else {
	    // have to check whether caller is allowed to see default session
	    if (defaultSession.authenticator == authenticator)
		;	// either same object or both null, either way OK
	    else if (defaultSession.authenticator != null &&
		    authenticator != null &&
		    defaultSession.authenticator.getClass().getClassLoader() ==
			authenticator.getClass().getClassLoader())
		;	// both objects came from the same class loader, OK
	    else
		// anything else is not allowed
		throw new SecurityException("Access to default session denied");
	}

	return defaultSession;
    
public static javax.mail.SessiongetDefaultInstance(java.util.Properties props)
Get the default Session object. If a default has not yet been setup, a new Session object is created and installed as the default.

Note that a default session created with no Authenticator is available to all code executing in the same Java virtual machine, and the session can contain security sensitive information such as user names and passwords.

param
props Properties object. Used only if a new Session object is created.
It is expected that the client supplies values for the properties listed in Appendix A of the JavaMail spec (particularly mail.store.protocol, mail.transport.protocol, mail.host, mail.user, and mail.from) as the defaults are unlikely to work in all cases.
return
the default Session object
since
JavaMail 1.2

        return getDefaultInstance(props, null);
    
public javax.mail.FoldergetFolder(javax.mail.URLName url)
Get a closed Folder object for the given URLName. If the requested Folder object cannot be obtained, null is returned.

The "scheme" part of the URL string (Refer RFC 1738) is used to locate the Store protocol. The rest of the URL string (that is, the "schemepart", as per RFC 1738) is used by that Store in a protocol dependent manner to locate and instantiate the appropriate Folder object.

Note that RFC 1738 also specifies the syntax for the "schemepart" for IP-based protocols (IMAP4, POP3, etc.). Providers of IP-based mail Stores should implement that syntax for referring to Folders.

param
url URLName that represents the desired folder
return
Folder
see
#getStore(URLName)
see
javax.mail.URLName
exception
NoSuchProviderException If a provider for the given URLName is not found.
exception
MessagingException if the Folder could not be located or created.

	// First get the Store
	Store store = getStore(url);
	store.connect();
	return store.getFolder(url);
    
public static javax.mail.SessiongetInstance(java.util.Properties props, javax.mail.Authenticator authenticator)
Get a new Session object.

param
props Properties object that hold relevant properties.
It is expected that the client supplies values for the properties listed in Appendix A of the JavaMail spec (particularly mail.store.protocol, mail.transport.protocol, mail.host, mail.user, and mail.from) as the defaults are unlikely to work in all cases.
param
authenticator Authenticator object used to call back to the application when a user name and password is needed.
return
a new Session object
see
javax.mail.Authenticator

	return new Session(props, authenticator);
    
public static javax.mail.SessiongetInstance(java.util.Properties props)
Get a new Session object.

param
props Properties object that hold relevant properties.
It is expected that the client supplies values for the properties listed in Appendix A of the JavaMail spec (particularly mail.store.protocol, mail.transport.protocol, mail.host, mail.user, and mail.from) as the defaults are unlikely to work in all cases.
return
a new Session object
since
JavaMail 1.2

	return new Session(props, null);
    
public javax.mail.PasswordAuthenticationgetPasswordAuthentication(javax.mail.URLName url)
Return any saved PasswordAuthentication for this (store or transport) URLName. Normally used only by store or transport implementations.

return
the PasswordAuthentication corresponding to the URLName

	return (PasswordAuthentication)authTable.get(url);
    
public java.util.PropertiesgetProperties()
Returns the Properties object associated with this Session

return
Properties object

 
   	return props; 
    
public java.lang.StringgetProperty(java.lang.String name)
Returns the value of the specified property. Returns null if this property does not exist.

return
String that is the property value

 
   	return props.getProperty(name); 
    
public synchronized javax.mail.ProvidergetProvider(java.lang.String protocol)
Returns the default Provider for the protocol specified. Checks mail.<protocol>.class property first and if it exists, returns the Provider associated with this implementation. If it doesn't exist, returns the Provider that appeared first in the configuration files. If an implementation for the protocol isn't found, throws NoSuchProviderException

param
protocol Configured protocol (i.e. smtp, imap, etc)
return
Currently configured Provider for the specified protocol
exception
NoSuchProviderException If a provider for the given protocol is not found.


	if (protocol == null || protocol.length() <= 0) {
	    throw new NoSuchProviderException("Invalid protocol: null");
	}

	Provider _provider = null;

	// check if the mail.<protocol>.class property exists
	String _className = props.getProperty("mail."+protocol+".class");
	if (_className != null) {
	    if (debug) {
		pr("DEBUG: mail."+protocol+
				   ".class property exists and points to " + 
				   _className);
	    }
	    _provider = (Provider)providersByClassName.get(_className);
	} 

	if (_provider != null) {
	    return _provider;
	} else {
	    // returning currently default protocol in providersByProtocol
	    _provider = (Provider)providersByProtocol.get(protocol);
	}

	if (_provider == null) {
	    throw new NoSuchProviderException("No provider for " + protocol);
	} else {
	    if (debug) {
		pr("DEBUG: getProvider() returning " + 
				   _provider.toString());
	    }
	    return _provider;
	}
    
public synchronized javax.mail.Provider[]getProviders()
This method returns an array of all the implementations installed via the javamail.[default.]providers files that can be loaded using the ClassLoader available to this application.

return
Array of configured providers

	Provider[] _providers = new Provider[providers.size()];
	providers.copyInto(_providers);
	return _providers;
    
private static java.io.InputStreamgetResourceAsStream(java.lang.Class c, java.lang.String name)

	try {
	    return (InputStream)
		AccessController.doPrivileged(new PrivilegedExceptionAction() {
		    public Object run() throws IOException {
			return c.getResourceAsStream(name);
		    }
		});
	} catch (PrivilegedActionException e) {
	    throw (IOException)e.getException();
	}
    
private static java.net.URL[]getResources(java.lang.ClassLoader cl, java.lang.String name)

	return (URL[])
		AccessController.doPrivileged(new PrivilegedAction() {
	    public Object run() {
		URL[] ret = null;
		try {
		    Vector v = new Vector();
		    Enumeration e = cl.getResources(name);
		    while (e != null && e.hasMoreElements()) {
			URL url = (URL)e.nextElement();
			if (url != null)
			    v.addElement(url);
		    }
		    if (v.size() > 0) {
			ret = new URL[v.size()];
			v.copyInto(ret);
		    }
		} catch (IOException ioex) {
		} catch (SecurityException ex) { }
		return ret;
	    }
	});
    
private java.lang.ObjectgetService(javax.mail.Provider provider, javax.mail.URLName url)
Get a Service object. Needs a provider object, but will create a URLName if needed. It attempts to instantiate the correct class.

param
provider which provider to use
param
url which URLName to use (can be null)
exception
NoSuchProviderException thrown when the class cannot be found or when it does not have the correct constructor (Session, URLName), or if it is not derived from Service.

	// need a provider and url
	if (provider == null) {
	    throw new NoSuchProviderException("null");
	}

	// create a url if needed
	if (url == null) {
	    url = new URLName(provider.getProtocol(), null, -1, 
			      null, null, null);
	}

	Object service = null;
	
	// get the ClassLoader associated with the Authenticator
	ClassLoader cl;
	if (authenticator != null)
	    cl = authenticator.getClass().getClassLoader();
	else
	    cl = this.getClass().getClassLoader();

	// now load the class
	Class serviceClass = null;
	try {
	    // First try the "application's" class loader.
	    ClassLoader ccl = getContextClassLoader();
	    if (ccl != null)
		try {
		    serviceClass =
			Class.forName(provider.getClassName(), false, ccl);
		} catch (ClassNotFoundException ex) {
		    // ignore it
		}
	    if (serviceClass == null)
		serviceClass =
		    Class.forName(provider.getClassName(), false, cl);
	} catch (Exception ex1) {
	    // That didn't work, now try the "system" class loader.
	    // (Need both of these because JDK 1.1 class loaders
	    // may not delegate to their parent class loader.)
	    try {
		serviceClass = Class.forName(provider.getClassName());
	    } catch (Exception ex) {
		// Nothing worked, give up.
		if (debug) ex.printStackTrace(getDebugOut());
		throw new NoSuchProviderException(provider.getProtocol());
	    }
	}

	// construct an instance of the class
	try {
	    Class[] c = {javax.mail.Session.class, javax.mail.URLName.class};
	    Constructor cons = serviceClass.getConstructor(c);

	    Object[] o = {this, url};
	    service = cons.newInstance(o);

	} catch (Exception ex) {
	    if (debug) ex.printStackTrace(getDebugOut());
	    throw new NoSuchProviderException(provider.getProtocol());
	}

	return service;
    
public javax.mail.StoregetStore()
Get a Store object that implements this user's desired Store protocol. The mail.store.protocol property specifies the desired protocol. If an appropriate Store object is not obtained, NoSuchProviderException is thrown

return
a Store object
exception
NoSuchProviderException If a provider for the given protocol is not found.

	return getStore(getProperty("mail.store.protocol"));
    
public javax.mail.StoregetStore(java.lang.String protocol)
Get a Store object that implements the specified protocol. If an appropriate Store object cannot be obtained, NoSuchProviderException is thrown.

param
protocol
return
a Store object
exception
NoSuchProviderException If a provider for the given protocol is not found.

	return getStore(new URLName(protocol, null, -1, null, null, null));
    
public javax.mail.StoregetStore(javax.mail.URLName url)
Get a Store object for the given URLName. If the requested Store object cannot be obtained, NoSuchProviderException is thrown. The "scheme" part of the URL string (Refer RFC 1738) is used to locate the Store protocol.

param
url URLName that represents the desired Store
return
a closed Store object
see
#getFolder(URLName)
see
javax.mail.URLName
exception
NoSuchProviderException If a provider for the given URLName is not found.

	String protocol = url.getProtocol();
	Provider p = getProvider(protocol);
	return getStore(p, url);
    
public javax.mail.StoregetStore(javax.mail.Provider provider)
Get an instance of the store specified by Provider. Instantiates the store and returns it.

param
provider Store Provider that will be instantiated
return
Instantiated Store
exception
NoSuchProviderException If a provider for the given Provider is not found.

	return getStore(provider, null);
    
private javax.mail.StoregetStore(javax.mail.Provider provider, javax.mail.URLName url)
Get an instance of the store specified by Provider. If the URLName is not null, uses it, otherwise creates a new one. Instantiates the store and returns it. This is a private method used by getStore(Provider) and getStore(URLName)

param
provider Store Provider that will be instantiated
param
url URLName used to instantiate the Store
return
Instantiated Store
exception
NoSuchProviderException If a provider for the given Provider/URLName is not found.


	// make sure we have the correct type of provider
	if (provider == null || provider.getType() != Provider.Type.STORE ) {
	    throw new NoSuchProviderException("invalid provider");
	}
		
	try {
	    return (Store) getService(provider, url);
	} catch (ClassCastException cce) {
	    throw new NoSuchProviderException("incorrect class");
	}
    
private static java.net.URL[]getSystemResources(java.lang.String name)

	return (URL[])
		AccessController.doPrivileged(new PrivilegedAction() {
	    public Object run() {
		URL[] ret = null;
		try {
		    Vector v = new Vector();
		    Enumeration e = ClassLoader.getSystemResources(name);
		    while (e != null && e.hasMoreElements()) {
			URL url = (URL)e.nextElement();
			if (url != null)
			    v.addElement(url);
		    }
		    if (v.size() > 0) {
			ret = new URL[v.size()];
			v.copyInto(ret);
		    }
		} catch (IOException ioex) {
		} catch (SecurityException ex) { }
		return ret;
	    }
	});
    
public javax.mail.TransportgetTransport()
Get a Transport object that implements this user's desired Transport protcol. The mail.transport.protocol property specifies the desired protocol. If an appropriate Transport object cannot be obtained, MessagingException is thrown.

return
a Transport object
exception
NoSuchProviderException If the provider is not found.

        return getTransport(getProperty("mail.transport.protocol"));
    
public javax.mail.TransportgetTransport(java.lang.String protocol)
Get a Transport object that implements the specified protocol. If an appropriate Transport object cannot be obtained, null is returned.

return
a Transport object
exception
NoSuchProviderException If provider for the given protocol is not found.

	return getTransport(new URLName(protocol, null, -1, null, null, null));
    
public javax.mail.TransportgetTransport(javax.mail.URLName url)
Get a Transport object for the given URLName. If the requested Transport object cannot be obtained, NoSuchProviderException is thrown. The "scheme" part of the URL string (Refer RFC 1738) is used to locate the Transport protocol.

param
url URLName that represents the desired Transport
return
a closed Transport object
see
javax.mail.URLName
exception
NoSuchProviderException If a provider for the given URLName is not found.

	String protocol = url.getProtocol();
	Provider p = getProvider(protocol);
	return getTransport(p, url);
    
public javax.mail.TransportgetTransport(javax.mail.Provider provider)
Get an instance of the transport specified in the Provider. Instantiates the transport and returns it.

param
provider Transport Provider that will be instantiated
return
Instantiated Transport
exception
NoSuchProviderException If provider for the given provider is not found.

	return getTransport(provider, null);
    
public javax.mail.TransportgetTransport(javax.mail.Address address)
Get a Transport object that can transport a Message of the specified address type.

param
address
return
A Transport object
see
javax.mail.Address
exception
NoSuchProviderException If provider for the Address type is not found


	String transportProtocol;
	transportProtocol =
	    getProperty("mail.transport.protocol." + address.getType());
	if (transportProtocol != null)
	    return getTransport(transportProtocol);
	transportProtocol = (String)addressMap.get(address.getType());
	if (transportProtocol != null)
	    return getTransport(transportProtocol);
	throw new NoSuchProviderException("No provider for Address type: "+
						address.getType());
    
private javax.mail.TransportgetTransport(javax.mail.Provider provider, javax.mail.URLName url)
Get a Transport object using the given provider and urlname.

param
provider the provider to use
param
url urlname to use (can be null)
return
A Transport object
exception
NoSuchProviderException If no provider or the provider was the wrong class.

	// make sure we have the correct type of provider
	if (provider == null || provider.getType() != Provider.Type.TRANSPORT) {
	    throw new NoSuchProviderException("invalid provider");
	}

	try {
	    return (Transport) getService(provider, url);
	} catch (ClassCastException cce) {
	    throw new NoSuchProviderException("incorrect class");
	}
    
private voidloadAddressMap(java.lang.Class cl)

	StreamLoader loader = new StreamLoader() {
	    public void load(InputStream is) throws IOException {
		addressMap.load(is);
	    }
	};

	// load default META-INF/javamail.default.address.map from mail.jar
	loadResource("/META-INF/javamail.default.address.map", cl, loader);

	// load the META-INF/javamail.address.map file supplied by an app
	loadAllResources("META-INF/javamail.address.map", cl, loader);

	// load system-wide javamail.address.map from the <java.home>/lib dir
	try {
	    String res = System.getProperty("java.home") + 
				File.separator + "lib" + 
				File.separator + "javamail.address.map";
	    loadFile(res, loader);
	} catch (SecurityException sex) {
	    if (debug)
		pr("DEBUG: can't get java.home: " + sex);
	}

	if (addressMap.isEmpty()) {
	    if (debug)
		pr("DEBUG: failed to load address map, using defaults");
	    addressMap.put("rfc822", "smtp");
	}
    
private voidloadAllResources(java.lang.String name, java.lang.Class cl, javax.mail.StreamLoader loader)
Load all of the named resource.

	boolean anyLoaded = false;
	try {
	    URL[] urls;
	    ClassLoader cld = null;
	    // First try the "application's" class loader.
	    cld = getContextClassLoader();
	    if (cld == null)
		cld = cl.getClassLoader();
	    if (cld != null)
		urls = getResources(cld, name);
	    else
		urls = getSystemResources(name);
	    if (urls != null) {
		for (int i = 0; i < urls.length; i++) {
		    URL url = urls[i];
		    InputStream clis = null;
		    if (debug)
			pr("DEBUG: URL " + url);
		    try {
			clis = openStream(url);
			if (clis != null) {
			    loader.load(clis);
			    anyLoaded = true;
			    if (debug)
				pr("DEBUG: successfully loaded resource: " +
				    url);
			} else {
			    if (debug)
				pr("DEBUG: not loading resource: " + url);
			}
		    } catch (FileNotFoundException fex) {
			// ignore it
		    } catch (IOException ioex) {
			if (debug)
			    pr("DEBUG: " + ioex);
		    } catch (SecurityException sex) {
			if (debug)
			    pr("DEBUG: " + sex);
		    } finally {
			try {
			    if (clis != null)
				clis.close();
			} catch (IOException cex) { }
		    }
		}
	    }
	} catch (Exception ex) {
	    if (debug)
		pr("DEBUG: " + ex);
	}

	// if failed to load anything, fall back to old technique, just in case
	if (!anyLoaded) {
	    /*
	    if (debug)
		pr("DEBUG: !anyLoaded");
	    */
	    loadResource("/" + name, cl, loader);
	}
    
private voidloadFile(java.lang.String name, javax.mail.StreamLoader loader)
Load from the named file.

	InputStream clis = null;
	try {
	    clis = new BufferedInputStream(new FileInputStream(name));
	    loader.load(clis);
	    if (debug)
		pr("DEBUG: successfully loaded file: " + name);
	} catch (FileNotFoundException fex) {
	    // ignore it
	} catch (IOException e) {
	    if (debug) {
		pr("DEBUG: not loading file: " + name);
		pr("DEBUG: " + e);
	    }
	} catch (SecurityException sex) {
	    if (debug) {
		pr("DEBUG: not loading file: " + name);
		pr("DEBUG: " + sex);
	    }
	} finally {
	    try {
		if (clis != null)
		    clis.close();
	    } catch (IOException ex) { }	// ignore it
	}
    
private voidloadProviders(java.lang.Class cl)
Load the protocol providers config files.

	StreamLoader loader = new StreamLoader() {
	    public void load(InputStream is) throws IOException {
		loadProvidersFromStream(is);
	    }
	};

	// load system-wide javamail.providers from the <java.home>/lib dir
	try {
	    String res = System.getProperty("java.home") + 
				File.separator + "lib" + 
				File.separator + "javamail.providers";
	    loadFile(res, loader);
	} catch (SecurityException sex) {
	    if (debug)
		pr("DEBUG: can't get java.home: " + sex);
	}

	// load the META-INF/javamail.providers file supplied by an application
	loadAllResources("META-INF/javamail.providers", cl, loader);

	// load default META-INF/javamail.default.providers from mail.jar file
	loadResource("/META-INF/javamail.default.providers", cl, loader);

	if (providers.size() == 0) {
	    if (debug)
		pr("DEBUG: failed to load any providers, using defaults");
	    // failed to load any providers, initialize with our defaults
	    addProvider(new Provider(Provider.Type.STORE,
			"imap", "com.sun.mail.imap.IMAPStore",
			"Sun Microsystems, Inc.", Version.version));
	    addProvider(new Provider(Provider.Type.STORE,
			"imaps", "com.sun.mail.imap.IMAPSSLStore",
			"Sun Microsystems, Inc.", Version.version));
	    addProvider(new Provider(Provider.Type.STORE,
			"pop3", "com.sun.mail.pop3.POP3Store",
			"Sun Microsystems, Inc.", Version.version));
	    addProvider(new Provider(Provider.Type.STORE,
			"pop3s", "com.sun.mail.pop3.POP3SSLStore",
			"Sun Microsystems, Inc.", Version.version));
	    addProvider(new Provider(Provider.Type.TRANSPORT,
			"smtp", "com.sun.mail.smtp.SMTPTransport",
			"Sun Microsystems, Inc.", Version.version));
	    addProvider(new Provider(Provider.Type.TRANSPORT,
			"smtps", "com.sun.mail.smtp.SMTPSSLTransport",
			"Sun Microsystems, Inc.", Version.version));
	}

	if (debug) {
	    // dump the output of the tables for debugging
	    pr("DEBUG: Tables of loaded providers");
	    pr("DEBUG: Providers Listed By Class Name: " + 
	       providersByClassName.toString());
	    pr("DEBUG: Providers Listed By Protocol: " + 
	       providersByProtocol.toString());
	}
    
private voidloadProvidersFromStream(java.io.InputStream is)

	if (is != null) {
	    LineInputStream lis = new LineInputStream(is);
	    String currLine;

	    // load and process one line at a time using LineInputStream
	    while ((currLine = lis.readLine()) != null) {

		if (currLine.startsWith("#"))
		    continue;
		Provider.Type type = null;
		String protocol = null, className = null;
		String vendor = null, version = null;
		    
		// separate line into key-value tuples
		StringTokenizer tuples = new StringTokenizer(currLine,";");
		while (tuples.hasMoreTokens()) {
		    String currTuple = tuples.nextToken().trim();
			
		    // set the value of each attribute based on its key
		    int sep = currTuple.indexOf("=");
		    if (currTuple.startsWith("protocol=")) {
			protocol = currTuple.substring(sep+1);
		    } else if (currTuple.startsWith("type=")) {
			String strType = currTuple.substring(sep+1);
			if (strType.equalsIgnoreCase("store")) {
			    type = Provider.Type.STORE;
			} else if (strType.equalsIgnoreCase("transport")) {
			    type = Provider.Type.TRANSPORT;
		    	}
		    } else if (currTuple.startsWith("class=")) {
			className = currTuple.substring(sep+1);
		    } else if (currTuple.startsWith("vendor=")) {
			vendor = currTuple.substring(sep+1);
		    } else if (currTuple.startsWith("version=")) {
			version = currTuple.substring(sep+1);
		    }
		}

		// check if a valid Provider; else, continue
		if (type == null || protocol == null || className == null 
		    || protocol.length() <= 0 || className.length() <= 0) {
			
		    if (debug)
			pr("DEBUG: Bad provider entry: " + currLine);
		    continue;
		}
		Provider provider = new Provider(type, protocol, className,
					         vendor, version);

		// add the newly-created Provider to the lookup tables
		addProvider(provider);
	    }
	}
    
private voidloadResource(java.lang.String name, java.lang.Class cl, javax.mail.StreamLoader loader)
Load from the named resource.

	InputStream clis = null;
	try {
	    clis = getResourceAsStream(cl, name);
	    if (clis != null) {
		loader.load(clis);
		if (debug)
		    pr("DEBUG: successfully loaded resource: " + name);
	    } else {
		/*
		if (debug)
		    pr("DEBUG: not loading resource: " + name);
		*/
	    }
	} catch (IOException e) {
	    if (debug)
		pr("DEBUG: " + e);
	} catch (SecurityException sex) {
	    if (debug)
		pr("DEBUG: " + sex);
	} finally {
	    try {
		if (clis != null)
		    clis.close();
	    } catch (IOException ex) { }	// ignore it
	}
    
private static java.io.InputStreamopenStream(java.net.URL url)

	try {
	    return (InputStream)
		AccessController.doPrivileged(new PrivilegedExceptionAction() {
		    public Object run() throws IOException {
			return url.openStream();
		    }
		});
	} catch (PrivilegedActionException e) {
	    throw (IOException)e.getException();
	}
    
private voidpr(java.lang.String str)

	getDebugOut().println(str);
    
public javax.mail.PasswordAuthenticationrequestPasswordAuthentication(java.net.InetAddress addr, int port, java.lang.String protocol, java.lang.String prompt, java.lang.String defaultUserName)
Call back to the application to get the needed user name and password. The application should put up a dialog something like:

Connecting to <protocol> mail service on host <addr>, port <port>.
<prompt>

User Name: <defaultUserName>
Password:

param
addr InetAddress of the host. may be null.
param
protocol protocol scheme (e.g. imap, pop3, etc.)
param
prompt any additional String to show as part of the prompt; may be null.
param
defaultUserName the default username. may be null.
return
the authentication which was collected by the authenticator; may be null.


	if (authenticator != null) {
	    return authenticator.requestPasswordAuthentication(
		addr, port, protocol, prompt, defaultUserName);
	} else {
	    return null;
	}
    
public synchronized voidsetDebug(boolean debug)
Set the debug setting for this Session.

Since the debug setting can be turned on only after the Session has been created, to turn on debugging in the Session constructor, set the property mail.debug in the Properties object passed in to the constructor to true. The value of the mail.debug property is used to initialize the per-Session debugging flag. Subsequent calls to the setDebug method manipulate the per-Session debugging flag and have no affect on the mail.debug property.

param
debug Debug setting

	this.debug = debug;
	if (debug)
	    pr("DEBUG: setDebug: JavaMail version " + Version.version);
    
public synchronized voidsetDebugOut(java.io.PrintStream out)
Set the stream to be used for debugging output for this session. If out is null, System.out will be used. Note that debugging output that occurs before any session is created, as a result of setting the mail.debug system property, will always be sent to System.out.

param
out the PrintStream to use for debugging output
since
JavaMail 1.3

	this.out = out;
    
public voidsetPasswordAuthentication(javax.mail.URLName url, javax.mail.PasswordAuthentication pw)
Save a PasswordAuthentication for this (store or transport) URLName. If pw is null the entry corresponding to the URLName is removed.

This is normally used only by the store or transport implementations to allow authentication information to be shared among multiple uses of a session.

	if (pw == null)
	    authTable.remove(url);
	else
	    authTable.put(url, pw);
    
public synchronized voidsetProtocolForAddress(java.lang.String addresstype, java.lang.String protocol)
Set the default transport protocol to use for addresses of the specified type. Normally the default is set by the javamail.default.address.map or javamail.address.map files or resources.

param
addresstype type of address
param
protocol name of protocol
see
#getTransport(Address)
since
JavaMail 1.4

	if (protocol == null)
	    addressMap.remove(addresstype);
	else
	    addressMap.put(addresstype, protocol);
    
public synchronized voidsetProvider(javax.mail.Provider provider)
Set the passed Provider to be the default implementation for the protocol in Provider.protocol overriding any previous values.

param
provider Currently configured Provider which will be set as the default for the protocol
exception
NoSuchProviderException If the provider passed in is invalid.

	if (provider == null) {
	    throw new NoSuchProviderException("Can't set null provider");
	}
	providersByProtocol.put(provider.getProtocol(), provider);
	props.put("mail." + provider.getProtocol() + ".class", 
		  provider.getClassName());