【问题标题】:Setting up context java:comp/env in Jetty running inside GWT 2.7在 GWT 2.7 中运行的 Jetty 中设置上下文 java:comp/env
【发布时间】:2015-04-11 08:06:34
【问题描述】:

/WEB-INF中jetty-web.xml的内容:

<Configure class="org.eclipse.jetty.webapp.WebAppContext">  
  <Array id="plusConfig" type="java.lang.String">
    <Item>org.eclipse.jetty.webapp.WebInfConfiguration</Item>
    <Item>org.eclipse.jetty.webapp.WebXmlConfiguration</Item>
    <Item>org.eclipse.jetty.webapp.MetaInfConfiguration</Item>
    <Item>org.eclipse.jetty.webapp.FragmentConfiguration</Item>
    <Item>org.eclipse.jetty.plus.webapp.EnvConfiguration</Item> <!-- add for jndi -->
    <Item>org.eclipse.jetty.plus.webapp.PlusConfiguration</Item>    <!-- add for jndi -->
    <Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item>
  </Array>
  <Call class="java.lang.System" name="setProperty">
    <Arg>java.naming.factory.initial</Arg>
    <Arg><Property name="java.naming.factory.initial" default="org.eclipse.jetty.jndi.InitialContextFactory"/></Arg>
  </Call>
  <Call class="java.lang.System" name="setProperty">
    <Arg>java.naming.factory.url.pkgs</Arg>
    <Arg><Property name="java.naming.factory.url.pkgs" default="org.eclipse.jetty.jndi"/></Arg>
  </Call> 
</Configure>

/WEB-INF中jetty-plus.xml的内容:

<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- =========================================================== -->
<!-- Add plus Configuring classes to all webapps for this Server -->
<!-- =========================================================== -->
  <Call class="org.eclipse.jetty.webapp.Configuration$ClassList" name="setServerDefault">
    <Arg><Ref refid="Server" /></Arg>
    <Call name="addAfter">
      <Arg name="afterClass">org.eclipse.jetty.webapp.FragmentConfiguration</Arg>
      <Arg>
        <Array type="String">
        <Item>org.eclipse.jetty.plus.webapp.EnvConfiguration</Item>
        <Item>org.eclipse.jetty.plus.webapp.PlusConfiguration</Item>
      </Array>
    </Arg>
  </Call>
</Call>
</Configure>

这是我在 Servlet 的 init() 方法中的调用代码:

Context _initCtx = new InitialContext();
Context _envCtx  = (Context) _initCtx.lookup("java:comp/env");

它抛出的错误:

javax.naming.NameNotFoundException; remaining name 'env'
at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:449)
at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:536)
at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:551)
at org.eclipse.jetty.jndi.java.javaRootURLContext.lookup(javaRootURLContext.java:117)
at javax.naming.InitialContext.lookup(Unknown Source)

我正在运行 vanilla GWT 2.7,并尝试在我的服务器代码中使用 JNDI 查找。 我还将 jetty-all-8.1.9.v20130131.jar 和 jetty-plus-8.1.9.v20130131.jar 附加到项目中,因为 GWT jar 中缺少一些 Context 和 JNDI 类。我尝试在 GWT 中验证 jetty 的版本,结果如​​下:

Server server = new Server(7070);
System.out.println(server.getVersion());

8.y.z-SNAPSHOT

我看到了可以通过其他方式配置 JNDI 的解决方案,但是由于我在 GWT 中运行,我只能使用 jetty-web.xml 和 jetty-plus.xml 文件。

在调试 servlet 时,我正在获取以下内容:

Context _envCtx  = (Context) _initCtx.lookup("java:comp");

但不适用于:

Context _envCtx  = (Context) _initCtx.lookup("java:comp/env");

Stacktrace 在上面。

我真的被困在这里了。那里有码头专家吗?


编辑 1:

添加 jetty-env.xml :

<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure id='portal' class="org.eclipse.jetty.webapp.WebAppContext">
  <New id="DStest" class="org.eclipse.jetty.plus.jndi.Resource">
  <Arg></Arg>
  <Arg>jdbc/DSTest</Arg>
  <Arg>
    <New class="org.hsqldb.jdbcDriver">
      <Set name="Url">jdbc:hsqldb:hsql://localhost</Set>
      <Set name="User">sa</Set>
      <Set name="Password"></Set>
    </New>
  </Arg>
</New>
</Configure>

这是我的 web.xml:

<resource-ref>
  <description>Primary database</description>
  <res-ref-name>jdbc/DSTest</res-ref-name>
  <res-type>javax.sql.DataSource</res-type>
  <res-auth>Container</res-auth>
</resource-ref>

仍然 _envCtx 为空,但以下例外。 _initCtx.lookup("java:comp") 确实返回 org.eclipse.jetty.jndi.NamingContext 实例。

Context           _initCtx          = new InitialContext();
Context           _envCtx           = (Context) _initCtx.lookup("java:comp/env");

结果

javax.naming.NameNotFoundException; remaining name 'env'

编辑 2:

我一定错过了其他东西(基本)....??!? 我将 jetty-env.xml 中的 1 行更改为:

<Arg><Ref refid="portal"/>jdbc/DSTest</Arg>

还有文档类型:

<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">

我找不到更适合 v8.X 的 .dtd 还是同样的问题。

【问题讨论】:

    标签: gwt jetty jndi


    【解决方案1】:

    什么对我有用(假设您没有使用 SuperDevMode):

    1. 在运行 DevMode 时将 -Djava.naming.factory.initial=org.eclipse.jetty.jndi.InitialContextFactory 添加到 JVM 参数中。 (在extraJvmArgs 中用于 gwt-maven-plugin)

    2. 将 Jetty Plus 和 JNDI 的依赖项添加到您的 POM:

      <dependency>
          <groupId>org.eclipse.jetty</groupId>
          <artifactId>jetty-jndi</artifactId>
          <version>8.1.12.v20130726</version>
          <scope>provided</scope>
      </dependency>
      <dependency>
          <groupId>org.eclipse.jetty</groupId>
          <artifactId>jetty-plus</artifactId>
          <version>8.1.12.v20130726</version>
          <scope>provided</scope>
      </dependency>
      
    3. jetty-web.xml 中配置JNDI 条目:

      <?xml version="1.0"?>
      <Configure class="org.eclipse.jetty.webapp.WebAppContext">
      
          <New id="DataSource" class="org.eclipse.jetty.plus.jndi.Resource">
              <Arg>jdbc/XYZ</Arg>
              <Arg>
                  <New class="org.postgresql.ds.PGSimpleDataSource">
                      <Set name="user">X</Set>
                      <Set name="password">Y</Set>
                      <Set name="databaseName">Z</Set>
                      <Set name="serverName">X</Set>
                      <Set name="portNumber">A</Set>
                  </New>
              </Arg>
          </New>
      
          <New class="org.eclipse.jetty.plus.jndi.EnvEntry">
              <Arg>config/ABC</Arg>
              <Arg type="java.lang.String">Value</Arg>
          </New>
          <!-- ... -->
      </Configure>
      

    就是这样。

    【讨论】:

    • 嗨,虽然这个答案没有被提问者接受,但我可以确认它对我有用。我正在使用 GWT 2.6.0,它使用相同的 Jetty 8.1.12.v20130726。但是,我还需要使用自定义的c.g.g.d.s.j.JettyLauncher.javabootStrapOnlyClassLoader() 返回Thread.currentThread().getContextClassLoader()(详细请参见:github.com/gwtproject/gwt/issues/8507
    • 感谢您的回答(和问题)。我提供了一个答案,其中包含我的设置细节,我终于让它工作了。欢迎评论!见stackoverflow.com/a/47318195/1168041
    【解决方案2】:

    这不是受支持的用法,但它应该可以工作:https://code.google.com/p/google-web-toolkit/issues/detail?id=8526

    您必须使用完全相同版本的 Jetty 依赖项,并且 GWT is using 8.1.12

    【讨论】:

    • 我将 8.1.9 (!?@) jar 换成了 8.1.12 :-)。我按照文章中的说明修改了 JettyLauncher,但没有额外的成功。
    【解决方案3】:

    You need to have a &lt;resource-ref&gt; declared for this resource in your WEB-INF/web.xml too.

    问题是,java:comp/env 直到:

    • 创建了一个引用(在您的 web 应用的特定 jetty-env.xml 或顶级服务器 xml 文件中)
    • 该引用绑定到 webapp 实例(而不是服务器实例)。请参阅 org.eclipse.jetty.plus.jndi.Resource 声明中的第一个参数。
    • 您的 webapp 的 WEB-INF/web.xml 声明了一个指向此资源的 &lt;resource-ref&gt;

    Jetty 只是在此处遵循 servlet 规范。

    对编辑 #1 的回应

    Jetty 8 is EOL (End of Life),升级到Jetty 9。

    这些说明适用于 Jetty 9。

    两件事......(就像上面原始答案中的链接)

    • 您的DOCTYPE 错误。更新它。
    <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
    
    • 您没有将您的引用绑定到您的 webapp,实际上,您的 XML sn-p 配置为绑定到 JVM 上下文。 (参数 #1 未指定/为空)
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
    <Configure id="portal" class="org.eclipse.jetty.webapp.WebAppContext">
      <New id="DStest" class="org.eclipse.jetty.plus.jndi.Resource">
        <Arg><Ref refid="portal"/></Arg> <!-- this is where the resource is bound -->
        <Arg>jdbc/DSTest</Arg>
        <Arg>
          <New class="org.hsqldb.jdbcDriver">
            <Set name="Url">jdbc:hsqldb:hsql://localhost</Set>
            <Set name="User">sa</Set>
            <Set name="Password"></Set>
          </New>
        </Arg>
      </New>
    </Configure>
    

    【讨论】:

    • 感谢您的提示...我的 cmets 在“编辑 1”中
    • 另外,Jetty 8 is EOL (End of Life),升级到 Jetty 9。
    • 谢谢乔金。我进行了更改(编辑#2)仍然是同样的问题?。 Jetty 8 附带 GTW,这就是我使用它的原因。
    【解决方案4】:

    感谢 Thomas 的提问和回答。我有一个非常相似的情况。获得正确的配置组合非常困难,但我终于让它工作了。我想我不妨在这里记录下我的发现。

    我这样做是为了设置GWT 2.6,它使用Jetty 8.1.12v20130726。我的 目标是为DBCP2 连接池设置JNDI。我在跑步 GWT in Eclipse in DevMode

    WEB-INF/jetty-web.xml

    我正在使用 JVM 范围,但在 WebAppContext 内设置值

    另请注意,使用的名称是java:comp/env/jdbc/datalakeDbcp2(即带有前缀java:comp/env/

    <?xml version="1.0"  encoding="ISO-8859-1"?>
    <!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
    <Configure id="wac" class="org.eclipse.jetty.webapp.WebAppContext">
    
        <New id="datalakeDsDbcp2" class="org.eclipse.jetty.plus.jndi.Resource">
            <Arg></Arg>                                 <!-- scope -->
            <Arg>java:comp/env/jdbc/datalakeDbcp2</Arg> <!-- name  -->
            <Arg>                                       <!-- value -->
                <New class="org.apache.commons.dbcp2.BasicDataSource">
                    <Set name="driverClassName">org.apache.hive.jdbc.HiveDriver</Set>
                    <Set name="url">jdbc:hive2://someServer:somePort/someDb</Set>
                    <Set name="username"></Set>
                    <Set name="password"></Set>
                </New>
            </Arg>
        </New>    
    
    </Configure>
    

    JettyLauncher.java

    JettyLauncher.javahere 复制到您自己的工作中 目录(自然在src/com/google/gwt/dev/shell/jetty/的路径下)

    只需要一个本地修改。

    bootStrapOnlyClassLoader

    /*
     * Change suggested by:
     * https://groups.google.com/forum/#!topic/google-web-toolkit/SBFltI27ssk 
     */
    private final ClassLoader bootStrapOnlyClassLoader 
        = Thread.currentThread().getContextClassLoader();
    //    private final ClassLoader bootStrapOnlyClassLoader = new ClassLoader(null) {
    //    };
    

    无需更改WebAppClassLoaderExtension -- 使用即可 作为原始代码:

    private class WebAppClassLoaderExtension extends WebAppClassLoader {
    
      private static final String META_INF_SERVICES = "META-INF/services/";
    
      public WebAppClassLoaderExtension() throws IOException {
        super(bootStrapOnlyClassLoader, WebAppContextWithReload.this);
      }
    

    pom.xml

    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-jndi</artifactId>
        <version>8.1.12.v20130726</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-plus</artifactId>
        <version>8.1.12.v20130726</version>
        <scope>provided</scope>
    </dependency>
    

    VM 参数(Eclipse

    -Djava.naming.factory.initial=org.eclipse.jetty.jndi.InitialContextFactory 
    

    WEB-INF/web.xml

    也许是因为我在 jetty-web.xml 中使用了 VM 范围,所以我这样做了 不需要更改我的web.xml

    获取 JNDI 命名连接的程序代码

    try {
       InitialContext ic = new InitialContext();
       DataSource ds 
           = (DataSource) ic.lookup("java:/comp/env/jdbc/datalakeDbcp2");
       conn = ds.getConnection();
    } catch (NamingException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
       throw new RuntimeException(e);
    };
    

    参考文献

    1. 代码使用Jetty v8.1.12.v20130726,但我找不到匹配的 文档,所以我一直在使用 'Jetty 9.3.x' 的文档。它 似乎仍然适用:
    2. GWT 问题 8507 here

    【讨论】:

      猜你喜欢
      • 2012-09-23
      • 1970-01-01
      • 2015-08-31
      • 1970-01-01
      • 1970-01-01
      • 2011-05-05
      • 1970-01-01
      • 2022-06-30
      • 1970-01-01
      相关资源
      最近更新 更多