java - 如何在 Tomcat 8 中使用全局 JNDI URL 资源?

标签 java xml tomcat8.5

我正在尝试设置运行 Tomcat 8 的服务器,以使 JNDI URL 资源可供该服务器上运行的大量应用程序使用。这些应用程序是带有 Maven 的普通 jsp/servlet(无 Spring)。

我有 2 个正在尝试使用的全局资源示例,一个是工作正常的数据源,一个是无法正常工作的 URL。

数据源

在 Tomcats context.xml 中的 GlobalNamingResources 元素内

<Resource name="APPNAME" auth="Container" type="javax.sql.DataSource"
   maxTotal="100" maxIdle="30" maxWaitMillis="10000" username="appuser"
   password="password" driverClassName="oracle.jdbc.driver.OracleDriver"
   url="aUrl" />

在 Tomcats web.xml 中,顶级元素

<resource-ref>
   <res-ref-name>APPNAME</res-ref-name>
   <res-type>javax.sql.DataSource</res-type>
   <res-auth>Container</res-auth>
   <res-sharing-scope>Unshareable</res-sharing-scope>
</resource-ref>

这就是数据源,它确实有效

对于 URL 资源,我在 server.xml 中有此

<Resource name="url/LOGIN_MODULE_CONFIGURATION_SERVICE" auth="Container"
   type="java.net.URL" factory="com.mycompany.objectfactory.JndiUrlObjectFactory"
   url="AValidUrl" />

我的对象工厂的创建方式与此答案相同:Tomcat: use FTP connection via JNDI除了我添加了一些 println 语句来证明它正在被使用并且具有正确的 url 之外。

我有以下 Tomcats web.xml

<resource-ref>
   <res-ref-name>url/LOGIN_MODULE_CONFIGURATION_SERVICE</res-ref-name>
   <res-type>java.net.URL</res-type>
   <res-auth>Container</res-auth>
</resource-ref>

最后是访问它的代码。这段代码是反编译jar的结果,它不是第三方jar,但我没有源代码。异常发生在 jndiReference = ic.lookup(serviceName); 行中。 serviceName 是资源的名称,jndiRoot 始终为 null(调用此方法的代码传入 null)。 getInitialContext() 方法只是创建一个 javax.naming.InitialContext 的新实例(如果尚未创建)。

public static URL getUrl(final String serviceName, final String jndiRoot) {
    URL result = null;
    if (!isEmpty((Object) serviceName)) {
        final InitialContext ic = getInitialContext();
        Object jndiReference = null;
        try {
            jndiReference = ic.lookup(serviceName);
        } catch (NamingException ex) {
            ex.printStackTrace();
            if (!isEmpty((Object) jndiRoot)) {
                final String name = String.valueOf(jndiRoot) + serviceName;
                try {
                    jndiReference = ic.lookup(name);
                } catch (NamingException ex2) {
                    ex.printStackTrace();
                }
            }
        }
        if (jndiReference instanceof URL) {
            result = (URL) jndiReference;
        } else if (jndiReference instanceof Reference) {
            final Reference reference = (Reference) jndiReference;
            final RefAddr refAddr = reference.get("spec");
            try {
                result = new URL(getString(refAddr.getContent()));
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
        }
    }
    return result;
}

属性文件中映射到资源的行propertyserviceurl=url/LOGIN_MODULE_CONFIGURATION_SERVICE

我还尝试将 ResourceLink 添加到 Tomcats context.xml 中。我尝试使 ResourceLink 的名称唯一,并使 global 的值与实际资源相同。还尝试修改属性文件以映射到 ResourceLink 名称而不是资源,但我总是得到相同的结果。

<ResourceLink name="url/LOGIN_MODULE_CONFIGURATION_SERVICE" 
    global="url/LOGIN_MODULE_CONFIGURATION_SERVICE" type="java.net.URL" />

异常

javax.naming.NameNotFoundException: Name [url/LOGIN_MODULE_CONFIGURATION_SERVICE] is not bound in this Context. Unable to find [url].
at org.apache.naming.NamingContext.lookup(NamingContext.java:816)
at org.apache.naming.NamingContext.lookup(NamingContext.java:173)
at org.apache.naming.SelectorContext.lookup(SelectorContext.java:163)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at com.mycompany.common.supplement.web.WebHelper.getUrl(WebHelper.java:739)

我在这个问题上花了几天时间,但无法弄清楚我需要什么配置才能让它工作。我认为最大的障碍是我无法更改尝试访问资源的java代码。

最佳答案

我让它工作了。我不太明白 ResourceLink 是如何工作的,因为它的名称没有在任何地方被引用。但如果有什么不同,那就不行了。基本上,我需要将 java:/comp/env/添加到资源名称的开头,因为我无法更新调用它的代码。

将 Tomcats server.xml 中的资源更新为

<Resource name="java:/comp/env/url/LOGIN_MODULE_CONFIGURATION_SERVICE" auth="Container"
    type="java.net.URL" factory="com.mycompany.objectfactory.JndiUrlObjectFactory"
    url="AValidUrl" />

将 Tomcats context.xml 中的 ResourceLink 更新为

<ResourceLink name="url/LOGIN_MODULE_CONFIGURATION_SERVICE" 
    global="java:/comp/env/url/LOGIN_MODULE_CONFIGURATION_SERVICE" type="java.net.URL" />

将属性文件条目更新为

propertyserviceurl=java:/comp/env/url/LOGIN_MODULE_CONFIGURATION_SERVICE

关于java - 如何在 Tomcat 8 中使用全局 JNDI URL 资源?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41835844/

相关文章:

java - 为什么我的 Java 线程不同时运行?

java - 在 Java 中为变量分配动态名称

java - 在 Java 中向 Rally 添加新用户

c# - 使用数据集的 xml 到 TreeView

css - 如何修复 apache-tomcat-8.5.39 中的默认内容类型呈现问题?

java - Tomcat 8.5 - 无法在 ServletContextListener 的 contextInitialized 方法中访问 mysql JDBC 资源

在 Linux 平台上部署 Java 应用程序

java - PDFBox 图像元数据

Android RecyclerView 在 XML 布局中呈现异常

javascript - 使用 node-elementtree (nodejs) 从 xml 文件中删除元素