2014-10-06 146 views
3

我正在使用標準的MySQL連接器API的Jetty 9.2(嵌入式),我很困惑這應該如何設置。目前,我有這個在我的的web.xml文件JNDI查找失敗與Jetty的JDBC連接池與MySQL?

<webapp ... 

    <resource-ref> 
     <description>JDBC Data Source</description> 
     <res-ref-name>jdbc/DataSource</res-ref-name> 
     <res-type>javax.sql.DataSource</res-type> 
     <res-auth>Container</res-auth> 
    </resource-ref> 
</webapp> 

......這在我的碼頭-env.xml:

<Configure class="org.eclipse.jetty.webapp.WebAppContext"> 

    <New id="DatabaseConnector" class="org.eclipse.jetty.plus.jndi.Resource"> 
     <Arg></Arg> 
     <Arg>jdbc/DataSource</Arg> 
     <Arg> 
      <New class="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource"> 
       <Set name="Url">jdbc:mysql://localhost:3306/DBName</Set> 
       <Set name="User">user</Set> 
       <Set name="Password">pass</Set> 
      </New> 
     </Arg> 
    </New> 

</Configure> 

......這碼初始化:

Context envCtx = (Context) new InitialContext().lookup("java:comp/env"); 
DataSource datasource = (DataSource) envCtx.lookup("jdbc/DataSource"); 

當我嘗試啓動服務器,我得到的錯誤javax.naming.NameNotFoundException; remaining name 'jdbc/DataSource'。我在代碼初始化時嘗試了很多不同的字符串,例如刪除InitialContext對象上的lookup調用,但我只是不斷得到相同錯誤的變體,其值爲name;

這兩個xml文件都位於我的/WAR/WEB-INF目錄中。我查看了大量以前的問題和教程,博客等,但我無處可去。

+0

你可以發佈你的Jetty Embedded實例的WebAppContext.setConfiguration()代碼嗎? – 2014-10-06 14:52:44

+0

我收到了我正在尋找其他地方的答案,我將發佈一個總結解決方案的答案。 – RTF 2014-10-06 19:00:32

回答

1

這是嵌入式Jetty特有的問題的組合。

首先,我配置和啓動Web服務器的啓動程序代碼是在我實際啓動Web服務器之前(即在調用server.start()之前進行JNDI查找),因此JNDI配置在該階段未初始化。

但即使進行此更改也不起作用,因爲需要從與WebApp關聯的線程中調用envCtx.lookup("jdbc/DataSource")。所以我將該代碼移動到一個靜態塊中,該塊在Web服務器請求首次請求數據庫連接時被調用。

最後,我結束了這樣的事情對我的啓動代碼

public static void main(String[] args) { 
    Server server = new Server(); 

    //Enable parsing of jndi-related parts of web.xml and jetty-env.xml 
    ClassList classlist = ClassList.setServerDefault(server); 
    classlist.addAfter(
      "org.eclipse.jetty.webapp.FragmentConfiguration", 
      "org.eclipse.jetty.plus.webapp.EnvConfiguration", 
      "org.eclipse.jetty.plus.webapp.PlusConfiguration"); 
... 
... 
server.start(); 

JNDI查找無法通過這個主線進行,所以把它放在什麼地方像一個的init方法servlet請求,或者像我一樣,一個靜態數據庫訪問器類的同步方法,被servlet使用,例如

public class DatabaseUtils { 

    private static DataSource datasource; 

    private static synchronized Connection getDBConnection() throws SQLException { 
     if (datasource == null) { 
      initDataSource(); 
     } 
     return datasource.getConnection(); 
    } 

    public static void initDataSource() { 
     try { 
      datasource = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/DataSource"); 
      LOG.info("Database connection pool initalized successfully"); 
     } catch (Exception e) { 
      LOG.error("Error while initialising the database connection pool", e); 
     } 
    }