2010
December 4, 2010
Excluding directories from ZIP and TAR archive
I’ve been using command line for zipping and ‘tarring’ for a while and never really needed to exclude directories from the archive.
I had to do this today and I worked out that I had to use absolute paths to achieve this.
The following examples will exclude multiple directories from tar and zip archives respectively:tar -cvf documents.tar.gz /home/user/Documents --exclude "/home/user/Documents/exclude1" --exclude "/home/user/Documents/exclude2" zip -vr -9 documents.zip /home/user/Documents -x "/home/user/Documents/exclude1" -x "/home/user/Documents/exclude2"
Marko
TopOctober 5, 2010
Load kernel and boot your system with GRUB2
I installed a new verison of Ubuntu Lucid Lynx the other day on a brand new formatted hard drive. Installation went smoothly as you’d expect, but when I rebooted the server I was stuck on GRUB menu (my worst nightmare). The server just wouldn’t load the operating system and typing ‘boot’ in GRUB gave me a No Loded Kernel error.
I tried re-installing, re-formating, various GRUB commands and nothing worked. Thankfully, I found a solution on a lengthy GRUB2 documentation page. In summary, I had to tell GRUB to boot from the most recent kernel and this is the way to do it:
set root=(hdX,Y) linux /vmlinuz root=/dev/sdXY ro initrd /initrd.img boot
Remember to specify correct X,Y values. For example, GRUB counts the first hard drive as 0, the first partition as 1. If your Ubuntu system is on sda1, enter set root=(hd0,1). You can list your partitions in GRUB2 using “ls” command.
Marko
TopSeptember 30, 2010
Monitor Railo on Tomcat using JConsole
At Learnosity, I’ve been trying to get to the bottom of a “Java Heap Space” error on my local Railo installation and decided to use JConsole to monitor Tomcat server. JConsole is a very useful Java application monitoring tool, which is bundled into every JRE. You can run it by simply executing jconsole binary:
$JAVA_HOME/bin/jconsole
Where $JAVA_HOME is the path to your Java installation.
By default, JConsole picks up all local Java processes, which you can monitor individually. Unfortunately, Tomcat doesn’t seem to be listed under local processes and I had to use remote connection instead. The way to connect to Tomcat with JConsole is a little tricky and this is what you need to do:
You need to tell Tomcat to accept clients on TCP port 8999, on the host “localhost”, without authentication.
DO NOT disable remote authentication in production environment. It should only be done for testing purposes in development/staging environments. closeTo translate this into code, set CATALINA_HOME environment variable to this:
$CATALINA_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=localhost"; $ export CATALINA_OPTS;
(Re)start Tomcat and you should now be able to monitor it on localhost:8999
Top
Here are some JConsole screen shots:


References:
Monitoring Tomcat with JMX
Using JConsole to Monitor ApplicationsSeptember 21, 2010
Create iPhone ringtone from iTunes library
Have you ever listened to a tune and said, man I wish I had that ringtone! If you have an iPhone and iTunes, you can convert your iTunes track into a ringtone very easily. This will probably work with other handsets too, but I have an iPhone and I know it works well with it.
The steps are:
1) Locate your song in iTunes and right-click on it.
2) Figure out what part of song you’d like to convert to your ringtone. E.g from 0:10 to 0:25. (from 10th second to 25th second).
3) Right-click on your chosen song and select “Get Info”. Then click the “Options” tab
4) This is where you specify part of the song you’d like to convert to ringtone by setting the Start Time and Stop Time. Set your values in “minute:seconds” format. You can also fine tune your values by adding milliseconds after your seconds, e.g “1:25.350″ (1 minute, 25 seconds and 350 milliseconds). Keep in mind that ringtones cannot exceed around 39 seconds in length. Press “OK” and you’re almost there.

5) Right click on the same song again and click “Create AAC Version”. This will create your shortened version of the song and add it to iTunes.
6) Locate your newly created file in iTunes, right-click on it and select “Show In Finder” on a Mac, or “Open in Windows Explorer” on Windows.
7) In your Win Explorer or Finder you’ll notice that the file has a .m4a extension. Rename the file to have .m4r extension.
Now delete your new file from iTunes, but leave it on your filesystem. Double click the .m4r file and it will get imported into your ringtones in iTunes.9) To load the ringtone into your iPhone, simply sync your phone with iTunes. Once the sync is complete, go to “Settings” in your iPhone, and then go to “Sounds” and “Ringtone”. Your new ringtone should be listed under “Custom” ringtones.
My first custom ringtone is Carousel by Mr Bungle from 0.09.25 to 0:23.15 and it’s a little beauty. What’s yours?
Have fun
Top
Marko
In one of my earlier posts Flex and Red5 simple demo, I demonstrated how to broadcast messages from Red5 server to all subscribed Flash clients and vice versa. This feature of Red5 open source Flash streaming server continues to impress me and I think everyone with a bit of AS3 and Java knowledge should take advantage of this fantastic piece of technology.
In this post I’d like to explain the code that’s required to exchange messages between Red5 and Flash/Flex client. There are 2 main components that make this happen:
1. Client-side code – AS3
2. Server-side code – JavaBefore I write any code, let’s assume the following:
1. My Red5 application name is “callMe”.
2. Red5 server runs on localhost or 127.0.0.1
3. My Flex main class is TestAS.asClient-Side – Flex/AS3
Now let’s do the following:
1. Connect to Red5 server
2. Set up a client class to accept broadcast messages from Red5
3. Call helloRed() method on Red5 that will return “Hello from Red5” back to Flex.public class TestAS extends Sprite { private var _nc:NetConnection; public function TestAS() { this._nc = new NetConnection(); this._nc.client = new Red5Client(); this._nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler); var nr:Responder = new Responder(responseHandler,null); this._nc.connect("rtmp://127.0.0.1/callMe"); this._nc.call("helloRed", nr); } private function netStatusHandler(e:NetStatusEvent) : void { if(e.info.code == "NetConnection.Connect.Success") { trace("Connection Successfull!") } private function responseHandler(responder:String) : void { trace("Responder says:: " + responder); //Responder should be 'Hello from Red5' } }
Red5Client.as will have a public method updateSubscribers(), which will accept broadcast messages containing the total number of subscribers from Red5 server.
public class Red5Client { public function updateSubscribers(connections:int):void { trace("Number of connections:: " +connections); } }
That’s it for client side!
Server-Side – Red5/Java
The beauty of Red5 is that it’s open source and you can easily extend it’s default functionality. Since the server is built on Java platform, you can do some very powerful things with it. All you need is a bit of imagination

Now, let’s write our custom Red5 application that will extend the default ApplicationAdapter class.public class Application extends ApplicationAdapter { private int _connections = 0; // public method called from Flex, remember? public String helloRed() { String myString = "Hello from Red5"; return myString; } public boolean appJoin(IClient client, IScope app) { // increase the number of connections whenever someone connects to the app this._connections ++; notifyAllClients(); return true; } public void appLeave(IClient client, IScope app) { //decrease number of connections whenever someone disconnects from the app if(this._connections > 0) { this._connections --; } notifyAllClients(); } /** * Invoke a method on all connections to a given scope. */ private void notifyAllClients() { IScope scope = Red5.getConnectionLocal().getScope(); // method to invoke on the client side. String method = "updateSubscribers"; Object[] params = new Object[] {this._connections}; List connections = new ArrayList(); Iterator iter = scope.getConnections(); while (iter.hasNext()) connections.add(iter.next()); for (IConnection conn: connections) //Notify all clients of connection change notifyClient(conn, method, params); // finally notify local client IConnection localConn = Red5.getConnectionLocal(); notifyClient(localConn, method, params); } private void notifyClient(IConnection conn, String method, Object[] params) { if (conn instanceof IServiceCapableConnection) { ((IServiceCapableConnection) conn).invoke(method, params); } } }
Compile your Application and copy the class into your Red5 application:
webapps/callMe/WEB-INF/classes/…./Application.class
The final step is to tell your Red5 server about your custom Application bean. At the bottom of your web.xml add this (pay attention to your class paths):<bean id="web.handler" class="com.mysite.red5.Application" />
That’s it for server-side!
Once again, here is the working example. Access this page with 2 or more browser windows and observe the number displayed in the middle.
Top
{swf}Red5Test|100|100{/swf} You also might find the following resources useful:
1. Red5 Server Documentation
2. Red5 User Reference ManualJuly 21, 2010
Couple of useful OS X Tricks
I just stumbled upon 30 Fantastic Geeky Tricks To Get The Most From Your Mac and I thought I’d write down a couple of tricks I found useful.
Recent Items Stack
Type this in terminal window to show a stack of your ‘recent applications’.
defaults write com.apple.dock persistent-others -array-add '{ "tile-data" = { "list-type" = 1; }; "tile-type" = "recents-tile"; }'
Show Hidden Files
The following command will show all hidden files in your Finder.
defaults write com.apple.Finder AppleShowAllFiles YESSimilarly, change the last bit to ‘NO’ to re-hide the files.
Enable Safari Inspector
I didn’t know that Safari had an Inspector that looks like the one in Google Chrome. As a web developer, I can say that this is music to my ears. Enable it in Terminal:
defaults write com.apple.Safari IncludeDebugMenu 1
Better Screen Sharing
When I first saw Screen Sharing on a Mac, I thought it was the best thing since sliced bread. Apparently, there are more nifty Screen Sharing features that are hidden by default. This includes a number of options for adjusting quality and allowed input on each side of the screen share. To turn them on, type this in your Terminal:
Topdefaults write com.apple.ScreenSharing \ 'NSToolbar Configuration ControlToolbar' -dict-add 'TB Item Identifiers' \ '(Scale,Control,Share,Curtain,Capture,FullScreen,GetClipboard,SendClipboard,Quality)'
June 16, 2010
Removing default icons from Flex Tree control
What’s so cool about Flex framework is the fact that it’s very extensible, which allows me to do almost anything I want with it.
For example, to remove folder/arrow icons from Flex Tree control, which prevents nodes from collapsing and also creates more space for labels, you can add the following in your stylesheet:
defaultLeafIcon: ClassReference(null); folderClosedIcon: ClassReference(null); folderOpenIcon: ClassReference(null); disclosureClosedIcon: ClassReference(null); disclosureOpenIcon: ClassReference(null);
For more information on Flex Tree CSS properties, refer to AS3.0 Reference.
Marko
TopI have just set up Apache Tomcat startup script on Snow Leopard and I thought I’d blog about it while it’s still fresh in my head. Assuming you have installed Tomcat in /usr/local/tomcat directory, you can do the following to start Tomcat on system startup.
1. Create your startup script:
sudo nano /usr/local/tomcat/bin/tomcat
#!/bin/sh # Tomcat Startup Script CATALINA_HOME=/usr/local/tomcat; export CATALINA_HOME JAVA_HOME=/Library/Java/Home; export JAVA_HOME TOMCAT_OWNER=root; export TOMCAT_OWNER start() { echo -n "Starting Tomcat: " su $TOMCAT_OWNER -c $CATALINA_HOME/bin/startup.sh sleep 2 } stop() { echo -n "Stopping Tomcat: " su $TOMCAT_OWNER -c $CATALINA_HOME/bin/shutdown.sh } # See how we were called. case "$1" in start) start ;; stop) stop ;; restart) stop start ;; *) echo $"Usage: tomcat {start|stop|restart}" exit esac
Set your TOMCAT_OWNER correctly. You should run it as a valid system user.
2. Create a symbolic link in /usr/bin for easier access
sudo ln -s /usr/local/tomcat/bin/tomcat /usr/bin/tomcat
3. Create the startup daemon which will start Tomcat when the system boots up
sudo mkdir /Library/StartupItems/tomcat
sudo nano /Library/StartupItems/tomcat/tomcat
#!/bin/sh . /etc/rc.common # The start subroutine StartService() { # Insert your start command below. tomcat start } # The stop subroutine StopService() { # Insert your stop command(s) below. tomcat stop } # The restart subroutine RestartService() { # Insert your start command below. tomcat restart } RunService "$1"
4. Create your startup parameters plist file
sudo nano /Library/StartupItems/tomcat/StartupParameters.plist
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd"> <plist version="0.9"> <dict> <key>Description</key> <string>Tomcat web server</string> <key>OrderPreference</key> <string>Late</string> <key>Provides</key> <array> <string>Local Web Services</string> </array> <key>Uses</key> <array> <string>SystemLog</string> </array> </dict> </plist>
Restart your Mac and you should be sweet.
For more info on how to install Tomcat, e.g. Railo on Tomcat via Apache see my blog post on Learnosity Website. Also, have a look at Mark’s version using Apache mod proxy
Marko
TopMay 19, 2010
MySQL startup script on Mac OS X Snow Leopard
I’ve had problems starting up MySQL database server on startup on Snow Leopard. MySQL preference pane seems to be flaky and it often fails to start MySQL server.
I created this startup script myself and it seems to work nicely.
sudo nano /System/Library/LaunchDaemons/org.mysql.mysqld.plist<?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>RunAtLoad</key> <true/> <key>Umask</key> <integer>7</integer> <key>UserName</key> <string>_mysql</string> <key>Disabled</key> <false/> <key>WorkingDirectory</key> <string>/usr/local/mysql</string> <key>GroupName</key> <string>_mysql</string> <key>KeepAlive</key> <true/> <key>Program</key> <string>/usr/local/mysql/bin/mysqld</string> <key>Label</key> <string>org.mysql.mysqld</string> <key>ProgramArguments</key> <array> <string>--user=_mysql</string> </array> </dict> </plist>
Now make sure file permission is correct and load the daemon.
sudo chown root:wheel /System/Library/LaunchDaemons/org.mysql.mysqld.plist
sudo launchctl load /System/Library/LaunchDaemons/org.mysql.mysqld.plist
sudo launchctl start org.mysql.mysqldRestart your Mac and your MySQL server should be running.
Marko
TopApril 24, 2010
Zen Cart to VirtueMart csv export
Following my post on Zen Cart friendly URLs, I would now like to give VirtueMart some love.
I’ve been looking for ways to export Categories and Products from Zen Cart and bulk insert them into VirtueMart. Wishful thinking? That’s what I thought after googling for a solution and couldn’t find anything that’s convincing and, of course, free.
This motivated me to download a free version of CSV Improved component for VirtueMart and have a look at the csv format required for importing products into VM. After a bit of head scratching I’ve come up with a pretty simple Zen Cart export tool that’s very primitive, but worked nicely for me. It can certainly save you days/months of manual data entry, depending on the number of products you have. Keep in mind that this tool will only export Categories and Products. If you need to export other stuff, you’ll have to extend this code a little bit. More info in readme.txt.
Download a copy of ZenCartToVirtueMartCSV.
Don’t run this script in production environment until you have tested it thoroughly. Make sure you read the readme.txt for requirements and instructions. Use it at your own risk. closeThis little script can definitely be improved, but it is all I have time for. Feel free to modify it and use it as a base for something more sophisticated.
Happy Exporting
Top
Marko