Testing Tools for Flex

Brian LeGros | February 20th, 2009 | programming  

Over the last few weeks, while preparing my presentation for FlexCamp Miami a bit more, I have run into quite the plethora of tools to help developers test their Flex applications. I thought I’d take some time to break down what types of tools are available to help us out.

Unit Testing Frameworks

Mock Object Frameworks

Other useful libraries

My favorite combination right now is fluint, mock-as3, hamcrest-as3, and asx. Although asmock supports type-safe mocking, I’m not a big fan of the record/replay model; for now I’m gonna stick with mock-as3 and wait until it supports type-safe mocks (<cough>loom integration<cough>. I’ve also found a major need for stubs when classes in my integration tests depend on HTTPService and RemoteObject. Sometimes its tough to mock out these classes because of complex interfaces these objects maintain, so I’ve come up with a pretty cool way of handling this. Hopefully I can publish the sample code here in the next few days for those who are interested.

I’d also like to give props to a couple people I’ve been working with in the community: Michael Labriola, Max Porges and Drew Bourne. Mike is working tirelessly to bring a more modern unit testing framework, a la JUnit 4 + more, to Flex via fluint along with tons of other initiatives. mock-as3, hamcrest-as3, and asx are all APIs that Drew has written; hamcrest-as3 alone is going to be providing some really powerful integration for assertions in unit testing frameworks. Max has been chipping away at the ABC spec with loom for months now, and once finished it’s going to provide a lot of great potential for more mature tooling/libraries in the Flex world … think AOP. Each of these code-bases are intuitive, easy to use, and were some of the biggest pieces missing from the Flex testing world until now. Keep up the great work guys! With any luck, we may soon have the tools we need to be as productive as developers in almost every other language out there.

Fluint 1.1.0 Released!

Brian LeGros | February 12th, 2009 | programming  

Over the last few months, I’ve been working with Michael Labriola on the next minor version release of Fluint. Well, this evening Michael and I put the finishing touches on release 1.1.0. This release brought all of the changes I made to get Fluint working at the office for our CI process to the community. There are a couple of cool little gems that I think will be helpful for some:

  • Separation of failures and errors in test reporting (visual and XML).
  • XML compliant output with most CI servers as well as the JUnitReport task in Ant and the Surefire Reporting plugin in Maven.
  • Support in the Ant task for truly headless executions of the AIR Test Runner via xvfb-run.
  • Support for relative paths in the Ant task and AIR Test Runner.
  • Better error handling for non-compliant modules loaded into the AIR Test Runner.
  • LogBook integration for debugging
  • A big folder re-organization and Ant scripts to support developers when they need specialty builds.
  • Agreed upon a branching and tagging strategy so the community can have stable snapshots of source to build.

We probably should put together a ChangeLog wiki page, so that may be available soon. We did a few updates to the wiki, so stop by the Google Code site and check out the changes. Also, provide feedback on the discussion list, if there are features you’d like to see implemented, bugs that you find, or just general questions you need help with. People are great about helping on the list, so don’t feel discouraged.

This is my first major release of an OSS project that I’ve had code go into, so thanks to everyone who helped with the release, especially my wife for putting up with a lot of late nights. There is a lot more to come with Fluint over the next year that is going to be really exciting. Look for announcements during my presentation at FlexCamp Miami and on the discussion mailing list. Hope you enjoy the new release!

Which assertions do you use in unit tests?

Brian LeGros | February 6th, 2009 | programming  

Over the last few days, I’ve decided to start putting some time into adding some new assertion functions into fluint. Here are a few that I was thinking of adding:

assertRegExp(expected : RegExp, actual : String) : void
assertArraysEqual(expected : Array, actual : Array, compare : Function) : void
assertDictionariesEqual(expected : Dictionary, actual  : Dictionary) : void

Along with each of these, their boolean counterpart would also be available (i.e. – assertArraysNotEqual). My question to other developers is, which assertions would you like to see available in your unit testing framework of choice? The way I figure, the more options available in the assertion stockpile, no matter how simplistic they may seem, the more explicit we can make our tests. Would anyone be interested in seeing some type of assertion using callbacks (i.e. assertReturnsEquals(actualCallback : Function, args ..rest, expectedResult)? Feels like a bit of a stretch, but it’s a datatype, so maybe it should be considered. Anything for events that may be useful?

What do you think?

Presenting at the Adogo this month

Brian LeGros | February 3rd, 2009 | news  

It seems like every month, the Adogo and RAnDOM meetings creep up on me. That being said, we’ve pushed the Adogo meeting for February back to February 9th this month instead of yesterday, February 2nd, to try and make up some time to prep. I will be presenting on the topic of “Continuous Integration” (primer) and afterward we’ll be having a round-table discussion about what everyone’s been up to and working on. Should be a pretty lay back meeting and I promise to put everyone to sleep, so bring your pillows. This will be a practice run for my the presentation that I will be giving at FlexCamp Miami on March 6th, so if you like what you see (with, or without. the sexual overtones), you should try to make it down for a day of fun with Flex.

See ya Monday, if you can make it; if not, thanks for sparing me the embarrassment that was inevitable. :’(

Thanks for the invitation KSC

Brian LeGros | January 17th, 2009 | programming  

Big thanks to Doug, Bill, Jim, Mike, Don, Boss boss, and everyone else who joined me for my presentation on Continuous Integration and Flex at Kennedy Space Center. I ended up running around an hour and forty minutes giving an overview of the Adobe Flex domain and continuous integration as a whole. Thank you everyone for taking the time out of your busy schedules to tough through the presentation; I hope I have failed you all equally.

As promised, below are links to the materials from the presentation that I used as well as links to other resources you may find helpful.

Subversion – http://subversion.tigris.org/
Apache Ant – http://ant.apache.org/
Flex Ant Tasks – Use the libraries included in the Flex SDK 3.2 distribution
Fluint Library and Ant Tasks – http://code.google.com/p/fluint/
mock-as3 – http://code.google.com/p/mock-as3/
Hudson – https://hudson.dev.java.net/
Example Application and Component – http://brianlegros.com/blog/files/example_apps.zip
Slides – http://brianlegros.com/blog/files/slides.pdf

If you have any questions, please don’t hesitate email @ me at brianlegros dot com.

NOTE: The Fluint test runners and reports that you saw in my presentation were using a code base that has yet to be released by the Fluint team, but will be hopefully soon. We have a lot of great working going on at the Fluint project, so I’d encourage you all to check out the Google Code site as well as the Fluint mailing list.

Continuous Integration with Maven, Flex, Fliunt, and Hudson

Brian LeGros | December 17th, 2008 | programming  

Recently I was tasked with streamlining our build process at work so we could get a continuous integration (CI) server up and running. We use the common stack of technologies found in most Flex shops (basic SDK, some libraries, and Flex Builder) as well as Maven. I ran into some challenges getting our CI process to work as we wanted, so I figured I’d go through some of the gotchas I encountered.

On the build side of things, when I came on, Maven was already in place using flex-mojos. Now I’m a big fan of the simplicity that Ant brings to the mix, but the issue of dependency management being baked into Maven makes it extremely appealing; I do like Ivy as an alternative when using Ant, but I wasn’t going to re-write the company’s build process. So we had flex-mojos building our source and producing artifacts for deployment to our team’s Maven repository, but we needed to integrate our unit tests into our build. We were using dpuint and were excited to see that fluint had been released with Ant support. Currently flex-mojos doesn’t support Fluint, although my colleagues tell me they’re working on it, so I knew I was going to have to use Ant. To start I had to get flex-mojos building my test SWF so I could use the Fluint Ant task. The Ant support in Fluint requires that you produce a module SWF that will work with their test runner written in AIR. After an hour of messing with flex-mojos, I was unable to get the compile, or test-compile, goal to do what I wanted, so I decided to use the maven-ant-run plugin to compile our tests as well.

Below is the snippet I was able to get working to compile our tests and execute the Fluint test runner:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<properties>
   <flex.home>PATH_TO_FLEX_SDK_HOME</flex.home>
   <fluint.testrunner>PATH_TO_FLUINT_AIR_RUNNER_EXECUTABLE</fluint.testrunner>
</properties>
...
<build>
   <plugins>
      <plugin>
         <groupId>info.flex-mojos</groupId>
         <artifactId>flex-compiler-mojo</artifactId>
         <version>2.0M9</version>
         <extensions>true</extensions>
         <configuration>
            <skipTests>true</skipTests>
         </configuration>
      </plugin>
      <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-antrun-plugin</artifactId>
         <executions>
            <execution>
               <id>fluint-test-compile</id>
               <phase>test-compile</phase>
               <configuration>
                  <tasks>
                     <!-- Pull in Flex Ant Tasks -->
                     <taskdef resource="flexTasks.tasks" />
 
                     <property name="FLEX_HOME" location="${flex.home}" />
 
                     <!-- Create test-classes directory -->
                     <mkdir dir="${project.build.testOutputDirectory}" />
 
                     <mxmlc file="${project.build.testSourceDirectory}/AirRunner.mxml" 
                        output="${project.build.testOutputDirectory}/AirRunner.swf" 
                        keep-generated-actionscript="false">
 
                        <load-config filename="${FLEX_HOME}/frameworks/flex-config.xml" />
                        <source-path path-element="${FLEX_HOME}/frameworks"  />
                        <compiler.library-path dir="${FLEX_HOME}/frameworks" append="true">
                           <include name="libs" />
                        </compiler.library-path>
                        <compiler.library-path dir="${project.build.directory}/.." append="true">
                           <include name="libs" />
                        </compiler.library-path>
                        <compiler.library-path dir="${project.build.directory}" append="true">
                           <include name="*.swc" />
                        </compiler.library-path>
                     </mxmlc>      
                  </tasks>
               </configuration>
               <goals>
                  <goal>run</goal>
               </goals>
            </execution>
            <execution>
               <id>fluint-test-run</id>
               <phase>test</phase>
               <configuration>
                  <tasks>
                     <!-- Pull in Fluint Ant Task -->
                     <taskdef name="fluint" classname="net.digitalprimates.ant.tasks.fluint.Fluint" />     
 
                     <property name="test.report.loc" location="${project.build.directory}/surefire-reports" />
 
                     <!-- Create reporting directory -->
                     <mkdir dir="${test.report.loc}" />
 
                     <fluint debug="true" 
                        headless="true"
                        testRunner="${fluint.testrunner}" 
                        outputDir="${test.report.loc}" 
                        workingDir="${project.build.testOutputDirectory}">
 
                        <fileset dir="${project.build.testOutputDirectory}">
                           <include name="**/AirRunner.swf"/>
                        </fileset>
                     </fluint>      
                  </tasks>
               </configuration>
               <goals>
                  <goal>run</goal>
               </goals>
            </execution>
         </executions>
         <dependencies>
            <dependency>
               <groupId>org.apache.ant</groupId>
               <artifactId>ant</artifactId>
               <version>1.7.0</version>
            </dependency>
            <dependency>
               <groupId>flex.ant</groupId>
               <artifactId>flexTasks</artifactId>
               <version>1.0.0</version>
            </dependency>
            <dependency>
               <groupId>net.digitalprimates</groupId>
               <artifactId>FluintAnt</artifactId>
               <version>1.0.1-SNAPSHOT</version>
            </dependency>
         </dependencies>
      </plugin>
   </plugins>
</build>

Couple of things to point out about the above snippet:

  • There are two dependencies on resources being available on the disk, the Flex SDK (flex.home property) and the Fluint Air Runner (fluint.testrunner property).
  • Using Ant I had to create the “test-classes” and “surefire-report” directory to stick with Maven conventions.
  • We adhered to the convention of naming our test runners for the Fluint Ant task “AirRunner.mxml” so we could use this snippet in a parent POM.
  • I had to change the dependency for the maven-ant-run plugin from Ant 1.6.5, which is the default, to Ant 1.7.0, which is required by the Fluint Ant task.

You may also notice that I’m using snapshot versions of the Fluint library and the Fluint Ant task. I ended up having to change the source of the Fluint library, Ant task, and AIR runner to get Fluint to work as I wanted it to with my build. Fluint is an awesome unit testing library, it just needed some tweaks. I made changes to fix the following:

  • The XML output from the Fluint AIR runner wasn’t compliant with what the Surefire Report plugin was expecting.
  • The name of output file from the Fluint AIR runner was in the convention “TEST-*.xml” which the SureFire reporting plugin expects.
  • Fluint had the notion of an error and failure being separate but it wasn’t implemented for the Flash or AIR test runners.
  • The Ant task didn’t allow the user to specify a working directory so that the AIR runner could be launched from the appropriate directory.

I later found out that AIR and relative paths don’t play nicely together (= at all, unless there is helper code), so we also had to re-factor our test suites to NOT rely on any assets unless they are embedded or referenced with absolute URIs. This made the change to the Fluint Ant task kinda worthless, but I kept it in anyway for when AIR works in the future. Additionally, it’s important to note, that the “headless” mode in the Fluint AIR runner is really just a minimized window that closes after the XML report is written; if you plan on running your CI build on an OS without a windowing solution, then FLuint will not work since AIR does not support running in a true headless mode. On a side note, my changes should address issues #5 and #22 on the Fluint Google Code site; issue #21 should be solved by the Ant dependency fix I spoke about above and issue #20 is just a matter of the fluintAnt15.jar being compiled with Java 1.6 instead of 1.5, I believe. I’ve submitted these fixes along with my code to the Fluint guys in an email, just haven’t heard anything back yet.

So at this point I had the build process working as I wanted such that I could run “mvn clean deploy site” and find a snapshot in our team’s maven repository and site documentation generated. On to CI. I have used CruiseControl many times in the past, but the idea of being entrenched in XML, especially with all the Maven and Ant fun, was discouraging so I decided to give Hudson a try this time around. Wow … Hudson is amazing improvement over CruiseControl. Completely UI driven, I have yet to find myself digging through XML and best of all. The post-build support feel a little lighter than CruiseControl’s, but I think that’s just because I haven’t come across an X10 plugin so we can get a stop light or glowing orb setup. Hudson provides trend reporting on builds and unit tests as well as embedded reporting for unit tests and xdoclet-like documentation; it also has tons of Groovy integration which I really like (not that we’re using it … yet). Initially I chose to go with the pure Maven build for our projects, but I then decided to switch back to the free-style build; I couldn’t get trend reporting for unit tests to work with the pure Maven build, so I think my conventions are off for the Fluint reporting. In the free-style build I set the “site” directory as the Javadoc location and the “surefire-report” directory as the test report directory. Even though there is more configuration in a free-style build, it was simpler in the short run to get what I wanted in Hudson running. If unit test trend reporting isn’t as important to your CI needs, then the pure maven build may be more along the lines of what you’d like to use so that you can get the additional build trigger “Build whenever a SNAPSHOT dependency is built”. On a side note, I’m working towards using the FlexCover support in flex-mojos to make our site reports complete, but haven’t had a chance to dive in yet.

I hope some of the hurdles I encountered can help if you’re trying to get your CI process working with Flex. The flex-mojos, Fluint, and Hudson guys have some good walkthroughs/tutorials to cover the details I left out. I’m always up for suggestions, so definitely feel free to rip into my solutions. :)

Mock objects and AS3 : Now I really don’t want to use explicit typing

Brian LeGros | October 25th, 2008 | programming  

So in my search for mock object libraries, I continue to run into frustration with explicit typing in ActionScript 3. I did some searching and found a really great mock object library called mock-as3. It’s an expectation based library, in its early stages, but surprisingly featured and intuitive. Here are some usage examples from the author.

I’ve been writing code in ActionScript using explicit types, like most everyone I know who uses AS3, so mock-as3 out of the box won’t meet my needs. If I wanted to begin using interface classes and stubbing out my mocks (as mentioned in the examples) I could, but I won’t; the author even comments that it is extremely tedious to do and doesn’t necessarily advocate it. He hopes to have features in future versions of the library available to handle this but for now they are not available. In general, implementing interfaces for all classes that I’d like to mock is something I don’t agree with in any language. I’m a believer that refactoring your code will make a use case for the use of a programmatic interface over time; there are explicit cases where they are useful, but in the case of mocking, I’m not a big fan.

In any case, I did some thinking and wondered if there was a way to convert an object to a different type at runtime. I figured it’d take some bytecode manipulation, but I’m new to the game, so others much have thought about this already I assumed. Sure enough, I found an implementation by Darron Schall called ObjectTranslator which will convert an object’s type at run-time. I ran through some basic examples and everything worked as expected, so I thought, why not try to convert Mock, which is the class used to mock an object, to the class type passed in at instantiation? The implementation of ObjectTranslator just switches a byte for the new class type and directly copies the bytes of the object into a new byte stream. Worth a shot right?

In mock-as3′s implementation Mock is a subclass of everyone’s favorite class, Proxy. I did a basic test creating an expectation with the same name as the method in my class I wanted to mock and then used ObjectTranslator to convert the mock’s type. I then passed the typed mock to something to consume it and test to see if my expectations return value was given. Below is a the code I wrote:

1
2
3
4
5
6
7
8
9
10
11
var mock : Mock = new Mock(new MyClass());
trace(describeType(mock));
 
mock.method("method1").returns("PASS!");
trace(mock.method1());
 
var newMock : MyClass = ObjectTranslator.objectToInstance(mock, MyClass);
trace(describeType(newMock));
 
var typedUsage : UsageClass = new UsageClass(newMock);
trace(typedUsage.method1() == "PASS!");

Everything works except the final call to trace() which shows false because the value being returned is “FAIL!”, which is the default value for the method in the class declaration. I thought, well maybe I can add functionality to Mock where on each call to method() or property() I will create a property on the mock with the same name of the property passed in and point it to callProperty or getProperty from Proxy. Mock is declared dynamic after all. I gave it a whirl but no luck, I’m guessing there is something special done with Proxy that when I used ObjectTranslator, didn’t come over. There were also some properties used by Mock that didn’t come over because they were not part of the new type, specifically expectations. Since mock-as3 uses its internal reference to expectations I was hoping I would get this for free, but it didn’t work out from what I can tell. Without a way to eval() the code necessary to create a method signature matching the existing signature in the class declaration, I’m pretty much stumped.

If anyone has any suggestions, I’m all for it, but I kinda threw up my hands and called it a day. The more I play with ActionScript 3, the more it feels like the Flex community is going to have to produce things equivalent to CGLib to do anything flexible with ActionScript3 that is still type-safe (e.g. – mocks, AOP, etc). It sounds like from a thread on FlexCoders that the community really wants a Proxy#newProxyInstance method, so hopefully this will make Proxy a little more useful. I’m not sure, however, if they want to be able to instantiate Proxy at run-time or be able to instantiate a formal target property from Proxy of the target’s type. I’m hoping for the latter, but I’m still new to AS3, so who knows. Back to stubs …

ActionScript: Just different enough to piss you off

Brian LeGros | October 19th, 2008 | programming  

So I’ve started my new job and I’m working with Flex and ActionScript 3. I was tasked with throwing together a couple classes and there respective unit tests this week. The classes don’t integrate with any external resources and mostly do pass through except for some cross cutting concerns (e.g. – logging, security, etc). I figured writing my tests would be pretty straight forward: throw together the appropriate test cases and in each mock out any dependencies.

Now when I think about a language I try to put it into the context of other languages I’ve had experience with, identify differences in language elements, and work from there. With respect to ActionScript, I tended to problem solve in the context of JavaScript since they are both based on ECMAScript, but I’ve run into some frustrations along the way.

To mock out an object in a test using JavaScript I’d typically write something like:

1
2
3
4
5
var dependency = new MyDependency();
dependency.methodToMock = function () { return true; };
 
var obj = new MyClass(dependency);
assertTrue(obj.passThroughMethodUsingMockThatICreated());

or if I wanted to mock out objects being instantiated by a dependency that I couldn’t inject:

1
2
3
4
MyDependency.prototype.methodToMock = function () { return true; };
 
var obj = new MyClass();
assertTrue(obj.passThroughMethodUsingMockThatIDidntCreate());

In ActionScript, assuming that MyDependecy is declared in an ActionScript class, the first and second approach I used in the above will not work. I did some reading on the Flex 3 livedocs and found out that the culprit was the traits object that was introduced in AS3. To abridge, the traits object is a copy of all applicable properties from parent classes and defined properties in the current class that need to be available at run-time to help reduce the performance hit of walking the prototype chain previously used for inheritance. The traits object is an internal mechanism which is not accessible by the developer. Prototype-base inheritance is still available, but falls secondary to traits. Awesome.

So unless I declare the methods of my class as members of the prototype for the class, I can’t manipulate them at run-time. So instead of the following:

1
2
3
4
5
public class MyDependency {
   public function methodToMock() : Boolean {
      ...
   }
}

I’d have to write:

1
2
3
4
5
public class MyDependency {
   prototype.methodToMock = function() : Boolean {
      ...
   }
}

So now I’ve got methodToMock available in a data structure I can mess with at run-time. I still, however, can’t accomplish what I did in JavaScript unless I add the keyword dynamic to the class declaration (as below) or remove the “strict” flag from the compiler:

1
2
3
4
5
public dynamic class MyDependency {
   prototype.methodToMock = function() : Boolean {
      ...
   }
}

Now I can manipulate the object and its class’ prototype the way I would in JavaScript. It irks me a bit that performance was the driving force for all of this hoopla, but I’m just an application developer, so I won’t pretend to understand all of the motivations for these decisions.

As another alternative, I thought about just using Object for all of my mocks, but I quickly dismissed the option since we’re using the explicit typing with ActionScript, as I suspect most are since its promoted for its performance boost. I also looked into using the Proxy class as a run-time solution, but alas it can’t be instantiated, only extended; this would mean writing class declarations for every mock I wanted to create, which seems kinda silly, and I still would have to deal with the explicit typing issue. On a side note, it would have been nice if Proxy had the option to be instantiated with the object it’s proxying as a constructor argument, mimic the type passed as the argument, and allow run-time manipulation. No idea if this is feasible though, so I’ll count it as a pipe dream for now. In any case, from my experience mocks are intended to be used within a context and disposable for the purpose of testing; why would I write anything more than inline code to utilize mock objects?

In the end, I’m probably going to be making end-to-end tests using stubs for the classes I want to test. Once we have some time to evaluate mock object libraries for ActionScript, I’ll probably start digging again for more answers. We’ll eventually need something to help us with expectation-based testing anyway, so a library will be the way to go. Hopefully I’ll end up finding something more like Mocha or Moq than JMock, although I think the opposite may be true.

There are language elements in ActionScript that I’m extremely grateful to have at my disposal (e.g. – events, properties, functions, etc). A few quirks exist though (e.g. – object/class manipulation at runtime and reflection) that still get me when I try to think about ActionScript in the context of JavaScript. Going forward I think I’m going to switch gears and solve problems more as I would a Java/C# developer than a JavaScript developer, favoring the use of libraries over the language features to get every day tasks done. I like ActionScript, but what good would a blog be if I couldn’t complain.

:)

NOTE: I can’t take credit for the tagline, some Flex developers I know have begun to adopt it and I borrowed it from Dan.

Moving into the .NET world

Brian LeGros | June 15th, 2008 | programming  

With my latest employer, I have taken the big dive into the .NET world. I’ve spent most of my career working with ColdFusion, Java, PHP, Flex and dabbled a little bit in the Ruby/Rails and Groovy/Grails world in addition to the obvious set of web technologies and standards that span all of these application languages. My limited experience with .NET was through some undergraduate and graduate work I did with C# as well as helping (if you can call it that) with an ASP.NET a long time ago with a colleague of mine. I am a application developer; even though I dabble in lots of different areas, the bulk of my knowledge is building applications in a corporate IT environment. I focus on implementing business requirements and managing technical concerns as it relates to the software development process. I’ve had jobs in the past associated with business and management roles but at the core I am a plain and simple application developer. As I’ve been getting my hands dirty in .NET over the last few months I figured I’d share some of my initial impressions. Please keep in mind, I may be looking at a lot of things in a very naive light, so read what I have as my opinion, ignorant or not.

With context out of the way, I have to say that so far working with .NET hasn’t been a negative experience. There is the whole you’re stuck with Windows thing, but since I’m in fully entrenched in the MS world now, I’ve been able to get past it. There have definitely been some nuances to get used to, but nothing extremely difficult to overcome. Here are a few comments on some of the things I’ve run into thus far:

  • Namespaces in C# aren’t constrained by the file system with respect to partitioning your code. Initially this seemed like a nice decoupling, but I’ve found myself forming more of a dependency on tools to navigate my classes hierarchy rather than just looking into a folder.
  • There is no notion of a shared class path as there is in Java. If you want to get a hold of an assembly to use in your application you’ve got to find it and pull it in. I think there is a configuration option on an assembly that you can use to help, but I haven’t had any experience using it.
  • Assemblies are pretty nice build artifacts. Versioning is addressed out of the box and integrated with the .NET framework. I’m not sure how they stack up against something like OSGI, but I’m enjoying having them around.
  • Everyone says the implementation for generics is better in C# than Java, but as an application developer I don’t notice a difference except that I’ve been told I can use reflection on them in C#. C# also seems to have made a much larger use of them in their core over Java. It seems like stronger typing is a very important practice in the C# world than in my experience with the Java world, but that is probably biased based on how I’ve used Java.
  • There appears to be a very balanced view on uses for metadata (attributes) in .NET. Annotations in the Java world were a great addition to the language, but sometimes their use comes off as abuse; look at a JUnit 4 test suite class for a great example.
  • There are lots of accepted libraries available that are direct ports from the Java community such as NUnit, NAnt, Spring.NET, CruiseControl.NET, NDocs, log4net, etc. Getting comfortable with these libraries was pretty easy since I’d had experience with the Java equivalents.
  • The help systems in .NET leave much to be desired and make me long for Javadocs, Livedocs, RDoc, or anything else. I find myself clicking through a class definitions on MSDN and after two or three links I can finally get to a list of “members” that belong to a class, only to click another link to load another page to see more about the details of that “member”. I have yet to find any easily usable API documentation.
  • .NET has a solid component model available out of the box. WCF is a really simple and tight implementation of a component architecture. Service-orientation is a focus with an emphasis on abstracting away protocols, execution environments, and exposing metadata for a more contractual usage. It has the feel of being an API built around WSDL 2 and many of the WS-* standards, but it goes by many of the concepts, although not by name, identified in Patterns of Enterprise Integration. It’s compatible with synchronous and asynchronous operations and did I mention simple to use? I hope to do some posting about it later.
  • Getting used to assimilating applications into the bowels of the OS seems to be core to the .NET mentality. This is probably just a matter of perspective for the developer, but based on the examples I’ve seen thus far, the user folder, the registry, and Windows\system32 folder are popular hang outs for lots of applications. I’ve been met by quite a looks of confusion when I mention deploying applications without the use of some type of installer. There is a lot of power that you get from this tight coupling with the OS I’ve been told. Unlike my previous shops, writing cross-platform applications doesn’t seem to be a priority for .NET developers, so tight coupling it is.
  • It took me listening to the episode of SER with Anders Hejlsberg to understand better it, but it appears to be that developing in .NET is meant to be an IDE integrated experience via Visual Studio. Regardless of the aspect of development I’ve worked with in .NET thus far, the development experience has been fairly consistent. There is always some visual representation of the code available (where applicable) and a debugger is always around and working no matter the context (desktop, web, etc.). At first it was so simple that I felt like I was missing something, but from what I have read and heard, as much work goes into VS as does the .NET framework, if not more. If anyone has used Netbeans for Java web development, it’s a very similar experience in terms of its integration with the environment.
  • I’ve always seen code insight as a supplemental thing, relying on documentation for the majority of my work, but wow, code insight (intellisense) seems to be the major crutch on which a lot of .NET developers place themselves within VS. What’s weird is that I don’t notice anything different than what you’ll experience when working with Eclipse and Java, in fact, the code insight seems to be limited to code only. I have yet to run into a situation where the IDE makes a suggestion on how something could be written or changed as IntelliJ does for Java. I will admit though, maybe I’m missing something.
  • The visual editors in VS seemed to get abused by .NET developers. I say abuse because quite a few .NET developers I’ve encountered can’t talk to me about their code in any other context but how they dragged-and-dropped controls onto a screen and edited properties. Since I don’t know the in’s and out’s of the tools quite yet, having a conversation is tough. I try to communicate in terms of language agnostic principles and patterns but most of the time all I get are blank stares and judgmental comments about how I am over complicating things.
  • MS alternatives exist in terms of the IDE and runtime, but they don’t seem to be popular at all. I really like SharpDevelop as an alternative to Visual Studio. It’s clean, easy to use, and integrates with a lot of OSS packages out of the box. Mono is available as a Linux-based .NET runtime that has a lot of .NET developers excited because of its potential to allow them to code for the Mac. I don’t know any Mac owners that have Mono installed however, so I don’t know if it’s really a viable cross-platform solution.
  • I have some thoughts on ASP.NET web forms that I want to share, but I’ll save that for my next post.
  • The developer community has always been important to me and I feel it’s always important to remain active in the community in some capacity. As I’ve begun attending the local .NET user group meetings, I don’t see a lot of topics that are not MS centric. There is no question that MS drives the releases of the .NET framework, but there have been lots of innovations coming out of the community that deserve attention. It feels like there are only a small minority of developers that actually utilize these contributions locally. I have yet to see any presentations on the various unit testing tools, build tools, ORM, IoC, etc. that have come out of this space. I do envy the direct support that MS has for its user groups, but I wonder if my expectations are too high.

In any case, so far the learning curve with .NET hasn’t been very steep and when I do get to code I feel fairly productive. I should be posting in the next few days on my thoughts about ASP.NET web forms so I’m sure that will get me flamed, but it’s a major part of the puzzle I’m having to work with that I feel needs some attention. Until next time.

Help with Introspection using ActionScript 3

Brian LeGros | April 12th, 2008 | programming  

Ok, I need help. I’ve been able to discover the coolness that is getQualifiedClassName() and getDefinitionByName() and describeType() when it comes to working with introspection/reflection in ActionScript 3. I am stuck however. I want to get a hold of all the class names available in the compiled Flash movie at runtime. I’m writing a library that will look for custom metadata on classes and associate functionality with the classes (or possibly objects) if they are annotated in a specific way. Right now, short of asking for a list of those classes from the developer, I don’t know of a way to build a bootstrap function/class that will introspection into the Flash movie and get me a list of them. I was thinking maybe if I could find a way to programmatically access the manifest file that would work, but again I can’t find a way to do that.

Does anyone know how to do this or am I doomed to introspecting on objects and programmer declared references rather than classes?

UPDATE: I found a feature request in the Flex 3 JIRA database. Basically it’s not in Flex yet, nor is it supported by the Flash movie, but 4 people have voted for the feature thus far. That being said, please vote for this feature so we can get one of the final pieces to reflection built into Flex. BTW – If anyone wants questions answered with regards to Flex, check out the flexcoders mailing list over on Yahoo. Everyone probably knows about it but I’m slow.