Error: cannot load class through its string name

We’re on Lucee 5.2.7.63 and experiencing some bad issues with loading in JAR’s in our Lucee app via CreateObject. We are not able to load ANY JAR-file - getting the below message everytime:

cannot load class through its string name, because no definition for the class with the specified name [JAR-functionname] could be found caused by (java.lang.ClassNotFoundException:JAR-functionname not found by lucee.core [64];java.lang.ClassNotFoundException:JAR-functionname;java.lang.ClassNotFoundException:JAR-functionname;)

What to do?

I’ve tried this: Calling Java from Lucee · Lucee (making use of this.javaSettings)

Done this: coldfusion - Where do I put Jar files in Lucee? - Stack Overflow and https://lucee.daemonite.io/t/where-to-place-3rd-party-jars/3369 (place JAR’s in /webappname/WEB-INF/lucee/lib/)

Utilized this: GitHub - markmandel/JavaLoader: JavaLoader is a library that has been built to ease the use, development and integration of Java within ColdFusion applications. Mark Mandel’s JavaLoader (works nicely in CF9+, but NOT in Lucee at all)

In all cases we get the above error-message. It seems like this issue [LDEV-604] - Lucee is still not resolved…

1 Like

Hi Seb

Loading jars via createObject() is working for me in Lucee 5.2.8.50 and it was fine in the previous 5.2.7.63 release too.

I’ve just done a simple test with a basic jar with one method located in the same directory as the calling script:

object = createObject( "java", "Basic", expandPath( "./" ) );
dump( object );

Are you using the Lucee spreadsheet library by any chance? If so is that giving the same error? By default that will load the POI etc jars in Lucee 5.x using createObject() but it can be configured to use JavaLoader.

2 Likes

Hi Julian, well, it seems that our JavaLoader being saved to a server variable for now was the culprit. Even a restart of Lucee didn’t clear the server-scoped object of loaded JAR’s. This was never an issue with ColdFusion. The JAR’s are for creating QR-codes and our own JAR’s with functions needed to create SPSS-files. Furthermore we have created a JAR that connects to a certain service, but they were not loaded either. Strange thing was that if I loaded the JAR somewhere in a CFC it went fine, doing the same operation in a CFM didn’t work. Anyways, Monday may be better, but porting a large webapp to Lucee from ACF is certainly proving to be difficult - way more so than I expected at first :frowning:

Strange. I use JavaLoader quite a bit in Lucee and haven’t had any issues putting instances in the server scope (including with the Spreadsheet lib). Here’s how I generally code my JAR wrappers’ init() methods (where the jars are in the same directory as the wrapper):

function init( javaLoaderPath=variables.javaLoaderPath ){
 var javaLoaderName = "myLoader";
 if( !server.keyExists( javaLoaderName ) ){
   var paths = [];
   paths.append( getDirectoryFromPath( getCurrentTemplatePath() ) & "my.jar" );
   server[ javaLoaderName ] = New "#arguments.javaLoaderPath#"( paths );
  }
 return this;
}

I sympathise. I wrote a whole series of blog posts a few years back on the woes we had transitioning to Railo, then Lucee. It all depends on which features you use. Good luck and shout if you need help.

Hi @Julian_Halliwell, thnx 4 the example, after the weekend stuff don’t work anymore. Here’s how we call the Javaloader from the Application.cfc:

/* JavaLoader: https://github.com/markmandel/JavaLoader */
if(NOT StructKeyExists(server,"romJavaLoader")) {
	local.paths = ArrayNew(1);
	local.libDir = ExpandPath("../../webapp/lib");
	directory action="list" directory="#local.libDir#" filter="*.jar" listinfo="name" name="local.jars";
	for(jar in local.jars) {
		ArrayAppend(local.paths,local.libDir & "#application.osFilePathSeparator#" & jar.name);
	}
	/* in the server scope because: https://github.com/markmandel/JavaLoader/wiki/Memory-Consumption */
	server.romJavaLoader = CreateObject("component","webapp.util.javaloader.JavaLoader").init(local.paths);
}

The local.paths array gives me this in return:

Array
Rows: 18 
1 string D:\path\to\webapp\lib\jar-one-versionnumber.jar
2 string D:\path\to\webapp\lib\jar-two-versionnumber.jar
3 string D:\path\to\webapp\lib\jar-three-versionnumber.jar
...
17 string D:\path\to\webapp\lib\jar-seventeen-versionnumber.jar
18 string D:\path\to\webapp\lib\jar-eightteen-versionnumber.jar

That is being loaded into the server variable. What are we doing wrong here? I get the error-message that the desired classes are not available.

Hmmm, if I skip the check in Application.cfc then the server-variable will be reloaded on each onApplicationStart. Is that bad? At least it works for now, as Lucee doesn’t seem to clear the server variables on Lucee Windows restart. Do you experience the same @Julian_Halliwell?

I think there must be something else going on that’s specific to your set up, Seb. As far as I’m aware server variables do not survive Lucee restarts - I’m not sure how they could without you manually serializing them to disk?

Personally I wouldn’t put this kind of logic in Application.cfc. I always use encapsulated wrappers, i.e. dedicated components which handle the loading/server scope checks for me and just let me call the classes/methods I need at the points in the app where I need them. Again, the Spreadsheet lib is an example of this.

I’m happy to test the specific jars you’re working with on my own setup if they can be shared privately or otherwise.

1 Like

Hi @Julian_Halliwell, you’re right, of course, I’ve refrained from restarting Lucee, because of this: [LDEV-1763] - Lucee Gives me 3-5 minutes downtime every time, so for now the variable is reset onApplicationStart. But happy to say all stuff now seems to work as on ACF. Incorporating JAR’s into Lucee webapps is fun and powerful!

Can I flag this as FIXED somewhere?

The OP (or moderators) can flag any post as the solution by expanding the menu at the foot of the post and selecting the check :slight_smile:

OK, kewl, but I do not have that option…

Edit: now I suddenly do :wink: