2012-05-30 28 views
3

我想以編程方式將DataSource對象綁定到(eclipse)jetty的JNDI上下文。我需要測試目的。下面是一段代碼,我現在有:Jetty綁定JNDI上下文中的數據源

server = new Server(SERVER_PORT); 
webAppContext = new WebAppContext(); 
webAppContext.setResourceBase("."); 
webAppContext.setContextPath("/" + SERVER_CONTEXT); 
webAppContext.addEventListener(prepareServletContextListener()); 
webAppContext.addFilter(GuiceFilter.class, "/*", null); 
webAppContext.addServlet(DefaultServlet.class, "/"); 
Resource r = new Resource(webAppContext,"jdbc/testDS",createDataSource()); 

server.setHandler(webAppContext); 
server.start(); 

當然與資源行不working.I不知道如何以編程方式綁定它來獲取某物類似於:

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

任何幫助將不勝感激。

回答

2

我遇到了同樣的問題,這裏是我做過什麼來解決這個問題:

server = new Server(PORT); 
    WebAppContext context = new WebAppContext(); 
    context.setContextPath(CONTEXT); 
    context.setConfigurationClasses(new String[] { "org.eclipse.jetty.plus.webapp.PlusConfiguration", 
      "org.eclipse.jetty.webapp.FragmentConfiguration" }); 
    // A filter needed by Guice, but this is independent 
    context.addFilter(GuiceFilter.class, "/*", 0); 
    PGSimpleDataSource simpleDataSource = new PGSimpleDataSource(); 
    simpleDataSource.setDatabaseName("db-name"); 
    simpleDataSource.setUser("user"); 
    simpleDataSource.setPassword("pwd"); 
    String jndiName = "jdbc/myDS"; 
    Resource resource = new Resource("java:comp/env/" + jndiName, simpleDataSource); 
    server.setHandler(context); 
    // an event listener (because I use Guice, but this is independent) 
    GuiceServletConfig guiceServletConfig = new GuiceServletConfig(); 
    context.addEventListener(guiceServletConfig); 
    server.start(); 

這需要具有以下附加庫:

  • jetty-jndi
  • jetty-plus

我在Embedded Jetty 7上測試了這個代碼(7.6.10.v20130312)

+1

請解釋資源如何連接到服務器! –

4

您需要將定義的資源對象作爲屬性添加到服務器對象。 下面應該工作:

Resource r = new Resource("jdbc/testDS",createDataSource()); 
server.setAttribute("myDs", r); 
1

該主題很舊但我遇到了同樣的問題。不幸的是現有的答案沒有提供任

當您創建指定DataSource的實例的Resource時,當請求JNDI資源時,Jetty不會提供此實例。相反,構造函數Resource會嘗試將實例轉換爲某種「配方」(準確地說是javax.naming.Reference),它告訴如何使用完全相同的內部構建新配置實例。

它在基本類的情況下運行良好,但無法重新創建複雜的數據結構(在我的情況下,它的失敗是List<String>)。所以,你最終沒有得到:

  • 完全相同的實例(如你期望一個單身的)
  • 實例的準確當量(按預期正常工作的JNDI)

我已經實現了一個包裝,允許在創建Resource時提供指定的實例。

import java.util.Hashtable; 
import javax.naming.Context; 
import javax.naming.Name; 
import javax.naming.Reference; 
import javax.naming.spi.ObjectFactory; 

public class ExistingInstanceReference extends Reference implements ObjectFactory { 

    private Object instance; 

    private static final long serialVersionUID = -2718709718400909747L; 

    public ExistingInstanceReference() { 
     super(null); 
    } 

    public ExistingInstanceReference(Object instance) { 
     super(instance.getClass().getName(), ExistingInstanceReference.class.getName(), null); 
     this.instance = instance; 
    } 

    @Override 
    public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception { 
     if (obj == null) { 
      return null; 
     } 
     ExistingInstanceReference reference = (ExistingInstanceReference) obj; 
     return reference.instance; 
    } 

} 

注意,此實現不遵守Serializable接口instance變量可以包含非序列化對象。

用法:

Resource r = new Resource(webAppContext, "jdbc/testDS", new ExistingInstanceReference(createDataSource())); 

請考慮此方案作爲一種解決方法,因爲真正的問題還是要某處碼頭的來源固定。不幸的是,我沒有時間追溯這種不道德行爲。

另外,我不得不設置webAppContext.setParentLoaderPriority(true),因爲webapp的類加載器在我的設置中沒有看到ExistingInstanceReference類。