Installing Servoy Application Server as a service in MacOS X

I wanted to install Servoy Application Server (v 4.0) as a service in MacOs X. The manual describes how to create a .plist inside the LaunchAgents folder in the Library folder, but it refers to an installation using Sybase iAnywhere as the repository server and I am using a MySQL db. The Servoy Server could not be launched at startup probably because MySQL was not yet running (I use the System Preferences to start it automatically every time I log in).

Therefore I modified the .plist script as follows and Servoy Server now starts as expected right after log in.

<?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>Label</key>
	<string>servoy</string>
	<key>OrderPreference</key>
	<string>Last</string>
	<key>ProgramArguments</key>
	<array>
		<string>/Users/rioba/Servoy4/application_server/servoy_server.sh</string>
		<string>&</string>
	</array>
	<key>RunAtLoad</key>
	<true/>
</dict>
</plist>

Hi Rioba,

I have had the same problem with PostgreSQL as you’ve had with mySQL. There is this free application called ‘Armadillo’ which creates startup items for Mac OS X – you can specify dependencies and the order in which to start things. Makes it all very easy.

Armadillo can be used to create StartupScripts but those won’t work on Leopard, use Lingon instead or have a look at the LaunchDaemon man page.

I tried both Armadillo and Lingon, but Armadillo doesn’t work in Leopard (sorry, I forgot to mention that this script works in Leopard, I don’t know if it is ok with previous versions of MacOS X) and Lingon did not solve the problem because it does not have an option to specify the load order preference

<key>OrderPreference</key> 

In fact I copied this key from the script generated by Armadillo and pasted it into the Lingon script.

Rioba, the key is not supported in LaunchDaemons, if you take a look at the man page for launchd.plist you can see:

DEPENDENCIES
     Unlike many bootstrapping daemons, launchd has no explicit dependency model.  Interdependencies are
     expected to be solved through the use of IPC.  It is therefore in the best interest of a job developer
     who expects dependents to define all of the sockets in the configuration file. This has the added bene-
     fit of making it possible to start the job based on demand instead of immediately.

Let’s have a little recap of how services/daemons are lauched in MacOS X:

  • MacOS X 10.4.x supports both StartupScripts and LaunchDaemons
  • MacOS X 10.5.x supports only LaunchDaemons

LaunchAgents and LaunchDaemons are two different things, you should always use LaunchDaemons for services that are not related to a single user.

Here’s my setup for a MacOS X 10.5 server running MySQL and Servoy, note the MySQL is started before Servoy simply because of the name of the plist file.

sintpro:~ nick$ ls -lah /Library/LaunchDaemons/
total 24
drwxr-xr-x   5 root  wheel   170B Mar  7 19:02 .
drwxrwxr-t+ 57 root  admin   1.9K Mar  6 19:04 ..
-rw-r--r--   1 root  wheel   903B Mar  6 16:01 com.mysql.mysqld
-rw-r--r--   1 root  wheel   675B Mar  6 16:04 com.servoy.server

com.mysql.mysqld:

<?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>Disabled</key>
        <false/>
    <key>GroupName</key>
        <string>_mysql</string>
    <key>KeepAlive</key>
        <true/>
    <key>Label</key>
        <string>com.mysql.mysqld</string>
    <key>Program</key>
        <string>/usr/local/mysql/bin/mysqld</string>
    <key>ProgramArguments</key>
        <array>
                <string>--user=_mysql</string>
        </array>
    <key>RunAtLoad</key>
        <true/>
    <key>Umask</key>
        <integer>7</integer>
    <key>UserName</key>
        <string>_mysql</string>
    <key>WorkingDirectory</key>
        <string>/usr/local/mysql</string>
    <key>StandardErrorPath</key>
        <string>/var/log/mysqlerr.log</string>
    <key>StandardOutPath</key>
        <string>/var/log/mysqlout.log</string>
</dict>
</plist>

com.servoy.server:

<?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>Disabled</key>
    <false/>
    <key>GroupName</key>
        <string>_servoy</string>
    <key>KeepAlive</key>
        <true/>
    <key>Label</key>
        <string>com.servoy.server</string>
    <key>Program</key>
        <string>/Applications/servoy/servoy_server.sh</string>
    <key>RunAtLoad</key>
        <true/>
    <key>Umask</key>
        <integer>7</integer>
    <key>UserName</key>
        <string>_servoy</string>
    <key>WorkingDirectory</key>
    <string>/Applications/servoy</string>
</dict>
</plist>

Note that both MySQL and Servoy are started using their own user (_mysql,_servoy) and groups. This is very important for security.

Using symlinks to point to the production Servoy installation is also useful beacuse allows you to keep many servoy versions installed and jump trough them just repointing the symlink without the need to update the LaunchDaemon script every time:

sintpro:~ nick$ ls -lah /Applications/
total 40
drwxrwxr-x+ 39 root     admin     1.3K Mar  7 18:54 .
drwxrwxr-t  34 root     admin     1.2K Mar  7 18:53 ..
... omissis...
drwxr-xr-x  23 _servoy  _servoy   782B Apr 15 16:06 Servoy_3.5.4
drwxr-xr-x  23 _servoy  _servoy   782B Apr 15 16:06 Servoy_3.5.5
drwxr-xr-x  23 _servoy  _servoy   782B Apr 15 16:06 Servoy_3.5.6
lrwxr-xr-x   1 root     admin       8B Mar  6 16:08 servoy -> Servoy_3.5.6

I hope this post will be useful in the future for people that want to deploy on MacOS X.

And for the sake of completeness, here’s the plist to start postgres:

<?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>GroupName</key>
        <string>_postgres</string>
        <key>KeepAlive</key>
        <true/>
        <key>Label</key>
        <string>com.postgres.postgresql</string>
        <key>ProgramArguments</key>
        <array>
                <string>/usr/local/pgsql/bin/postgres</string>
                <string>-D</string>
                <string>/usr/local/pgsql/data</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>UserName</key>
        <string>_postgres</string>
        <key>WorkingDirectory</key>
        <string>/usr/local/pgsql</string>
</dict>
</plist>

Nicola,

thanks for your explanations (your tutorial on how to set up MySQL published by Servoy Magazine is a must read for everybody).

I used because I couldn’t manage to start Servoy server after MySQL. And the script now works, even if this key is deprecated.

I will now try your scripts.

rioba:
I tried both Armadillo and Lingon, but Armadillo doesn’t work in Leopard

:shock: I set up a Leopard 10.5.4 server last week using it… it restarts fine.

Maybe StartupItems are deprecated but are still working at some degree, I had difficulties with MySQL and startupItems on leopard.

It would be wise for you to upgrade that installation, it could break on the first system update.