2014-07-21 35 views
1

我有一個EmailService EJB,它有一個非常簡單的'send_email'方法。儘管顯然有一個不帶參數的公共構造函數,但我仍然接受了標題中的錯誤。以下是確切的錯誤和類代碼。這很混亂。'Bean沒有一個沒有參數錯誤的公共構造函數',儘管顯然有一個錯誤?

錯誤:

[ERROR ] CNTR5007E: The websphere.jaxrs.service.EmailService bean class for the WebApiConsole#WebApiConsole.war#EmailService bean does not have a public constructor that does not take parameters.

在這裏看到錯誤的詳細信息(不多見):http://pic.dhe.ibm.com/infocenter/wxdinfo/v6r1/index.jsp?topic=%2Fcom.ibm.websphere.messages.doc%2Fcom.ibm.ejs.container.container.html

代碼:

package websphere.jaxrs.service; 

import javax.ejb.EJB; 
import javax.ejb.LocalBean; 
import javax.ejb.Stateless; 

import org.apache.commons.mail.Email; 
import org.apache.commons.mail.EmailException; 
import org.apache.commons.mail.SimpleEmail; 

import websphere.jaxrs.helpers.ContextFinder; 

    /** 
    * This class provides an interface for emailing messages. It uses server environment variables to configure SMTP server and port and authentication. 
    * 
    * @author me 
    * 
    */ 
    @Stateless 
    @LocalBean 
    public class EmailService { 

     @EJB ContextFinder ctf; 

     private static final String EMAIL_PASSWORD_JNDI_NAME = "EMAIL_PASSWORD"; 
     private static final String EMAIL_USERNAME_JNDI_NAME = "EMAIL_USERNAME"; 
     private static final String SMTP_SERVER_JNDI_NAME = "SMTP_SERVER"; 
     private static final String SMTP_PORT_JNDI_NAME = "SMTP_PORT"; 

     private String username; 
     private String password; 
     private String server; 
     private Integer port; 


     public EmailService() { 
      username = (String) ctf.lookup(EMAIL_USERNAME_JNDI_NAME); 
      password = (String) ctf.lookup(EMAIL_PASSWORD_JNDI_NAME); 
      server = (String) ctf.lookup(SMTP_SERVER_JNDI_NAME); 
      port = (Integer) ctf.lookup(SMTP_PORT_JNDI_NAME); 
     } 

     /** 
     * Sends an email to a specific user. 
     * 
     * @param sendTo 
     * @param subject 
     * @param message 
     */ 
     public void sendMail(String sendTo, String subject, String message) { 

      try { 
       Email email = new SimpleEmail(); 
       email.setHostName(server); 
       email.setSmtpPort(port); 
       email.setAuthentication(username, password); 
       email.setSSLOnConnect(true); 
       email.setFrom(username); 
       email.setSubject(subject); 
       email.setMsg(message); 
       email.addTo(sendTo); 
       email.send(); 
      } catch (EmailException e) { 
       System.err.println("Failed to email"); 
       e.printStackTrace(); 
      } 

     } 

    } 

我傾向於認爲這是一個錯誤。我可能是錯的,但是在上面的類中,一切都非常獨立(沒有其他配置,我知道它是必需的),並且我不斷收到此錯誤。我嘗試重建項目。

[編輯]我做了一些實驗,非常具體,刪除sendMail()導致它沒有錯誤。

回答

2

爲什麼不從構造函數中移除初始化到@PostConstruct方法中?

@Stateless 
public class EmailService { 
    @EJB ContextFinder ctf; 

    private static final String EMAIL_PASSWORD_JNDI_NAME = "EMAIL_PASSWORD"; 
    private static final String EMAIL_USERNAME_JNDI_NAME = "EMAIL_USERNAME"; 
    private static final String SMTP_SERVER_JNDI_NAME = "SMTP_SERVER"; 
    private static final String SMTP_PORT_JNDI_NAME = "SMTP_PORT"; 

    private String username; 
    private String password; 
    private String server; 
    private Integer port; 

    @PostConstruct 
    public void init() { 
     username = (String) ctf.lookup(EMAIL_USERNAME_JNDI_NAME); 
     password = (String) ctf.lookup(EMAIL_PASSWORD_JNDI_NAME); 
     server = (String) ctf.lookup(SMTP_SERVER_JNDI_NAME); 
     port = (Integer) ctf.lookup(SMTP_PORT_JNDI_NAME); 
    } 

    public void sendMail(String sendTo, String subject, String message) { 
     // send mail 
    } 

} 
+0

因爲我從來不知道它。 [編輯] Woops,太快擊中'輸入'。它的工作!我可以問爲什麼? – user2316667

2

注射尚未發生。

簡而言之:

  1. 容器調用構造
  2. 那麼注入的領域獲得注入
  3. 那麼postconstruct事情發生

因此提取查詢,所建議的,成postconstruct方法

0

我寧願註釋你的結構或@Inject代替:

@Stateless 
@LocalBean 
public class EmailService { 

    .... 
    @Deprecated 
    public EmailService(){}  

    @Inject 
    public EmailService(ContextFinder ctf) { 
     username = (String) ctf.lookup(EMAIL_USERNAME_JNDI_NAME); 
     password = (String) ctf.lookup(EMAIL_PASSWORD_JNDI_NAME); 
     server = (String) ctf.lookup(SMTP_SERVER_JNDI_NAME); 
     port = (Integer) ctf.lookup(SMTP_PORT_JNDI_NAME); 
    } 

... 
} 

>>使用@PostConstruct是不是你有完全一樣的。 init()方法在JUnit測試中不會在容器外工作。

您仍然需要提供默認的非參數化構造函數(The EJB 3.1 spec, section 4.9.2 Bean Classes的一部分)。

+0

我有一個非常類似的問題,但此解決方案對我無效。應用程序服務器(Websphere Liberty Base)無法初始化該Bean。 – Joko

+0

嗨@Joko,沒有理由爲什麼'@Inject'在consructor上失敗了。這是一個非常常見的用法,也是標準的一部分。你的用例是什麼? –

相關問題