Archive for category xcelsius
Xcelsius Custom Component Logger
If you’ve ever had the pleasure (cough) of developing custom Xcelsius (XC) components then you know it’s synonymous with the arcane days of the early 2000s and developing Flash applications — no real debugging tools to speak of and traditional enterprise devs that were trying to get into the Flash game were left playing with a black box at runtime — it was incredibly painful and we were left up to our own innovative devices when it came time to perform runtime debugging.
So now I find myself coming back full circle to these “techniques” when trying to debug Xcelsius custom components, as there’s no real way to actually debug these suckers once you’re out of FlexBuilder and running them in the Xcelsius IDE, and for some reason SAP doesn’t feel the need to help developers be successful when dev’n custom components and provide tools like this, not to mention that the docs are…uhmmm…lacking at best???…but I digress…so without further delay, here’s one of my debugging tools called the Xcelsius Custom Component Logger, which is basically a revamp of the same logger I created to debug Flash apps at runtime waaaaay back…think Flash 5 or 6 when the LocalConnection was introduced into AS…anyone else remember these days?
The LocalConnection (LC) logger consists of 2 parts:
- A SWF with a LC that receives messages — ie, logs statements — and displays them in a simple TextArea.
- A Logging Framework that provided basic logging methods you’d expect (debug, info, warn, error, and fatal) with a LC sender that pushed these messages to the receiving SWF
Since the logger leverages the basic Flex logging framework, it should seem pretty familiar — here’s how to get started:
- Import the XCLoggerLibrary.swc into your XC Custom Component project.
- Add a private static reference of your logger (example below).
- Create some log statements in your app…maybe some in your custom property sheet and some in the custom connector/uicomponent that you’re creating.
- Fire up the XcelsiusLogger.swf
- Open up XC with the Logger still open and you should start to see log statements (assuming you put log stmts in your XC Custom Component) when working in custom component property sheets (since they are just Flex apps); you’ll also see the log statements when previewing your XC app.
Quick Example
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="this.init()">
<mx:Script>
<![CDATA[
import com.webappsolution.xcelsius.logging.LocalConnectionLog;
import mx.utils.ObjectUtil;
import mx.logging.ILogger;
// NOTE: Must have this line in to create an instance of the logger -- pass it the
// name of the class it's debugging.
private static var logger:ILogger = LocalConnectionLog.getLogger(XCLoggerTEST);
private static const TEST_VALUE:int = 101;
private function init():void
{
// all log levels
logger.debug("init");
logger.info("init");
logger.warn("init");
logger.error("init");
logger.fatal("init");
// testing sptting out a quick var
logger.debug("init: TEST_VALUE = " + TEST_VALUE);
// sometimes I spit out the entire contents of an object to see what's in it
// ...especially when working with the XC API
var person:Object = {firstName:"Brian", lastName:"Riley", age:31, colors:["red", "blue"]};
logger.debug("init: person = " + ObjectUtil.toString(person));
}
private function onSubmitClick(e:MouseEvent):void
{
var firstAndLastName:String = this.firstNameTextInput.text + " " + this.lastNameTextInput.text;
logger.debug("onSubmitClick: firstAndLastName = " + firstAndLastName);
this.firstAndLastNameLabel.text = firstAndLastName;
}
]]>
</mx:Script>
<mx:Form width="100%" defaultButton="{this.submitBtn}">
<mx:FormItem width="100%" label="First Name" required="true">
<mx:TextInput id="firstNameTextInput" />
</mx:FormItem>
<mx:FormItem width="100%" label="Last Name" required="true">
<mx:TextInput id="lastNameTextInput" />
</mx:FormItem>
<mx:Button id="submitBtn" label="Submit" click="onSubmitClick(event)" />
</mx:Form>
<mx:Label id="firstAndLastNameLabel" />
</mx:Application>
I find this tool really helpful when debugging the Custom PropertySheets for XC Components, as you can easily write test harnesses for the actual custom connection and custom UI components and debug in FlexBuilder.
Finally, it’s nothing fancy, but it at least allows you to see what’s going on once you’re in the Xcelsius IDE — I probably could have used one of the LC loggers on OS Flash like LuminicBox.Log, but I decided to just roll my own since I had it lying around on an old hard drive
Oh, and I could’ve made this an AIR app, but leaving it as SWF suits my needs just fine.
Assets
- XCLoggerLibrary.swc
- XcelsiusLogger.swf
- Example Flex App With XCLogger
Any questions?
NOTE: Since this uses LC under the covers you can’t have multiple instances of this running at once, as I’m using the same ID.
Where Can I Find fds.swc?
If you ever need to compile a Flex app that requires classes like:
mx.messaging.channels.RTMPChannel mx.messaging.channels.SecureRTMPChannel
then you’ll need fds.swc which isn’t shipped with the Flex SDK, but is shipped with LCDS. Download a trial vr of LCDS and grab this file from the web-app:
WEB-INF/flex/libs/fds.swc
…why might you need these classes?…perhaps if you’re building a Bootstrap loader for LCDS apps loading sub-apps and you want to share the messaging classes between the parent and child apps…I had to do this for an Xcelsius application.
Content-Disposition Header May Prevent SWF Files From Playing
A Little Background Information for Context
I’m working with Xcelsius (”XC”) and Flex and I had to create a custom SWFLoader component to fix some issues with the out of the box (”OOTB”) SlideShow (”SS”) component in XC…without getting into too much detail, developers are currently using the SS component to load child SWFs into their parent SWFs (main XC Flex application) in order to make the application smaller; however, there’s a bug in the SS component that kills any previous and new LCDS connections created in either the parent or child SWFs — this is bad — so again, I decided to create my own SWFLoader component using the native, AS3 SWFloader class.
So I rolled my own custom SWFLoader component and voila, the LCDS connections and my loader worked as expected in my small PoC. I then ported my work over to our real application, and blam…no loading…nothing…nada…crap.
Naturally I had to locate the differences in my small PoC app and our real app and the one thing that struck me was that the real app was using an OOTB servlet by Business Objects to serve up the SWFs, whereas mine was just loading them by direct URLs. I then proceeded to create my seemingly simple test servlet to do the same. Here’s a simplified version of my Servlet without all the try/catches/error handling in order to be concise and just give you the idea:
SendSWF.java
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
ServletContext servletContext = getServletContext();
String fileName = (String) request.getParameter("file");
String mimetype = "application/x-shockwave-flash";
InputStream inputStream =
servletContext.getResourceAsStream("/XcelsiusFlex/" + fileName);
// set response headers
response.setContentType(mimetype);
response.addHeader("Content-Type", mimetype);
// KILLER - You bruised my head...
//response.addHeader("Content-Disposition",
"attachment; filename=" + (String) request.getParameter("file"));
int read = 0;
byte[] bytes = new byte[1024];
OutputStream outputStream = response.getOutputStream();
while((read = inputStream.read(bytes)) != -1)
{
outputStream.write(bytes, 0, read);
}
outputStream.flush();
outputStream.close();
inputStream.close();
}
Solution
Simple enough, right? Send the binary SWF back to my Flex client and make sure it has the proper header mimetype of:
application/x-shockwave-flash
But it didn’t work…I spent some time banging my head against my MacBook Pro and my partners until one them shot me this link. As you can see in my comments in the code, the line that killed me was adding the “Content-Type” of “attachment” to my header:
Content-Disposition: attachment
Apparently this is a new security feature of FP 10 that keeps a SWF file from playing. I simply commented it out and I was good to go.
Speacial Thanks…
To my buddy Greg DeMelo for pointing me to this link.
Xcelsius 2008 SP1 SDK Not Compatible with Flex 3.x SDK
Apparently you can’t use the Flex 3.x SDK to create custom components with the Xcelsius 2008 SP1 SDK — you must use the Flex 2.01 SDK. Maybe I just overlooked it, but I didn’t see anything in the Xcelsius SDK’s docs/tutorials that you said you must use the Flex 2.01 SDK, so I’ve been banging my head against my new desk wondering why my custom componets wouldn’t work…oh, and as a side note, the only way you know your custom components bomb is that they blow up Xcelsius, meaning most commonplace functions like File -> Open are disabled…no error messages, no warnings, nada…good stuff.
Since I didn’t see this info in the docs, I started googling issues and I ran across this blog post — Top 10 Xcelsius 2008 SDK FAQs — thanks for tip.