Jetty在JNDI上下文中绑定DataSource

时间:2012-05-30 12:47:27

标签: eclipse jetty datasource jndi

我想以编程方式将DataSource对象绑定到(eclipse)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();

当然使用Resource的行不起作用。我不知道如何以编程方式绑定它以获得类似于:

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

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:4)

您需要将已定义的资源对象作为属性添加到服务器对象。 以下应该有效:

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

答案 1 :(得分: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();

这需要具有以下附加库:

  • 码头-JNDI
  • 码头加

我在Embedded Jetty 7(7.6.10.v20130312)上测试了这段代码

答案 2 :(得分:1)

主题已陈旧但我遇到了同样的问题。不幸的是,现有的答案没有解决方案。

当您创建Resource指定DataSource的实例时,Jetty将在请求JNDI资源时不提供此实例。相反,Resource的构造函数尝试将实例转换为某种&#34;配方&#34; (准确地说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()));

请将此解决方案视为一种解决方法,因为真正的问题仍然需要在Jetty的源代码中修复。不幸的是,我没有时间将这种不端行为追溯到根源。

此外,我必须设置webAppContext.setParentLoaderPriority(true),因为webapp的类加载器在我的设置中没有看到ExistingInstanceReference类。