1

I'm trying to make a Spring Boot 1.5 project to use the embedded Tomcat Server it can come with. The project is configured for Tomcat 8.5, with a META-INF/context.xml, WEB-INF/web.xml and a specific server.xml holding the global resources the context is referring to.

I followed online guides and was able to include most of my Resource objects from those configuration files into my embedded server. To do so, I extended the TomcatEmbeddedServletContainerFactory class and override the postProcessContext function. For the most part, it works and the project can lookup JNDI names successfully.

There is, however, one Resource I'm unable to import.

META-INF/context.xml

<ResourceLink name="rlname"
              type="java.lang.Object"
              global="path/to/resource" />

There is no Resource in the GlobalNamingResources element that is directly referred by this global property. There are, however, multiple Resource with name/global which are children to this path:

server.xml

<GlobalNamingResources>
    <Resource global="path/to/resource/0/item1"
              name="path/to/resource/0/item1" />
    <Resource global="path/to/resource/0/item2"
              name="path/to/resource/0/item2" />
    <Resource global="path/to/resource/0/item3"
              name="path/to/resource/0/item3" />
</GlobalNamingResources>   
              

Here's how this Resource is being called in Java code:

Context initialContext = new InitialContext();
Context rlContext = (Context) initialContext.lookup("java:comp/env/rlname");
NamingEnumeration<Binding> names = rlContext.listBindings(""); // this would contain only one item in this isntance, with the binding for "path/to/resource/0"

Context contextZero = (Context) names.next().getObject();

// with this, we can access the three child subitems
contextZero.lookup("item1");
contextZero.lookup("item2");
contextZero.lookup("item3");

Basically, the ResourceLink is used as a "subcontext", used later to get the other Resource. This works for an external Tomcat installation, but I'm unable to make it work with the embedded one. The lookup always fails.

How can I translate this Tomcat configuration quirk into embedded server configuration language?

I tried the following:

  • Adding the rlname ResourceLink as a ContextResource object. This makes the lookup throw a NamingException.
  • Adding the rlname ResourceLink as a ContextResourceLink object. With this, the lookup does not throw an exception but returns null instead.
  • Replacing the type property from "java.lang.Object" to "javax.naming.Context". Changes nothing.
@Override
protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer (Tomcat tomcat) {
    tomcat.enableNaming();
    return super.getTomcatEmbeddedServletContainer(tomcat);
}

@Override
public void postProcessContext(Context context) {
    ContextResource resource1 = new ContextResource();
    resource1.setName("path/to/resource/0/item1");
    resource1.setProperty("global", "path/to/resource/0/item1");
    context.getNamingResources().addResource(resource1);

    ContextResource resource2 = new ContextResource();
    resource2.setName("path/to/resource/0/item2");
    resource2.setProperty("global", "path/to/resource/0/item2");
    context.getNamingResources().addResource(resource2);

    ContextResource resource3 = new ContextResource();
    resource3.setName("path/to/resource/0/item3");
    resource3.setProperty("global", "path/to/resource/0/item3");
    context.getNamingResources().addResource(resource3);

    // Scenario 1. As a ContextResourceLink
    ContextResourceLink rLink1 = new ContextResourceLink();
    rLink1.setName("rlink");
    rLink1.setType("java.lang.Object");
    rLink1.setProperty("global", "path/to/resource");
    context.getNamingResources().addResourceLink(rLink1);

    // Scenario 2. As a ContextResource
    ContextResource rLink2 = new ContextResource();
    rLink2.setName("rlink");
    rLink2.setType("java.lang.Object");
    rLink2.setProperty("global", "path/to/resource");
    context.getNamingResources().addResource(rLink2);
}

I also tried other things, including messing around with the Tomcat object given by getTomcatEmbeddedServletContainer function, but to no avail.

One thing to note is that, with other Resource, I don't use the ContextResourceLink object. For those, I created a single ContextResource object and "merged" the properties from the link and the GlobalNamingResources element into a single object. From my testings, applying the same distinction of global resources and context resource links and adding them onto context.getNamingResources() doesn't work. Same thing goes with tomcat.getServer().getGlobalNamingResources() .

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.