Skip to main content
Inspiring
January 10, 2022
Answered

CF2021 Issue with Java Date Object

  • January 10, 2022
  • 15 replies
  • 2508 views

Here's another issue I'm running into with our new CF2021 instance. This function worked fine with CF2016 using Java 11

 

    public date function convertEpochToODBCDate( required numeric ts ){
	var objTZ = createObject( "java", "java.util.TimeZone" );
	var objDF = createObject( "java", "java.text.SimpleDateFormat" );
	var objDate = createObject( "java", "java.util.Date" );
        var dte = objDate.init( JavaCast("long",arguments.ts) * 1000 );
	var tz = objTZ.getTimeZone( JavaCast("string", 'UTC') );
	var outputFormat = objDF.init( javaCast( "string", "yyyy-MM-dd HH:mm:ss" ) );
	    outputFormat.setTimeZone(tz);
        return CreateODBCDateTime( outputFormat.format(dte.getTime()) );
    }

 

 

Here's the stack trace:

DetailEither there are no methods with the specified method name and argument types or the init method is overloaded with argument types that ColdFusion cannot decipher reliably. ColdFusion found 2 methods that match the provided arguments. If this is a Java object and you verified that the method exists, use the javacast function to reduce ambiguity.
MessageThe init method was not found.
MethodNameinit
StackTracecoldfusion.runtime.java.MethodSelectionException: The init method was not found. at coldfusion.runtime.java.ObjectHandler.findConstructorUsingCFMLRules(ObjectHandler.java:496) at coldfusion.runtime.java.JavaProxy.CreateObject(JavaProxy.java:222) at coldfusion.runtime.java.JavaProxy.invoke(JavaProxy.java:89) at coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:4254) at coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:4217) 
    This topic is closed to new replies. Start a new post to keep the conversation going.
    Correct answer BKBK
     

    You can pass any epoch value (e.g. 1646874000) - ...


    By @--jojo--

     

    But beware. ColdFusion is weakly typed. Under the bonnet, it may make a funky conversion like 1.646874E+012 for 1646874000 * 1000.


    Yet another solution:

     public date function convertEpochToODBCDate( required numeric ts ){
     	...
            // Use BigDecimal to prevent ColdFusion from automatically  
            // converting 1646874000000 to 1.646874E+012
    	 var numberAsLong=createobject("java","java.math.BigDecimal").init(arguments.ts*1000).longValue();
    	var dte = objDate.init( numberAsLong );
            ...
     }

    15 replies

    Charlie Arehart
    Community Expert
    Community Expert
    January 10, 2022

    Please output and tell us the value of your arguments.ts value. The root cause of the error is likely in what's being passed in, rather the init itself. Indeed, you could also try to output or just refer to the JavaCast("long",arguments.ts), alone, to see if THAT is the actual error on that line.

     

    Someone might guess this could have something with the change in how cf 2021 handles date formats with D (vs d), but you don't show doing that in this code. And you're passing in a NUMBER in that ts argument, not a date.

     

    Let us know what you find. 

    /Charlie (troubleshooter, carehart. org)
    --jojo--Author
    Inspiring
    January 10, 2022

    You can pass any epoch value (e.g. 1646874000) - unfortunately cffidle won't let you instantiate java objects. 

    BKBK
    Community Expert
    Community Expert
    January 11, 2022
     

    You can pass any epoch value (e.g. 1646874000) - ...


    By @--jojo--

     

    But beware. ColdFusion is weakly typed. Under the bonnet, it may make a funky conversion like 1.646874E+012 for 1646874000 * 1000.

    --jojo--Author
    Inspiring
    January 10, 2022

    And it's specifically failing on 

    objDate.init( JavaCast("long",arguments.ts) * 1000 );

     

    BKBK
    Community Expert
    Community Expert
    January 11, 2022

    And it's specifically failing on 

    objDate.init( JavaCast("long",arguments.ts) * 1000 );

     


    By @--jojo--

     

    I think that ColdFusion is justified in throwing an error on that line. According to the API for java.util.Date, the constructor's argument should be of type long.

     

    Whereas, there is no guarantee that JavaCast("long",arguments.ts) * 1000 is of long type. To make sure it is, you could correct the code to:

     

     public date function convertEpochToODBCDate( required numeric ts ){
     	var dateAsNumber=arguments.ts*1000;
    	 ...
    	
        var dte = objDate.init( JavaCast("long",dateAsNumber) );
    
    	...
     }

     

     

    James Moberg
    Inspiring
    July 21, 2022

    TLDR: Always explicitely case the entire value.

    I recently tweeted about this... casting to a specific data type and then performing any math will cause that variable to lose the explicit type.  I've found that IncrementValue() will retain INT type, but only increment a value by 1 and return an INT (identified in the docs), but haven't found any other way to retain value other than consistently and explicitly re-casting after performing math. 

    By comparison during cross-compatible CFML research, I've noticed that any numeric value in Lucee becomes a DOUBLE if you add 1 to it.  When using IncrementValue, Lucee can properly increment a decimal (DOUBLE) value and correctly increments by 1.