This blog isn't maintained anymore. Check out my current project, an agile/scrum management tool.

Sunday, September 30, 2007

MAX - D1

Day 1 of Adobe MAX... liking it so far, I think tomorrow is going to be amazing :)

I scored a new laptop bag, the old one I have from WWDC 2001 is really starting to fall apart. I need to make sure to hit a conference giving away bags at least once every 3 years :)

Friday, September 28, 2007

Modal dialog blur

I usually want to turn off the modal dialog blur in applications but can never remember how. This blog post is here so I can find it quickly next time.

Set this style:

Application {
modalTransparencyBlur: 0;
modalTransparencyDuration: 0;
modalTransparency: 0;
}

Labels:

Thursday, September 27, 2007

Red5, 1&1, and epoll

If you're trying to run red5 on a 1&1 managed server, you have to turn epoll support off because their linux distribution chokes on it. To do that, add this command paramater:

-Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.PollSelectorProvider


The error looks something like this:

Exception in thread "main" java.lang.InternalError: unable to get address of epoll functions, pre-2.6 kernel?
at sun.nio.ch.EPollArrayWrapper
.init(Native Method)
at sun.nio.ch.EPollArrayWrapper.(EPollArrayWrapper.java:227)
at sun.nio.ch.EPollSelectorImpl.( EPollSelectorImpl.java:52)
at sun.nio.ch.EPollSelectorProvider.openSelector(EPollSelectorProvider.java:18)
at java.nio.channels.Selector.open(Selector.java:209)
at org.apache.mina.transport.socket.nio.SocketAcceptor.startupWorker (SocketAcceptor.java:162)
at org.apache.mina.transport.socket.nio.SocketAcceptor.bind(SocketAcceptor.java:141)
at org.apache.mina.common.support.BaseIoAcceptor.bind(BaseIoAcceptor.java:42)
at org.red5.server.net.rtmp.RTMPMinaTransport.start(RTMPMinaTransport.java:218)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java :39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod (AbstractAutowireCapableBeanFactory.java:1240)

Labels:

Wednesday, September 26, 2007

AMFPhp -> RED5

Last night I finished translating all my web services from AMFPhp to Red5. Assuming my web-host problems are sorted out by the weekend I'll be switching the beta version of AgileAgenda to that.

I've found huge benefits in converting including:
  • Everything now has unit tests using JUnit. You can do unit testing with PHP, but it's way easier in Java.
  • JDT (Eclipse Java Development Tool) is the best development environment I've ever used.
  • Debugger! I can now attach a debugger to the server to see why things don't work right.
  • Logging - I used all the cool Log4j stuff, so I'll have as much detail in my logs as I want.
  • Spring is awesome.
  • Now I have a platform to extend for realtime messaging. I'll be able to push schedule changes to clients instead of relying on a polling mechanism.

Tuesday, September 25, 2007

DataGrid can go DIAF

(That's "Die in a fire" for those of you not hip to texting lingo and don't have a little sister to help make you hip)


Making the DataGrid do things it's not meant to do is amazingly hard. Look at this gem that's found in the itemEditorItemEditEndHandler method:

if (event.reason == DataGridEventReason.OTHER || !event.isDefaultPrevented())
{
destroyItemEditor();
}

If the event is canceled it goes ahead and destroys your item renderer.

So if you want to say, NOT end editing and you cancel the event, it goes ahead and kills your editor anyways.

No problem... we could just override the method and fix it. Except someone on the 2.0 SDK team got private method happy with that one.

Are there any good DataGrid alternatives out there? Especially for mimicking spreadsheet functionality where you're adding and removing rows dynamically through user input?

Labels: ,

1&1 Internet woes

I've been a 1&1 (www.1and1.com) customer for a few years now on their shared hosting plan.

On Saturday I ordered an upgrade of my website hosting package because I'll be showing off one of my projects to a largish group of people next Monday and want to make sure the performance is there.

They said it'd take 6 hours to complete.

6 hours later I emailed to find out the status and was told 24-48 hours. Ouch. But no problem, that gives me plenty of time to set things up.

Now, it's Tuesday and no upgrade. Every time I inquire to an update I get a response of "It's in process and we'll let you know when it's ready". Apparently, they can't even give me an estimate anymore.

If my site isn't migrated by tomorrow I'm going to have to find a new webhost in order to get things set up and let DNS propogate in time for Monday. Any favorites for a cheap ($100 a month ish) dedicated hosting solution with decent bandwidth and uptime ratings?

Sunday, September 23, 2007

My first Red5 experience

I've worked with both Chris Allen and John Grden on some projects for my employer. During that time, I can't count the number of times I heard about Red5, but I never got a chance to try it out.

This past week I caught Chris' "Building Red5 Applications" session at FlashForward. I finally got up the motivation to download and try it out.

Here's my experience. It's my first time playing with Red5 (but I have plenty of java & eclipse experience) so it's almost guaranteed I'm not doing everything the "right way". But this way worked for me, maybe it'll help someone else. If it does help you, please leave a comment. Writing this up takes a while and I'm not going to bother in the future for other things if nobody gets value out of it.


Attempt #1

I wanted to try out the .tar.gz package so I would know how to deal with it on Linux as well as Windows. That way I'd be able to deploy anything I built on my webhost fairly easily.

I unpacked it, ran ant, and let it all build. So far so good.

Then I ran the red5.bat file. Lots of exceptions. Like millions, maybe billions, I lost track. Seems my sample applications weren't found. I poked around a bit, but no good. Screw this.

Attempt #2
I went for the windows installation package. That unpacked everything and the server ran fine. I could open up a web browser to http://localhost:5080/ and view the demos, admin panel, etc.

Note: The default admin username/password is admin/admin. You can change that in conf/tomcat-users.xml I'd suggest changing it.

Eclipse

So now I want to get it rocking with eclipse. I launch eclipse (I'm lazy and like things easy so I use easy eclipse.)

I select File->Import->Existing project, then pick my Red5 project. Bamn, I got an eclipse project set up.

But there's compile errors.

Severity and Description Path Resource Location Creation Time Id
Project red5_server is missing required source folder: 'test' red5_server Build path 1190574481375 173990
The project cannot be built until build path errors are resolved red5_server Unknown 1190574530687 173992


So I closed the red5 eclipse project, fired up a text editor, and looked in my .classpath file inside the red5 folder. It had the offending entry.

<classpathentry kind="src" path="test"/>

Note... I delete this line later on:
<classpathentry kind="con" path="org.jayasoft.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/ivy.xml/test,"/>
You might as well do it now since you're in there.



So I removed it, and repopened eclipse.

A quick Project->Clean and...
3656 Errors

Ok, seems it doesn't see some libraries. Right click on my project, select properties. Go into "Java Build Path", select the "Libraries" tab, click the "Add Jars..." button, and add all of the .jar files in the lib directory.

A quick Project->Clean and...
0 Errors

WOOT

Running it from Eclipse

Now I go into src/org/red5/server, find the StandAlone.java, right click it, and select "Run as..."->"Java Application".

I check my eclipse console panel and get a bunch of lines the last one being:

[INFO] 2007-09-23 15:14:20,875 main:( org.red5.server.Standalone.main ) Startup done in: 5875 ms

Nice.

I point a web browser at: http://localhost:5080/ and see that the red5 server is indeed running. I launch the ball demo and push the connect button. Then I make a new browser window and launch the demo again. When I move the red5 logo in one window, it moves in the other. That means it's all working.

Eclipse also helpfully added an entry to my run button (the green circle with the play button) in my toolbar so I don't have to find the StandAlone.java file again.

I want a quick launch button for debugging too, so I kill the server (click the red square on the console panel) and right click the StandAlone.java and select "Debug as java application". The server starts in debug mode, and eclipse adds it to my debug button on the toolbar. (the green beetle button)

Making something

Now, I want to make something. But first, I want to get rid of the samples. So I kill the server, close the eclipse project, and edit the .classpath file again. I know there's a way to do this through eclipse, but I find editing the file quicker.

I get rid of these entries:
<classpathentry excluding=".svn/*" kind="src" path="webapps/echo/WEB-INF/src"/>
<classpathentry excluding=".svn/*" kind="src" path="webapps/tutorial/WEB-INF/src"/>
<classpathentry excluding=".svn/*" kind="src" path="webapps/fitcDemo/WEB-INF/src"/>
<classpathentry excluding=".svn/*" kind="src" path="webapps/oflaDemo/WEB-INF/src"/>
<classpathentry excluding=".svn/*" kind="src" path="conf"/>
<classpathentry excluding=".svn/*" kind="src" path="webapps/test/WEB-INF/src"/>
<classpathentry excluding=".svn/*" kind="src" path="webapps/midiDemo/WEB-INF/src"/>
<classpathentry excluding=".svn/*" kind="src" path="webapps/agile/WEB-INF/src"/>

And I add one for my project, I'm going to work on something for AgileAgenda, so I'll call it agile.

<classpathentry excluding=".svn/*" kind="src" path="webapps/agile/WEB-INF/src"/>

Then I go rename the "echo" example to "agile", and delete all the other samples (I deleted admin too, not sure if that was a good idea or not)

Open up the project in Eclipse again.

And I don't see my agile webapp. WTF? Oh yeah... Eclipse is retarded. Right Click->Refresh and it shows up.

I want to rename the Application class in my webapps folder (see the picture).



Luckily, Eclipse rocks Java more than it rocks Flex, so I can just right click, select refactor, and pick move. Then I click "Create Package" enter in com.agileagenda.services and click ok a bunch of times.



I delete the rest of the webapp echo source tree.

A project->Clean and...



I think I broke something. Oh well.

Project->Properties->Builders and remove the invalid entry.



Project->Clean and build successful.

I hit the debug button, and search the console output. No errors reported and:

[INFO] 2007-09-23 15:44:45,375 main:( /agile.invoke0 ) Initializing Spring root WebApplicationContext

So I guess it found my new app. Yay!

Kill the server.

So I go back to my Application class and make a new method.

public function login(username:String, password:String) : Boolean
{
return true;
}

Then I remember that this is Java and not Actionscript so I rewrite it...

public boolean login(String username, String password)
{
return true;
}

I go to my project menu and turn on "Build Automatically" and get...

Severity and Description Path Resource Location Creation Time Id
Unbound classpath container: 'org.jayasoft.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/ivy.xml/test,' in project red5_server red5_server Build path 1190576857156 182811


WTF?

Close the project, open my .classpath file, remove the offending line:
<classpathentry kind="con" path="org.jayasoft.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/ivy.xml/test,"/>

Open the project, Project->Clean, build success.

I have no idea why that didn't bite me earlier.

I press the debug button. The red5 server launches.
[INFO] 2007-09-23 15:51:26,062 main:( org.red5.server.Standalone.main ) Startup done in: 4937 ms

Yay.

Writing some actionscript

Now that I have a (dumb) login method, I want to try it out in Flex.

I have a "Sandbox" AIR application set up in Eclipse that I use when I want to quickly play with something. I highly suggest everyone do that. So I open my sandbox, open the MXML and create a quick login form.

<mx:Label x="26" y="43" text="Username:"/>
<mx:TextInput x="101" y="41" id="txtUsername"/>
<mx:TextInput x="101" y="71" id="txtPassword" displayAsPassword="true"/>
<mx:Label x="26" y="73" text="Password"/>
<mx:Button x="196" y="101" label="Login" click="onLoginClick()"/>
<mx:Label x="58" y="148" text="Label" id="lblResult" width="281"/>

And then add in some code (remembering that this is Actionscript!)...

private var netConn:NetConnection;

protected function onLoginClick() : void

{
NetConnection.defaultObjectEncoding = flash.net.ObjectEncoding.AMF0;
SharedObject.defaultObjectEncoding = flash.net.ObjectEncoding.AMF0;

netConn = new NetConnection();
netConn.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus );
netConn.addEventListener( SecurityErrorEvent.SECURITY_ERROR, errorHandler );
netConn.addEventListener( AsyncErrorEvent.ASYNC_ERROR, errorHandler );
netConn.addEventListener( IOErrorEvent.IO_ERROR, errorHandler );

netConn.connect("rtmp://localhost/agile");

}

protected function sendLogin() : void
{
var responder:Responder = new Responder( onLoginResult );
netConn.call("login",responder,txtUsername.text, txtPassword.text);
}

protected function onLoginResult( result:Boolean ) : void
{
lblResult.text = result ? "Login Success!" : "Login Fail!?!";
}

protected function onNetStatus(event:NetStatusEvent) : void
{
switch( event.info.code )
{
case "NetConnection.Connect.Success":
lblResult.text = "Connected, sending login";
sendLogin();
break;

default:
lblResult.text = "ERROR!! " + event.toString();
break;
}

}

protected function errorHandler(event:Event) : void
{
lblResult.text = "ERROR! " + event.toString();
}


I start the server, run my sandbox app, click the login button, and get a connection error. Something went wrong somewhere.

I bet it's a configuration problem. I open webapps/agile/WEB-INF and notice 3 config files.

in web.xml I make this change:

<context-param>
<param-name>webAppRootKey</param-name>
<param-value>/agile</param-value>
</context-param>

In red5-web.xml I make this change:

<bean id="web.handler"
class="com.agileagenda.services.Application"
singleton="true" />

In red5-web.properties, I make this change:

webapp.contextPath=/agile

Kill the server, restart it (debug mode), try my app again. "Login Sucess" YES!

Now I head into the java class and put a breakpoint on the "return true;" line. I hit the button on my AIR app and Eclipse correctly breaks on the line. Yay!

I inspect the username and password parameters, and the values I had filled into the AIR app are present. Yay!

I'm now to the point where I can start actually writing my application.


Labels: , , ,

Saturday, September 22, 2007

Moving to a new webhost

I'm moving all of my websites to a new web host, so they'll be unavailable for a bit. Hopefully they'll be a lot faster after the switch.

Sunday, September 16, 2007

Developer interface to schedules

I've been working on a project scheduling application, and have a sneak peek at a new feature.

Wouldn't it be great if every developer on your team could go in to the schedule and update the tasks they're responsible for? They could mark them complete when they finish them, suggest new estimates, or make comments. Or even just to look at the latest set of tasks they have.

But doesn't it suck to have to worry about developers mucking around in your precisely laid out schedule?

Now, there's a developer interface that lets them subscribe to your schedule, and then update and comment on tasks with a simplified user interface.

Using the interface, they can subscribe to multiple schedules using a special key you can generate from the AgileAgenda main interface.



Then they can synchronize their view with the network version and take a local copy with them.




Right now, it's read-only, but I'll be adding all that 2-way stuff soon. And don't worry, any changes made through the dev interface will have to be approved by the project manager in the main AgileAgenda interface.

I'll have to slap on a slick interface at some point as well.

Labels:

Thursday, September 13, 2007

Upcoming conferences

I'll be at FlashForward in Boston next week and most likely will be at Adobe MAX in Chicago on the 30th. If anyone else is planning on being there and is interested in meeting for a bit, let me know.

Tuesday, September 11, 2007

What's the right amount of copy protection?

I'm currently working on a piece of commercial software that will be available through a download and will use a license key to activate it. The software is aimed at helping people schedule projects and will be targeted mostly to corporate users.

With the recent Windows Vista black screen of death, it got me thinking about what sort of measures I should go through to prevent unauthorized users from using the software.

While I don't wish to burden legitimate users, I do want to prevent most piracy. How much copy protection is appropriate?

Is it acceptable for the software to phone home? If so, what data is appropriate to report on? The license key? Software version? What about a unique installation ID?

Should I disable license keys for small amounts of piracy, like when there's 3 active installations of the software? What about widespread piracy where we detect dozens or hundreds of uses of the same license key? Would a simple message stating the software may be pirated with instructions on how to purchase a valid license be sufficient?

As a more general question, what licensing schemes have you seen that work the best?

Labels: ,

Monday, September 10, 2007

New tutorials

There's a new AgileAgenda tutorial showing off the basic functionality of the software. See it at this url:

http://www.agileagenda.com/help/createproject.html

You can view the previous tutorial on the light table at:

http://www.agileagenda.com/help/lighttable.html

Labels:

AIR + Flash Player Beta = bad?

After installing the 9.0r60 beta from Adobe Labs, I can't seem to install an AIR application I've been working on. I get the error message

"This application could not be installed or launched"

This is on a Windows XP machine running Firefox.

I'll have to investigate further, but was wondering if anyone else has run into the same problem? Perhaps I need new installation badge code or something.

Thursday, September 06, 2007

AgileAgenda Light Table

The latest feature to AgileAgenda is the "Light Table", where you can drag your tasks around to modify their priority, who they're assigned to, and the estimated duration. I think this feature has the possibility to be a huge help to some people.

Take a look at a short video showing it.

Labels:

Flex SDK nightly builds

Just read about Flex having nightly builds available of the SDK at these url's

http://labs.adobe.com/technologies/flex/sdk/flex2sdk.html
http://labs.adobe.com/technologies/flex/sdk/flex3sdk.html

Nice.


(Blogging so I can find them later)

Labels: ,

Wednesday, September 05, 2007

AirDerbyEntries++

Last night I submitted agile agenda for the AIR derby. I wasn't going to originally since I didn't think I had a chance in hell, but then I got thinking. Even making some kind of entry-list might generate some good publicity. With beta starting within the next week or two, I could use a little press.

Labels: , ,

Monday, September 03, 2007

AgileAgenda facelift progress

I've been feverishly working on some of the UI elements of AgileAgends that have been sorely lacking in recent revisions. I've gotten a lot closer to something I'm proud to admit to doing. Here's a couple screenshots.







Go see a full listing of screenshots.


Also, we're still accepting beta apps...

Labels: , ,