gpt4 book ai didi

tomcat - 邮件/ session 资源工厂在 Struts 应用程序中不起作用

转载 作者:行者123 更新时间:2023-11-28 21:48:52 25 4
gpt4 key购买 nike

我想使用 Tomcat 6.0 提供的标准资源工厂,它为我创建了 javax.mail.Sessions 实例。如 JNDI Resource HOW-TO tutorial 中所述.

我的 META-INF/context.xml 看起来像:

<?xml version="1.0" encoding="UTF-8"?>
<Context reloadable="true">
<Resource name="mail/Session"
auth="Container"
type="javax.mail.Session"
mail.smtp.host="smtp.gmail.com"
mail.smtp.port="587"
mail.smtp.auth="true"
mail.smtp.user="someone@gmail.com"
mail.smtp.password="secretpassword"
mail.smtp.starttls.enable="true"/>
</Context>

我的 WEB-INF/web.xml 中有下一个资源引用,就在 之前。 Web.xml 验证。我使用 McDowell's way 进行了验证.

<resource-ref>
<description>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.
</description>
<res-ref-name>mail/Session</res-ref-name>
<res-type>javax.mail.Session</res-type>
<res-auth>Container</res-auth>
</resource-ref>

我正在使用下一个代码片段访问我的 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 应用程序时,我在上面的打印语句中得到 NULL。我在名为 mailer 的单例类(在我的 WEB-INF/classes 文件夹中定义)中查找上下文,但是如果我在 Struts 操作类中查找上下文,我会遇到同样的问题。

我一直在思考有什么不同才找到问题所在。我的 struts 应用程序 web.xml 比简单应用程序的 web.xml 更复杂。它具有安全约束、过滤器和 Struts Servlet 配置。我将 resource-ref 定位在 servlet 定义之前。似乎资源引用被忽略了。

我还有一个问题。如果我在 myapp/WEB-INF/lib 文件夹中有 javax.mail.Session 所需的 mailapi.jar,我会得到:

java.lang.NoClassDefFoundError: javax/mail/Authenticator

如果我把它放在 $CATALINA_HOME/lib 中就可以找到。

有什么想法吗?我用struts和hibernate。也许与此有关。

调试

我尝试调试它,将调试属性放在上下文中

<Context reloadable="true" debug="99" ...  

但我没有看到任何有趣的东西。

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 文件时,它起作用了。

最佳答案

JNDI 查找代码怪癖

我见过多个找不到 JNDI 资源的问题。在 Websphere 上(我知道,你不使用它,但很高兴知道......)你会遇到问题

Context envCtx = (Context) initCtx.lookup("java:comp/env");Session session = (Session)envCtx.lookup("mail/Session");

What works (on Websphere) is

Session session = (Session) initCtx.lookup("java:comp/env/mail/Session");

From what you wrote in another answer I understand that this is not your problem - I'm leaving it here for people coming across the same problem under different circumstances later.

Lookup of JNDI Resources from self-spawned threads

Also, access to JNDI resources might depend upon the thread looking up the resources. As far as I remember, threading is not well defined in the servlet api (or Java EE or related areas. It might even be voluntarily and explicitly be non-defined.) Therefor it's not mandatory for the server to provide JNDI resources in threads that you've spawned yourself (again Websphere did bite me with this, I haven't tested Tomcat6 in this regard, earlier versions used to provide JNDI resources to all threads)

You've written that you are looking up JNDI resources from a singleton. If you, at the point of looking up resources, examine the stacktrace (either in your IDE, by throwing an exception or messing with Thread.currentThread().getStacktrace()): is there any Tomcat connector in the stacktrace or is one of your own Thread's run() method at the root of the stacktrace ? This would answer the question behind Jacks question if you are making the lookup from an Action class. (see Jack's answer)

Threads and call-environment part two

Create a new Struts Action and call your JNDI lookup code from there, see if this works if placed as close to struts and within the processing of a http request. If it works here, continue with the steps above.

validity of web.xml

Also, you might want to have a look at the schema definition for web.xml to make sure your resource-ref is positioned correctly. The servlet spec 2.4 is available at jcp.org and should be sufficient to check, even if tomcat implements 2.5.

After all, I believe that tomcat6 validates web.xml, so that you probably already have it at the correct position. (Can't remember, as my IDEs editor complains when I get it wrong, should I need to write a web.xml)

Tomcat debug options

Many context.xml entries honour the attribute 'debug'. Though I believe that low one-digit values are sufficient, I've adopted the habit to add 'debug="99"' to elements like 'Context' or others. You might want to see if this results in some helpful log entries.

Make sure it's not the classpath

As you seem to have fundamentally changed the environment, make sure that you have all required libraries on board - the mail api consists of several jars. Download a new copy and unpack all libraries to $CATALINA_HOME/lib. You might take unused away once it worked with all libraries in there.

Regarding your classpath question:

The reason for finding the class when put into $CATALINA_HOME/lib is, that the connection is done by the server (remember - you've defined it in context.xml which is read by the server in order to start the application), thus the jar must be on the servers classpath - not just on the applications (see the tomcat class loader HOWTO for more information)

EDIT:

Regarding your partial solution:

$CATALINA_HOME/conf/context.xml contains the global "default" context elements. This is not where you want your application specific configuration to be.

The standard position for tomcat is either in the webapps META-INF/context.xml or in an xml file (named as you like, ending .xml) in $CATALINA_HOME/conf/Catalina/localhost/. The later solution is actually prefered with regards to META-INF/context.xml because this way the configuration is independent of the application and doesn't get overwritten when a new application is deployed.

This context usually contains additional attributes like docBase and path:

<Context docBase="/location/where/you/deployed/your/application" path="/app">
...
</Context>

这样您的应用程序就可以在 http://servername:8080/app 上使用。如果部署到 $CATALINA_HOME/webapps 目录,docBase 值可以是相对于 webapp 的。但要注意竞争条件:Tomcat 将在 $CATALINA_HOME/webapps 中自动部署应用程序并可能创建上下文文件。此外,删除 webapp 以部署新的 webapp 可能会导致 tomcat 删除 xml 配置文件。

因此 - 无论您的问题是什么:尝试将上下文定义/应用程序放置在 $CATALINA_HOME/conf/Catalina/localhost/app.xml 中时是否正常工作。我感觉它非常简单,为了查看真正的问题,只缺少最后一点信息。

关于tomcat - 邮件/ session 资源工厂在 Struts 应用程序中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/494985/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com