3

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

任何帮助将不胜感激。

4

3 回答 3

4

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

Resource r = new Resource("jdbc/testDS",createDataSource());
server.setAttribute("myDs", r);
于 2013-01-28T09:01:48.313 回答
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) 上测试了这段代码

于 2013-06-11T12:50:51.353 回答
1

这个话题很老,但我遇到了同样的问题。不幸的是,现有的答案没有提供任何解决方案。

当您创建一个Resource指定的实例时DataSource,当请求 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()));

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

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

于 2016-11-14T21:54:36.857 回答