Sunday, September 23, 2012

Run Tomcat as a Start-Up Service Daemon in Mac OS X

Before you begin:

The instructions below are to be followed at your own discretion and at your own risk. It is up to you to execute the commands outlined  in this tutorial and is strongly advised that if you do not understand the implications or repercussions one or more of the following instructions, that you do not proceed.

Note that I am on Mac OS X Snow Leopard (version 10.5.8). If you are on a different version of OS X, please consult the documentation specific to your version prior to following this tutorial.

Some of the lines below require altering sensitive system files and processes. Make sure that you are comfortable altering these files and processes before you proceed and that you understand the consequences.

All the commands below are intended to be executed in a terminal window and it is assumed that you are using the default bash terminal for Mac OS X. If you are using another terminal, it is up to you to adjust the commands to fit your terminal.

Now, let's get started...

If you would like to have Tomcat as a start-up service daemon when your system boots up, follow the steps below. These steps assume Tomcat is installed in /Library/Tomcat/Home on your machine and that you have set the $CATALINA_HOME environment variable to /Library/Tomcat/Home. For more information on installing Tomcat on Mac OS X, see "Build and Install Tomcat 7 FROM Source on Mac OS X".

Mac OS X uses launchd to launch daemons at system start-up. To make use of launchd, we will need to make two files:
  1. Create a tomcat-launchd.sh file and give execute permissions to it. sudo touch $CATALINA_HOME/bin/tomcat-launchd.sh
    sudo chmod a+x $CATALINA_HOME/bin/tomcat-launchd.sh
  2. Add the following code to the tomcat-launchd.sh file and save it: #!/bin/bash
    # NOTE: this is an OSX launchd wrapper shell script for Tomcat (to be placed in $CATALINA_HOME/bin)

    function shutdown() {
        date
        echo "Shutting down Tomcat"
        $CATALINA_HOME/bin/catalina.sh stop
    }

    date
    echo "Starting Tomcat"
    export CATALINA_PID=/tmp/$$

    # Uncomment to increase Tomcat's maximum heap allocation
    # export JAVA_OPTS=-Xmx512M $JAVA_OPTS

    . $CATALINA_HOME/bin/catalina.sh start

    # Allow any signal which would kill a process to stop Tomcat
    trap shutdown HUP INT QUIT ABRT KILL ALRM TERM TSTP

    echo "Waiting for `cat $CATALINA_PID`"
    wait `cat $CATALINA_PID`
  3. Create a property list file called org.apache.tomcat.plist. sudo touch /Library/LaunchDaemons/org.apache.tomcat.plist
  4. Add the following code to the property list file. As you can see, this file contains properties that will help launchd successfully run the tomcat-launchd.sh file that we created above. <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
        <dict>
            <key>Label</key>
            <string>org.apache.tomcat</string>
            <key>OnDemand</key>
            <false/>
            <key>RunAtLoad</key>
            <true/>
            <key>EnvironmentVariables</key>
            <dict>
                <key>CATALINA_HOME</key>
                <string>/Library/Tomcat/Home</string>
            </dict>
            <key>ProgramArguments</key>
            <array>
                <string>/Library/Tomcat/Home/bin/tomcat-launchd.sh</string>
            </array>
            <key>ServiceDescription</key>
            <string>Tomcat</string>
            <key>StandardErrorPath</key>
            <string>/Library/Tomcat/Home/logs/tomcat-launchd-errors.log</string>
            <key>StandardOutPath</key>
            <string>/Library/Tomcat/Home/logs/tomcat-launchd-output.log</string>
            <key>UserName</key>
            <string>root</string>
        </dict>
    </plist>
  5. Now load the property list file into launchd sudo launchctl load /Library/LaunchDaemons/org.apache.tomcat.plist When you run the command above it will start Tomcat if it isn't already running.
  6. If you need to restart Tomcat simply run the following command: sudo $CATALINA_HOME/bin/shutdown.sh This will stop the current running Tomcat process and launchd will start a new one.
    *Note: This is the same command I had you create a stop-tomcat alias for in "Build and Install Tomcat 7 From Source on Mac OS X".
  7. If you need to stop Tomcat for any length of time, or if you need to prevent Tomcat from starting as a system process, simply unregister it from launchd with the following command sudo launchctl unload /Library/LaunchDaemons/org.apache.tomcat.plist
For a great run-down on how launchd works check out this post on Nathan's Blog. You can get into the details by taking a look at the "About Daemons and Services" section on Apple's developer website.

Well, that wraps it up for this tutorial. I appreciate any comments.

Saturday, August 25, 2012

Build and Install Tomcat 7 From Source on Mac OS X

Before you begin:

The instructions below are to be followed at your own discretion and at your own risk. It is up to you to execute the commands outlined  in this tutorial and is strongly advised that if you do not understand the implications or repercussions one or more of the following instructions, that you do not proceed.

Note that I am on Mac OS X Snow Leopard (version 10.5.8). If you are on a different version of OS X, please consult the documentation specific to your version prior to following this tutorial.

You must have both Java and Apache Ant installed to complete this tutorial. The instructions in this tutorial assume that Ant is located at /usr/share/ant and Java is located at /Library/Java/Home. If they are in different locations on your machine, please make adjustments accordingly.

These instructions also assume the latest release of Tomcat as of the time of this writing, which is version 7.0.29. If you want to install a different version of Tomcat, please consult the Apache Tomcat documentation.

Some of the lines below require altering the ~/.bash_profile file. Your machine may require that you alter the ~/.bash_login file or the ~/.profile file instead. See this page on stack overflow for some information on which one you may want to edit. Make sure that you are comfortable editing these files before you proceed and that you understand the consequences.

All the commands below are intended to be executed in a terminal window and it is assumed that you are using the default bash terminal for Mac OS X. If you are using another terminal, it is up to you to adjust the commands to fit your terminal.

If, at any time, you need to know what your current directory is, type pwd (print working directory) into the the terminal.

Now, let's get started...

  1. See if you have the JAVA_HOME and ANT_HOME environment variables set. If you do, the following command should print out the directories that the variables are pointed to:
    echo $JAVA_HOME && echo $ANT_HOME If no directory path is printed out for one, or both, of these, then follow the instructions below to set the JAVA_HOME and ANT_HOME environment variables.

    The following commands will set the variables for your current command-line (terminal) session: export JAVA_HOME=/Library/Java/Home
    export PATH="$JAVA_HOME/bin:$PATH"
    export ANT_HOME=/usr/share/ant
    export PATH="$ANT_HOME/bin:$PATH"
    And these commands will make sure these variables are available for future terminal sessions: echo 'export JAVA_HOME=/Library/Java/Home' >> ~/.bash_profile
    echo 'export PATH="$JAVA_HOME/bin:$PATH"' >> ~/.bash_profile
    echo 'export ANT_HOME=/usr/share/ant' >> ~/.bash_profile
    echo 'export PATH="$ANT_HOME/bin:$PATH"' >> ~/.bash_profile
  2. Now, let's make some directories to download the Tomcat source code into. sudo mkdir /Library/Tomcat && cd /Library/Tomcat
    sudo mkdir src && cd src
    sudo mkdir src-downloads
  3. Download the Tomcat 7 source code into the current directory /Library/Tomcat/src. sudo wget http://apache.mirrors.tds.net/tomcat/tomcat-7/v7.0.29/src/apache-tomcat-7.0.29-src.tar.gz
  4.  Expand the tar.gz file you just downloaded into the current directory, this will create a new directory called apaache-tomcat-7.0.29-src.
    sudo tar -zxvf apache-tomcat-7.0.29-src.tar.gz
  5. Change directories into the new directory. cd apache-tomcat-7.0.29-src
  6. Create a build.properties file. sudo touch build.properties
  7. Now open the build.properties file in your preferred editor and add the following line to it to tell Ant which directory to download dependencies into: base.path=/Library/Tomcat/src/src-downloads
  8. Run Ant on the current directory (which should be /Library/Tomcat/src/apache-tomcat-7.0.29-src). sudo ant
  9. Once Ant completes successfully, it will have created a folder named build in the directory /Library/Tomcat/src/output.
  10. We want to move this build directory up to the /Library/Tomcat directory and rename it something more relevant. sudo mv output/build /Library/Tomcat/apache-tomcat-7.0.29
  11. Change directories back to the /Library/Tomcat directory. cd ../../
  12. Create a symbolic link called Home and point it to the new tomcat build. sudo ln -svhf apache-tomcat-7.0.29 Home
  13. Go into the bin folder, remove any Windows .bat files and give execute permissions to the shell scripts. cd Home/bin
    sudo rm *.bat
    sudo chmod 755 *.sh
  14. Create a CATALINA_HOME environment variable and add it to the PATH for your current terminal session. export CATALINA_HOME=/Library/Tomcat/Home
    export PATH="$CATALINA_HOME:$PATH"
  15. Now, add CATALINA_HOME for future terminal sessions. echo 'export CATALINA_HOME=/Library/Tomcat/Home' >> ~/.bash_profile
    echo 'export PATH="$CATALINA_HOME:$PATH"' >> ~/.bash_profile
  16. Add aliases for the Tomcat startup and shutdown scripts to the current terminal session. alias start-tomcat="sudo $CATALINA_HOME/bin/startup.sh"
    alias stop-tomcat="sudo $CATALINA_HOME/bin/shutdown.sh"
  17. Add the above aliases in ~/.bash_profile so they are available for all future terminal sessions as well. echo 'alias start-tomcat="sudo $CATALINA_HOME/bin/startup.sh"' >> ~/.bash_profile
    echo 'alias stop-tomcat="sudo $CATALINA_HOME/bin/shutdown.sh"' >> ~/.bash_profile
  18. Add roles and users to /Library/Tomcat/Home/conf/tomcat-users.xml.
  19. Start up Apache Tomcat. start-tomcat
  20. Browse to http://localhost:8080 in your browser to see the Tomcat home page.
  21. Shutdown Apache Tomcat. stop-tomcat
If you are interested in running Tomcat on system start-up, see Run Tomcat as a Start-Up Service Daemon in Mac OS X. Thanks for reading!

Monday, June 25, 2012

Setting up CherryPy using mod_wsgi on Mac OS X Snow Leopard

Getting CherryPy 3.2 setup on Snow Leopard with mod_wsgi is relatively easy. Here is a step-by-step guide.

A word of caution:

This tutorial requires you to modify sensitive system files on your computer. If you are uncomfortable doing this or unaware of the repercussions, take some time and do your due-diligence to understand the repercussions before following these steps or do not follow the steps outlined in this tutorial.


Step 1 (optional) - Download and install Python 2.7.3  

Python is installed on SnowLeopard by default, but it's an older version 2.6. If you want to use that, you can skip this section.

  • Download Python 2.7.3 from the Python standard releases page
  • Browse to the downloaded python-2.7.3-macosx10.6.dmg file in Finder
  • Double-click on it and follow the installation instruction

The Python standard release of 2.7.3 installs the python executable to the following location on your Mac by default:
        /Library/Frameworks/Python.framework/Versions/2.7/bin

Add the above location to your $PATH environment variable.

Python 2.7.3 should now be up-and-running. To test this, open a terminal and type:
        python -V

The following text should show up (If not, you may have your $PATH environment variable set incorrectly).:
        Python 2.7.3

Step 2 - Download and install mod_wsgi

There are a few ways to do this. If you are sticking with Python 2.6 that comes pre-installed on Snow Leopard, you can download and install the Snow Leopard binary. If you have macports or homebrew you can use one of those if you prefer. Here, I will demonstrate how to compile it from source. It's quick, easy and puts the resulting mod_wsgi.so file in the same place as all of the other Apache mods.

To download and compile from source, open up a terminal and type the following commands (Hit the [return] key after each command, you will see output from some of them. Also, the terminal may ask for your password at some point):
cd ~/Downloads/
wget http://modwsgi.googlecode.com/files/mod_wsgi-3.3.tar.gz
tar -zxvf mod_wsgi-3.3.tar.gz
cd mod_wsgi-3.3
sudo ./configure
sudo make
sudo make install
Now, you should have mod_wsgi.so installed with your other Apache modules in /usr/libexec/apache2. To confirm this, keep the terminal open and type the command: ls /usr/libexec/apache2/mod_wsgi.so The terminal should print back the file path (if not, something went awry, try again): /usr/libexec/apache2/mod_wsgi.so

Step 3 - Test mod_wsgi on Apache

You have downloaded mod_wsgi, now let's get Apache to load it.

First, you need to edit some of the Apache configuration files. FYI, you will need to make hidden files and folders visible if they aren't already.
  •  Tell Apache to load the mod_wsgi.so file that you installed. Open the following file in your favorite text editor:Macintosh HD/private/etc/apache2/httpd.conf
  • Find the big list of lines that begin with LoadModule. After the last LoadModule line, add the following line and save the file. You will be prompted for your password when saving. (Note, if you used macports or homebrew to install mod_wsgi, the location of mod_wsgi.so will be different):LoadModule wsgi_module  libexec/apache2/mod_wsgi.so
  • Now, create a VirtualHost in Apache. Open up the following file in your favorite text editor: Macintosh HD/private/etc/apache2/extra/httpd-vhosts.conf  
  • Add the following lines to the bottom of the file and save it: <VirtualHost *:80>
        ServerAdmin me@test-cherry-py
        ServerName test-cherrypy

        DocumentRoot "/Library/WebServer/test-cherrypy/documents"
       
        <Directory "/Library/WebServer/test-cherrypy/documents">
            Options Indexes FollowSymLinks Includes
            AllowOverride All
            Order allow,deny
            Allow from all
        </Directory>

        WSGIScriptAlias / /Library/WebServer/test-cherrypy/wsgi-scripts/test-cherrypy.py

        <Directory "/Library/WebServer/test-cherrypy/wsgi-scripts">
            Order allow,deny
            Allow from all
        </Directory>
    </VirtualHost>
In the above VirtualHost code-block, you told Apache to answer to the domain name test-cherrypy, and to look for files and folders that probably don't exist on your machine yet. Let's get your machine set up so that Apache can find these files, directories and the domain name.

  • Fake the domain name. In Finder, open up the file Macintosh HD/etc/hosts in your favorite text editor and add the following line to the end of the file:127.0.0.1     test-cherrypy
  • Create the directories and files that your VirtualHost directive above refers to. Go to the terminal and type the following commands (hit [return] after each command):
    cd /Library/Webserver
    sudo mkdir test-cherrypy
    sudo mkdir test-cherrypy/documents
    sudo mkdir test-cherrypy/wsgi-scripts
    sudo touch test-cherrypy/wsgi-scripts/test-cherrypy.py
  • In Finder, open up the following file in your favorite text editor: Macintosh HD/Library/Webserver/test-cherrypy/wsgi-scripts/test-cherrypy.py
  • It should be empty. Add the following lines of code to the file and save it: def application(environ, start_response):
        status = '200 OK'
        output = 'Hello, from mod_wsgi!'

        response_headers = [('Content-type', 'text/plain'),
                            ('Content-Length', str(len(output)))]
        start_response(status, response_headers)

        return [output]
Now, go to the Apple menu and open up System Preferences > Sharing  and uncheck and re-check the Web Sharing checkbox. This will restart Apache. Alternatively, you could type the following in the terminal:sudo apachectl restart
Open up your favorite browser and go to http://test-cherrypy. You should be greeted with the following text:
Hello, from mod_wsgi!

Thursday, June 14, 2012

Sublime Text 2 Plugin Authoring Resources

I recently found myself authoring a Sublime Text 2 plugin for use at work. When it was all said and done, the process was fairly straight-forward. Plugins are written in python and follow simple conventions. If you too are interested in creating your own Sublime Text 2 plugins, here are some of the resources that I found useful:




Also, just take a look through the Sublim packages directory at the installed packages, almost anything you need to learn can be found in the code that is in there.

Customizing ColdFusion Highlighting in Sublime Text 2


This post assumes that you have Package Control installed in Sublime Text 2. If not, find out more about it here:  http://wbond.net/sublime_packages/package_control

If you haven't already installed the ColdFusion package in Sublime Text 2, you will need to do so before continuing. To install the ColdFusion package through Package Control:

  • In Sublime, type [ctrl]+[shift]+p (Win/Lin) or [cmd]+[shift]+p (Mac) to open the Command Pallette
  • Choose "Package Control: Install Package" from the list
  • Type ColdFusion in the text box
  • Select the ColdFusion package from the list
Once the ColdFusion package is installed, take it for a spin and give it time to sink in that you won't have to rely on the bloated clunkiness of ColdFusion Builder any longer. WIN!


For me, one thing I needed to change was the color scheme for ColdFusion versus HTML tags, since by default they both have the same color scheme. To highlight ColdFusion tags in a different color from the html tags:
  • In Sublime Text 2 open up Preferences -> Browse Packages and then go to the Color Scheme - Default directory
  • Open the theme file for the theme you are using. For instance, I am using the Monokai theme, so I opened the Monokai.tmTheme file
  • Add the following code before the final </array> tag in this file
<!-- BEGIN ColdFusion specific coloring -->
<dict>
    <key>name</key>
    <string>CF tag name</string>
    <key>scope</key>
    <string>entity.name.tag.conditional.cfml, entity.name.tag.declaration.cfml, entity.name.tag.other, entity.name.tag.cf, entity.name.tag.inline.other.cfml</string>
    <key>settings</key>
    <dict>
         <key>fontStyle</key>
         <string>bold</string>
         <key>foreground</key>
         <string>#A9BBDB</string>
    </dict>
</dict>
<dict>
    <key>name</key>
    <string>CF tag brackets</string>
    <key>scope</key>
    <string>punctuation.definition.tag.begin.cfml, punctuation.definition.tag.end.cfml, punctuation.definition.tag.begin.ctml, punctuation.definition.tag.end.ctml, punctuation.definition.tag.start.cfml</string>
    <key>settings</key>
    <dict>
         <key>fontStyle</key>
         <string></string>
         <key>foreground</key>
         <string>#A9BBDB</string>
    </dict>
</dict>
<dict>
    <key>name</key>
    <string>CF tag attribute</string>
    <key>scope</key>
    <string>meta.tag.block.other.cfml, entity.other.attribute-name.cfml, entity.other.attribute-name.name.cfml</string>
    <key>settings</key>
    <dict>
         <key>fontStyle</key>
         <string></string>
         <key>foreground</key>
         <string>#CF99D1</string>
    </dict>
</dict>
<dict>
    <key>name</key>
    <string>CF tag attribute quotes</string>
    <key>scope</key>
    <string>punctuation.definition.string.begin.cfml, punctuation.definition.string.end.cfml</string>
    <key>settings</key>
    <dict>
         <key>fontStyle</key>
         <string></string>
         <key>foreground</key>
         <string>#A9BBDB</string>
    </dict>
</dict>
<dict>
    <key>name</key>
    <string>CF tag attribute values</string>
    <key>scope</key>
    <string>string.quoted.double.cfml</string>
    <key>settings</key>
    <dict>
         <key>fontStyle</key>
         <string></string>
         <key>foreground</key>
         <string>#CCCCCC</string>
    </dict>
</dict>
<dict>
    <key>name</key>
    <string>CF tag equals signs</string>
    <key>scope</key>
    <string>meta.tag.inline.cfml, punctuation.separator.key-value.cfml</string>
    <key>settings</key>
    <dict>
         <key>fontStyle</key>
         <string></string>
         <key>foreground</key>
         <string>#CF99D1</string>
    </dict>
</dict>
<dict>
    <key>name</key>
    <string>CF tag variables</string>
    <key>scope</key>
    <string>meta.tag.inline.cfml variable.other.cfscript, meta.tag.block.conditional.cfml variable.other.cfscript</string>
    <key>settings</key>
    <dict>
         <key>fontStyle</key>
         <string></string>
         <key>foreground</key>
         <string>#FFFFFF</string>
    </dict>
</dict>
<dict>
    <key>name</key>
    <string>CF comments</string>
    <key>scope</key>
    <string>comment.block.cfml, comment.line.cfml, comment.line.double-slash.cfscript, comment.block.cfscript</string>
    <key>settings</key>
    <dict>
         <key>fontStyle</key>
         <string></string>
         <key>foreground</key>
         <string>#000000</string>
         <key>background</key>
         <string>#999999</string>
    </dict>
</dict>
<!-- END ColdFusion specific coloring -->
  • Save the file and then open up a ColdFusion page, your CF tags should be a different color
  • To change the color of the CF tags, adjust the hexadecimal colors in the new code block

More info:

Sublime text uses selectors to identify parts of the code for coloring. You will see that the outer <dict></dict> code blocks contain a <key>scope</key> section followed by a <string></string> section. You put the selectors in this <string></string> section.

You can get the selector names to identify different parts of your code by going to one of your code pages and highlighting the code you want to color. Then hit [ctrl]+[alt]+[shift]+p (Win/Lin) or [cmd]+[opt]+p (Mac) to display the selector in the status bar at the bottom. To copy the selectors to the clipboard hit [ctrl]+` (Win/Lin) or [cmd]+`(Mac) to open the console and paste the following code into it: sublime.set_clipboard(view.syntax_name(view.sel()[0].b)) If you find a good resource for altering/creating themes post it here! The basis for the information on this page can be found at: http://stackoverflow.com/questions/9345222/syntax-specific-highlighting-with-sublime-text-2