سؤال

أرغب في استخدام مصنع الموارد القياسي الذي يوفره Tomcat 6.0، والذي ينشئ مثيل javax.mail.Sessions لي.كما هو موضح في JNDI الموارد HOW-TO البرنامج التعليمي.

يبدو ملف 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 الخاص بي، قبل </webapps> مباشرةً.يتم التحقق من صحة Web.xml.لقد قمت بالتحقق من صحة استخدام طريقة ماكدويل.

<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"));

لقد اختبرت ذلك في نموذج التطبيق وعملت.لسوء الحظ عندما قمت بنقل نفس الكود إلى تطبيق الدعامات، حصلت على NULL في بيان الطباعة أعلاه.أقوم بالبحث عن السياق في فئة مفردة تسمى mailer (والتي تم تعريفها في مجلد WEB-INF/classes الخاص بي) ولكني أواجه نفس المشكلة إذا قمت بالبحث عن السياق في فئة الإجراء Struts.

لقد كنت أفكر في ما هو مختلف للعثور على المشكلة.يعد web.xml لتطبيق الدعامات الخاص بي أكثر تعقيدًا من web.xml الخاص بالتطبيق البسيط.يحتوي على قيود أمنية ومرشحات وتكوين Struts Servlet.أقوم بوضع Resource-ref قبل تعريفات servlet مباشرةً.يبدو أنه يتم تجاهل مرجع المورد.

لدي قضية أخرى.إذا كان لدي mailapi.jar، الذي تحتاجه javax.mail.Session، في المجلد myapp/WEB-INF/lib، أحصل على:

java.lang.NoClassDefFoundError:javax/mail/Authenticator

إذا قمت بوضعه في $CATALINA_HOME/lib فسيتم العثور عليه.

أيه أفكار؟أستخدم الدعامات والسبات.ربما يكون له علاقة بذلك.

تصحيح

لقد حاولت تصحيحه من خلال وضع سمة التصحيح في السياق

<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.

الحل الجزئي

عندما أضع عنصر المورد داخل ملف $CATALINA_HOME/conf/context.xml، فإنه يعمل.

هل كانت مفيدة؟

المحلول

مراوغات رمز بحث 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 (أو Java EE أو المناطق ذات الصلة.بل قد يكون غير محدد طوعًا وبشكل صريح.) لذلك ليس من الضروري أن يقوم الخادم بتوفير موارد JNDI في المواضيع التي كنت قد ولدت نفسك (مرة أخرى، أزعجني Websphere بهذا، ولم أختبر Tomcat6 في هذا الصدد، حيث تم استخدام الإصدارات السابقة لتوفير موارد JNDI لجميع سلاسل الرسائل)

لقد كتبت أنك تبحث عن موارد JNDI من ملف واحد. اذا أنت, ، عند نقطة البحث عن الموارد، فحص التتبع المكدس (إما في IDE الخاص بك، عن طريق طرح استثناء أو العبث به Thread.currentThread().getStacktrace()): هل هناك أي موصل Tomcat في مكدس أو هي إحدى طرق run() الخاصة بخيطك في الجذر من المكدس ? هذا من شأنه أن يجيب على السؤال وراء سؤال جاك إذا كنت تقوم بالبحث من فئة العمل.(انظر إجابة جاك)

المواضيع وبيئة الاتصال الجزء الثاني

قم بإنشاء إجراء Struts جديد واتصل برمز بحث JNDI الخاص بك من هناك، وتحقق مما إذا كان هذا يعمل إذا تم وضعه بالقرب من الدعامات وضمن معالجة طلب http.إذا كان يعمل هنا، تابع الخطوات المذكورة أعلاه.

صلاحية web.xml

قد ترغب أيضًا في إلقاء نظرة على تعريف المخطط لـ web.xml للتأكد من وضع مرجع المورد الخاص بك بشكل صحيح.مواصفات servlet 2.4 متاحة في jcp.org ويجب أن يكون كافيًا للتحقق، حتى إذا كان Tomcat يطبق 2.5.

بعد كل شيء، أعتقد أن Tomcat6 يتحقق من صحة web.xml، لذلك ربما يكون لديك بالفعل في الموضع الصحيح.(لا أتذكر، حيث اشتكى محرر IDEs الخاص بي عندما أخطأت في الأمر، هل أحتاج إلى كتابة web.xml)

خيارات تصحيح Tomcat

تحترم العديد من إدخالات context.xml السمة "debug".على الرغم من أنني أعتقد أن القيم المنخفضة المكونة من رقم واحد كافية، إلا أنني اعتدت على إضافة 'debug='99' إلى عناصر مثل 'Context' أو غيرها.قد ترغب في معرفة ما إذا كان هذا يؤدي إلى بعض إدخالات السجل المفيدة.

تأكد من أنه ليس مسار الفصل

كما يبدو أنك قد غيرت البيئة بشكل جذري، تأكد من أن لديك جميع المكتبات المطلوبة على متن الطائرة - تتكون واجهة برمجة تطبيقات البريد من عدة جرارات.قم بتنزيل نسخة جديدة وفكها الجميع المكتبات إلى $CATALINA_HOME/lib.يمكنك التخلص من الأشياء غير المستخدمة بمجرد العمل مع جميع المكتبات الموجودة هناك.

بخصوص سؤالك classpath:

سبب العثور على الفئة عند وضعها في $CATALINA_HOME/lib هو أن الاتصال يتم بواسطة الخادم (تذكر - لقد قمت بتعريفه في context.xml الذي يقرأه الخادم لبدء التطبيق)، وبالتالي يجب أن تكون الجرة على الخوادم classpath - ليس فقط على التطبيقات (راجع ملف كيفية تحميل فئة Tomcat للمزيد من المعلومات)

يحرر:

فيما يتعلق بالحل الجزئي الخاص بك:

يحتوي $CATALINA_HOME/conf/context.xml على عناصر السياق "الافتراضية" العامة.هذا ليس المكان الذي تريد أن يكون فيه التكوين الخاص بالتطبيق الخاص بك.

الموضع القياسي لـ Tomcat هو إما في webapps META-INF/context.xml أو في ملف xml (يُسمى كما تريد، وينتهي بـ .xml) في $CATALINA_HOME/conf/Catalina/localhost/.يُفضل الحل الأحدث بالفعل فيما يتعلق بـ META-INF/context.xml لأن التكوين بهذه الطريقة يكون مستقلاً عن التطبيق ولا يتم استبداله عند نشر تطبيق جديد.

يحتوي هذا السياق عادةً على سمات إضافية مثل docBase والمسار:

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

بهذه الطريقة يكون طلبك متاحًا على http://servername:8080/app.إذا قمت بالنشر في دليل $CATALINA_HOME/webapps، فيمكن أن تكون قيمة docBase مرتبطة بتطبيق الويب.كن حذرًا فيما يتعلق بظروف السباق على الرغم من:سيقوم Tomcat بنشر التطبيقات تلقائيًا في $CATALINA_HOME/webapps وقد يقوم بإنشاء ملف السياق.كما أن حذف تطبيق الويب لنشر تطبيق جديد قد يتسبب في قيام Tomcat بحذف ملف تكوين XML.

لذلك - مهما كانت مشكلتك:حاول أن يعمل تعريف السياق/التطبيق الخاص بك عند وضعه في $CATALINA_HOME/conf/Catalina/localhost/app.xml .لدي شعور بأنه شيء بسيط للغاية، حيث يتم فقدان الجزء الأخير فقط من المعلومات من أجل رؤية المشكلة الحقيقية.

نصائح أخرى

وأعتقد أنكم ينبغي أن تحدد السياق الخاص بك في META-INF / context.xml، وليس ميتا-INF / web.xml (رغم أن هذا قد يكون مجرد خطأ مطبعي في مشاركتك الأصلية).

وعندما قلت أنك انتقلت التعليمات البرمجية لتطبيق الدعامات، هل يمكن أن يكون أكثر تحديدا؟ هل يعني تقومون به السياق الخاص بالبحث في فئة العمل الآن؟

وكما تعلمون هذا بالفعل، ولكن مع تحديد السياق الخاص بك (إدخالات JNDI الخ) في تطبيقات الويب الخاص بك META-INF / context.xml هو مقبول في بيئة مطور، وأنا جدا تثني استخدامه في أي شكل من أشكال البيئات المشتركة ، وبالتأكيد ليس في بيئة الإنتاج.

<اقتباس فقرة>   

وماذا تنصحني؟

وحدد في JNDI، ولكن خارج التطبيق الخاص بك على شبكة الإنترنت / WAR. في القط، يمكنك القيام بذلك من خلال وضعه في ملف $ {CATALINA_BASE} /conf/context.xml. وهذا يسمح الموارد الخارجية (البريد، وقاعدة البيانات وغيرها) التكوين إلى تعريف خارج تطبيق الويب الخاص بك، وتجنب الحاجة إلى حزم WAR الخاص بك عند التغييرات تكوين قاعدة بيانات، أو تنتقل إلى بيئة مختلفة مع قاعدة بيانات مختلفة، على سبيل المثال.

<اقتباس فقرة>   

وأفعل سياق البحث عنها في الدرجة المفرد يسمى الارسال.

وهذه الفئة الارسال، هل هو في WEB-INF / الطبقات، أو JAR داخل WEB-INF / ليب؟ أم أنها تعرف مكان آخر في CLASSPATH الخاص بك؟ إذا كان هذا الأخير، قد ترغب في النظر في نقله إلى التطبيق الخاص بك.


وتحرير: بناء على آخر ما توصل إليه، فإنه يبدو وكأنه تطبيق ويب الخاص بك META-INF / context.xml لا تتخذ تأثير. هناك عدة سيناريوهات في القط من شأنها أن تؤدي إلى ذلك. أنا لا أعرف هذه في التفاصيل، ولكن هنا بعض المعلومات وكنت قادرا على العثور على:

ولكل - http://tomcat.apache.org/tomcat -5.5-وثيقة / التكوين / host.html

إذا تم تعيين "deployXML" السمة إلى false في العنصر المضيف الخاص بك (أنا أؤمن server.xml).

<اقتباس فقرة>   

وdeployXML - تعيين على خطأ إذا كنت تريد   لتعطيل تحليل context.xml   ملف مضمن داخل التطبيق   (الموجود في /META-INF/context.xml).   البيئات الأمنية consious ينبغي   تعيين هذا إلى كاذبة لمنع   التطبيقات من التفاعل مع   تكوين الحاوية. ال   سوف يكون المسؤول ثم مسؤولا   لتوفير السياق الخارجي   ملف التكوين، ووضعها في   $ CATALINA_HOME / أسيوط / [enginename] / [المضيف] /.   القيمة الافتراضية العلم لصحيح.

ولكل - http://tomcat.apache.org/tomcat -5.5-وثيقة / التكوين / context.html

إذا كان لديك $ CATALINA_HOME / أسيوط / [enginename] / [المضيف] / [سياق مسار] ملف. xml محددة.

وأنا متأكد من أن هناك آخرين، وهذه هي فقط تلك التي كنت قادرا على العثور بسرعة.

ولما كان هذا هو سيناريو مختلف تماما بالمقارنة مع الحل أعلاه، لقد اختارت لإضافة إجابة أخرى بدلا من تحرير سابقة واحدة:

وفقط في حالة: إصنع خارج من خارج <م> خارج -sure أنه لا يوجد خطأ مطبعي في تعريف السياق الخاص بك. قارن ذلك خارج بعناية مع الإصدار العاملة في $ CATALINA_HOME / أسيوط / context.xml

ونحن لن ترغب في "البريد / Sessoin" لجعل الفرق ...

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top