• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
1

CF2021 Issue with Java Date Object

Explorer ,
Jan 10, 2022 Jan 10, 2022

Copy link to clipboard

Copied

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) 

Views

969

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Jan 11, 2022 Jan 11, 2022

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 );
        ...
 }

Votes

Translate

Translate
Explorer ,
Jan 10, 2022 Jan 10, 2022

Copy link to clipboard

Copied

And it's specifically failing on 

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

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 10, 2022 Jan 10, 2022

Copy link to clipboard

Copied

I can't explain why CF2016 and CF2021 would behave differently if both are using Java 11, but my guess would be that by multiplying the casted long value by 1000, it's probably getting converted back to a CF integer, and when that's passed in the constructor call, there are no methods that accept an integer. Multiply by 1000 before JavaCast-ing, see if that works.

 

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

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jan 10, 2022 Jan 10, 2022

Copy link to clipboard

Copied

It's a good thought @TheRealMC - however the error is indicating that the Java Date class does not have an init() method, not that the value is incorrect. With that said, I did what you suggested and got the same error - The init method was not found.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 10, 2022 Jan 10, 2022

Copy link to clipboard

Copied

That's weird, I just tried this and the function returned the date correctly:

 

<cfscript>
	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()) );
		}

		test = convertEpochToODBCDate(1646874000);
		writeDump(test);
</cfscript>

 

I believe the error message is a little misleading. In addition to getting thrown when a method doesn't exist, I think this exception also gets thrown when the method name does exist but the correctly typed parameter(s) have not been passed.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jan 11, 2022 Jan 11, 2022

Copy link to clipboard

Copied

@TheRealMC - I'm currently on patch #3 - 2021.0.03.329779 and Java 11.0.2 - which version did you tested the code?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jan 11, 2022 Jan 11, 2022

Copy link to clipboard

Copied

@--jojo--, I tested with 2021.0.03.329779 and Java 11.0.12.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 11, 2022 Jan 11, 2022

Copy link to clipboard

Copied

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) );

	...
 }

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jul 21, 2022 Jul 21, 2022

Copy link to clipboard

Copied

LATEST

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 10, 2022 Jan 10, 2022

Copy link to clipboard

Copied

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)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jan 10, 2022 Jan 10, 2022

Copy link to clipboard

Copied

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 11, 2022 Jan 11, 2022

Copy link to clipboard

Copied

 

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 11, 2022 Jan 11, 2022

Copy link to clipboard

Copied

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 );
        ...
 }

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jan 12, 2022 Jan 12, 2022

Copy link to clipboard

Copied

This solution worked. Thanks @BKBK 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jan 10, 2022 Jan 10, 2022

Copy link to clipboard

Copied

Also, the actual error on the line is the the "init" method being non-existent or not found. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 11, 2022 Jan 11, 2022

Copy link to clipboard

Copied

quote

Also, the actual error on the line is the the "init" method being non-existent or not found. 


By @--jojo--

 

Here, "init" represents a constructor of java,util.Date.

 

Suppose, as I had said earlier, that ColdFusion is implicitly converting to Scientific Notation, 1.646874E+012. Then the error message is simply telling you that the Date constructor that can accept 1.646874E+012 as argument does not exist.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation