2

I am trying to set up a server running Tomcat 8 to have JNDI URL resources available to a large number of apps running on that server. The apps are plain jsp/servlet with Maven (No Spring).

I have 2 examples of global resources I am trying to use, one is a DataSource which is working correctly and one is the URL that does not.

DataSource

In Tomcats context.xml inside the GlobalNamingResources element

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

In Tomcats web.xml, top level element

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

That's it for the DataSource, and it does work

For the URL resource, I have this in the server.xml

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

My object factory was created the same way as in this answer: Tomcat: use FTP connection via JNDI Except I added a few println statements to prove that it was being used and had the correct url which it does.

I have the following 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>

Finally the code that accesses this. This code was the result of decompiling a jar, it is not a third party jar but I do not have the source code. The exception occurs in the jndiReference = ic.lookup(serviceName); line. serviceName is the name of the resource and jndiRoot is always null (The code that calls this method passes in null). The getInitialContext() method just creates a new instance of javax.naming.InitialContext if one was not already created.

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

The line from the properties file that maps to the resource propertyserviceurl=url/LOGIN_MODULE_CONFIGURATION_SERVICE

I have also tried adding a ResourceLink to Tomcats context.xml. I have tried making the name of the ResourceLink unique and the value of global the same as the actual Resource. Also tried modifying the property file to map to the ResourceLink name instead of the Resource but I always get the same results.

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

The Exception

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)

I have spent a few days on this one and am having trouble figuring out what configuration I need to get this to work. I think the biggest hurdle is that I can't change the java code that tries to access the resource.

Community
  • 1
  • 1
Tim
  • 41
  • 1
  • 5

1 Answers1

2

I got it to work. I don't really understand how the ResourceLink is working since it's name is not referenced anywhere. But if anything is different it won't work. Basically I needed to add java:/comp/env/ to the beginning of the Resource name since I cannot update the code that calls this.

Updated the Resource in Tomcats server.xml to

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

Updated the ResourceLink in Tomcats context.xml to

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

Updated the properties file entry to

propertyserviceurl=java:/comp/env/url/LOGIN_MODULE_CONFIGURATION_SERVICE
Tim
  • 41
  • 1
  • 5