Highlighted

Change to javacast or json in CF2016?

Explorer ,
May 03, 2016

Copy link to clipboard

Copied

We were running CF8 and the following code worked.

<cfset attributes.email = "manual2016@2016.com">
<cfset attributes.bday = "05-04">
<cfset attributes.name = "test">
<!--- <cfparam name="attributes.email" default="#form.email#">
<cfparam name="attributes.bday" default="#form.month#-#form.year#-1900">
<cfparam name="attributes.name" default="#form.name#"> --->

<cfset attributes.sdk.addContactStruct = structNew()/>
<cfset attributes.sdk.addContactStruct["Email"] = JavaCast("string", "#attributes.email#") />
<cfset attributes.sdk.addContactStruct["Birthday"] = JavaCast("string", "#attributes.bday#") />
<cfset attributes.sdk.addContactStruct["FirstName"] = JavaCast("string", "#attributes.name#") />
<cfset variables.optinreason = JavaCast("string", "Store newsletter form") />

<cfset contactId = application.sdk.addWithDupCheck(attributes.sdk.addContactStruct, "Email", variables.optinreason) />

<cfset TagcontactId = application.sdk.addToGroup(contactId, 178)/>

We did an upgrade to CF2016 and part of this code no longer works. Specifically:

<cfset TagcontactId = application.sdk.addToGroup(contactId, 178)/>

Did something in the newer versions of CF change how we need to cast variables like this when they are being past to Java?

I've tried to get error messages with CFTRY back but only get

Diagnostics: null null
The error occurred on line -1.

Views

597

Likes

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

Change to javacast or json in CF2016?

Explorer ,
May 03, 2016

Copy link to clipboard

Copied

We were running CF8 and the following code worked.

<cfset attributes.email = "manual2016@2016.com">
<cfset attributes.bday = "05-04">
<cfset attributes.name = "test">
<!--- <cfparam name="attributes.email" default="#form.email#">
<cfparam name="attributes.bday" default="#form.month#-#form.year#-1900">
<cfparam name="attributes.name" default="#form.name#"> --->

<cfset attributes.sdk.addContactStruct = structNew()/>
<cfset attributes.sdk.addContactStruct["Email"] = JavaCast("string", "#attributes.email#") />
<cfset attributes.sdk.addContactStruct["Birthday"] = JavaCast("string", "#attributes.bday#") />
<cfset attributes.sdk.addContactStruct["FirstName"] = JavaCast("string", "#attributes.name#") />
<cfset variables.optinreason = JavaCast("string", "Store newsletter form") />

<cfset contactId = application.sdk.addWithDupCheck(attributes.sdk.addContactStruct, "Email", variables.optinreason) />

<cfset TagcontactId = application.sdk.addToGroup(contactId, 178)/>

We did an upgrade to CF2016 and part of this code no longer works. Specifically:

<cfset TagcontactId = application.sdk.addToGroup(contactId, 178)/>

Did something in the newer versions of CF change how we need to cast variables like this when they are being past to Java?

I've tried to get error messages with CFTRY back but only get

Diagnostics: null null
The error occurred on line -1.

Views

598

Likes

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
May 03, 2016 0
Most Valuable Participant ,
May 03, 2016

Copy link to clipboard

Copied

What, specifically is application.sdk.addToGroup()?  Is that a Java object method?

If so, is that Java object compatible with the JVM version that ColdFusion 2016 runs on (Java 8)?  ColdFusion 8 ran on a much older version of Java and the object may not be compatible with Java 8.

Likes

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
Reply
Loading...
May 03, 2016 0
Explorer ,
May 04, 2016

Copy link to clipboard

Copied

These are the java objects created:

<cfscript>
this.setApiKey(arguments.apiKey);
try
{
variables.url = CreateObject("java", "java.net.URL").init("https://#arguments.subdomain#.infusionsoft.com/api/xmlrpc");
variables.configImpl = CreateObject("java", "org.apache.xmlrpc.client.XmlRpcClientConfigImpl");
variables.configImpl.setServerURL(variables.url);
variables.configImpl.setConnectionTimeout(arguments.timeout * 1000);
// create the client object
variables.client = CreateObject("java", "org.apache.xmlrpc.client.XmlRpcClient");
variables.client.setConfig(variables.configImpl);
variables.client.setTransportFactory(CreateObject("java", "org.apache.xmlrpc.client.XmlRpcCommonsTransportFactory").init(variables.client));
}
catch (any e)
{
variables.javaLib = false;
variables.client = CreateObject("component", "com.liquifusion.xmlrpc.Client").init(ssl=true, host=arguments.subdomain & ".infusionsoft.com", path="/api/xmlrpc", timeout=arguments.timeout);
variables.transform = CreateObject("component", "com.liquifusion.xmlrpc.Transform").init();
}
return this;
</cfscript>

Likes

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
Reply
Loading...
May 04, 2016 0
Most Valuable Participant ,
May 04, 2016

Copy link to clipboard

Copied

Once again, is that Java object compatible with Java 8?  Just because one or more methods in the object work on Java 8 doesn't mean all of them will.  You can't see the Java dependencies that are inside the Java classes, so you don't know if they are relying on an older dependency class signature or a deprecated/removed class.  And the limited error message you are getting seems to indicate the problem is with Java, not ColdFusion.

Likes

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
Reply
Loading...
May 04, 2016 1
Adobe Community Professional ,
May 03, 2016

Copy link to clipboard

Copied

I would dump or log contactId and take a look.

Likes

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
Reply
Loading...
May 03, 2016 0
Explorer ,
May 04, 2016

Copy link to clipboard

Copied

The first part of the code still works where a call to Infusionsoft creates a contact and generates an id.

The problem is this second piece that sends back the contactID and an integer representing a category tag.

sdk.addtogroup is a function

<cfargument name="contactId" required="true" type="numeric" />

<cfargument name="groupId" required="true" type="numeric" />

<cfset var loc = StructNew() />

<cfset loc.array = ArrayNew(1) />

<cfset ArrayAppend(loc.array, JavaCast("int", arguments.contactId)) />

<cfset ArrayAppend(loc.array, JavaCast("int", arguments.groupId)) />

<cfreturn this.call("ContactService.addToGroup", loc.array) />

<cffunction name="addToGroup" output="false" access="public" returntype="boolean" hint="http://developers.infusionsoft.com/classes/contact/##addToGroup"> <cfargument name="contactId" required="true" type="numeric" /> <cfargument name="groupId" required="true" type="numeric" /> <cfset var loc = StructNew() /> <cfset loc.array = ArrayNew(1) /> <cfset ArrayAppend(loc.array, JavaCast("int", arguments.contactId)) /> <cfset ArrayAppend(loc.array, JavaCast("int", arguments.groupId)) /> <cfreturn this.call("ContactService.addToGroup", loc.array) /> </cffunction>

Likes

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
Reply
Loading...
May 04, 2016 0
Adobe Community Professional ,
May 04, 2016

Copy link to clipboard

Copied

athanasiusrc wrote:

<cfreturn this.call("ContactService.addToGroup", loc.array) />

That line raises questions:

1) What is ContactService.addToGroup?

2) If, as you say, addToGroup is a function, then what is the string "ContactService.addToGroup" doing there as argument of a function?

3) Assuming you can justify the use of "ContactService.addToGroup", then why not just <cfreturn call("ContactService.addToGroup", loc.array)>?

Likes

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
Reply
Loading...
May 04, 2016 0
Explorer ,
May 05, 2016

Copy link to clipboard

Copied

I was able to get a more useful error message.

Diagnostics: java.lang.Long cannot be cast to java.lang.String null

Here's the code sequence where the error is occurring:

This takes an integer contactid (confirmed that it gets created):

<cfset TagcontactId = application.sdk.addToGroup(contactID, 202)/>

Which calls this:

<cffunction name="addToGroup" output="false" access="public" returntype="boolean" hint="http://developers.infusionsoft.com/classes/contact/##addToGroup">
<cfargument name="contactId" required="true" type="numeric" />
<cfargument name="groupId" required="true" type="numeric" />
<cfset var loc = StructNew() />
<cfset loc.array = ArrayNew(1) />
<cfset ArrayAppend(loc.array, JavaCast("int", arguments.contactId)) />
<cfset ArrayAppend(loc.array, JavaCast("int", arguments.groupId)) />
<cfreturn this.call("ContactService.addToGroup", loc.array) />
</cffunction>

this.call breaks here:

<cfset loc.requestXml = variables.transform.cfmlToXmlRpcRequest(arguments.method, loc.parameters) />

because something goes wrong in this string of functions:

<cffunction name="cfmlToXmlRpcRequest" access="public" returntype="string" output="false" hint="I create the XML necessary to make an XML-RPC call.">
<cfargument name="method" required="true" type="string" />
<cfargument name="parameters" required="true" type="array" />
<cfset var loc = StructNew() />
<cfset loc.loopCounter = 0 />
<cfset loc.method = arguments.method />
<cfset loc.parameters = arguments.parameters />
<cfset loc.parameterXml = "<param>{value}</param>" />
<cfset loc.parameterString = "" />
<cfsavecontent variable="loc.xml">
<methodCall>
<methodName>{method}</methodName>
  <params>
{parameters}
</params>
</methodCall>
</cfsavecontent>
<cfset loc.xml = Replace(loc.xml, "{method}", loc.method) />
<cfloop index="loc.loopCounter" from="1" to="#ArrayLen(loc.parameters)#">
<cfset loc.parameterString = loc.parameterString & Replace(loc.parameterXml, "{value}", this.serialize(loc.parameters[loc.loopCounter])) />
</cfloop>
<cfset loc.xml = Replace(loc.xml, "{parameters}", loc.parameterString) />
<cfreturn loc.xml />
</cffunction>

<cffunction name="serialize" access="public" output="false">
<cfargument name="branch" required="true" type="any" />
<cfset var loc = StructNew() />
<cfset loc.results = "" />
<cfset loc.temp = "" />
<cfset loc.arrayWrapper  = "<value><array><data>{items}</data></array></value>" />
<cfset loc.structWrapper = "<value><struct>{items}</struct></value>" />
<cfset loc.structMember  = "<member>{name}{value}</member>" />
<cfset loc.structKey     = "<name>{key}</name>" />
<cfset loc.branch = arguments.branch />
<cfset loc.loopCounter = 0 />
<cfif IsStruct(loc.branch)>
<cfloop item="loc.loopCounter" collection="#loc.branch#">
<cfset loc.temp = Replace(loc.structKey, "{key}", loc.loopCounter) />
<cfset loc.temp = Replace(loc.structMember, "{name}", loc.temp) />
<cfset loc.results = loc.results & Replace(loc.temp, "{value}", this.serialize(loc.branch[loc.loopCounter])) />
</cfloop>
<cfset loc.results = Replace(loc.structWrapper, "{items}", loc.results) />
<cfelseif IsBinary(loc.branch)>
<cfset loc.results = variables.toXml(ToBase64(loc.branch), "base64") />
<cfelseif IsArray(loc.branch)>
<cfloop index="loc.loopCounter" from="1" to="#ArrayLen(loc.branch)#">
<cfset loc.results = loc.results & this.serialize(loc.branch[loc.loopCounter]) />
</cfloop>
<cfset loc.results = Replace(loc.arrayWrapper, "{items}", loc.results) />
<cfelseif IsDate(loc.branch)>
<cfset loc.results = variables.toXml(variables.formatDateTime(loc.branch), "dateTime.iso8601") />
<cfelseif loc.branch.getClass().isInstance(variables.instance.integer)>
<!---
Note: in order to be CF7 compatible, we cannot use IsInstanceOf()
<cfelseif IsInstanceOf(loc.branch, "java.lang.Integer")>
--->
<cfset loc.results = variables.toXml(Int(loc.branch), "int") />
<cfelseif loc.branch.getClass().isInstance(variables.instance.double)>
<!---
Note: in order to be CF7 compatible, we cannot use IsInstanceOf()
<cfelseif IsInstanceOf(loc.branch, "java.lang.Double")>
--->
<cfset loc.results = variables.toXml(loc.branch, "double") />
<cfelseif loc.branch.getClass().isInstance(variables.instance.boolean)>
<!---
Note: in order to be CF7 compatible, we cannot use IsInstanceOf()
<cfelseif IsInstanceOf(loc.branch, "java.lang.Boolean")>
--->
<cfset loc.results = variables.toXml(Int(loc.branch), "boolean") />

<cfelseif loc.branch.getClass().isInstance(variables.instance.string)>
<!---
Note: in order to be CF7 compatible, we cannot use IsInstanceOf()
<cfelseif IsInstanceOf(loc.branch, "java.lang.String")>
--->
<cfset loc.results = variables.toXml(XmlFormat(loc.branch), "string") />
</cfif>

<cfreturn loc.results />
</cffunction>

Ending with this function:

<cffunction name="toXml" output="false" access="private" returntype="string">
<cfargument name="value" required="true" type="any" />
<cfargument name="tagName" required="true" type="string" />
<cfset var loc = StructNew() />
<cfset loc.simpleTag = "<value><{tagName}>{value}</{tagName}></value>" />
<cfset loc.results = "" />
<cfset loc.results = Replace(loc.simpleTag, "{tagName}", arguments.tagName, "all") />
<cfset loc.results = Replace(loc.results  , "{value}"  , arguments.value) />
<cfreturn loc.results />
</cffunction>

Likes

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
Reply
Loading...
May 05, 2016 0
Explorer ,
May 05, 2016

Copy link to clipboard

Copied

I've found the developer and he is going to take a look at this. Thank you for the assist.

Likes

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
Reply
Loading...
May 05, 2016 0
Adobe Community Professional ,
May 05, 2016

Copy link to clipboard

Copied

<cfset ArrayAppend(loc.array, JavaCast("int", arguments.contactId)) />

<cfset ArrayAppend(loc.array, JavaCast("int", arguments.groupId)) />

ContactId and GroupId are integers so I would just do this instead:

<cfset ArrayAppend(loc.array, arguments.contactId) >

<cfset ArrayAppend(loc.array, arguments.groupId) >

Likes

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
Reply
Loading...
May 05, 2016 0
Explorer ,
May 06, 2016

Copy link to clipboard

Copied

Nope, didn't fix it.

Likes

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
Reply
Loading...
May 06, 2016 0