steveduke
09/26/2022, 7:37 PMnew DatabaseReader.Builder(file).withCache(new CHMCache()).build();
Builder
is an inner class of DatabaseReader
.
I’m able to init() Builder (and subsequently the database reader API) using the $
notation as defined in the Lucee docs. However I am unable to call the Builder withCache()
method.
The API docs for build()
and withCache()
are here.
This is the code I’m running; 1st what works, and then 2nd my failing attempt at including the cache object.
1st:
This works, it creates a database using a maxmind DB file, and the database reader API:
<cfscript>
ip = '209.85.231.104';
// build the database file object
dbfile = "/pathto/geoip/lib/GeoLite2-Country.mmdb";
db = createObject("java","java.io.File").init(expandpath(dbfile));
// initiate the database reader object
reader = createObject("java", "com.maxmind.geoip2.DatabaseReader$Builder",expandpath('/pathto/geoip/lib/geoip2-3.0.1.jar')).init(db).build();
// create ipaddr class
iaddrClass=CreateObject("java", "java.net.InetAddress");
// test
address=iaddrClass.getByName(ip);
writedump(reader.country(address).getCountry().getName());
writedump(reader.country(address).getCountry().getIsoCode());
</cfscript>
2nd:
This doesn't work, I create the cache object and attempt to call it on the builder object with .withCache(maxMind_CHMCaching)
and returns the following error:
No matching Method/Function for com.maxmind.geoip2.DatabaseReader$Builder.withCache(com.maxmind.db.CHMCache) found
<cfscript>
ip = '209.85.231.104';
// build the database object
dbfile = "/pathto/geoip/lib/GeoLite2-Country.mmdb";
db = createObject("java","java.io.File").init(expandpath(dbfile));
// initiate a maxmind caching object
maxMind_CHMCaching = createObject("java", "com.maxmind.db.CHMCache",expandpath('/pathto/geoip/lib/maxmind-db-2.0.0.jar')).init();
// initiate the database reader object using cache
reader = createObject("java", "com.maxmind.geoip2.DatabaseReader$Builder",expandpath('/pathto/geoip/lib/geoip2-3.0.1.jar')).init(db).withCache(maxMind_CHMCaching).build();
// create ipaddr class
iaddrClass=CreateObject("java", "java.net.InetAddress");
// test
address=iaddrClass.getByName(ip);
writedump(reader.country(address).getCountry().getName());
writedump(reader.country(address).getCountry().getIsoCode());
</cfscript>
If anyone has an idea of what I should try next I would appreciate the feedback.bdw429s
09/26/2022, 9:54 PMthis.javaSettings
and see if that worksbdw429s
09/26/2022, 9:55 PMmaxMind_CHMCaching
object is created from another create object call which is going to have use another class loader. I know part of the check Lucee's reflection does when calling a method is that the object must not only be of the correct type, but also from the same classloader which is likely related.
See the comment thread on this ticket:
https://luceeserver.atlassian.net/browse/LDEV-2296?focusedCommentId=45849bdw429s
09/26/2022, 9:55 PMcreateObject("java", "com.maxmind.geoip2.DatabaseReader$Builder",expandpath('/pathto/geoip/lib/geoip2-3.0.1.jar')).init(db)
and make sure it has a withCache()
methodsteveduke
09/26/2022, 11:22 PMthis.javaSettings
. I changed it to specify each jar file and still no luck. I also modified the createObject to include an array of all the jar files too, and still this fails.
Your thoughts on how createObject loads the class may have some bearing on whats happening.
I dumped out the Builder, and it does have the withCache() method:bdw429s
09/26/2022, 11:24 PMI already had the geoip jar directory path inHold on-- you have the jar files in the. I changed it to specify each jar file and still no luck. I also modified the createObject to include an array of all the jar files too, and still this fails.this.javaSettings
this.javaSettings
AND in the arguments to createObject? That in itself seems problematic. What happens if you use this.javaSettings and don't pass anything to createObject at all?steveduke
09/26/2022, 11:35 PM"com.maxmind.geoip2.DatabaseReader$Builder",expandpath('/pathto/geoip/lib/geoip2-3.0.1.jar')).init(db).withCache(maxMind_CHMCaching).build();
to this:
reader = createObject("java", "com.maxmind.geoip2.DatabaseReader$Builder" ).init(db).withCache(maxMind_CHMCaching).build();
And it works!steveduke
09/26/2022, 11:36 PMbdw429s
09/26/2022, 11:37 PMbdw429s
09/26/2022, 11:37 PMsteveduke
09/26/2022, 11:37 PMsteveduke
09/26/2022, 11:39 PMbdw429s
09/26/2022, 11:40 PMbdw429s
09/26/2022, 11:40 PMbdw429s
09/26/2022, 11:41 PMbdw429s
09/26/2022, 11:41 PMbdw429s
09/26/2022, 11:41 PMbdw429s
09/26/2022, 11:41 PMbdw429s
09/26/2022, 11:42 PMthis.javaSettings
in your Application.cfc
will load those jars into yet another class loader in the appsteveduke
09/26/2022, 11:46 PMthis.javaSettings
in my Application.cfc
but removing the jar list from createObject means Lucee uses the same class loader. Hence, the withCache() method is found.steveduke
09/26/2022, 11:46 PMbdw429s
09/26/2022, 11:57 PM