【问题标题】:Jetty Bind DataSource in JNDI ContextJNDI 上下文中的 Jetty 绑定数据源
【发布时间】:2012-06-04 17:00:06
【问题描述】:

我想以编程方式将 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>

任何帮助将不胜感激。

【问题讨论】:

    标签: eclipse jetty datasource jndi


    【解决方案1】:

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

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

    【讨论】:

      【解决方案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) 上测试了这段代码

      【讨论】:

      • 请解释资源如何连接到服务器!
      【解决方案3】:

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

      当您创建Resource 指定DataSource 的实例时,当请求JNDI 资源时,Jetty 不会提供此实例。相反,Resource 的构造函数尝试将实例转换为某种“配方”(准确地说是javax.naming.Reference),告诉如何使用完全相同的内部结构构建新的配置实例。

      它在基本类的情况下运行良好,但无法重新创建复杂的数据结构(在我的情况下,List&lt;String&gt; 失败)。所以你最终没有得到:

      • 完全相同的实例(如您所期望的单例)
      • 实例的完全等价物(正如您期望的正常工作的 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),因为 web 应用的类加载器在我的设置中没有看到 ExistingInstanceReference 类。

      【讨论】:

        猜你喜欢
        • 2013-01-08
        • 2012-11-23
        • 2020-07-19
        • 1970-01-01
        • 1970-01-01
        • 2015-05-31
        • 1970-01-01
        • 2016-06-25
        • 1970-01-01
        相关资源
        最近更新 更多