Thursday, 26 February 2009

uid property on ActionScript object breaks mx:List

I don't know if this is expected behaviour, but this evening I noticed, much to my annoyance, that having a uid property on an Object causes mx:List to stop handling rollovers and selections properly. Take the following extremely simple example (compared to the code I was actually working on):

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">

<mx:ArrayCollection id="sampleData">
<mx:Object uid="" label="Sample 1" />
<mx:Object uid="" label="Sample 2" />
<mx:Object label="Sample 3" />
<mx:Object uid="" label="Sample 4" />
<mx:Object uid="" label="Sample 5" />
</mx:ArrayCollection>

<mx:List dataProvider="{sampleData}" />

</mx:Application>

Only the last and 3rd item in the list receive roll over events, and while selection does actually appear to work, the highlighting of the selected item doesn't.

You can see it working (or not) here.

backups

It seems to me that backups are a fundamental requirement for any IT professional. I'm not talking about those monolithic backups for various disparate systems, I'm talking about backing up your day to day working environment or even just those essential documents that you happen to keep on your machine, if things go wrong this can cause a lot of hassle, extreme embarrasement, or worse - loss of income.

The Good

Mac. One of the things I love about my Mac(s) is Time Machine. Having TimeCapsule also helps, but I suspect that one could even manage without that. I don't have to worry what I need to backup, I worry about what I don't need to backup. Time Machine gives me incremental backups and a fantastic UI to go hunting for those old files when I need to do a restore.

It has already proved it's worth to me when I cocked up my Eclipse environment. Setting up Eclipse, various plugins and Flex Builder can take several painful hours, but I just headed back to the last known good version of Eclipse that was backed up and simply restored it.

And in a really bad situation, for instance if my MacBook Pro were to go kaput and I have to get a new one, I simply select to do a full restore from my TimeCapsule when I set up the OS for the first time. It might take an hour or so because it'll be several GB in size, but it's easier than reconfiguring the OS and reinstalling all that software from scratch.

The Bad

Windows. I was never able to work out a really satisfactory backup solution. I used AlwaysSync for some stuff and xcopy batch scripts for others. I had to maintain what was backed up and when and the OS just didn't seem to come with a straight forward backup solution. At a minimum you should synchronize important folders *daily* and preferably to multiple locations.

The Ugly

Not having any backup. Using Google Documents (as I do) and Google Mail (as I do) means that actually I don't have a lot to worry about, but having important documents on your computer and not backing them up is unforgiveable. Even if your machine doesn't out-right die, you risk corruptions or virus infection.

So ask yourself - how quickly could you get back up and running if your machine died right now, or if your important document folder somehow got deleted? Have you tested restoring from your backup strategy? Give yourself some piece of mind; get a backup strategy and test it. Make it the next thing on your to do list.

Backups - come on ... that's IT 101!

Thursday, 5 February 2009

thoughts on jsr294 - v0.0.2

It occurred to me overnight that the solution I proposed in my last entry does not address the problem. The main reason is, there is nothing stopping a developer from writing a class and giving it the same package as one of my classes. As a result, that class now has access to any of the classes with the new modifier I was proposing.

But what is to stop someone writing a class and marking it as part of my module, thus granting it access to those classes I wanted to restrict access to?

I think my brain is catching up with the reason for some of the discussions I've been reading in the observer mailing list.

Wednesday, 4 February 2009

thoughts on jsr294 - v0.0.1

I've been trying to follow the recently renewed discussions around JSR 294. The discussion can be followed here:
http://cs.oswego.edu/mailman/listinfo/jsr294-modularity-observer

I'm not sure how you get to contribute to the JSR itself, by being a member of the Expert Group, I suppose, but you do seem to be able to post to the observer mailing list and have separate discussions which the main contributors may or may not read/choose to respond to.

At first I thought the JSR seemed somewhat vague, but after reading it and understanding what it is really saying, I'm think I'm starting to get it. These are my thoughts on what I understand so far and these thoughts are likely to change as time goes on.

Firstly, one thing that concerns me is that so far the main people contributing to discussion seem to be talking at cross purposes, putting forward how they think modularity should work without really addressing what the JSR sets out:

Today, an implementation can be partitioned into multiple packages. Subparts of such an implementation need to be more tightly coupled to each other than to the surrounding software environment. Today designers are forced to declare elements of the program that are needed by other subparts of the implementation as public - thereby making them globally accessible, which is clearly suboptimal.

Alternately, the entire implementation can be placed in a single package. This resolves the issue above, but is unwieldy, and exposes all internals of all subparts to each other.

The language changes envisioned will resolve these issues. In particular, we expect to introduce a new notion of modules (superpackages) at the language level where existing public access control would apply only within a language level module and access to API's from outside a module would be restricted to API's the module explicitly exports.

It may not be immediately obvious what this means, so here's a quick explaination.

If you have class Foo in package com.mypack and you want class Foo to access class Bar which is in package com.mypack.support then class Bar has to be public for class Foo to access it.

Foo.java:
package com.mypack;

public class Foo {

private Bar bar = // ... initialise the bar instance variable somehow

// ... methods to do something with the bar instance variable

}

Bar.java:
package com.mypack.support;

public class Bar {

// ... further definition of Bar

}

That seems to be a fairly typical example. However, maybe this is a utility library of some kind that you want to release in to the public domain and you only wanted Foo to be the access point in to the library. The bad news is that users have direct access to Bar as well, because it is public.

The JSR then points out that a work around is to put all classes in the same package, but this is undesirable since developers tend to group classes together in to packages (especially if trying to maintain low-coupling and high cohesion, not to mention structuring the code helps maintain a mental picture of it).

So the answer is a module system. This solves the problem by allowing the developer to explicitly state which artifacts (classes or packages or maybe both, I'm still not clear) are exported to other modules for direct access.

I would hope that this is optional and that code that hasn't been 'modularised' just behaves in the same way or that's backwards compatibility out of the window. I will address this later, when it is clearer how modules are going to be marked up.


How does this differ from OSGi?

OSGi does not do this at compile time. Details about which packages are exported and imported are part of the meta information that accompanies the 'code container', typically a standard JAR file with some additional headers in the MANIFEST.MF and collectively called a bundle.

The discussions around JSR 294 seems to be proposing that this module information will be stated in the code itself and statically checked at compile time. When I first read this, I gave out a little sigh, but now I am seeing how important this actually is.

OSGi is effectively oblivious about how you compile and build your bundles so long as the headers correctly define the dependencies. You only need to compile your class with the right classes in the classpath, the compiler does not do any checking about whether you're compiling against the right version or not. (That said, Eclipse PDE can enforce usage of the right package version during the development process, but that is a feature of the tool, not the language.)

For example with OSGi, I decide that I will import a package from a library which I know will be available in my deployment environment. I still need to compile my class against the classes in the package I'll be using so I download a version of that library to compile my class against and then specify in my meta information that I'm importing package com.x.y version 1.2. After installing my bundle in to my OSGi container then starting it I get an error because while the package I depend upon is being exported and my bundle is importing it, I actually compiled my class against the wrong version of the library which contains an extra method not available in my deployment environment.

Of course, realistically I would download the version I expect to be available and specify the verison of the package I want to use explicitly. In OSGi it is possible to import a package and not specify a version, but that can be risky if you are not in full control of your development environment.

Is JSR 294 and OSGi compatible?

Yes, I can't see why not so long as the implementation remains sensible and the language level modularity remains optional, i.e. remaining backwards compatible with the millions of libraries that will not have any idea about JSR 294 modularity.

Additionally, as more and more libraries start implementing JSR 294 modularity, it also acts as an additional safety net for OSGi bundles, ensuring at compile time that they are explicit about their dependencies. However, it will mean that this information is duplicated in the MANIFEST.MF.

One thing that OSGi has, which is not touched on at all by this JSR, is dynamism. However, given the JSR's definition of modularity, I don't see that any discussion on dynamism will have any purpose, but if it crops up, or I have any additional thoughts I'll be sure to address them here.

My Solution

My solution addresses the needs stated by JSR 294 directly.

I would simply add a new keyword which identifies that a class is accessible from it's parent package. Let's face it, developers create package hierarchies to structure their collections of classes, so this isn't such a big leap.

The class visibility keywords we have right now are:

Access Levels
Modifier Class Package Subclass World
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N
Source: http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html

So add an extra column and row to that table:
Access Levels
Modifier Class Package Subclass Parent
Package
World
public Y Y Y Y
Y
xxx
Y
Y
Y
Y
N
protected Y Y Y N
N
no modifier Y Y N N
N
private Y N N N
N

So in my Foo Bar example, Bar's class modifier would be my new keyword (i.e. xxx in the above table). This would protect the class from the rest of the world, but leave it exposed to any class in the parent package or same package, in much the same way as the protected modifier.

I'm sure this solution can be picked apart and I suspect that it comes across as quite naive to think that developers package their classes in the same way, or that a class in a sub-package might not want to access a class in it's parent package, but that isn't really my point. By simply adding this new keyword public can be public and mean it.

You may also note, I don't mention version control, but that's because the JSR doesn't mention it either.

So, perhaps JSR 294 isn't describing modularity at all, but a requirement for a new access modifier. That is, rather than adding a new paradigm ("modularity"), perhaps JSR 294 should look to extend the paradigms that already exist in the Java language, namely access modifiers.

If the JSR is implying more than that, it needs to be clarified or the JSR process needs to be reviewed.