2012-02-24 131 views
0

我正在使用GlassFish作为应用程序服务器来处理Java EE应用程序。我开发了一个用于发送电子邮件的可插入插件(我已将其命名为EmailProvider)。为此,我使用后期绑定来在运行时加载EmailProvider jar。我有一个加载EmailProvider类文件的自定义URLClassLoader。电子邮件提供商使用JavaMail API发送电子邮件。这是代码片段。如果我在Java EE应用程序中包含EmailProvider类,但在 处引发异常,此代码完美起作用Transport transport = session.getTransport(“smtp”); 说“javax.mail.NoSuchProviderException:smtp”我f我在运行时使用customClassLoader加载类。我知道这是类加载问题。我也通过自定义加载器加载javax.mail.jar。我认为问题是从两个不同的类加载器加载相同的类(javax.mail.jar)。如果我省略javax.mail.jar然后我得到的ClassNotFoundException为javax.mail类javax.mail.NoSuchProviderException:从定制类加载器加载类时发生smtp

Class EmailProvider{ 
try { 
     Properties props = new Properties(); 

     props.put("mail.smtp.host", "IP ADDRESS"); 
     props.put("mail.smtp.starttls.enable", "false"); 
     props.put("mail.transport.protocol", "smtp"); 
     props.put("mail.smtp.class", "com.sun.mail.smtp.SMTPTransport"); 

     Session session = Session.getInstance(props, null); 

     session.setDebug(false); 
     Provider provider = session.getProvider("smtp"); 
     javax.mail.Message message = new MimeMessage(session); 

     InternetAddress addressFrom = new InternetAddress("[email protected]"); 
     message.setFrom(addressFrom); 
     InternetAddress[] addressTo = new InternetAddress[1]; 
     addressTo[0] = new InternetAddress("[email protected]"); 
     //msg.setRecipients(javax.mail.Message.RecipientType.TO, addressTo); 
     message.setSubject("Hello"); 
     message.setContent("testing..", "text/plain"); 
     session.setProvider(provider);    
     Transport transport = session.getTransport("smtp"); 
     transport.connect("IP ADDRESS", "domain\\username", "password");    
     transport.sendMessage(message, addressTo); 


    } catch (Exception ex) { 
     Logger.getLogger(SendEmail.class.getName()).log(Level.SEVERE, null, ex); 
    } } 

回答

1

首先,there's nothing named "JEE"。正确的名称是“Java EE”。

问题是JavaMail无法在javax.mail.jar文件中找到配置文件。它使用线程的上下文类加载器的getResource()方法来查找它。假设你已经设置了自定义的类加载器,以便你的应用程序类加载器是父类加载器,那么可以将线程的上下文类加载器设置为你的自定义类加载器。

+0

非常感谢。设置ContextClassLoader工作。这是我补充说的。 Thread.currentThread()setContextClassLoader(myLoader)。 – androider 2012-02-24 19:21:10