我想使用Tomcat 6.0提供的标准资源工厂,它为我创建了javax.mail.Sessions实例.如JNDI Resource HOW-TO教程中所述.
我的META-INF/context.xml看起来像:
我在WEB-INF/web.xml中有下一个resource-ref,就在 webapps>之前.Web.xml验证.我使用McDowell的方式进行了验证.
Resource reference to a factory for javax.mail.Session instances that may be used for sending electronic mail messages, preconfigured to connect to the appropiate SMTP server. mail/Session javax.mail.Session Container
我正在使用下一个代码snipett访问我的javax.mail.Session对象.
Context initCtx = new InitialContext(); Context envCtx = (Context) initCtx.lookup("java:comp/env"); Session session = (Session)envCtx.lookup("mail/Session"); System.out.println("HERE smtp.user: " + session.getProperty("mail.smtp.user"));
我在一个示例应用程序中测试它并且它工作 不幸的是,当我将相同的代码移动到struts应用程序时,我在上面的print语句中得到NULL.我在单例类中查找上下文,称为邮件程序(在我的WEB-INF/classes文件夹中定义)但如果我在Struts操作类中查找上下文,我会遇到同样的问题.
我一直在考虑找到问题的不同之处.我的struts应用程序web.xml比简单应用程序的web.xml更复杂.它具有安全性约束,过滤器和Struts Servlet配置.我在servlet定义之前定位resource-ref.似乎资源引用被忽略了.
我有另一个问题.如果我有javax.mail.Session需要的mailapi.jar,在myapp/WEB-INF/lib文件夹中,我得到:
java.lang.NoClassDefFoundError:javax/mail/Authenticator
如果我把它放在$ CATALINA_HOME/lib中找到了.
有任何想法吗?我使用struts和hibernate.也许它与此有关.
我尝试调试它将调试属性放在上下文中
但我没有看到任何有趣的东西.
01-feb-2009 17:39:09 org.apache.catalina.core.ApplicationContext log INFO: ContextListener: contextInitialized() 01-feb-2009 17:39:09 org.apache.catalina.core.ApplicationContext log INFO: SessionListener: contextInitialized() 01-feb-2009 17:39:09 org.apache.catalina.core.ApplicationContext log INFO: ContextListener: contextInitialized() 01-feb-2009 17:39:09 org.apache.catalina.core.ApplicationContext log INFO: SessionListener: contextInitialized() 01-feb-2009 17:39:09 org.apache.catalina.core.ApplicationContext log INFO: ContextListener: contextInitialized() 01-feb-2009 17:39:09 org.apache.catalina.core.ApplicationContext log我试过了:
Session session = (Session) initCtx.lookup("java:comp/env/mail/Session");代替:
Context envCtx = (Context) initCtx.lookup("java:comp/env"); Session session = (Session)envCtx.lookup("mail/Session");但我仍然得到一个NULL Session对象.
部分解决方案
当我将Resource元素放在$ CATALINA_HOME/conf/context.xml文件中时,它可以工作.
1> Olaf Kock..:JNDI查找代码怪癖
我发现没有找到JNDI资源的多个问题.在Websphere上(我知道,你不使用它,但知道它很好......)你会遇到问题
Context envCtx = (Context) initCtx.lookup("java:comp/env"); Session session = (Session)envCtx.lookup("mail/Session");什么有效(在Websphere上)是
Session session = (Session) initCtx.lookup("java:comp/env/mail/Session");从你在另一个答案中所写的内容我明白这不是你的问题 - 我将它留在这里,以便后来在不同情况下遇到相同问题的人.
从自生成的线程中查找JNDI资源
此外,对JNDI资源的访问可能取决于查找资源的线程.据我所知,在servlet api(或Java EE或相关领域)中没有很好地定义线程.它甚至可能是自愿的,也可能是非定义的.)因此,服务器不必在线程中提供JNDI资源.你自己催生了(再次,Websphere确实咬了我这个,我没有在这方面测试过Tomcat6,早期的版本用来为所有线程提供JNDI资源)
您已经写过要从单例中查找JNDI资源.如果您在查找资源时检查堆栈跟踪(在IDE中,通过抛出异常或搞乱
Thread.currentThread().getStacktrace()
):堆栈跟踪中是否有任何Tomcat连接器,或者是您自己的Thread的run()方法之一堆栈跟踪的根?如果您从Action类进行查找,这将回答Jacks问题背后的问题.(见杰克的回答)线程和调用环境第二部分
创建一个新的Struts Action并从那里调用你的JNDI查找代码,看看它是否有效,如果放置在struts附近和http请求的处理范围内.如果在此处有效,请继续执行上述步骤.
web.xml的有效性
此外,您可能希望查看web.xml的架构定义,以确保正确定位resource-ref.servlet规范2.4可以在jcp.org上获得,并且应该足以检查,即使tomcat实现了2.5.
毕竟,我相信tomcat6会验证web.xml,所以你可能已经把它放在了正确的位置.(不记得了,因为我的IDE编辑器在我弄错了时会抱怨,我是否需要编写web.xml)
Tomcat调试选项
许多context.xml条目都支持属性"debug".虽然我认为低一位数值就足够了,但我习惯于在'Context'或其他元素中添加'debug ="99"'.您可能希望查看是否会产生一些有用的日志条目.
确保它不是类路径
由于您似乎从根本上改变了环境,请确保您拥有所有必需的库 - 邮件api包含几个罐子.下载新副本并将所有库解压缩到$ CATALINA_HOME/lib.一旦它与那里的所有库一起工作,你可能会把它用掉.
关于你的类路径问题:
放入$ CATALINA_HOME/lib时找到类的原因是,连接是由服务器完成的(记住 - 你已经在context.xml中定义了它,服务器为了启动应用程序而读取它),因此jar必须在服务器类路径上 - 而不仅仅是在应用程序上(有关更多信息,请参阅tomcat类加载器HOWTO)
编辑:
关于部分解决方案:
$ CATALINA_HOME/conf/context.xml包含全局"默认"上下文元素.这不是您希望特定于应用程序的配置.
tomcat的标准位置是在webapps META-INF/context.xml中,或者在$ CATALINA_HOME/conf/Catalina/localhost /中的xml文件(以您喜欢的名字命名,结尾.xml).后面的解决方案实际上是关于META-INF/context.xml的,因为这种方式配置独立于应用程序,并且在部署新应用程序时不会被覆盖.
此上下文通常包含其他属性,如docBase和path:
... 这样您的应用程序就可以在
http://servername:8080/app
.如果部署到$ CATALINA_HOME/webapps目录,则docBase值可以相对于webapp.但是要注意竞争条件:Tomcat将在$ CATALINA_HOME/webapps中自动部署应用程序,并可能创建上下文文件.此外,删除webapp以部署新的webapp可能会导致tomcat删除xml配置文件.因此 - 无论您遇到什么问题:尝试放置在$ CATALINA_HOME/conf/Catalina/localhost/app.xml中的上下文定义/应用程序.我觉得这很简单,只有最后一点信息缺失才能看到真正的问题.