Lucee 6 & 7 Redis Issue (Bug?)

So I am having this really weird issue that I cannot figure out. I assume it is a bug, but figured I would post here first.

I have a custom redis caching that I built for my servers. It is built on Jedis. This code works perfectly on my production and development environments all running 5.4.6.9. I put the redis and related jar files in the lib/ext folder. When I updated my server to 6.2.1.122 I start getting an error saying the (org.apache.commons.pool2.impl.GenericObjectPoolConfig, java.net.URI) is not found.

I thought maybe this was something about my environment so I launched a docker 7.0.0.229-SNAPSHOT put the files in the lib/ext and still the same result.

Then I updated my code to put the jar files in a sub folder and not in the lib/ext and when doing createObject() I pass “jars/” as my final argument. When I do this everything works as expected.

So my question is WHY? Why is it different if I put the files in lib/ext vs in a subfolder of the cfm file? Why would version 6 and 7 make my jedis jar think that method doesn’t exist when it clearly does (you can dump the object to see it)

I have attached a .cfm and the jars and the test code accordingly. This issue is preventing me from upgrading to V6 or V7.

redis issue.zip (3.1 MB)

It’s probably a class conflict, Lucee 6 switch to pool2

So, with Lucee 6.2 or 7.0, rather than messing around with jar files, try the new enhanced support for java and maven and just let Lucee manage it automatically.

It’s much quicker, cleaner and will avoid any such problems!

While this is super cool, it kinda sucks that I would need to go through my whole application and now make a specific version of my code for this version of the server. The way java has been handled in Lucee has been the same for years and years and now it appears it is isn’t backward compatible.

Should I report this as a bug, or should I chalk it up to undocumented breaking change?

Do all the jars you have added have OSGI metadata?

i.e. is there a Bundle-SymbolicName in the /META-INF/MANIFEST.MF

can you share the actual stack traces?

Any bug report always requires a reproducible example, otherwise, it goes to straight to need more details, which is why we triage everything here first.

This isn’t an extension it is a function in the functions folder within library.

I attached a complete example of the issue with the jars and a cfm file. Literally copy the exact same jars into the lib/ext and run the code and get the error. Then remove the jars from lib/ext and run the code that points to the jars folder within my code and it works.

I am going to try the new way of doing things because I do love the idea of not managing the jars (incredible update to Lucee, great work). My main issue is, I don’t know what else is broken and really want to update to 6 or 7 but without being able to run my site it makes it hard to know what else is broken or needs addressed.

oops, sorry missed the examples you included, been a long day.

both examples for me without problem, 6.2.2.10-SNAPSHOT and 6.2.2.22-SNAPSHOT, same dump info

As you are loading a newer version of commons pool than Lucee bundles, did you try specifying the exact commons pool using the osgi bundle version?

redisPoolConfig = createObject( "java", 
"org.apache.commons.pool2.impl.GenericObjectPoolConfig", 
"commons-pool2", 
"2.12.1").init();

The stack trace would be useful… :slight_smile:

I don’t read Zac’s note (that you were replying to) as saying it was required. It seemed just a suggestion.

It doesn’t seem the rest of the replies between you two in this thread addressed that aspect of your concern, so I hope someone will clarify.

as I said early on in the thread, I’m pretty sure it’s just a classloader conflict with the commons-pool2 osgi bundle used by Lucee core in 6 and 7 and the one being added, tho Lucee 7 bundles the same version 2.12.1, 6 uses 2.9.0

The stack traces / logs would explain it all

bumping up the log level is always useful when debugging these kind of problems

Zac, if this is your reply to my comment,
which precedes yours
, I don’t see it as addressing the point which Lyle had raised. Please clarify if you feel it does, or if it was responding to another of his comments in the thread.

You mean his question if this a breaking change or undocumented bug?

Yes, and specifically what I’d quoted (hoping to void any doubt), where he’d said it “sucks that I would need to go through my whole application and now make a specific version of my code for this version of the server. The way java has been handled in Lucee has been the same for years and years and now it appears it is isn’t backward compatible”.

I was saying I didn’t think that’s what you were saying to him, in your reply I’d also linked to. Or were you?

To say I am confused is a complete understatement. This makes no sense. I did not include the pool2.jar in the ext folder since it is already part of lucee. I can see the file in the bundles folder. BUT there is also a 2.8.1 in there

redisPoolConfig = createObject( “java”, “org.apache.commons.pool2.impl.GenericObjectPoolConfig”, “commons-pool2”, “2.12.1”).ini


t()

redisPoolConfig = createObject( “java”, “org.apache.commons.pool2.impl.GenericObjectPoolConfig”).init()

<cfscript>
	redisUri = "redis://redis:6379";

	try {
		uri = createObject("java", "java.net.URI").init(redisUri);
		redisPool = createObject( "java", "redis.clients.jedis.JedisPooled");
		redisPoolConfig = createObject( "java", "org.apache.commons.pool2.impl.GenericObjectPoolConfig").init()

		redisConnection = redisPool.init(redisPoolConfig, uri);

		dump(redisConnection);
	}

	catch(any e){
		dump(e);
	}
</cfscript>


Hi @Lyle_Karstensen , there might be some conflict among the 10 Jar files you are using. Perhaps an incompatibility when some of them are used together.

I say this because, when I experimented with your code and Jar files on ColdFusion 2025, I got ClassNotFoundException and ClassCastException. That prompted me to look for an implementation that works without errors and that contains the minimum set of Jar files.

I found one. Its description follows.

The Jar files required:

  • jedis-6.0.0.jar
  • commons-pool2-2.12.1.jar
  • commons-logging-1.2.jar

The set-up (directories and files, under the web-root):
/redis_test/jars/jedis-6.0.0.jar
/redis_test/jars/commons-logging-1.2.jar
/redis_test/jars/commons-pool2-2.12.1.jar

/redis_test/Application.cfc
/redis_test/default.cfm

The test code:
Application.cfc

<cfcomponent>

    <!--- Application settings --->
    <cfset this.name = "MyRedisTest">
    <cfset this.sessionManagement = true>
    <cfset this.sessionTimeout = createTimeSpan(0, 0, 20, 0)> 
    <cfset this.applicationTimeout = createTimeSpan(1, 0, 0, 0)> 
	<!--- Jars stored in the directory redis_test/jars/ under the ROOT --->
	<cfset this.javaSettings = {
		loadPaths = [expandPath("/redis_test/jars/")],
		loadColdFusionClassPath = true,
		reloadOnChange = true,
		watchInterval = 5
	} />
    
    <!--- Called when the application is first initialized --->
    <cffunction name="onApplicationStart" returnType="boolean">
      
        <cfreturn true>
    </cffunction>

    <!--- Called when a session starts --->
    <cffunction name="onSessionStart" returnType="void">
       
    </cffunction>

    <!--- Called for every request --->
    <cffunction name="onRequestStart" returnType="boolean">
        <cfargument name="targetPage" type="string" required="true">

        <cfreturn true>
    </cffunction>

</cfcomponent>

default.cfm

<cfscript>
	redisUri = "redis://redis:6379";

	try {
		uri = createObject("java", "java.net.URI").init(redisUri);
		jedisPooled = createObject("java", "redis.clients.jedis.JedisPooled");
		genericObjectPoolConfig = createObject("java", "org.apache.commons.pool2.impl.GenericObjectPoolConfig").init();
	    hostAndPort = createObject("java", "redis.clients.jedis.HostAndPort").init("redis://redis",6379);
	    
		genericObjectPoolConfig.setMaxTotal(100);
		genericObjectPoolConfig.setMaxIdle(10);
		genericObjectPoolConfig.setMinIdle(10);
		genericObjectPoolConfig.setTestOnBorrow(true);
		genericObjectPoolConfig.setBlockWhenExhausted(true);
		genericObjectPoolConfig.setMaxWaitMillis(3000);
		genericObjectPoolConfig.setTestOnCreate(true);
		genericObjectPoolConfig.setTestWhileIdle(false);
		genericObjectPoolConfig.setTimeBetweenEvictionRunsMillis(60000);
		genericObjectPoolConfig.setMinEvictableIdleTimeMillis(300000);


		redisConnection = jedisPooled.init(genericObjectPoolConfig, uri);
		
		// Alternative definition of 'redisConnection' to be tested
 		// redisConnection = jedisPooled.init(hostAndPort,genericObjectPoolConfig);
 		
		writedump(var=redisConnection, label="Dump of redisConnection");
		
	}

	catch(any e){
		writedump(e);
	}	
</cfscript>

Test procedure:

  1. Launch the file default.cfm in a browser. You should get the dump of the redisConnection object.
  2. Comment out the line
    redisConnection = jedisPooled.init(genericObjectPoolConfig, uri); and uncomment the line redisConnection = jedisPooled.init(hostAndPort,genericObjectPoolConfig);.
  3. Relaunch the file default.cfm in a browser. You should again get the dump of the redisConnection object.

Lucee version: lucee-express-6.2.1.122
ColdFusion version: ColdFusion 2025 Update 2
Operating System: Windows 10 Pro

I think may have missed where I pointed out that moving the files to its own folder works. In my original post I stated that in Lucee 5 the exact same files in the ext folder where I put all my other .jar files works and has for many years. As soon as upgrade I get the class not found.

I tested over and over. The more confusing part is that if you look at my screenshots it tells me the class is not there yet in the other screenshot it shows it clearly is.

I will try the extension way of this with Maven and hope that fixes this. To say I am frustrated that I cannot upgrade to a “better” version is maddening. I have been using Lucee/Railo for many many years and have never had an issue like this.