Status/Resolution/Reason: Closed/Withdrawn/ThirdParty
Reporter/Name(from Bugbase): Andre Münz / Andre Münz (Andre Münz)
Created: 09/19/2016
Components: Web Container (Tomcat)
Versions: 2016
Failure Type: Crash
Found In Build/Fixed In Build: CF2016_Update1 /
Priority/Frequency: Normal / All users will encounter
Locale/System: ALL / Linux
Vote Count: 0
Problem Description:
We are using ColdFusion 9 (Stage Beta and Production) and ColdFusion 2016 (Stage Development and Alpha)
We deploy the Server as a J2EE container in a Tomcat 7 environment (for ColdFusion 9) and Tomcat 8 (for ColdFusion 2016)
We use global JNDI ressources, defined in Tomcat (<GlobalNamingResources>-section) to store parameter, paths and passwords to develop stage-indepentent ColdFusion code
Since a new Tomcat8 release (8.0.37) it is not possible to get access to the global JNDI resources from ColdFusion server.
Every try to read a JNDI ressource returns "undefined" (or more correct NULL)
ColdFusion fails to has access on global JNDI ressources (plz habe a look on the new "feature" of Tomcats ResourceLinkFactory)
Steps to Reproduce:
Deploying a pure Java application on Tomcat 8.0.37 returns the correct values.
Deploying a ColdFusion 9 or 2016 on Tomcat 8.0.37 returns NULL on accessing a global ressource and the correct value on acessing a local context ("my/local/test" as defined in context.xml)
Downgrading to Tomcat 8.0.35 returns the correct results on both ColdFusion versions
Actual Result:
with Tomcat 8.0.37: undefined (NULL)
Expected Result:
with Tomcat 8.0.35: JohnDoe (as defined in <GlobalNamingResources> of server.xml)
Any Workarounds:
downgrading Tomcat to version 8.0.35
compiling a modified Tomcat 8.0.37 without the following lines in apache-tomcat-8.0.37-src/java/org/apache/naming/factory/ResourceLinkFactory.java
... //line 142-144
if (!validateGlobalResourceAccess(globalName)) {
return null;
}
...
----------------------------- Additional Watson Details -----------------------------
Watson Bug ID: 4190478
External Customer Info:
External Company:
External Customer Name: Andre Münz
External Customer Email:
External Test Config: server.xml (within Tomcat)
==========================
<GlobalNamingResources>
<Environment name="my/secret/password" value="JohnDoe" type="java.lang.String"/>
</GlobalNamingResources>
context.xml (/META-INF/context.xml)
===================================
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Environment name="my/local/test" value="local test" type="java.lang.String" override="false"/>
<ResourceLink name="my/secret/password" global="my/secret/password" type="java.lang.String" />
</Context>
jndi.cfc
========
component {
public jndiReader function init() {
variables.ctx = createobject("java","javax.naming.InitialContext");
variables.envCtx = ctx.lookup("java:comp/env/");
return this;
}
public any function read(required string keyName) {
try{
return envCtx.lookup(arguments.keyName);
}
catch(any e){
throw(type = "Application", message = "Error: Could not read service key. Maybe the key is not bind via JNDI.");
}
}
}
By the way, I wrote a Java component too, which I place outside the ColdFusion server into the lib-folder of our Tomcat
EnvironmentJndiWrapper.java
================
package my.test.wrapper;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
/**
* Created by amz
* on 2016/Sep/14 14:55.
*/
public class EnvironmentJndiWrapper {
public EnvironmentJndiWrapper() throws NamingException {}
public String lookupKey(String key) throws NamingException {
InitialContext initCtx = new InitialContext();
Context rootCtx = (Context) initCtx.lookup("java:comp/env");
String value = (String) rootCtx.lookup(key);
return value;
}
}
ColdFusion Template
===================
<cfscript>
try {
//access via instanciating existing Java components
ctx = createobject("java", "javax.naming.InitialContext");
envCtx = ctx.lookup(JavaCast("string", "java:comp/env"));
test = envCtx.lookup("my/secret/password");
writeDump(test);
}
catch(any e){
writeDump(e);
}
try {
//access via JNDI wrapper (see Java component above)
ctx = createobject("java", "my.test.wrapper.EnvironmentJndiWrapper");
test = ctx.lookupKey(JavaCast("String", "my/secret/password"));
writeDump(test);
}
catch(any e){
writeDump(e);
}
</cfscript>
Attachments:
Comments: