I can now start using Safari, ClickToFlash FTW

October 6th, 2009

For a long time my "browser of choice" was Firefox because of fantastic Flashblock add-in. Today I found out that there is similar add-in for Safari called ClickToFlash. Here is a nice article describing what it can do and here is the link to a github project. Pefect!

ColdFusion compiler is broken

September 22nd, 2009

Following on a tweet from Sean Corfield, I couldn’t believe it is possible to create a function called if, else, while and so on as well as declare variable called var. Here is the code that may hurt your head:

[sourcecode lang="cf"]
<cffunction name="if">
	<cfargument name="val1" />
	<cfargument name="val2" />
	<cfif val1 eq val2>
		<cfreturn true />
	</cfif>
	<cfreturn false />
</cffunction>
<cffunction name="hello">
	<cfset var var = 2 />
	<cfreturn var />
</cffunction>
<cfif if( hello(), 2 )>
	LOL
</cfif>
[/sourcecode]

How cool is that ;)

Greasemonkey script to remove unwanted results from Google

September 15th, 2009

For myself, for future reference:

[sourcecode lang="js"]
// ==UserScript==
// @name           Expert blocker
// @namespace      my
// @description    Eliminate Experts Exchange results from Google searches.
// @include        http://*.google.com/search?*
// @include        http://*.google.co.uk/search?*
// ==/UserScript==

var results = document.getElementsByTagName("a");
for ( var i=0; i<results.length; i++ ) {
	if (
		results[i].href.indexOf("http:/ /www.experts-exchange.com") == 0
		|| results[i].href.indexOf("http:/ /swik.net") == 0 ) {
		results[i].parentNode.parentNode.style.display = "none";
	}
}
[/sourcecode]

Before using, in the URLs replace http:/ / with http://.

ColdFusion to Flex serializer needs better error messages

September 2nd, 2009

I’m using Flex with ColdFusion for a long time now but sometimes I really can’t stand these two products together. I’m sending nested CFCs through the remote object back to Flex so ColdFusion has to serialize them to the form that may be understood by Flex. But I’ve got an error, somewhere I have an empty string where number is expected. You would expect that CF is smart enough to tell you what the problem is? Nope, it says:

Unable to invoke CFC - The value '' cannot be converted to a number.

And here is the stack trace:

[sourcecode lang="cf"]
        [0] "coldfusion.runtime.Cast._double(Cast.java:652)"
        [1] "coldfusion.runtime.Cast._double(Cast.java:632)"
        [2] "coldfusion.runtime.Cast._double(Cast.java:786)"
        [3] "coldfusion.flash.messaging.io.amf.Translator.CFASSerializer.translate(CFASSerializer.java:545)"
        [4] "coldfusion.flash.messaging.io.amf.Translator.CFASSerializer.translate(CFASSerializer.java:494)"
        [5] "coldfusion.flash.messaging.io.amf.Translator.CFASSerializer.translate(CFASSerializer.java:387)"
        [6] "coldfusion.flash.messaging.io.amf.Translator.CFASSerializer.translate(CFASSerializer.java:81)"
        [7] "coldfusion.flash.messaging.io.amf.Translator.CFASSerializer.translate(CFASSerializer.java:512)"
        [8] "coldfusion.flash.messaging.io.amf.Translator.CFASSerializer.translate(CFASSerializer.java:494)"
        [9] "coldfusion.flash.filter.CFCInvokeFilter.invoke(CFCInvokeFilter.java:160)"
        [10] "coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:279)"
        [11] "coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40)"
        [12] "coldfusion.flash.filter.CFCInvokeDebugFilter.invoke(CFCInvokeDebugFilter.java:54)"
        [13] "coldfusion.flash.filter.CFCInvokePathFilter.invoke(CFCInvokePathFilter.java:70)"
        [14] "coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28)"
        [15] "coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38)"
        [16] "coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22)"
        [17] "coldfusion.flash.messaging.ColdFusionAdapter.invoke(ColdFusionAdapter.java:223)"
        [18] "flex.messaging.services.RemotingService.serviceMessage(RemotingService.java:173)"
        [19] "flex.messaging.MessageBroker.routeMessageToService(MessageBroker.java:1165)"
        [20] "flex.messaging.endpoints.AbstractEndpoint.serviceMessage(AbstractEndpoint.java:757)"
        [21] "flex.messaging.endpoints.amf.MessageBrokerFilter.invoke(MessageBrokerFilter.java:117)"
        [22] "flex.messaging.endpoints.amf.LegacyFilter.invoke(LegacyFilter.java:158)"
        [23] "flex.messaging.endpoints.amf.SessionFilter.invoke(SessionFilter.java:48)"
        [24] "flex.messaging.endpoints.amf.BatchProcessFilter.invoke(BatchProcessFilter.java:67)"
        [25] "flex.messaging.endpoints.amf.SerializationFilter.invoke(SerializationFilter.java:145)"
        [26] "flex.messaging.endpoints.AMFEndpoint.service(AMFEndpoint.java:122)"
        [27] "flex.messaging.MessageBrokerServlet.service(MessageBrokerServlet.java:438)"
        [28] "coldfusion.flex.ColdFusionMessageBrokerServlet.service(ColdFusionMessageBrokerServlet.java:50)"
        [29] "javax.servlet.http.HttpServlet.service(HttpServlet.java:853)"
        [30] "coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89)"
        [31] "jrun.servlet.FilterChain.doFilter(FilterChain.java:86)"
        [32] "coldfusion.filter.FlashRequestControlFilter.doFilter(FlashRequestControlFilter.java:71)"
        [33] "coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46)"
        [34] "jrun.servlet.FilterChain.doFilter(FilterChain.java:94)"
        [35] "jrun.servlet.FilterChain.service(FilterChain.java:101)"
        [36] "jrun.servlet.ServletInvoker.invoke(ServletInvoker.java:106)"
        [37] "jrun.servlet.JRunInvokerChain.invokeNext(JRunInvokerChain.java:42)"
        [38] "jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:286)"
        [39] "jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:543)"
        [40] "jrun.servlet.jrpp.JRunProxyService.invokeRunnable(JRunProxyService.java:203)"
        [41] "jrunx.scheduler.ThreadPool$DownstreamMetrics.invokeRunnable(ThreadPool.java:320)"
        [42] "jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:428)"
        [43] "jrunx.scheduler.ThreadPool$UpstreamMetrics.invokeRunnable(ThreadPool.java:266)"
        [44] "jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)"
[/sourcecode]

Helpful, heh?

Why, WHY! it does not say what property is causing the problem? Surely it knows, it just keeps it for itself. Adobe – please fix!

Flex DateFormatter bug, missing January 1970 month name

June 18th, 2009

Today, while working on a small piece of code I discovered something that appears to be a DateFormatter bug. I was using following DateFormatter:

[sourcecode lang='as3']
private var formatter:DateFormatter = new DateFormatter();
...
 formatter.formatString = "MMMM";
[/sourcecode]

to display just the month names. I didn’t really care about the year when constructing new Date so I thought I would pick 1970. It appears that for January 1970 the DateFormatter returns an empty string while for 1969, 1971 and any other dates it works fine. Here is the demo.

[SWF]/wp-content/uploads/2009/06/DateFormatterBug.swf, 450, 300[/SWF]

And the source code below.

[sourcecode lang='as3']



 
  

 
  
  
  
 

 


[/sourcecode]

It appears that the bug was logged quite a few times, just one of the tickets I’ve found: https://bugs.adobe.com/jira/browse/SDK-14528. It also appears that it won’t be fixed. According to the comments under the linked story DateFormatter class is not an Adobe code. Interesting…

Flex DataGridColumn width set to the longest value of that column

June 16th, 2009

There was an interesting question on stackoverflow.com today. Some unnamed user asked:

Can we change the width of the datagrid column dynamically by clicking on the border of the column in order to display the complete string which is too long to be displayed and needs to be scrolled ? If so, How ?

Also, how can we ensure that the column width changes dynamically based on the number of characters / length of string; since many a times the data is too long to be displayed. Can we set the column width to take the length of data into consideration before displaying onto the datagrid ?

It looked like a cool practice so I thought I would give it a go. This is what I came up, it doesn’t resize columns on double click but rather automatically when data provider is set/updated.

[sourcecode lang="as3"]
 
 

  
    0 ) {
      // and no SPECIAL child exists:
      if ( getChildByName("$someTempUICToRemoveAfterFinished") == null ) {
       // create new SPECIAL child
       // this is required to call measureText
       // if you use custom data grid item renderer
       // then create instance of it instead of UIComponent:
       var uic:UIComponent = new UIComponent();
       // do not show and do not mess with the sizes:
       uic.includeInLayout = false;
       uic.visible = false;
       // name it to leverage get getChildByName method:
       uic.name = "$someTempUICToRemoveAfterFinished";
       // add event listener:
       uic.addEventListener(FlexEvent.CREATION_COMPLETE, onTempUICCreated);
       // add to parent:
       addChild(uic);
      }
     }
     // return an input:
     return input;
    }

    // called when SPECIAL child is created:
    private function onTempUICCreated(event:FlexEvent):void {
     // keep the ref to the SPECIAL child:
     var renderer:UIComponent = UIComponent(event.target);
     // output - this will contain max size for each column:
     var maxLengths:Object = {};
     // temp variables:
     var key:String = "";
     var i:int=0;
     // for each item in the DP:
     for ( i=0; i maxLengths[key] ) {
         // set it as the longest one:
         maxLengths[key] = cellMetrics.width;
        }
       }
      }
     }

     // apply column sizes:
     for ( key in maxLengths ) {
      for ( i=0; i

  
   
    
    
   
  

 
[/sourcecode]

Sample:

[SWF]/wp-content/uploads/2009/06/TextTest.swf, 450, 240[/SWF]

This code works just fine however it may be not efficient enough when applied to large data providers.

Source code is also available on stackoverflow.com under the original entry.

XMLSocket.send / Socket.writeUTFBytes doesn’t work?

June 11th, 2009

Disclamer
In first words – no, of course it is not broken, it is working fine. But there is a specific issue with these two methods when the socket server is implemented incorrectly. I noticed I’ve been looking for the solution using these phrases and that’s why the post it titled like that.

I just finished writing an ActionScript 3 SWC library which is going to be used with Flex and Flash applications. The library uses Socket connection to provide some statistical information to the Java socket server. As part of the project I had to create simple socket server which simply writes what it gets to the standard output.

The code was working fine when running in Flex Builder debugger. However, as soon as I started the test application in the Flash IDE I found following problem:

  • SWF was requesting policy file
  • my Java socket server was serving policy file
  • SWF was showing that it was connected
  • any other messages sent to the socket were not coming through

Exactly the same problem appeared when I deployed Flex version on the external server. It worked while running in the debugger but not from the browser. So it was clearly something wrong with the socket server. Once the policy file was served any other communication wasn’t working. My socket server looked like this:

[sourcecode lang='java']
package uk.co.test;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketTest {
 public static void main(String[] args) throws Exception {
  System.out.println("Starting...");
  start();
 }
 public static void start() throws Exception {
  // create socket server
  ServerSocket ss = new ServerSocket(1234);
  for (;;) {

   System.out.println("Waiting for the client.");
   Socket cs = ss.accept();
   System.out.println("Connection...");

   InputStream in = cs.getInputStream();
   OutputStream out = cs.getOutputStream();
   boolean isConnected = true;
   StringBuffer soFar = new StringBuffer();
   byte b;

   while (isConnected) {
    // let it rest a bit:
    Thread.sleep(10);
    // read everything what's coming in:
    while ( (b = (byte)in.read()) > -1 ) {
     if ( b == 0 ) {
      // zero byte, process:
      String value = soFar.toString();
      // get the value
      if ( value.equals("
") ) {
       // policy file requested, sent the policy back:
       System.out.println("Policy file request.");
       String crossdomain = "";
       crossdomain += "";
       crossdomain += "";
       crossdomain += "";
       out.write(crossdomain.getBytes());
       out.write((byte)0);
       out.flush();
       System.out.println("Policy file sent.");

      } else {

       if ( value.equals("exit") ) {
        // if exit command received, finish:
        isConnected = false;
       } else {
        // just output the message:
        System.out.println(value);
       }

      }
      soFar.setLength(0);
     } else {
      // append the character to the buffer:
      byte[] buf = new byte[1];
      buf[0] = b;
      soFar.append( new String(buf) );
     }
    }
   }
  }
 }
}
[/sourcecode]

While looking for the solution I found the following article: Setting up a socket policy file server. Peleus Uhley from Adobe describes how to use policy files effectively. In What data is sent in the request and response? section of the article there is a solution..

Once Flash Player receives the socket policy file, it closes the connection and opens a new connection if the policy file approves the request.

Looking at the above socket server code I could now clearly see what’s wrong. Once the connection is accepted no other connections are coming in until the first client sends exit message. So I modified my socket server, here it is:

SocketTest.java

[sourcecode lang='java']
package uk.co.test;

import java.net.ServerSocket;
import java.net.Socket;

public class SocketTest {

 public static void main(String[] args) throws Exception {
  System.out.println("Starting...");
  start();
 }

 public static void start() throws Exception {
  // create socket:
  ServerSocket ss = new ServerSocket(1234);
  for (;;) {
   System.out.println("Waiting for the client.");
   Socket cs = ss.accept();
   System.out.println("Connection...");
   // create socket connection handler and run it in separate thread:
   new SocketHandler(cs);
  }
 }
}
[/sourcecode]

SocketHandler.java

[sourcecode lang='java']
package uk.co.test;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class SocketHandler
implements Runnable {

 private Socket _client;

 public SocketHandler(Socket s) {
  _client = s;
  // create new thread from this instance and start it:
  Thread t = new Thread(this);
  t.start();
 }

 public void run() {
  try {
   // get client in/out:
   InputStream in = _client.getInputStream();
   OutputStream out = _client.getOutputStream();
   boolean isConnected = true;
   StringBuffer soFar = new StringBuffer();
   byte b;

   while (isConnected) {
    // let it rest a bit:
    Thread.sleep(10);
    // read everything coming in:
    while ( (b = (byte)in.read()) > -1 ) {
     if ( b == 0 ) {
      // zero byte, process what already came in:
      String value = soFar.toString();
      if ( value.equals("
") ) {
       // policy file requested, send it to the client:
       System.out.println("Policy file request.");
       String crossdomain = "";
       crossdomain += "";
       crossdomain += "";
       crossdomain += "";
       out.write(crossdomain.getBytes());
       out.write((byte)0);
       out.flush();
       System.out.println("Policy file sent.");

      } else {

       if ( value.equals("exit") ) {
        // exit command received, exit then...
        isConnected = false;
       } else {
        // just print the message to the stdout:
        System.out.println(value);
       }

      }
      soFar.setLength(0);
     } else {
      // append the char to the buffer:
      byte[] buf = new byte[1];
      buf[0] = b;
      soFar.append( new String(buf) );
     }
    }
   }
  } catch (Exception e) {
   // ignore
  }
 }
}
[/sourcecode]

The second socket server fixed the problem. It is working for connections with and without policy requests, from Flash IDE, Flex Builder and the browser.

It took me 5 hours to figure out the solution (process client connections in separate threads) so if you’re in the same situation as I was I hope this post helps you.

Google Wave – Microsoft OneNote anyone?

June 1st, 2009

Right… just before SotR09 London I can’t get sleep. I just watched the Google Wave recording from Google I/O. After 5 minutes I had this feeling I’ve seen it somewhere already…, think, think! And BING ;) It was Microsoft OneNote.

All that real-time typing capabilities, dropping images, commenting is already in OneNote. Until I see and "touch" Wave I claim – Wave is OneNote on steroids. Is it going to be successful? I really don’t know, probably yes. I’m just not sure if I really want Google to know everything about me, where I go, what do I do in my spare time, what do I work on.

Why crossdomain.xml is even more than a good thing

May 22nd, 2009

For a long time I couldn’t really understand what crossdomain.xml is for. Today, after finishing one the Flex projects I finally figured it out. At least one of two reasons. About 4 years ago Martijn de Visser described one of them – defending your internal network from the attacks. But there is another way reason why crossdomain.xml is good.

Let’s say I’m developing some smart module and I let people download and load it from their domains but there are some specific sites that I want to prohibit. I’m going to use this very simple module to demonstrate how this can be achieved.

[sourcecode lang='xml']


 

[/sourcecode]

Suppose that I let http://www.friend1.com and http://www.friend2.com use it but http://www.pron.com shouldn’t be allowed. When I modify the code a bit I will use Flash Player sandboxing to do so.

[sourcecode lang='as3']


 
  
 

[/sourcecode]

Next, I have to create following crossdomain.xml file:

[sourcecode lang='xml']

 
 
 

[/sourcecode]

The extended example in the conjunction with the above policy file protects this module from being used by the http://www.pron.com. When the module is created it simply calls home, policy file is returned and the module checks if the domain from which it is being used is allowed. Because http://www.pron.com is not on the list SecurityErrorEvent is fired and browser’s alert message pops up. Once the user clicks OK button he will be redirected to the module’s license. This is just a prototype but it should be quite solid.

I’ve created this code outside the IDE so it may have some bugs.

This approach should be very easy to apply in Silverlight as well.

Adobe and feeds.adobe.com team, please accept my apology

May 17th, 2009

It’s been a long time since I last blogged, I’ve been on holiday and following week was kind of busy. It turned out that in my last post, Thank you Adobe for removing me from feeds.adobe.com, I accused Adobe/feeds.adobe.com team of doing something that never happened. As johnb and Big Mad Kev pointed out the situation was caused by a failure in feeds.adobe.com system.

Previous post is totally my fault, I should have ask what happened before writing my post. It is a lesson for the future. I’m leaving that unfortunate post on my blog but I updated it with the explanation and link to this post.