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

Change to javacast or json in CF2016?

Explorer ,
May 03, 2016 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

807

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
Guide ,
May 03, 2016 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.

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 ,
May 04, 2016 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>

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
Guide ,
May 04, 2016 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.

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 ,
May 03, 2016 May 03, 2016

Copy link to clipboard

Copied

I would dump or log contactId and take a look.

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 ,
May 04, 2016 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>

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 ,
May 04, 2016 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)>?

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 ,
May 05, 2016 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>

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 ,
May 05, 2016 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.

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 ,
May 05, 2016 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) >

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 ,
May 06, 2016 May 06, 2016

Copy link to clipboard

Copied

LATEST

Nope, didn't fix it.

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