`
xiaolongfeixiang
  • 浏览: 236836 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

Tomcat6中JavaMail JNDI配置

阅读更多

最经在研究Tomcat,今天看到JNDI这一章,在测试Mail Session的配置时,发现了一个问题:在使用需要配置密码时,Tomcat会报错。

错误:
root cause

java.lang.NoClassDefFoundError: javax/mail/Authenticator
org.apache.naming.factory.MailSessionFactory.getObjectInstance(MailSessionFactory.java:105)
。。。。。。。。。。。。

root cause

java.lang.ClassNotFoundException: javax.mail.Authenticator

。。。。。。。。。。。。
 

(我的Tomcat是6.0.20,JDK1.6update14)

 

参看Tomcat的源码:

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.naming.factory;

import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.naming.Name;
import javax.naming.Context;
import javax.naming.RefAddr;
import javax.naming.Reference;
import javax.naming.spi.ObjectFactory;

/**
 * <p>Factory class that creates a JNDI named JavaMail Session factory,
 * which can be used for managing inbound and outbound electronic mail
 * messages via JavaMail APIs.  All messaging environment properties
 * described in the JavaMail Specification may be passed to the Session
 * factory; however the following properties are the most commonly used:</p>
 * <ul>
 * <li>
 * <li><strong>mail.smtp.host</strong> - Hostname for outbound transport
 *     connections.  Defaults to <code>localhost</code> if not specified.</li>
 * </ul>
 *
 * <p>This factory can be configured in a <code>&lt;DefaultContext&gt;</code>
 * or <code>&lt;Context&gt;</code> element in your <code>conf/server.xml</code>
 * configuration file.  An example of factory configuration is:</p>
 * <pre>
 * &lt;Resource name="mail/smtp" auth="CONTAINER"
 *           type="javax.mail.Session"/&gt;
 * &lt;ResourceParams name="mail/smtp"&gt;
 *   &lt;parameter&gt;
 *     &lt;name&gt;factory&lt;/name&gt;
 *     &lt;value&gt;org.apache.naming.factory.MailSessionFactory&lt;/value&gt;
 *   &lt;/parameter&gt;
 *   &lt;parameter&gt;
 *     &lt;name&gt;mail.smtp.host&lt;/name&gt;
 *     &lt;value&gt;mail.mycompany.com&lt;/value&gt;
 *   &lt;/parameter&gt;
 * &lt;/ResourceParams&gt;
 * </pre>
 *
 * @author Craig R. McClanahan
 * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (Tue, 24 Oct 2006) $
 */

public class MailSessionFactory implements ObjectFactory {


    /**
     * The Java type for which this factory knows how to create objects.
     */
    protected static final String factoryType = "javax.mail.Session";


    /**
     * Create and return an object instance based on the specified
     * characteristics.
     *
     * @param refObj Reference information containing our parameters, or null
     *  if there are no parameters
     * @param name The name of this object, relative to context, or null
     *  if there is no name
     * @param context The context to which name is relative, or null if name
     *  is relative to the default initial context
     * @param env Environment variables, or null if there are none
     *
     * @exception Exception if an error occurs during object creation
     */
    public Object getObjectInstance(Object refObj, Name name, Context context,
				    Hashtable env) throws Exception 
    {

        // Return null if we cannot create an object of the requested type
	final Reference ref = (Reference) refObj;
        if (!ref.getClassName().equals(factoryType))
            return (null);

        // Create a new Session inside a doPrivileged block, so that JavaMail
        // can read its default properties without throwing Security
        // exceptions.
        //
        // Bugzilla 31288, 33077: add support for authentication.
        return AccessController.doPrivileged( new PrivilegedAction() {
		public Object run() {

                    // Create the JavaMail properties we will use
                    Properties props = new Properties();
                    props.put("mail.transport.protocol", "smtp");
                    props.put("mail.smtp.host", "localhost");

                    String password = null;

                    Enumeration attrs = ref.getAll();
                    while (attrs.hasMoreElements()) {
                        RefAddr attr = (RefAddr) attrs.nextElement();
                        if ("factory".equals(attr.getType())) {
                            continue;
                        }

                        if ("password".equals(attr.getType())) {
                            password = (String) attr.getContent();
                            continue;
                        }

                        props.put(attr.getType(), (String) attr.getContent());
                    }

                    Authenticator auth = null;
                    if (password != null) {
                        String user = props.getProperty("mail.smtp.user");
                        if(user == null) {
                            user = props.getProperty("mail.user");
                        }
                        
                        if(user != null) {
                            final PasswordAuthentication pa = new PasswordAuthentication(user, password);
                            auth = new Authenticator() {
                                    protected PasswordAuthentication getPasswordAuthentication() {
                                        return pa;
                                    }
                                };
                        }
                    }

                    // Create and return the new Session object
                    Session session = Session.getInstance(props, auth);
                    return (session);

		}
	    } );

    }


}

 

第105行的代码是:

return AccessController.doPrivileged( new PrivilegedAction() {

 

如果不是AccessController的问题,那么我就不晓得问题出在哪了。自己写了个MySessionFactory的类:

package tomcat.jndi.provider;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.RefAddr;
import javax.naming.Reference;
import javax.naming.spi.ObjectFactory;

public class MySessionFactory implements ObjectFactory {

	public Object getObjectInstance(Object refObj, Name name, Context context,
			Hashtable<?, ?> environment) throws Exception {
		final Reference ref = (Reference) refObj;

		// 创建默认的Properties属性集
		Properties props = new Properties();
		props.put("mail.transport.protocol", "smtp");
		props.put("mail.smtp.host", "localhost");

		String password = null;

		// 遍历所有的设定参数
		Enumeration<RefAddr> attrs = ref.getAll();

		while (attrs.hasMoreElements()) {
			RefAddr attr = (RefAddr) attrs.nextElement();

			// 忽略factory参数
			if ("factory".equals(attr.getType())) {
				continue;
			}

			// 密码的设定使用“password”
			if ("password".equals(attr.getType())) {
				password = (String) attr.getContent();
				continue;
			}

			// 其他的参数,如调试、验证等,直接设置在properties中
			props.put(attr.getType(), (String) attr.getContent());
		}

		Authenticator auth = null;

		if (password != null) {

			// 在properties中寻找用户的邮件信息
			String user = props.getProperty("mail.smtp.user");
			if (user == null) {
				user = props.getProperty("mail.user");
			}

			if (user != null) {
				final PasswordAuthentication pa = new PasswordAuthentication(
						user, password);
				auth = new Authenticator() {
					protected PasswordAuthentication getPasswordAuthentication() {
						return pa;
					}
				};
			}
		}

		// Create and return the new Session object
		Session session = Session.getInstance(props, auth);
		return (session);

	}

}

 修改META-INF/context.xml文件:

	<Resource name="mail/Session" auth="Container"
		type="javax.mail.Session"
		factory="tomcat.jndi.provider.MySessionFactory"
		mail.smtp.auth="true"
		mail.smtp.host="smtp.sohu.com"
		mail.smtp.user="XXX@sohu.com"
		mail.debug="true"
		password="XXXXXX"/>
 

MySessionFactory基本上是仿照Tomcat的MailSessionFactory写的, 测试竟然正常了!!!不知道是不是 AccessController的问题。也不清楚是否是我的配置在某些细微之处错了。先记录一下,研究过AccessController之后,再修改本文!!也欢迎大家和我一起探讨这个问题!!

 

 

问题解决了:

从报错的具体细节,推测出是jar包的导入出问题了。删除 application/WEB-INF/lib目录下的mail.jar,在Tomcat/lib目录中添加mail.jar这样就可以使用 MailSessionFactory了!!

 

再细心地核对了一下Tomcat的说明文档:

写道
Download the JavaMail API. The JavaMail API requires the Java Activation Framework (JAF) API as well. The Java Activation Framework can be downloaded from Sun's site.

This download includes 2 vital libraries for the configuration; activation.jar and mail.jar. Unpackage both distributions and place them into $CATALINA_HOME/lib so that they are available to Tomcat during the initialization of the mail Session Resource. Note: placing these jars in both $CATALINA_HOME/lib and a web application's lib folder will cause an error, so ensure you have them in the $CATALINA_HOME/lib location only.

 

呵呵,是自己看的时候漏掉了。

0
0
分享到:
评论

相关推荐

    JBuilderX中JNDI联接池的配置工具

    在JBuilderX中配置JNDI连接池,可以极大地简化开发流程,避免手动编写和管理复杂的XML配置文件,如`context.xml`或`web.xml`。通过OPENTOOL,开发者可以在图形化的界面上设定数据源,包括驱动类名、URL、用户名和...

    JNDI的包 java命名与服务

    - **邮件服务**: JavaMail API 通过JNDI查找邮件会话,以配置邮件服务器的参数。 - **JMS队列和主题**: JNDI也用于查找Java消息服务(JMS)的队列和主题,便于发送和接收消息。 **5. JNDI的实现** JNDI本身只定义了...

    Tomcat配置连接池

    在配置Tomcat连接池的过程中,正确设置JNDI资源非常重要。通过合理设置最小连接数和最大连接数,可以有效地提高数据库操作的性能,同时也要注意驱动程序的兼容性和配置文件的位置。正确地配置连接池不仅可以提高系统...

    apache-tomcat-7.0.59-x64.rar

    Tomcat的体系结构基于Java Naming and Directory Interface (JNDI)、JavaMail、Java Persistence API (JPA) 和Java Transaction API (JTA) 等Java标准。它由以下几个核心组件构成: 1. Catalina:这是Tomcat的主要...

    tomcat7 解压版 免安装

    8. **扩展性**:Tomcat支持与其他Java EE组件集成,例如JavaMail、JNDI(Java Naming and Directory Interface)和JMS(Java Message Service)等,可以构建更复杂的企业级应用。 9. **性能优化**:通过调整JVM参数...

    eclipse Tomcat5.5 java

    在本压缩包中,我们关注的是如何在Eclipse中配置和使用Tomcat 5.5版本来开发和部署Java Web应用程序。 首先,安装Eclipse集成Tomcat 5.5的过程至关重要。你需要确保你的系统已经安装了Java Development Kit(JDK)...

    《Tomcat与Java Web开发技术详解(第2版)》_(孙卫琴)_源码.zip

    它实现了Java Servlet和JavaServer Pages(JSP)规范,同时也支持Java EE的其他部分,如JavaMail和JNDI(Java Naming and Directory Interface)。 在Tomcat的配置方面,读者会学习到如何安装和启动Tomcat服务器,...

    tomcat7.0 depend-lib

    6. **JNDI (Java Naming and Directory Interface)**: 用于访问目录服务和命名服务的API,Tomcat使用它来管理应用的上下文和资源。 7. **JAVAX Mail**: 如果Tomcat需要处理邮件发送,这个库将被包含,提供发送电子...

    tomcat 6.0 lib jar

    6. **JDBC驱动**:如果你的Web应用需要连接数据库,那么对应的JDBC驱动jar文件(如`mysql-connector-java.jar`)会放在lib目录下,以便Tomcat能正确地加载和使用。 7. **其他依赖**:`commons-logging.jar`、`...

    apache-tomcat-7.0.107-windows-x64

    Apache Tomcat 7.0.107还包含了日志记录、JMX(Java Management Extensions)支持、热部署功能,以及对其他Java EE组件如JavaMail、JNDI(Java Naming and Directory Interface)的支持。通过这些特性,开发者能够...

    apache-tomcat-7.0.19.rar

    6. **可扩展性**:Tomcat设计为轻量级服务器,但具有高度可扩展性,可以与其他Java EE组件如JavaMail、JNDI等集成,满足复杂的企业级需求。 7. **配置与安装**:在“apache-tomcat-7.0.19.exe”这个压缩包中,包含...

    apache-tomcat.rar

    3. **Java EE兼容性**:虽然Tomcat主要是一个轻量级的服务器,但通过与其他Java EE组件(如JavaMail、JNDI等)配合使用,可以实现Java EE的部分标准,例如Java Servlet 4.0和JSP 2.3规范。 4. **配置管理**:Tomcat...

    Java.Web应用开发.J2EE和Tomcat第2版

    1. JDBC数据源配置:在Tomcat的context.xml中配置JNDI数据源,供EJB和JSP/Servlet使用。 2. J2EE安全:角色、认证和授权机制,以及如何在Tomcat中配置。 3. 集成其他服务:如邮件服务(JavaMail)、定时任务(Quartz...

    Tomcat与Java.Web开发技术详解附书光盘2

    Tomcat的配置简单,易于管理和调试,且与Java EE的其他组件(如JavaMail、JNDI等)集成良好。 【Tomcat核心概念】 1. **Context**:对应一个Web应用,负责管理该应用的所有Servlet和JSP。 2. **Connector**:处理...

    最新JavaWeb开发手册.pdf

    JavaWeb开发是构建基于互联网的Web应用程序的一种技术,主要涉及Java语言、Servlet、JSP、JNDI、JDBC、JavaMail等Java技术,以及Web服务器和应用服务器的配置与使用。以下是一份详细的JavaWeb开发相关知识点: 1. *...

    NetBeans下的j2ee培训.rar

    学习如何在NetBeans中配置和连接不同的应用服务器,如Tomcat、GlassFish或JBoss,以及如何部署和调试应用。 通过这份《NetBeans下的J2EE培训》教程,开发者将能够全面掌握NetBeans IDE的使用,并在实际项目中有效...

    发送邮件(开发包)

    在提供的压缩包“JavaMailinTomcatjar”中,很可能包含了运行JavaMail应用所需的全部依赖,特别是针对在Tomcat这样的Servlet容器中部署时。 JavaMail API 提供了丰富的类和接口,如`javax.mail.Session`,`javax....

    《程序天下:J2EE整合详解与典型案例》光盘源码

    5.3.2 为Eclipse配置Tomcat插件 5.4 使用Eclipse建立Web开发项目 5.5 Eclipse的常用快捷键 5.5.1 有关格式化的快捷键 5.5.2 有关调试的快捷键 5.5.3 有关重构的快捷键 5.6 小结 第六章 Log4j使用指南 6.1 Log4j介绍 ...

Global site tag (gtag.js) - Google Analytics