I have a website running fine on my mac running commandbox v5.0.1+00137 (cfengine: [email protected]+330608). I'm setting up a new MBP (M3) which installed commandbox v6.0.0+00787 (cfengine: [email protected]+330617). After starting up my dev server and launching the site, I'm getting the following error from a third party component I use called timezone.cfc.

java.lang.reflect.InaccessibleObjectException: Unable to make public sun.util.calendar.ZoneInfo(java.lang.String,int) accessible: module java.base does not "exports sun.util.calendar" to unnamed module @591fd34d

The specific parts of the code it chokes on within timezone.cfc (line 87) follows...

82: <!--- the time zone object itself --->
83: <cfset variables.tzObj = createObject("java","java.util.TimeZone")>
84: <!--- list of all available timezone ids --->
85: <cfset variables.tzList = listsort(arrayToList(variables.tzObj.getAvailableIDs()), "textnocase")>
86: <!--- default timezone on the server --->
87: <cfset variables.mytz = variables.tzObj.getDefault().ID>

Whether I dump variables.tzObj.getDefault() -OR- variables.tzObj.getDefault().ID, I get...

[undefined struct element]

When I dump variables.tzObj, I get...

enter image description here

Based on the initial error, this feels like more of a Java issue than a commandbox issue, but I'm not sure. it seems that the `sun.util.calendar.ZoneInfo(java.lang.String, int) should be public, but is not. Assuming that's the problem, how do I make that public?

Any and all thoughts welcome. I've tried various methods on the object, some work...some do not. The ones that do not (such as getID()) seem to throw this error...

Object instantiation exception. An exception occurred while instantiating a Java object. The class must not be an interface or an abstract class. If the class has a constructor that accepts an argument, you must call the constructor explicitly using the init(args) method. Error : ''

1

There are 1 best solutions below

10
Chris Geirman On

I only used the castToUTC and castFromUTC methods of the timezone.cfc library, so rather than continue to troubleshoot why it wasn't working...I wrote my own component limited to the functionality I needed. Here's that component for anyone else who may come across this issue.

component displayname="Timezone Service" hint="Provides methods to convert from/to UTC timezone" {

    public any function init() {
        this.format = "yyyy-MM-dd HH:mm:ss";
        this.LocalDateTime = createObject("java", "java.time.LocalDateTime");
        this.ZoneId = createObject("java", "java.time.ZoneId");
        this.ZonedDateTime = createObject("java", "java.time.ZonedDateTime");
        this.DateTimeFormatter = createObject("java", "java.time.format.DateTimeFormatter");

        return this;
    }
    
    /**
     * Converts given local date-time to UTC.
     * @param localDateTime
     * @param localTimezone Timezone of the local date-time.
     * @return ColdFusion DateTime Object in UTC Timezone
     */
    public date function toUTC(date localDateTime, string localTimezone) {
        var localZone = this.ZoneId.of(localTimezone); // e.g. "US/Pacific"
        var utcZone = this.ZoneId.of("UTC");
    
        // Parse localDateTime to a ZonedDateTime in the local timezone
        var zonedDateTime = this.ZonedDateTime.of(
            this.LocalDateTime.parse(
                DateTimeFormat(arguments.localDateTime, "yyyy-mm-dd'T'HH:nn:ss")
            ), 
            localZone
        );
        
        // Convert to UTC
        var utcDateTime = zonedDateTime.withZoneSameInstant(utcZone);
        
        return utcDateTime.format(
            this.DateTimeFormatter.ofPattern(this.format)
        );
    }
    
    /**
     * Converts given UTC date-time to local timezone.
     * @param utcDateTime 
     * @param localTimezone target timezone
     * @return ColdFusion DateTime Object in Local Timezone
     */
    public date function fromUTC(date utcDateTime, string localTimezone) {
        var localZone = this.ZoneId.of(localTimezone); // e.g. "US/Pacific"
        var utcZone = this.ZoneId.of("UTC");        
        
        // Parse utcDateTime to a ZonedDateTime in UTC
        var zonedDateTime = this.ZonedDateTime.of(
            this.LocalDateTime.parse(
                DateTimeFormat(arguments.utcDateTime, "yyyy-mm-dd'T'HH:nn:ss")
            ), 
            utcZone
        );
        
        // Convert to local timezone
        var localDateTime = zonedDateTime.withZoneSameInstant(localZone);

        return localDateTime.format(
            this.DateTimeFormatter.ofPattern(this.format)
        );
    }
}