I am working on a ColdFusion app to send Push Notifications via Apple's APNS service. I am using the notnoop apns java library. I have successfully sent push notifications using this, but, recently have run into some issues. I want to use the ApnsDelegate Interface that is provided in order to help debug the issue, but, I do not know how to implement a Java interface in ColdFusion. I am not a Java programmer. Please help.
Update: So far, I've actually written a Java class to implement the interface, but, I cannot figure out how to "bubble" the events to ColdFusion. I've tried logging within the java methods (using log4j), but that's not working either.
I really just need a way to capture when these java methods are called, and to log some info from the arguments being passed.
(Expanded from comments)
For CF8, it can be done with the JavaLoader's CFCDynamicProxy. It is a fantastic feature Mark Mandel added a while back. Essentially it lets you use a CFC, as if it were a concrete java class. Note, it only applies to interfaces. (CF10+ contains a rip of the JavaLoader, so the proxy feature is baked in. See Creating a Dynamic Proxy example.).
To use the dynamic proxy, just create a CFC that implements all of the methods defined in the interface. It is important that the function signatures match the methods in the interface (types, access, etcetera). Looking over the API, something like this should work.
<cfcomponent>
<!--- Note: If the argument is a java class, use type="any" --->
<cffunction name="connectionClosed" returntype="void" access="package">
<cfargument name="DeliveryError" type="any" required="true" />
<cfargument name="MessageIdentifier" type="numeric" required="true" />
<!--- do stuff here --->
</cffunction>
<cffunction name="messageSendFailed" returntype="void" access="package"
hint="Called when the delivery of the message failed for any reason">
<cfargument name="message" type="any" required="true" />
<cfargument name="failedError" type="any" required="true" />
<!--- do stuff here --->
</cffunction>
<cffunction name="messageSent" returntype="void" access="package"
hint="Called when message was successfully sent to the Apple servers">
<cfargument name="message" type="any" required="true" />
<!--- do stuff here --->
</cffunction>
</cfcomponent>
Then use the dynamic proxy to create an instance of it. You can then use the instance anywhere that expects an ApnsDelegate
object, just as if it were a concrete class you wrote in java.
<cfscript>
// add the paths of required jars into an array
paths = [ expandPath("/path/to/cfcdynamicproxy.jar")
, expandPath("/path/to/the_apns.jar")
];
// MUST load the CF class path in order to use the proxy
loader = createObject("component", "javaLoader.JavaLoader").init(
loadPaths=paths
, loadColdFusionClassPath=true
);
// store "names" of all interfaces the proxy implements
interfaces = [ "com.notnoop.apns.ApnsDelegate" ];
// grab reference to proxy class
proxy = loader.create("com.compoundtheory.coldfusion.cfc.CFCDynamicProxy");
// finally create the delegate
delegate = proxy.createInstance( "c:/path/to/YourComponent.cfc"
, interfaces );
// debugging
writeDump( delegate );
// .. now pass the delegate into some other java method
</cfscript>