Skip to main content
George____
Inspiring
March 25, 2021
Question

CFLDAP timeout not working and JNDI.properties

  • March 25, 2021
  • 2 replies
  • 2146 views

How can I set the "com.sun.jndi.ldap.read.timeout" value, or otherwise get a CFLDAP call to properly timeout.

 

I have an Active Directory (AD) server that I'm making CFLDAP calls to.   Randomly the calls will hang for approximately 900 seconds.  The AD server admins say they don't see any issues on their end, but the 900 seconds does correspond to a default MaxConnIdleTime setting on the AD server.   In FusionReactor it will show that it's stuck on "java.net.SocketInputStream.socketRead0"

 

This page matches with the issue I'm seeing:  java.net.socketinputstream.socketread0 Problem patterns 

 

According to the various pages I've found on this issue I need to set the "com.sun.jndi.ldap.read.timeout" value.   I've tried setting this in the jvm.config, but I found web pages that say you can't set it there.  That it needs to be set in the jndi.properties file.  All of the web pages I find for ColdFusion and jndi.properties are from CF9 and older, those paths appear to no longer be valid.    I've tried JAVA_HOME\lib and runtime\lib.   Neither worked, but I'm not sure how to verify that the jndi.properties file is even being loaded.

 

I also tried setting it on the calling page with

<cfset system = createObject("java", "java.lang.System")>

<cfset system.setProperty("com.sun.jndi.ldap.read.timeout","1000")>

but that doesn't appear to work, when I do system.getProperties() I can see it set there, but I suspect I'm not setting it right in the first place.

 

I do have the timeout value set on the cfldap call, and if I set it for a couple milliseconds I can force timeouts.   The timeout value is being ignored though for these random hangs.   The issue isn't with the specific LDAP call, because the exact same call reran will work fine.

 

I'm open to any suggestions anyone has for preventing the CFLDAP call getting stuck on "java.net.SocketInputStream.socketRead0"

This topic has been closed for replies.

2 replies

Charlie Arehart
Community Expert
Community Expert
March 29, 2021

George, I have not hit this problem (and can't recreate it), but I have a couple of suggestions that may work for you.

 

1) First, you say you "tried setting this in the jvm.config, but I found web pages that say you can't set it there." So first, how did you try to set it? According to this page on ldap/jndi configuration, it does discuss that particular timeout and later in the doc it shows you CAN set such jndi.ldap settings there. It shows an example of setting other related ones. Is this what you tried?

-Dcom.sun.jndi.ldap.read.timeout=1000

 

(BTW, note also that the doc I shared indicates that this timeout is in milliseconds, so 1000 would be only 1 second. Is that what you were wanting? I might suggest giving it at least a few seconds, as things can happen on any server randomly to slow it down a little, even an ldap server.)

 

2) And are you saying you added that to the java-args in the jvm.config file of the instance in which you were trying things? I'd recommend you try it there rather than in the CF Admin itself, because if you make any mistake you may find CF would not come up (and you could not then see the Admin to correct your mistake).

 

On the other hand, you COULD use the CF Admin as a checkpoint after you make the above change and restart CF. Then in the admin it SHOULD show put in the java args textarea on the CF Admin "java and jvm" page. If you somehow do NOT see it there, then you are NOT editing the right jvm.config. (If you are running an instance of CF, be sure to edit the one in the instance's bin/jvm.config, rather than the cfusion/jvm.config, for example.)

 

3) You say also that you tried to set this in a jndi.proporties file, but you were stumped as to where to put the file. You said you "tried JAVA_HOME\lib and runtime\lib". Can you be more specific? Those can be translated into various locations (by you or by us reading your words), and there are indeed various lib folders within CF. 🙂

 

More specifically, did you try it in the cfusion/lib folder, right under your main CF folder? Or if you are running an instance, then its sibling instancename/lib folder? Those are the folders where one would modify the various jars related to JDBC drivers that CF loads, for instance).

 

And then you restarted CF, and then did your test, and it didn't help? There could be still other reasons the properties file didn't work, if indeed you did put it there. (The Java doc I linked to made no mention of a jndi.properties file.)

 

So I am inclined to think that the first approach above should work.

 

4) Finally, you mention how the cfldap timeout attribute did not help. I will note  that this has been a problem also with cfquery's timeout, cfhttp's timeout, and so on. Folks find that it "doesn't work". I think the problem is in what the timeout is intending to do (but the CF docs are not as clear as they could be).

 

Again, if you look at that Java document I linked to, you will see that besides the read.timeout you are trying to set, there is a VERY similar-looking com.sun.jndi.ldap.connect.timeout, which controls how long the JVM should be willing to wait to obtain a connection to the jndi server. I suspect you're getting a quick connection, but then you are not getting any response.

 

And I won't be surprised if the CFLDAP timeout is instead just about a connection timeout (setting connect.timeout) rather than a response timeout (read.timeout).

 

So let us know if you can try the options above and if this gets you going (and I hope you may try it before writing a tracker ticket to Adobe. The more info you have, the more useful that ticket would be for Adobe and future readers).

/Charlie (troubleshooter, carehart. org)
George____
Inspiring
March 29, 2021

Charlie, thanks for the reply.
1) This was one of the pages I saw that states it can't be set in the jvm.config:
"The simple answer is that JNDI properties are not system properties, so setting them as system properties has no effect. You can provide them either in the environment of a Context or else via a /jndi.properties file in the root directory of your JAR file."

 

Providing them in the environment of the Context is what BKBK suggested, but that would require me to essentaily write my own java LDAP function and not use CFLDAP. That's why I was hoping to figure out where to put the jndi.properties file.

 

I'm trying the timeout of 1000, to increase the likelyhood of getting timeouts and to know that it's working, I probably should have set it even lower.

 

2) The java-args were added directly to the jvm.config file and CF was restarted. We verified the right jvm.config file was modified. It was also verified, because our CF instance didn't come up the first time due to a typo.  I saw various pages where some said you can set it the jvm.config and others say you can't. So we went ahead and tried it without any luck.   Of course I'm only assuming it didn't work because we still get hung connections and no timeouts.  Do you know a way I can output the jndi properties from within ColdFusion?  I'll see if I can figure that out.

 

3) JAVA_HOME would be the path where the admin had our upgraded version of Java installed \Program Files\Java\jdk11.  We're on version 11.0.10.   The runtime\lib would be \Coldfusion2018\cfusion\runtime\lib. This is actually being done by our server admin so I'll need to have him check if there's a lib folder under the instance. Unfortunately I don't have direct access and it's a shared environment, so everytime we reboot it to test, it stops a bunch of people from working.

 

This is an example Coldfusion MX document that mentions the jndi.properties file is located at cf_root/runtime/servers/default/SERVER-INF/jndi.properties.

This page talks about how the jndi.properties is used to configure the jndi properties of a java application.

4) Based on FusionReactor and the packet capture with wireshark it appears the connection happens quickly, but gets hung during the communication. It appears that CF gets the response back from the AD server, but is expecting more so the connection stays open until the AD server closes it at the 900 second idle timeout. FusionReactor is showing that the connection is hung on the "java.net.socketinputstream.socketread0". If I set the timeout attribute on the cfldap tag to something really low I can generate timeouts but it's these socketRead0 ones that ignore the timeout.

 

I've already opened an Adobe bug report since I saw Lucee had the same bug reported and is implementing a fix for it.

Charlie Arehart
Community Expert
Community Expert
March 29, 2021

Sorry, I had a client call so couldn't respond to George's comment before I did BKBK's (my disagreement reply below). I just felt that was important to get out first, while I had time. So now, back to George's reply to me.

 

To your point 1, I see you quote a stackoverflow topic saying these cannot be set in the JVM args. FWIW I quoted an Oracle Java doc that implied that they can. 🙂 I could only go on what I saw and shared. So again, I would recommend you have your admin try it.

 

As for your point 2, you say you "did try", but I can't tell if you're saying you tried exactly that arg as I proposed it. If you did, and the request still hung, that's indeed a bummer to hear. As for how to print out the jndi properties, I don't know that off the top of my head.

 

As for your point 3, no, the JVM location is NOT where to put it (or not where I was proposing to put it). Again, I was sharing from prior experience that the way to modify things loaded by CF was to put them into the cfusion/lib folder (or instance/lib, if running instances), and no not runtime/lib. Again, there are indeed many lib folders where you may find people propsing things over the years.

 

Indeed, your next point offered links to CFMX docs. To be clear, MX was CF6, from 20 years ago--when CF ran atop JRun, and the folder structure changed dramatically in CF10 and above, so do be VERY cautious about following any recommendations from such an old doc (even if the "update date" on the page suggests Adobe has blessed it. That would be in the context the version it was written for. For example, that article refers to the Verity K2 server, which was removed in CF9.)

 

As for that Java 11 doc on configuring JNDI settings, that confirms that the jndi.properties should be put in the classpath. In CF's case, that's a lot of possible folders, but again the key one is the cfusion/lib. (You can see all folders in the classpath in the CF Admin "settings summary", if you wanted to. That will NOT show if it pulls in a specific FILE from that path, but if a file is in a folder in that path, it can be expected to be loaded.) That said, there are matters of order of classloading that can sometimes complicate even that. But try it and see how it goes.

 

As for your point 4, you're confirming what I said: that it's NOT a "connection" issue but a read issue, so again getting the read.timeout should be the ticket.

 

Finally, about the Tracker ticket, ok. And you may well want to wait to see if/when you get any response there. But I am inclined to think that we still have not exhausted our efforts here and may solve it before they would. (And if anything, your ticket reads like you want them to change how the timeout attribute works. I doubt that will be done, since it would conflict with its current use, which I suspect is to set the connect timeout. That's not what you want, but others may want it, so if anything they'd need to consider adding a NEW attribute.)

 

And as for the Lucee ticket, I had read it before I wrote my last reply to you. While I agree that Pete (who wrote it) is indeed asking about the same issue as you, I'll note that the responses have not been about addressing that but instead talking about the current timeout that they DO see--which I am betting is again a connection timeout rather than a read timeout--and about whether their doc should show it being seconds or ms. Perhaps in time they may take it the direction you want, though that would only be for the sake of Lucee of course, and won't help you.

 

That's why I am pressing for you to be sure to try the things I've proposed. 🙂 As always, just trying to help. It's not like I get paid to write such detail. It's because I find often that other resources people rely on can be misleading. I simply want to present as much detail as seems needed. (I know it's more than some want to see or read--not referring to either of you, necessarily.)

/Charlie (troubleshooter, carehart. org)
BKBK
Community Expert
Community Expert
March 27, 2021

I think it is incorrect to set it as an environment property of your operating system. As far as I know, "com.sun.jndi.ldap.read.timeout" pertains to the custom environment that you yourself create for LDAP authentication. 

 

The relevant part of the Java code is:

 

// Set up the environment for creating the initial context
Hashtable<String, Object> env = new Hashtable<String, Object>();

// Set up the properties of the environment
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put("com.sun.jndi.ldap.read.timeout", "1000");
env.put(Context.PROVIDER_URL, "ldap://localhost:2001");

 

See the LDAP Simple.java example

George____
Inspiring
March 29, 2021

Thanks for the response.  I'd prefer to stick with Coldfusion instead of rewriting everything as Java code, but I might have to go that route if I'm unable to find the proper place to put the jndi.properties file.

 

Looks like someone reported this as a bug against Lucee back in 2018.   I'll do the same on adobe's site.  https://luceeserver.atlassian.net/browse/LDEV-1860