Solved

Coldfusion cfobject general coding

Posted on 2014-07-28
4
369 Views
Last Modified: 2014-07-31
I guess I just don't understand object oriented coding using cfobject type=java.  Specifically I am using the Exchange EWS managed API.  I'm stuck on updating the appointment item.  I seem to be binding to the item as I can display the start time, the end time, and the subject.  But when I do appointment.update I get one of several errors depending on the params I pass.

appointment.Update();   "The Update method was not found"

appointment.Update(ConflictResolutionMode, SendInvitationsOrCancellationsMode);   "Variable CONFLICTRESOLUTIONMODE is undefined."

appointment.Update('ConflictResolutionMode', 'SendInvitationsOrCancellationsMode');   "The Update method was not found"

<cfobject type="Java" class="microsoft.exchange.webservices.data.ExchangeService" name="service">
		<cfset service.init()>
		<cfobject type="Java" class="microsoft.exchange.webservices.data.ExchangeVersion" name="version">
		<cfset service.init(version.Exchange2010)>
		<cfobject type="Java" class="microsoft.exchange.webservices.data.WebCredentials" name="credentials">
		<cfset Arguments.Pword = Trim(FetchExchangePassword(Arguments.EmailAddress)) />
			<cfset credentials.init("#Arguments.EmailAddress#","#Arguments.Pword#")>
			<cfset service.setCredentials(credentials) />
			<cfobject type="Java" class="java.net.URI" name="uri">
			<cfset uri.init("exchabc.serverdata.net/EWS/Exchange.asmx?wsdl")>
			<cfset service.setUrl(uri) />
			<cfobject type="Java" class="microsoft.exchange.webservices.data.Appointment" name="appointment">
			<cfobject type="Java" class="microsoft.exchange.webservices.data.AppointmentSchema" name="appointmentschema">
			<cfset appointment.init( service )>
			<cfobject type="Java" class="microsoft.exchange.webservices.data.PropertySet" name="propertyset">
			<cfset propertyset.init()>
			<cfobject type="Java" class="microsoft.exchange.webservices.data.ItemId" name="thisitemid">
			<cfset thisitemid.init("#arguments.ExchangeID#")>
			<cfobject type="Java" class="microsoft.exchange.webservices.data.MessageBody" name="MessageBody">
			<cfset appointment = appointment.Bind(service, thisitemid) />
			<cfscript>
					appointment.setStart(#StartDate#);
					appointment.setEnd(#EndDate#);
					appointment.setSubject("#Arguments.EventName#");
					appointment.setBody(MessageBody.getMessageBodyFromText("#Arguments.EventDescription#"));
					appointment.Update('ConflictResolutionMode', 'SendInvitationsOrCancellationsMode');
			</cfscript>

Open in new window


In the appointment class there is the method;
update(microsoft.exchange.webservices.data.ConflictResolutionMode, microsoft.exchange.webservices.data.SendInvitationsOrCancellationsMode)
0
Comment
Question by:lanterv
  • 2
  • 2
4 Comments
 
LVL 52

Accepted Solution

by:
_agx_ earned 500 total points
Comment Utility
(I don't have access to an Exchange2010 server, so unfortunately can't test your code ...)

A few observations that might help ... Rather than mixing cfml and cfscript, it's better to pick a single style. Preferably cfscript since it's more familiar to the java experts (who are more likely to be familiar with EWS than CF-ers). I attempted to convert your code to CFSCRIPT.  Run the example below.  Assuming there are no typos, you get the same error you're getting now ... and we can go from there.


The thing to keep in mind about using java or .net classes is that they're not native code. So don't expect CF to provide detailed error messages.  It won't.  CF won't tell you if you passed a method a "thing-a-ma-bob" when it was really expecting a "what-ya-callit" object instead. Nor will it tell you if you passed in 2 "thing-a-ma-bob"'s when the method was expecting 3 of them. CF will only return one of a few generic messages like "can't find method...". As you get familiar with using java objects you get to know what those error message mean and now how to fix it.  The good news is that about 95% of the time the cause is one of a few common mistakes:

- The method name is misspelled
- You're called a method with the wrong number or type of arguments
- You forgot to create or initialize the right java object

You have to use the API to understand what the method is expecting. It also helps to just create an instance of the class. Dump it and look for the method you need. Compare it to what the API tells you. Take your appointment class.

     // this is just for testing.  create the class
    appointment = createObject("java", "microsoft.exchange.webservices.data.Appointment");
    // then dump it. look for the update(...) method
    writeDump( appointment );

Open in new window


Dumping it should show a single update(..) method that looks like this.

     
update(  
       microsoft.exchange.webservices.data.ConflictResolutionMode
      , microsoft.exchange.webservices.data.SendInvitationsOrCancellationsMode
     ) 

Open in new window


That's the method "signature". Or in other words, the name of the method and what "type" of parameters it expects, and how many. Just like when you dump a cffunction.  

appointment.Update();   "The Update method was not found"

You can see in the earlier dump that method expects 2 parameters. You passed in 0. That's why you get an error. CF couldn't find a method named "update" with 0 parameters. (If you read over the error message details, it mentions this as a possible cause).

appointment.Update( ConflictResolutionMode,  SendInvitationsOrCancellationsMode );   "Variable CONFLICTRESOLUTIONMODE is undefined."

That's strictly a CF error. You didn't create variables named "ConflictResolutionMode" or "SendInvitationsOrCancellationsMode". Hence the undefined error. The same thing would happen if you to use any variable that didn't exist ie <cfdump var="#ThisVariableNameDoesntExist#">

appointment.Update( 'ConflictResolutionMode',  'SendInvitationsOrCancellationsMode' );  


There you're passing in the correct number of parameters, but ... they're the wrong type.  Look at the method signature again.  The parameter names

             * microsoft.exchange.webservices.data.ConflictResolutionMode
             * microsoft.exchange.webservices.data.SendInvitationsOrCancellationsMode

... tell you the TYPE of object you need to pass in. (Those are EWS java classes). That means you can't just pass in the words "ConflictResolutionMode". You need to actually create instances of those classes. Same as you did for the service and all the other ones ...

Look up the EWS class ConflictResolutionMode API. Figure out how to create an instance of it. Lather, rinse, repeat for the SendInvitationsOrCancellationsMode class. Once you've created the two objects - only then can you call the update(...) method.

Make sense?

CFSCRIPT

<cfscript>
	// declare all your arguments in one place
	Arguments.ExchangeID = "something...";
	Arguments.EmailAddress = "something...";
	Arguments.EventName = "something...";
	Arguments.EventDescription = "something...";
	Arguments.Pword = Trim(FetchExchangePassword(Arguments.EmailAddress));
	StartDate = "something...";
	EndDate = "something...";
	

	uri = createObject("java", "java.net.URI").init("exchabc.serverdata.net/EWS/Exchange.asmx?wsdl");
	version = createObject("java", "microsoft.exchange.webservices.data.ExchangeVersion");
	credentials = createObject("java", "microsoft.exchange.webservices.data.WebCredentials").init( Arguments.EmailAddress , Arguments.Pword );

	// initialize service
	service = createObject("java", "microsoft.exchange.webservices.data.ExchangeService").init(version.Exchange2010);
	//service.setCredentials( credentials );
	service.setUrl( uri );


    // create appointment properties
	appointment = createObject("java", "microsoft.exchange.webservices.data.Appointment").init( service );
	writeDump(appointment);
	appointmentschema = createObject("java", "microsoft.exchange.webservices.data.AppointmentSchema");
	propertyset = createObject("java", "microsoft.exchange.webservices.data.PropertySet").init();

    // initialize all in one line
	thisitemid = createObject("java", "microsoft.exchange.webservices.data.ItemId").init( arguments.ExchangeID);
	MessageBody = createObject("java", "microsoft.exchange.webservices.data.MessageBody");
	appointment = appointment.Bind(service, thisitemid);
	appointment.setStart( StartDate );
	appointment.setEnd( EndDate );
	appointment.setSubject( Arguments.EventName );
	appointment.setBody( MessageBody.getMessageBodyFromText( Arguments.EventDescription ));
	appointment.Update('ConflictResolutionMode', 'SendInvitationsOrCancellationsMode');
</cfscript>

Open in new window

0
 

Author Comment

by:lanterv
Comment Utility
That explains a lot.  It helped me decipher the Microsoft documentation.  They could have done a much better job or posted a certification level required to read the documentation. :)  Many thanks.
0
 

Author Closing Comment

by:lanterv
Comment Utility
Thank you.
0
 
LVL 52

Expert Comment

by:_agx_
Comment Utility
Yeah, there's a bit of learning curve. You need to know more than just cfml before you can use java/.net objects from CF. You have to know something about the API you're using as well.

> They could have done a much better job

Well on the one hand, it makes sense that they don't write detailed documentation or error handling for every 3rd party app or API you can use from within CF, because it's not their product.  Documentation is the job of whoever wrote the lib (MS, Apache, etc...). That said, I agree they could do a better job of documenting what you should and shouldn't expect to see when working with java/.net object in general. How to interpret the cfdump of an object, common error messages, etc... I stumbled through it and learned most of it through lots of cfdumps and trial and error ;-)  On the plus side, it's a one time event. Once you figure out the rules for one lib it's the same for all of them.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Hi, I will be creating today a basic tutorial on how we can create a Mail Custom Function and use it where ever we want. The main advantage about creating a custom function is that we can accommodate a range of arguments to pass to the Function and …
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Viewers learn about the third conditional statement “else if” and use it in an example program. Then additional information about conditional statements is provided, covering the topic thoroughly. Viewers learn about the third conditional statement …
Video by: Michael
Viewers learn about how to reduce the potential repetitiveness of coding in main by developing methods to perform specific tasks for their program. Additionally, objects are introduced for the purpose of learning how to call methods in Java. Define …

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now