April 23, 2009
A new understanding: XUL and .app
After talking to some guys in the #xulrunner channel on IRC, I foundout that my Mac applications were setup all wrong. At first I was like, why would they do that? But after getting it to work, I figured that it was pure genius! First of all, I was simply copying over my XUL app directly from my Linux box to a Mac, and then running it from Terminal:
//Library/Frameworks/XUL.framework/xulrunner-bin /path/to/app/application.ini
It worked, so I went with it. To install an app, you just add ‘–install-app’ to the end of ‘xulrunner-bin’, and it will stick it into the Applications folder. For some reason or another, Once it was installed, I could run it. But when I tried that same procedure on other machine, it didn’t work. Hmm. After some conversations, and reading, notice and article on MDC on Deploying XULRunner 1.8, and there was my answer.
Basically XULRunner on Mac has a different file structure, which is as follows:
MyApp.app/
- Contents/
- Info.plist
- Frameworks/
- XUL.framework/
- …all the XULRunner files
- Resources/
- application.ini
- icon.icns
- components/
- everything in your normal component directory
- chrome/
- everything in your normal chrome directory
- all your additional files and folders
- MacOS/
- xulrunner (the file copied from the ‘xulrunner’ stub, not the xulrunner-bin)
MyApp.app is actually a directory, with a ‘.app’ extension on it. All it did was create a directory, put all my files in the correct structure, add the ‘Info.plist’ file, and rename the directory with the ‘.app’ extension. The Info.plist file was probably the most complicated to recreate. The example from MDC is not very helpful, especially if you don’t know what your doing, and have to write it by hand. However there is a “Property List Editor” application on Mac, which will help you create the file.

Property List Editor
These are the properties which must be in your Info.plist file, for your XULRunner application to work. Key fields which are important are:
| Executable File | This is the name of the xulrunner stub file in the MacOS directory |
| Icon File | The name of your Icon in the Resources directory |
| Bundle name | Name of the .app directory |
The actually XML file looks like this:
<?xml version=“1.0″ encoding=“UTF-8″?>
<!DOCTYPE plist PUBLIC “-//Apple//DTD PLIST 1.0//EN” “http://www.apple.com/DTDs/PropertyList-1.0.dtd”>
<plist version=“1.0″>
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>XRap</string>
<key>CFBundleGetInfoString</key>
<string>XRap 0.9</string>
<key>CFBundleIconFile</key>
<string>xulwizard-window</string>
<key>CFBundleIdentifier</key>
<string>net.sourceforge.xrap</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>XRap</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.9</string>
<key>CFBundleSignature</key>
<string>Mac</string>
<key>CFBundleVersion</key>
<string>0.9</string>
<key>NSAppleScriptEnabled</key>
<true/>
</dict>
</plist>
Its best to do all your work in your application directory, before adding the .app extension, because then it is treated like a file, and you will be unable to enter the directory, unless you remove the extension.
In refactoring XRap, I was still able to access the directory even though it was a .app. Using nsIFile to add files (the License), and read the application.ini, with no problem. In packaging, using pkg-dmg script, I had to create a staging area (temporary directory) and copy the .app into it, because the script only accepts directories to be imaged. If I tried to image the .app, it would image it as a directory and add .dmg to the end, defeating the purpose.
Well now I am proud to say that Mac packaging is complete. You can now package an application as an dmg image. When a user downloads the image, all they need to do is mount it, and run your app.
I want to eat an apple now.
February 26, 2009
Networking Services…IPv6 and a Corrupt Database
All I wanted to do is install the Peer to Peer Networking Service for Windows XP. A process I have done many times. For some reason I have never installed it on my home computer (which has Windows Media Center Edition 2005), I guess because I usually use that computer to play games, rather than work ( I have a laptop which I use for developing), but have found myself doing more work on it after I got my new 22″ screen.
1st Problem:
I tried to install Peer to Peer Networking Service through the settings: Control Panel->Add or Remove Programs -> Add/Remove Windows Components ->Networking Services-> ‘Click’ Details-> Check off Peer to Peer. I clicked ‘OK’ and it starts installing, only to stop half with the error ‘extended error has occured‘.
Great. There always seems to be a problem when I try to do something simple. So, after doing some research, I learned that Peer to Peer Networking relies upon IPv6, which for some reason I didn’t have installed. Another reason could have been that I exceeded the number of connections, where XP Pro only has 10, and XP Home has 5. But I went with the IPv6 solution, especially since when checked in the Properties of my Network Connection, it did not come up.
Reference: http://www.neowin.net/forum/index.php?showtopic=541890
2nd Problem:
I went into Control Panel -> Network and Internet Connections -> Network Connections ->Right Click on any of the Connections and go to ‘Properties’ -> Click ‘Install’ -> Select ‘Protocol’ -> Click ‘Add’ -> Select ‘IPv6′ -> and Click ‘OK’. It should have installed, but didn’t, once again I got ‘extended error has occured‘.
An easy way to install IPv6 is to open up the Command Prompt and type:
C:\>netsh interface ipv6 install
Unfortunately I got the same error on the Command Prompt as well. Which lead me to believe that at least I was on the right track on finding my error, since the message was the same, maybe a single fix will solve both problems.
Solution:
First to fix the error, open the Command Prompt and enter:
C:\>esentutl /p %windir%\security\Database\secedit.sdb
This will basically open and run a Windows Database Utility program to repair (what seems to be) a Windows security database. What bothers me is that I don’t know how this error happened. The feedback that I got was:
The database is not up-to-date. This operation may find that this database is corrupt because data from the log files has yet to be placed in the database.
Why is it not up-to-date? and why were the log files on placed in the database? It could be from a previous bad shut down, or something. Either way, this opertation will fix the database, but recommend that you run the ‘Recovery’ operation. I did not.
Next rerun the IPv6 command, either from Command Prompt, or from the Network Connection properties. If you run from the Command Prompt, you should get in nice ‘Ok’ when the operation has completed successfully. Finally going back to my original issue, installing the Peer to Peer Networking Service, attempt to install it. In my case success! Worked like a charm.
…now stop EXTENDING MY ERRORS!!!
February 24, 2009
Servlet not found!
I just wasted about 2 hours trying to figure out why my java servet won’t compile. The answer was actually very simple, so I want to save people that time, which I wasted.
The error:
package javax.servlet does not exist
import javax.servlet.*;
^
1 error
This caused about 10 other errors, all related. You must include in the CLASSPATH the .jar file which contains the servlet class. Unfortunately I included the wrong .jar file. I was using the javaee.jar file in ‘C:\Sun\SDK\lib\‘, which while it does have the classes, does not work. I am using a Tomcat server for my servlets, and in the Tomcat installation directory is the d servlet-api.jar, which also contains the servlet classes.
The Answer:
- Open the System Properties (Windows+Break)
- Click the Advanced Tab and open Environment Variables
- Under System Variables, edit the CLASSPATH field
- If there is already data in there then add a ‘;’ at the end of the line and then the location of servlet-api.jar. If you are using Tomcat and used the default installation directory, then you should be entering: C:\Program Files\Apache Software Foundation\Tomcat 6.0\lib\servlet-api.jar;
- Ok all the changes and restart whatever app you are using to compile, so that the new Environment Variables can be loaded.
Here is my reference: http://www.sitepoint.com/article/java-servlets-1/3/
…You’ve been served
November 26, 2008
XUL File I/O: Write Files
Writing files in XUL isn’t that much harder than reading a file, in fact its very similar. What a relief. In my example I am appending the data “Appending Data” to my file.
function writeFile()
{
var data = “Appending Data”;var filePath = “C:\\text.txt”;
var file = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
.createInstance(Components.interfaces.nsIFileOutputStream);
file.initWithPath(filePath);
if ( file.exists() == false ) {
alert(“File does not exist”);
}
foStream.init(file, 0×02 | 0×10, 00666, 0);
foStream.write(data, data.length);
foStream.close();
}
file – gets the nsILocalFile interface component, making file of type nsILocalFile
foStream – gets the nsIFileOutputStream interface component, inherited from nsIOutputStream, making foStream of type nsIFileOutputStream
- init(file, file_io_flags,file_mode_flags, behavior_flags) –
| Option | Type | |
| file | nsIFile | |
| File_io_flags | 0×01 | Read only |
| 0×02 | Write only | |
|
0×04 |
Read and Write | |
| 0×08 | Create File | |
| 0×10 | Append | |
| 0×20 | Truncate | |
| 0×40 | Sync | |
| 0×80 | Exclude | |
| File_mode_flags | 00400 | Read by owner |
| 00200 | Write by owner | |
| 00100 | Execute by owner | |
| 00040 | Read by Group | |
| 00020 | Write by Group | |
| 00010 | Execute by Group | |
| 00004 | Read by Others | |
| 00002 | Write by Others | |
| 00001 | Execute by Others | |
| * Mode flags can by added to combine flag * File_mode_flags is only applicable to UNIX based systems |
||
| Behavour_flags | 0 | Default |
write(data, count) – sends the data string parameter to the output stream buffer, and writes the number of bytes according to count
close() – closes the stream
Not too difficult, but it is sure difficult to find the instructions and documentation
November 25, 2008
How-to: Read Files in XUL
After some weeks of procrastination and going nuts over other projects, I’m getting back to XUL and my XRap program. I’ve been asked to change my current XRap code (currently the 0.1 is in C#) to XUL, which would increase its portability, and it just makes sense to make a XULRunner Packager in XUL. Unfortunately, I must undertake the task of learning how to program in XUL and JavaScript. So I’ve managed to complete most of my other programming courses, so now I can focus on this. One of my main problems was that I had no idea of how the JavaScript file was linked to the XUL file, and how it would know where to pass output, or where to get output. My second major problem was that I couldn’t find any help on how to access the file system using JavaScript.
After a quick chat on IRC, a colleague directed me to the File I/O site on the Mozilla Developer Network. I found it to be only somewhat useful, but even more so when you take a look at the ‘Read local files and write local files’ page at Captain’s Universe. Combining the two I’ve managed to come up with this function in my .js file:
function getFile()
{
var dup = document.getElementById(‘tb_input’);var file = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);var fstream = Components.classes["@mozilla.org/network/file-input-stream;1"]
.createInstance(Components.interfaces.nsIFileInputStream);
var sstream = Components.classes["@mozilla.org/scriptableinputstream;1"]
.createInstance(Components.interfaces.nsIScriptableInputStream);file.initWithPath(filePath);
if ( file.exists() == false ) {
dup.value = “File does not exist”;
}fstream.init(file, 0×01, 00004, null);
sstream.init(fstream);var output = sstream.read(sstream.available());
dup.value = output;
sstream.close();
fstream.close();
}
file – gets the nsILocalFile interface component, making file of type nsILocalFile
filepath – use the absolute path, and the double backslash to avoid the escape character.
file – gets the nsILocalFile interface component, making file of type nsILocalFile inherited from nsIFile
- initWithPath(filepath) – takes in the file path, and initializes it
- exists() – checks if there is a valid file associated with file
fstream – gets the nsIFileInputStream Interface component, making fStream of type nsIFileInputStream
- init(file, file_io_flags,file_mode_flags, behavior_flags) –
| Option | Type | |
| file | nsIFile | |
| File_io_flags | 0×01 | Read only |
| 0×02 | Write only | |
|
0×04 |
Read and Write | |
| 0×08 | Create File | |
| 0×10 | Append | |
| 0×20 | Truncate | |
| 0×40 | Sync | |
| 0×80 | Exclude | |
| File_mode_flags | 00400 | Read by owner |
| 00200 | Write by owner | |
| 00100 | Execute by owner | |
| 00040 | Read by Group | |
| 00020 | Write by Group | |
| 00010 | Execute by Group | |
| 00004 | Read by Others | |
| 00002 | Write by Others | |
| 00001 | Execute by Others | |
| * Mode flags can by added to combine flag * File_mode_flags is only applicable to UNIX based systems |
||
| Behavour_flags | 0 | Default |
sstream – gets the nsIScriptableInputStream interface component, making sStream of type nsIScriptableInput Stream
- init(nsIFileInputStream) – initializes the file input stream
- read(int32 count) – reads the count bytes in the stream
- available() – returns the number of bytes in the stream
Well, it actually didn’t give me as much of a headache that I thought it might have. It is just a matter of thinking like a Mozilla/JavaScript person, and knowing what the interfaces can do. Next up Writing Files…
November 5, 2008
Installing PHPUnit on Ubuntu 8.04
- You need to get the latest release of PHP
$sudo apt-get install php5
- To get PHPUnit you need to get the PEAR installer, which is part of PHP
$sudo apt-get install php-pear
- Once you have PEAR installed you must register the PEAR channel with the PEAR environment
$sudo pear channel-discover pear.phpunit.de
- The and the last step is to get and install PHPUnit
$sudo pear install phpunit/PHPUnit
Good luck!
Installing WAMP and PHPUnit on Windows
- Download and Install WAMP
- Once you have installed and setup WAMP, open up the command prompt and go to your php directory in WAMP
C:\>cd wamp\bin\php\php5.2.5
- From here you must run the go-pear.bat file to install PEAR and all the files needed for it
C:\wamp\bin\php\php5.2.5>go-pear.bat
- When executed PEAR will ask you a series of question to set itself up correctly, if you don’t know what your doing then just accept the defaults
- Once installed you must run the PEAR_ENV.reg which will create the environment variables for the user, so that PEAR can be called in any directory on the command line>
C:\wamp\bin\php\php5.2.5>PEAR_ENV.reg
For me, it seemed to work no problem, but if you cannot call PEAR from the command prompt, then you must manually add the directory to the path in the Environment Variables list, found in System Properties -> Advanced-> Environment Variables, then add the directory C:\wamp\bin\php\php5.2.5 to the PATH variable
- Once you have PEAR setup, then you must register the PHPUnit channel with PEAR
C:\wamp\bin\php\php5.2.5>pear channel-discover pear.phpunit.de
- Now you can use the PEAR to install packages from the PHPUnit channel
C:\wamp\bin\php\php5.2.5>pear install phpunit/PHPUnit
- You should now find the PHPUnit source files under the PHP directory
…Happy Days
October 23, 2008
XML Listing of File System
One of the challenges of automatically preparing a wxs (which is in xml) file for WiX to process into an msi file for installation, was creating a recursive algorithm to read a target directory an get all sub-directories and corresponding files. The problem I was having, was that I could get all directories and files, but I couldn’t add them to the wxs file with the depth which they came out.
Finally, after much experimenting and searching around, I found a project by Damian Castroviejo, which was written in VB, but exactly what I was looking for. Here is my interpretation on it:
| public class loopDirectoryNodes { public void getDirNodes(XmlDocument xmlDoc, XmlElement xe, String path) { foreach (String dir in Directory.GetDirectories(path)) { XmlElement dirChild = xmlDoc.CreateElement(“Directory”); dirChild.SetAttribute(“Name”, dir); Console.WriteLine(“Adding Directory: ” + dir); xe.AppendChild(dirChild); foreach (String fileName in Directory.GetFiles(dir, “*.*”)) { XmlElement xeCom = xmlDoc.CreateElement(“Component”); xeCom.SetAttribute(“Guid”, Guid.NewGuid().ToString().ToUpper()); XmlElement xeFile = xmlDoc.CreateElement(“File”); xeFile.SetAttribute(“Id”, fileName); xeFile.SetAttribute(“Name”, fileName); xeFile.SetAttribute(“DiskId”, “1″); xeFile.SetAttribute(“Source”, fileName); xeFile.SetAttribute(“Vital”, “yes”); dirChild.AppendChild(xeCom); xeCom.AppendChild(xeFile); Console.WriteLine(“Adding File: ” + fileName); } getDirNodes(xmlDoc, dirChild, dir); } } } |
The parameters passed to the method getDirNodes, are the xmlDoc which is the XML document which the nodes will be added to, xe is the XML Element which is the node you want the directories to be added to, and path is the Directory which you wish you map the sub-directories and files.
The first foreach statement will loop through the Directory passed to find all sub-directories and add each of them to the xe XML Element passed in the parameter, while the second foreach will loop through each of those sub-directories found, and add the files within them to the sub-directory node being searched. Once all the file for the sub-directory are found (if any), the method calls itself, passing the same XML Document xmlDoc, but with the XML Element of the sub-directory just searched and it path, to search that sub-directory for any other directories within.
Once all sub-directories of a folder are found, the method returns to where it was called in itself, and continues on to the next directory, until all directories are found. Genius, thanks Damian, you helped me a lot!
September 23, 2008
Blackberry Pearl Trackball Stopped Working!
I am the owner of the Blackberry Pearl, and I must admit like many other Blackberry owners that I know, IT IS VERY ADDICTIVE! I actually got it about a year ago, I’ve had a few cases for it, one of which was the glove which it slides into, that was annoying because I would always forget to put it back in after a call, and then I lost it. The second was the belt holster, which I could definitely feel when I was getting a call rather than when it was in my pocket, and it was easier to put away after a call, but I felt like an idiot walking around with this thing sticking out of the side my body, and I would usually get in the way of what I was doing (I know I am picky). So forget the cases, I just left it in my pocket.
Unfortunately for me, with my dirty pockets and a blackberry with no warranty, one day while I am going through my calendar, my trackball stopped moving to the right! I tried pushing down hard and moving the ball, I tried moving it softly, I even tried blowing it with compressed air, but the most I would get is two or three icons to the right. I was able to live with it for a few weeks, by just dialing numbers, but after a while I was fed up and just had to fix it. After looking at the unit a little more, and playing with the trackball some more, I realized the trackball can easily be compared to those old computer mice that used a ball to move the cursor. I had one, and it stopped working as well, I had to take out the ball and clean the mechanisms on the inside to get it working again, but I never really knew how it got so dirty. Anyway, I figured it needed a good and proper cleaning, here’s what I did:
*** I DO NOT TAKE RESPONSIBILITY FOR ANY DAMAGES DONE TO YOUR DEVICE
***ANYTHING YOU DO TO YOUR BLACKBERRY, DO AT YOUR OWN RISK!
Tools required: Small flat-head screwdriver, a pin, and a cotton swab with alcohol
1. Power Off
Turn off the power of your Blackberry device, by holding down the red ‘End Call’ key on the keypad for a few seconds.
2. Removing the Silver Ring
Around the trackball is a silver plastic ring, which is held in place by clips on the left, right and bottom of the ring. By placing the screwdriver or your fingernail in the bottom left corner on the outside of the plastic ring, and pulling the ring up, you should easily get the clip on the left and the bottom out. The clip on the right might be a bit hard, you need just to pull it up carefully, trying not to bend or break the clip.
3. Taking out the trackball unit
Once the clip is out simply turning your Blackberry upside down and shaking a little should pop out the trackball unit. Make sure your hand is there to catch it!
4. Opening the trackball unit
First take note on the bottom of the unit the silver lead going down from the middle, it is important, I will keep the metal lead pointing down throughout the rest of the steps. ***The metal ring keeping the unit together is very brittle, if you bend it too much it WILL BREAK!*** Using a pin or screwdriver, on the left and right side of the unit, lift the metal down and out of the clip keeping it in place. On the top and bottom of the unit the metal ring is held in place by a butterfly clip wrapping around the plastic, using the pin or screwdriver pull the metal out and down. Without taking off the metal, the plastic top should come off, which would expose the ball and tracking wheels.
5. Cleaning
Remove the plastic top keeping everything in place, and take note of the position of the tracking wheels, the bottom wheel should have the black piece on the left, the left wheel should have the black piece on the top, the top wheel should have the black piece on the right, and the right wheel should have the black piece on the bottom. Using your swab with alcohol, clean off all the dirt from each tracking wheel, which can come out very easily, that’s why it is important to know how they go back in. Make sure you clean all around each of the tracking wheels.
6. Putting it back together
With all the tracking wheels in place, put the plastic cover back on, and reattach the metal to each clip. Make sure the metal butterfly clip is around the plastic cover on the top and bottom, and the plastic is through the metal opening on the left and right. With the unit securely closed, turn it over so the ball is on top with the metal lead still pointing down on the bottom; place it back in your Blackberry. Clip the plastic silver ring back in, with the leads on the left, bottom and right. Turn on your Blackberry and test it out!
Approximate time: 15 minutes
Should you break, loose, or find that some part is unusable, replacement parts can be located at BBRepairShop, they ship around the world.








