Install LEMP on Ubuntu WSL on Windows 10

Windows Development No Comments

To facilitate web development, I wanted the same environment on my Windows 10 desktop as exists on my Ubuntu VPS server. With WSL (Windows Subsystem for Linux), I can have the same LEMP (Linux, Nginx, MySQL, and PHP) setup on my Windows 10 desktop.

See my previous post, Install Subversion on Ubuntu WSL on Windows 10, to get an Ubuntu-flavored WSL working on your Windows 10 system.

Instructions to install LEMP on Ubuntu WSL are almost the same as what I used to install LEMP on my Ubuntu server (see Install Ubuntu, LEMP, and WordPress on an Unmanaged VPS).

Install PHP

The latest Ubuntu WSL version is 18.04.1 LTS, which supports the latest PHP 7.2 version.

# Install PHP 7.2 and support packages:
# - php7.2-cli - PHP command line
# - php-mysql - PHP library to call MySQL database
# - php-fpm - PHP FastCGI Process Manager for Nginx integration
sudo apt install php7.2 php7.2-cli php7.2-mysql php7.2-fpm

# List the installed packages and grep for php-specific packages:
dpkg --get-selections | grep -i php

# Get the version of PHP installed
php -version

Install MySQL

# Install MySQL server.
sudo apt install mysql-server

# Get version of MySQL server and CLI installed
mysqld --version
mysql --version

# Start MySQL server
sudo service mysql start
sudo service mysql status

# Log into MySQL server as root user with blank password.
sudo mysql -u root
mysql> show databases;
mysql> quit

Note: Instead of using the “quit” command to exit the MySQL client, you can also use the “exit” command. Semi-colon termination (for example, “quit;” or “exit;”) are optional for these close connection commands.

By default, the MySQL server is configured to only allow root MySQL login from the root Linux user. Thus, we had to use “sudo mysql -u root” above. If we wish to allow a non-root Linux user to login using the root MySQL user (eliminate need for “sudo”), we’ll need to change how the root MySQL user is athenticated (switch to “mysql_native_password” plugin instead of the “auth_socket” plugin).

# Log into MySQL server as root user with blank password.
sudo mysql -u root

# Allow connection from a non-root Linux user
mysql> use mysql;
mysql> update user set plugin='mysql_native_password' where User='root';
mysql> flush privileges;

# Exit MySQL client.
mysql> quit

# Log into MySQL server as root user without "sudo".
mysql -u root
mysql> show databases;
mysql> quit

If you wish to secure the MySQL server, you can use the convenient “mysql_secure_installation” utility. Run the utility to enable password validation, set a root user password, remove anonymous users, disable remote root login, and remove the test database. You can re-run the utility again to reset the root user password if you need to.

# Run utility to secure MySQL server
sudo mysql_secure_installation

# Log into MySQL server as root user with password prompt
mysql -u root -p
mysql> show databases;
mysql> quit

If you wish to go back to using a blank MySQL root password, run the following to disable password validation and set a blank root password:

mysql -u root -p
mysql> uninstall plugin validate_password;
mysql> set PASSWORD for root@localhost=PASSWORD('');
mysql> quit

Install Nginx

# Install Nginx
sudo apt install nginx

# Start Nginx server
sudo service nginx start

Browse to http://localhost/ and you should see the initial Nginx welcome page.

Start the PHP-FPM service so Nginx can execute PHP scripts.

# Locate unix socket file which PHP-FPM service will listen to.
grep "listen =" /etc/php/7.2/fpm/pool.d/www.conf
# output: listen = /run/php/php7.2-fpm.sock

# Start PHP-FPM service.
sudo service php7.2-fpm start

Edit the default Nginx server block file to use the PHP-FPM service:

sudo nano /etc/nginx/sites-available/default

In the “default” server block file, change the following:

server {
        # Add index.php to the list if you are using PHP
        #index index.html index.htm index.nginx-debian.html;

        # Add index.php to front of "index" to execute it first
        index index.php index.html index.htm index.nginx-debian.html;

        # pass PHP scripts to FastCGI server
        #location ~ \.php$ {
        #       include snippets/fastcgi-php.conf;
        #       # With php-fpm (or other unix sockets):
        #       fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
        #       # With php-cgi (or other tcp sockets):
        #       fastcgi_pass;

        location ~ \.php$ {
                include snippets/fastcgi-php.conf;

                # Make sure unix socket path matches PHP-FPM configured path above
                fastcgi_pass unix:/run/php/php7.2-fpm.sock;

                # Prevent ERR_INCOMPLETE_CHUNKED_ENCODING when browser hangs on response
                fastcgi_buffering off;

Restart the Nginx service to have the changes take effect:

sudo service nginx restart

Test PHP and MySQL Integration

Create a PHP test script by running this edit command:

sudo nano /var/www/html/info.php

In the “info.php” file, input the following content:


Browse to http://localhost/info.php and you should see a page containing information about the PHP installation.

Create a PHP MySQL test script by running this edit command:

sudo nano /var/www/html/mysql.php

In the “mysql.php” file, input the following content:

// HTML response header
header('Content-type: text/plain');

// Database connection parameters
$DB_HOST = 'localhost';
$DB_PORT = 3306; // 3306 is default MySQL port
$DB_USER = 'root';
$DB_PASS = ''; // blank or password (if you set one)
$DB_NAME = 'mysql'; // database instance name

// Open connection (all args can be optional or NULL!)
$mysqli = new mysqli($DB_HOST, $DB_USER, $DB_PASS, $DB_NAME, $DB_PORT);
if ($mysqli->connect_error) {
  echo 'Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error . PHP_EOL;
} else {
  // Query users
  if ($result = $mysqli->query('SELECT User FROM user')) {
    echo 'Database users are:' . PHP_EOL;
    for ($i = 0; $i < $result->num_rows; $i++) {
      $row = $result->fetch_assoc();
      echo $row['User'] . PHP_EOL;
  } else {
    echo 'Query failed' . PHP_EOL;

// Close connection

Browse to http://localhost/mysql.php and you should see a page listing the MySQL database users.

If you have problems, you can debug by enabling PHP-FPM error logging. Edit the configuration for the PHP-FPM pool:

# Edit www.conf file and add an error_log directive.
sudo nano /etc/php/7.2/fpm/pool.d/www.conf
    # Add an error log file location in the "/tmp" directory
    ;php_admin_value[error_log] = /var/log/fpm-php.www.log
    php_admin_value[error_log] = /tmp/fpm-php.log

# Restart PHP-FPM service for change to take effect
sudo service php7.2-fpm restart

Note: There exists a “/etc/php/7.2/fpm/php.ini” configuration file but that is not used by the Nginx PHP-FPM connection. Also, putting the error log file in a directory other than the “/tmp” directory (like “/var/log”) may not work due to permission issues.

Info above derived from:

No Comments

Install Subversion on Ubuntu WSL on Windows 10

Windows Development No Comments

I needed Subversion client access on a fresh Windows 10 installation. Rather than installing one of the Subversion clients for Windows (for example, CollabNet Subversion or SlikSVN), I decided to take advantage of the new WSL (Windows Subsystem for Linux).

The best part of macOS is the Linux system which macOS runs on. And now, the latest Windows 10 has something equivalent. Below are the steps I took to install WSL (Ubuntu flavor) and Subversion.

Install WSL Ubuntu

  1. Enable the WSL feature.
    • Run “Turn Windows features on or off” and check the box for the “Windows Subsystem for Linux” feature.
    • Alternatively, launch the Windows PowerShell as an administrator and run this command:
      Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
  2. Restart the computer to finish enabling the WSL feature.
  3. Launch the “Windows Store” and search for “Run Linux on Windows”.
    • Click on Ubuntu (or your favorite flavor of Linux).
    • Click on Get (or Install) to install Ubuntu.
  4. Run the installed “Ubuntu” app to configure the WSL.
    • After several minutes, it will prompt you to input a Unix username and password for your default sudo user. (This will be the default user that your bash shell runs under.)
  5. You can run “Ubuntu” or “bash” to launch the bash terminal shell.
    • “Ubuntu” will put you in the “/home/<username>” directory.
    • “bash” will keep the current directory.
  6. Some Linux commands to try out:
    # Show version of Linux
    lsb_release -a

    # Show HOME variable and current directory
    echo $HOME

    # Two ways to list the contents of the "C:\Program Files" directory
    ls "/mnt/c/Program Files"
    ls /mnt/c/Program\ Files

    # Log into root user
    sudo su

While it is easy to access the Windows drive from Ubuntu by using “/mnt/c” for the C:\ drive, the Linux root “/” directory maps to the Windows directory at “C:\Users\<username>\AppData\Local

I recommend creating a NTFS symbolic link to make it easier to access the Linux home directory. Open a Command Prompt as administrator and run this command:

mklink /d c:\ubuntu "C:\Users\<username>\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_<UID>\LocalState\rootfs"

Note: Strangely, if I create a new file in the Ubuntu’s rootfs directory using Windows, the file is not visible under the Ubuntu shell. Editing an existing file from Windows works fine.

Install Subversion

Installing Subversion on WSL Ubuntu is identical to installing Subversion on my unmanaged Ubuntu virtual server (see Subversion Over SSH on an Unmanaged VPS).

Note: You may notice the switch from the “apt-get” command to the “apt” command when installing and updating Ubuntu packages. The “apt” command is a slightly smaller subset of the “apt-get” command, more user-friendly, and appears to be the recommended command to use going forward.

Below are the steps I took to update Ubuntu, install Subversion, and connect to the remote Subversion repository on my server.

  1. Update Ubuntu packages using the bash shell:
    # Refresh the APT repository index
    # If you don't update, the install command below will fail.
    sudo apt update

    # List packages that can be upgraded
    apt list --upgradable

    # Upgrade packages with auto-handling of dependencies
    # (same as "apt-get dist-upgrade")
    sudo apt full-upgrade

    # Remove dependencies which are no longer used (frees up space)
    sudo apt autoremove
  2. Install Subversion:
    # Install subversion
    sudo apt install subversion

    # Check that subversion is installed
    svn --version
  3. Because my server uses a custom SSH port and requires the Subversion client to use the SVN+SSH protocol, we must configure SSH to use the custom port automatically because there is no option to input the custom port on the command line.
    # Create .ssh configuration directory under the home directory
    mkdir ~/.ssh

    # Optionally, restrict access to the directory to just the user/owner
    chmod 700 ~/.ssh

    # Create SSH config file
    cat > ~/.ssh/config
      Port 3333
      PreferredAuthentications publickey,password
    # Press CTRL-D to save and exit the file

    # SSH requires that only the user has access to files under the ~/.ssh directory.
    # If you don't restrict, SSH will throw a "Bad owner or permissions" warning and ignore the files.
    chmod 600 ~/.ssh/config

    # Copy the trusted client "id_rsa" and "" identity files to the ~/.ssh directory
    # to eliminate the need to input the password when using SSH.
  4. Connect to the remote Subversion repository:
    # List all projects in the remote repository.
    svn list svn+ssh://

    # Check out a local, working copy of the project from the repository
    svn co svn+ssh:// ./myproject

    # View the working copy's info (no need to input the svn+ssh URL once inside the project)
    cd ./myproject
    svn info

See my followup post, Install LEMP on Ubuntu WSL on Windows 10, for instructions on getting a full LEMP (Linux, Nginx, MySQL, PHP) development environment working on Ubuntu WSL.

Info above derived from:

No Comments

Nginx with PHP and MySQL on Windows 7

Windows Development 12 Comments

In the past, whenever I needed a web server on Windows, I would install the XAMPP distribution (comes with Apache, PHP, and MySQL) and call it a day. This time, I wanted to use Nginx instead of Apache as the web server. Below are the steps I took to install Nginx, PHP and MySQL separately on Windows 7.

Install Nginx

Nginx is pretty easy to install on Windows. Just do the following:

  1. Download the latest Nginx for windows version. (Currently, only 32-bit versions are available.)
  2. Unzip to a directory like “c:\nginx”.
  3. Create two subdirectories which “nginx.exe” expects to exist:
    mkdir c:\nginx\logs
    mkdir c:\nginx\temp
  4. If you want to change the document root from the default “c:\nginx\html” and/or enable directory listing, edit the “c:\nginx\conf\nginx.conf” file and adjust the global “location /” declaration like so:
            location / {
                #root   html; # comment out default root at "nginx_install_dir\html"
                root   /www;  # use new root "c:\www" (assuming nginx is install on c: drive)
                index  index.html index.htm;
                autoindex on; # Add this to enable directory listing
  5. To run the Nginx web server, launch the “Command Prompt” and issue these commands:
    # Go to Nginx installation directory
    cd \nginx

    # Start Nginx
    start nginx.exe


    • Running “c:\nginx\nginx.exe” without changing to the “c:\nginx” directory will fail because Nginx will look for the log and temp subdirectories, which won’t exist under another directory.
    • The “start” command will launch Nginx in a separate window; otherwise, Nginx would take control of the current “Command Prompt” window. That separate window will appear and quickly disappear.
    • It is not necessary to run the “Command Prompt” as an administrator.
  6. Browse to http://localhost/ . You should see a “Welcome to nginx!” page.
  7. To quit Nginx, in the “Command Prompt” window, do the following:
    # Go to Nginx installation directory
    cd \nginx

    # Quit Nginx
    nginx.exe -s quit

    If you have started Nginx more than once, the quit command above will only kill the last Nginx process started. To kill all Nginx processes, run the following:

    taskkill /F /IM nginx.exe

To avoid launching multiple instances of Nginx, I created the following “intelligent” Nginx start and stop batch script files.

Create a file named “start_nginx.bat” with the content below:


REM Start Nginx
tasklist /FI "IMAGENAME eq nginx.exe" 2>NUL | find /I /N "nginx.exe">NUL
   REM Nginx is NOT running, so start it
   cd \nginx
   start nginx.exe
   ECHO Nginx started.
) else (
   ECHO Nginx is already running.

And create a file named “stop_nginx.bat” with this content:


REM Stop Nginx
tasklist /FI "IMAGENAME eq nginx.exe" 2>NUL | find /I /N "nginx.exe">NUL
IF "%ERRORLEVEL%"=="0" (
   REM Nginx is currently running, so quit it
   cd \nginx
   nginx.exe -s quit
   ECHO Nginx quit issued.
) else (
   ECHO Nginx is not currently running.

Install and Configure PHP

To install PHP on Windows:

  1. Browse to, click on the “Windows downloads” link, and download the latest thread safe version. Either 32-bit or 64-bit versions will work.
  2. Unzip to a directory, like “c:\nginx\php”.
  3. Select a PHP configuration (I recommend the development version):
    copy c:\nginx\php\php.ini-development c:\nginx\php\php.ini

We will run the “c:\nginx\php\php-cgi.exe” server to allow Nginx to execute PHP scripts using the FastCGI protocol.

  1. Edit “c:\nginx\conf\nginx.conf” to uncomment the FastCGI section and update the fastcgi_param entries like so:
            # pass the PHP scripts to FastCGI server listening on
            location ~ \.php$ {
                root           html;
                fastcgi_index  index.php;
                #fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
                fastcgi_param  REQUEST_METHOD $request_method;
                fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include        fastcgi_params;


    • Don’t forget to update the “root” location value if you are not using the default “c:\nginx\html” directory.
    • The fastcgi_param values are recommended extra parameters passed to PHP scripts for their optional use.
  2. Add the following to the bottom of the “start_nginx.bat” file:
    REM Start php-cgi
    tasklist /FI "IMAGENAME eq php-cgi.exe" 2>NUL | find /I /N "php-cgi.exe">NUL
    IF NOT "%ERRORLEVEL%"=="0" (
       REM php-cgi is NOT running, so start it
       start /min c:\nginx\php\php-cgi.exe -b localhost:9000 -c c:\nginx\php\php.ini
       ECHO php-cgi started.
    ) else (
       ECHO php-cgi is already running.


    • Use localhost instead of to support both IPv4 and IPv6 addressing (if it is enabled). was not resolvable on my IPv6-enabled Windows installation. (Strangely, using in the nginx.conf’s FastCGI section above is okay though.)
    • Unfortunately, “start php-cgi.exe” will show a separate “Command Prompt” window which will remain visible; the “/min” parameter flag is used to minimize that window. If you really want to prevent that window from appearing, you’ll need to use a VBScript to execute the batch file.
    • The order in which Nginx and php-cgi are launched does not matter.
    • The PHP distribution has a “php-win.exe” file which supposedly is the same as “php-cgi.exe” but without throwing up a “Command Prompt” window; however, I could not get “php-win.exe” to run as a server.
  3. Add the following to the bottom of the “stop_nginx.bat” file:
    REM Stop php-cgi
    tasklist /FI "IMAGENAME eq php-cgi.exe" 2>NUL | find /I /N "php-cgi.exe">NUL
    IF "%ERRORLEVEL%"=="0" (
       REM php-cgi is currently running, so quit it
       taskkill /f /IM php-cgi.exe
       ECHO php-cgi killed.
    ) else (
       ECHO php-cgi is not currently running.
  4. Create a PHP test script at “c:\nginx\html\info.php”with the following content:
  5. Run “start_nginx.bat” to launch Nginx and php-cgi. Browse to http://localhost/info.php and you should see information about the PHP installation.

Install MySQL

Let’s get MySQL up and running:

  1. Download the latest MySQL Community Server. I suggest the “ZIP Archive” distributions, either the 32-bit or 64-bit version. Click the Download button. You don’t need to log in to download, just click the “No thanks, just start my download” link at the bottom of the page.
  2. Unzip to a directory like “c:\nginx\mysql”.
  3. Select the default MySQL configuration:
    copy c:\nginx\mysql\my-default.ini c:\nginx\mysql\my.ini
  4. Initialize MySQL by running the “Command Prompt” as an administrator (so Windows registry keys and service can be created) and these commands:
    # Current directory must be the MySQL installation directory
    cd c:\nginx\mysql

    # Initialize database with root user and blank password
    bin\mysqld --initialize-insecure

    # Install MySQL as a Windows service
    bin\mysqld --install-manual

    # Start MySQL Server service
    net start mysql
  5. Test by running these commands (administrator privileges not required):
    # Run MySQL client, skipping password input since blank
    c:\nginx\mysql\bin\mysql.exe -u root --skip-password

    # Run some commands and a query
    mysql> SHOW databases;
    mysql> USE mysql;
    mysql> SHOW tables;
    mysql> DESC user;
    mysql> SELECT * FROM user;

    # Assign new root password
    mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';

    # Quit MySQL client
    mysql> quit;

    # Run MySQL client with password prompt
    c:\nginx\mysql\bin\mysql.exe -u root -p
    # Input the new_password
  6. Enable PHP mysqli extension by uncommenting the line below in “c:\nginx\php\php.ini”:
  7. Create a test script named mysql.php with the following content:
    // HTML response header
    header('Content-type: text/plain');

    // Database connection parameters
    $DB_HOST = 'localhost';
    $DB_PORT = 3306; // 3306 is default MySQL port
    $DB_USER = 'root';
    $DB_PASS = ''; // blank or new_password
    $DB_NAME = 'mysql'; // database instance name

    // Open connection (all args can be optional or NULL!)
    $mysqli = new mysqli($DB_HOST, $DB_USER, $DB_PASS, $DB_NAME, $DB_PORT);
    if ($mysqli->connect_error) {
      echo 'Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error . PHP_EOL;
    } else {
      // Query users
      if ($result = $mysqli->query('SELECT User FROM user')) {
        echo 'Database users are:' . PHP_EOL;
        for ($i = 0; $i < $result->num_rows; $i++) {
          $row = $result->fetch_assoc();
          echo $row['User'] . PHP_EOL;
      } else {
        echo 'Query failed' . PHP_EOL;

    // Close connection
  8. Run “stop_nginx.bat” followed by “start_nginx.bat” to restart Nginx and php-cgi processes. Browse to http://localhost/mysql.php and you should see a listing of the MySQL database users.
  9. You can stop and/or uninstall the MySQL Server service by running “Command Prompt” as an administrator and issuing these commands:
    # Stop MySQL Server service
    net stop mysql

    # Uninstall MySQL Server service
    sc delete mysql

You don’t have to run MySQL Server as a Windows service. Instead, you can run MySQL Server from the “Command Prompt” (administrator privileges not required) like so:

# Start MySQL Server

# Stop MySQL Server
c:\nginx\mysql\bin\mysqladmin.exe -u root shutdown

Unfortunately, the “mysqld.exe” will take control of the “Command Prompt” window and the “start” command does not work in this case, so you will need to open a second “Command Prompt” window in order to issue the shutdown command.

Some info taken from:


Install Eclipse Indigo 64bit on Windows 7 64bit

Windows Development 6 Comments

I recently installed the latest version of Eclipse on Windows 7 64bit and noticed some changes which I wanted to document below. I will copy some tips from my previous posts concerning Eclipse (on Mac OS X and Windows) here for your convenience.

Note: These instructions also work for the latest Eclipse Juno version. Just replace references to Indigo, like in the Eclipse plugin URLs, with Juno.

Install Eclipse

  1. Download the latest Eclipse. I chose the “Windows 64 Bit” download link for the “Eclipse IDE for Java Developers” package. (I downloaded a zip archive named “”.)
  2. Unzip the Eclipse zip archive using WinZip or 7-Zip (7-Zip is free). Do not use Windows’ built-in zip support as it will create a corrupt Eclipse installation. (Update: With the latest Eclipse Juno release, Winzip will return an error. 7-Zip will still work fine.)
    • When I attempted to run Eclipse after unzipping with the Windows’ built-in zip support, I got an error. In the error log file was this exception: “java.lang.IllegalStateException: Unable to acquire application service. Ensure that the org.eclipse.core.runtime bundle is resolved and started (see config.ini).” I was not able to find the “config.ini” file.
  3. Start Eclipse and select your workspace location. (If you select an old location which was used by an older version of Eclipse, make sure to delete the “.metadata” sub-directory there first; otherwise, your new Eclipse will display old plug-ins and IDE modes which may not be installed.)
  4. The latest Eclipse versions set the default search behavior to reuse the editor. This default behavior can be annoying because it prevents you from being able to simultaneously view more than one search result. Opening a new search result would reuse the editor tab and cause the previous search result to become unavailable. To configure Eclipse to open each search result in a new editor tab, do the following:
    • Go to menu “Windows->Preferences->General->Search”.
    • Uncheck the “Reuse editors to show matches” option.

Install Javascript Development Tools (JSDT)

  1. Run Eclipse.
  2. Go to the Eclipse menu “Help->Install New Software…”
  3. Click on the dropdown arrow for the “Work with:” box and select “Indigo –”. (If you don’t see this entry, just type in the URL manually.) The table will populate with a bunch of Indigo-compatible plugins (it may take a couple of minutes to do so the first time).
  4. Type “javascript” into the “type filter text” field to show only the Javascript related plugins.
  5. Check the “JavaScript Development Tools (JSDT)” (under “Programming Languages”) and click Next, Next, accept the license, Finish.
  6. Click on “Restart Now” to restart Eclipse.

Install PHP Development Tools (PDT)

To install the PDT, repeat the steps above with the following modifications:

  1. Type “PHP” into the “type filter text” field to show only the PHP related plugins.
  2. Check the “PHP Development Tools (PDT)” (under “Programming Languages”) and click Next, Next, accept the license, Finish.
  3. Note: For Eclipse Juno, when I first selected the PDT under “Programming Languages”, the installation failed. When I then selected the PDT under “General Purpose Tools” after restarting Eclipse, it installed successfully. So if it fails for you, just restart Eclipse and try again with the PDT under “General Purpose Tools”.

Install Subversion Integration (Subclipse)

  1. Run Eclipse.
  2. Go to the Eclipse menu “Help->Install New Software…”
  3. Type “” into the “Work with” field and the table will be updated with installation packages available at that location.
    • You can look up the latest Eclipse update site URL for Subclipse here.
  4. Check the “Subclipse” package and click Next, Next, accept the license, Finish.
  5. If the Security Warning dialog about the “unsigned content” appears, click Ok to accept.
  6. Click on “Restart Now” to restart Eclipse.

Note: If you install a command line Subversion client (I’ve successfully used the CollabNet Subversion Client on Windows 7 64bit) and put it in the Windows search path (%PATH% environment variable), make sure that the Subversion client version is compatible with Subclipse. Otherwise, Subclipse will stop working. For example, Subclipse 1.8.x is compatible with Subversion 1.7.x.

Problem: I cannot pin Eclipse to the taskbar!

If you find that you cannot pin the running Eclipse icon (right-click menu doesn’t have the option) to the Windows 7 taskbar, it may be because Eclipse is using the JRE (“C:\Windows\System32\java.exe”), instead of the JDK. Even if you find the Eclipse.exe file directly and pin it (using the right-click menu), when you run Eclipse, the running Eclipse icon will be a separate, second icon in the taskbar.

The solution is to install the JDK (Java SDK 1.6 or newer), set the %JAVA_HOME% environmental variable to the JDK directory, and set the %PATH% to have “%JAVA_HOME%\bin” as the first entry. This will ensure that Eclipse will use the JDK and you will then be able to pin the running Eclipse icon to the taskbar.

  1. Right click on Start->Computer and select Properties.
  2. Click on the “Advanced system settings” link on the left and then the “Environment Variables” button.
  3. Under “System variables”, click on the “New…” button, input JAVA_HOME as the name and the JDK installation path as the value, and click OK.
  4. Under “System variables”, double-click on the “Path” variable and add “%JAVA_HOME%\bin;” (without double-quotes) to the front of the “Path” value, and click OK.
  5. Run Eclipse and pin its icon to the taskbar.

Problem: Eclipse complains about a missing org.eclipse.swt jar file!

Note: This issue occurs with Eclipse Mars, a newer version than Indigo.

When attempting to do an Ant build, Eclipse throws the following error message: “The archive: C:/Program%20Files/eclipse_lunar/plugins/org.eclipse.swt.win32.win32.x86_64_3.104.0.v20150528-0211.jar which is referenced by the classpath, does not exist.”

This is an Eclipse Mars bug which occurs when Eclipse is installed under a directory path with a space in its name, such as “C:\Program Files”.

To fix, create the requested “C:\Program%20Files” as a symbolic link:

mklink /d C:\Program%20Files "C:\Program Files"

Setup Android Development on Windows 7 64bit

Windows Development 39 Comments

androidwindowsRecently, I started looking into Android development. What I found was that it was very easy to do Android application development and best of all, it is free (unlike Apple’s $99/year development fee). All you need is a computer, your Android phone, and a USB cable to connect the two. (Actually, you don’t even need a phone because you can use an emulated Android phone.)

Here are the steps I took to setup an Android development environment on my Windows 7 64bit desktop:

  1. Download Java JDK 64bit. I downloaded “jdk-6u24-windows-x64.exe” and ran it to install the JDK.
    • Add these User environment variables by running “Edit the system environment variables”, clicking “Environment Variables” button, and setting the following under “User variables…”:
      JAVA_HOME=C:\Program Files\Java\jdk1.6.0_24
    • Test by opening a command prompt and running “javac -version” to check that Windows can successfully find the javac.exe executable in the PATH.
  2. Download Eclipse 64bit. I downloaded “” and unzipped it to a convenient directory. You can run Eclipse by launching “eclipse.exe”.
  3. Download the Android SDK. I downloaded “” and unzipped it to “C:\Bin\android-sdk-windows”.
    • Important: The Android SDK path must not contain a space!
    • Add these User environment variables using “Edit the system environment variables” like above:

      Note: We just appended the %SDK_ROOT% paths to the existing PATH definition which has the previous %JAVA_HOME% path.

  4. Download the platform files for the Android SDK using the SDK Manager (which is installed as part of the SDK) by following the instructions below.
    • Manually create two folders, “add-ons” and “platforms”, under the %SDK_ROOT% directory. If you don’t, you will see an error like “Error: Error parsing the sdk.” or “Error: C:\Bin\android-sdk-windows\platforms is missing.” in the next step.
    • Run the SDK Manager to download the SDK; look for “SDK Manager.exe” in the %SDK_ROOT% directory. Alternatively you could run from the command line: “android.bat update sdk”.
    • You can use the initial “Choose Packages to Install” dialog to select or reject packages, or you can cancel it and do the following:
      • Select “Available packages” on left.
      • Expand the “Android Repository” on right.
      • Check “Android SDK Platform-tools, revision 3”.
      • Check the Platform, Documentation, or Samples for the Android OS version you want to develop on (which should match the Android OS version on your Android phone). (Eclaire is 2.1, Froyo is 2.2, Gingerbread is 2.3.)
      • For more details on the packages, check the Android SDK Install Guide.
  5. Add the Android Eclipse Plugin (ADT) to Eclipse:
    • Run Eclipse.
    • Select Help->Install New Software…
    • In the “Work with:” field, replace the “type or select a site” with “”.
    • Expand “Developer Tools”.
    • Check the “Android Development Tools” box.
    • Click Next, Next, select Accept License…, click Next.
    • Accept the unsigned warning to continue installation.
    • Restart Eclipse.
  6. Configure the ADT:
    • Under Eclipse, go to menu Windows->Preferences.
    • Select Android
    • In the “SDK Location”, browse to your android install directory %SDK_ROOT%.
    • Hit Apply and you should see the Android platform versions you installed earlier populate the table.

Now that you are all setup, let’s use Eclipse to create a project, build it, and then test it.

  1. Create an Android project:
    • Under Eclipse, go to menu File->New->Project…->Android->”Android Project”.
    • Select the Android version in the “Build Target”.
    • Input the “Project name”, “Application name”, and Activity (the primary java class’s filename). (These can all be the same like “HelloWorld”.)
    • Input the Java package hierarchy like “”.
    • Input the “Min SDK Version” like the 8 for Froyo 2.2’s API Level.
    • Click Finish and the project will be created.
  2. Create an emulated Android for our development purpose.
    • Under Eclipse, go to menu Windows->”Android SDK and AVD Manager”.
    • Select “Virtual devices” on the left.
    • Click the New button on the right.
    • Input a name for your virtual device, select a target which should be the same as your project’s build target.
    • Click on “Create AVD” and close this dialog.
    • Click on the Workbench icon on the top-right or close the Welcome tab to see your newly-created project in the Package Explorer.
  3. Under Eclipse, to build and run the project, click on menu Run->Run.
    • The virtual android device should be selected automatically or you will be prompted to select it.
    • To modify this, check menu Run->”Run Configurations…” and select the Target tab for your Android application. Pick Manual so you can have the option to select a real Android phone instead of the virtual one later.
  4. Connecting an Android phone to your computer
    • You will need to find and install the USB drivers for your Android phone. You can usually find them on the phone manufacturer’s website.
    • Note: If you cannot find your Android phone’s USB drivers for your operating system (for example, Windows 7 64bit), try installing PDAnet. It is a free tethering application which comes with USB drivers for a bunch of phones. Make sure to disconnect the phone before installing PDANet.
    • On the phone, go to Settings->Applications->Development and enable “USB debugging” before reconnecting the phone to the computer. This will allow Eclipse to install onto and debug applications on your Android phone.

Hopefully the guide above will help you get started with Android Development. Have fun!

Info above derived from the following sources:


Secure Subversion on the XAMPP Apache Server

Windows Development 2 Comments

To secure subversion, we just need to create a password file and configure apache to use it for subversion repository access.

  1. Open up the apache config file “C:\xampp\apache\conf\httpd.conf”. At the end, look for the subversion repository URL location and add the additional text below, starting with “AuthType”:
    <Location /repos>
        DAV svn
        SVNPath c:/svn_repos

        AuthType Basic
        AuthName "Subversion Repository"
        AuthUserFile conf/svn-password.pass
        Require valid-user
  2. Create the “svn-password.pass” file by launching the “Start->All Programs->Accessories->command Prompt” and running these commands:
    c:\xampp\apache\bin\htpasswd.exe -cm c:\xampp\apache\conf\svn-password.pass username1
    c:\xampp\apache\bin\htpasswd.exe -m c:\xampp\apache\conf\svn-password.pass username2
    c:\xampp\apache\bin\htpasswd.exe -m c:\xampp\apache\conf\svn-password.pass username3

    You will be prompted to input the password for each user. I’m suggesting that the full path to htpasswd.exe be used because other programs (such as PUTTY) may have incompatible versions.

  3. Restart the Apache server.
  4. Browse to http://localhost/repos/ and you will be asked to input a username and password.

Additionally, we can create an authorization file to assign permissions to users or groups of users.

  1. Open up the apache config file “C:\xampp\apache\conf\httpd.conf”. At the end, look for the subversion repository URL location and add the additional line called “AuthzSVNAccessFile”:
    <Location /repos>
        DAV svn
        SVNPath c:/svn_repos
        AuthType Basic
        AuthName "Subversion Repository"
        AuthUserFile conf/svn-password.pass
        AuthzSVNAccessFile conf/svn-authz.conf
        Require valid-user
  2. Create the “c:\xampp\apache\conf\svn-authz.pass” file. Here is some example content:
    devteam = username1,username2
    qateam = username3,username4,username5

    @devteam = rw
    username6 = r

    @devteam = rw
    @qateam = r
    username7 = rw
  3. Restart the Apache server.
  4. Browse to http://localhost/repos/ and you will be prompted to input a username and password.
  5. When using the subversion command line, you can use the –username flag to pass in your username the first time:
    svn --username username1 co http://localhost/repos/myproject

The info above was derived from How to Setup Subversion + Apache + WebSVN.


Using Eclipse to Debug PHP

Windows Development 1 Comment

With EasyEclipse and the PHP Debugger extension, you can debug and step through a PHP call.

Installing the PHP Debugger (DBG) Extension

  1. Download the PHP Debugger (DBG); specifically the DBG 2.15.5 dbg modules for windows.
  2. Unzip the dbg modules to a temporary directory.
  3. Copy the relevant php extension file, currently “x86\php_dbg.dll-5.2.x” in the archive (since XAMPP 1.6 comes with PHP 5.2.5), to the extension directory “c:\xampp\php\ext” and rename it to “php_dbg.dll”.
  4. Open up the “c:\xampp\apache\bin\php.ini” config file.
    • Add this to the end of php.ini:
      debugger.ports=7869, 10000/16
    • Search for the first instance of “zend_extension_ts” in php.ini (it should be right underneath the “[Zend]” section) and before it, add this line:
      zend_extension_ts = "c:\xampp\php\ext\php_dbg.dll"
  5. Verify that the DBG Extension is loaded:
    • Stop and start the apache http server (a reload or restart won’t work).
    • Create a phpinfo.php file with this content:
      <title>PHP Test Script</title>
    • Install phpinfo.php under the apache root document directory and then browse to it. You will see the info on the PHP environment. If DBG is installed correctly, you should see this line:
      Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies
          with DBG v2.15.5, (C) 2000,2007, by Dmitri Dmitrienko
    • Search on “dbg” and you will see the configuration section for dbg also.

Disabling PHP Debugging

  • Once you have installed the DBG extension, debugging will be enabled and for any PHP file that is browsed to, the PHP engine will attempt to debug and fail because we have not setup a PHP Debugger service yet.
  • To disable debugging permanently:
    1. Open up the “c:\xampp\apache\bin\php.ini” config file.
    2. Change the “debugger.enabled=on” to “debugger.enabled=off”.
    3. Restart the Apache HTTP server.
  • To disable debugging for the current active HTTP session:
    1. Browse to “http://localhost/myproject/index.php?DBGSESSID=-1”.
    2. This URL will remove the cookie added by the DBG extension to enable PHP debugging.

Starting the PHP Debugger Service

In order for PHP debugging to work, we must configure and start a PHP Debugger service using EasyEclipse:

  1. Run EasyEclipse and go to menu “Run->Debug…”. If you don’t see the Run->Debug menu, then open up the Debug perspective, switch back to PHP perspective, and try again.
  2. Select and highlight the “PHP DBG Script” and click on the New icon on the upper-left.
  3. Input whatever Name you want.
  4. Under the File tab, input “index.php” (or your main entrypoint PHP file). (Alternatively, you can Browse… and select it.)
  5. Under the Arguments tab, you should see “Use default working directory” checked and the “Working Directory” is “C:\Projects”.
  6. Under Environment tab:
    • Under the Interpreter sub-tab, click the New button and browse to “c:\xampp\php\php.exe”
    • Under the “Remote Debug” sub-tab, check “Remote Debug” and uncheck “Open with DBGSession URL in internal Browser”. Make sure that the Remote Sourcepath is “C:\Projects\myproject”.
    • Note: It is very important that the Remote Sourcepath (and all other paths) is set correctly; otherwise the PHP debug won’t work.
  7. Hit the Apply button.
  8. Start the PHP Debugger service by clicking on the Debug button below the Apply button. Take note of the port number (should be 10001) that the PHP Debugger service is listening on.

Debug Tracing PHP

  1. Open up “index.php” and set a breakpoint inside it (I suggest setting a breakpoint in the main entry routine).
    • You can set a breakpoint by clicking on the leftmost vertical blue bar in the file viewer. You should see a blue dot show up and an entry added to the Debug perspective’s Breakpoints window.
    • Alternatively, you can right-click on the leftmost vertical blue bar and select “Toggle PHP Breakpoint”.
  2. Browse to “http://localhost/myproject/index.php?DBGSESSID=1@localhost:10001” and the breakpoint should be hit. You can then step into, over, or out. Yippee!
    • Note: The 10001 in “localhost:10001” should match the port that the PHP Debugger is listening on in the EasyEclipse debug window.
    • Passing in the request parameter DBGSESSID will create a cookie (session based), so you no longer have to pass in the DBGSESSID http parameter in subsequent requests. Yipee again!
  3. Disable debug tracing for the current session by browsing to “http://localhost/myproject/index.php?DBGSESSID=-1”. Adding the parameter “DBGSESSID” with value “-1” will delete the debugging cookie.
  4. CAVEAT: Unfortunately, there is a bug with the PHP Debugger service in that after servicing the HTTP request, the PHP Debugger service will terminate.
    • You can quickly start the PHP Debugger service again by hitting F11 shortcut key. You will want to do this after each HTTP request is debugged.

Note: Some info above was derived from XOOPS Docman – Installing DBG.

1 Comment

Using Eclipse to Develop in PHP

Windows Development No Comments

easyeclipseThe EasyEclipse distribution is a quick and easy packaging of Eclipse with plugins for different purposes. I recommend using EasyEclipse for PHP which comes with PHP edit mode and useful plugins like SubEclipse for subversion source control integration.

  1. Download and install the latest version of EasyEclipse for PHP.
    • When you launch EasyEclipse, it will prompt you for the workspace directory. Input “c:\projects”. If EasyEclipse doesn’t prompt you for a workspace and instead uses a workspace from an old project, you can manually change the workspace by going to menu “File->Switch workspace”.
    • Note: It is not recommended for you to move or rename your workspace directory once created. The workspace properties have a reference to the original workspace directory.
  2. At this time, checkout the myproject codeline to c:\projects.
    • Go to the EasyEclipse menu “File->New->Project->SVN->Checkout Projects from SVN”.
    • Enter the Repository URL: http://localhost/repos/
    • Then select directory: /myproject
    • Change the project name to: myproject
  3. Edit PHPEclipse options to run XAMPP server:
    • Go to the php external tools settings “Windows->Preferences->PHPeclipse Web Development”. (The following steps will be referenced off of this location.)
    • Set the xampp start and stop buttons under “PHP External Tools->XAMPP”.
    • Set the DocumentRoot path under “Project Defaults” to: C:\projects
    • Add the following to the “Include Paths” under “Project Defaults” to: C:\projects\myproject
    • (Optional) Turn off php file browser preview. Under “Browser Preview Defaults”, uncheck “Refresh PHP browser view…” and “Show PHP browser view…” selections.
  4. (Optional) Configure the tab width to be 3:
    • Go to “Windows->Preferences->PHPeclipse Web Development->PHP”
    • Set “Displayed tab width” to 3.
  5. (Future) Synchronize your source to the latest SVN repository:
    • In the left-hand Navigator, right-click on “myproject”.
    • Select right-click menu “Team->Update”.
  6. Hint: If you are not in PHP edit mode, you can always go to it by going to menu “Windows->Open Perspective->PHP”

Note: If the subversion commands you issue using SubEclipse return errors, you may have an incompatible SVN install directory in the “path” environmental variable. To resolve this, you can remove the SVN install directory from the “path” environmental variable or you can re-install a compatible SVN version. For example, SVN 1.4.6 is compatible with SubEclipse 1.2.1 which comes with EasyEclipse 1.2.2.

No Comments

Add Subversion to the XAMPP Apache Server

Windows Development 9 Comments

subversionSubversion is a simple and popular source control system. It has the option of running as part of the Apache server. We’ll examine how to quickly get subversion up and running with the Apache server which comes with XAMPP.

  1. Download the latest subversion windows archive. Look for a file named “” (or with a later version number) at the bottom of the list.
  2. Unzip it to a local directory “c:\bin” and you will end up with “c:\bin\svn-win32-1.4.6”.
    • Add “c:\bin\svn-win32-1.4.6\bin” to the end of the Windows “path” environmental variable. This will allow us to run the command line subversion client and repository administration tool.
    • Warning: If you use Eclipse and the SubEclipse plugin, putting subversion in the “path” environmental variable may break the SubEclipse plugin. If this happens, just remove subversion from the “path” environmental variable and use Eclipse to perform subversion functions exclusively. Or ensure that your installed SVN version is compatible with SubEclipse; for example, SVN 1.4.6 is compatible with SubEclipse 1.2.1.
    • Also set “SVN_EDITOR=notepad.exe” to identify the default text editor to be used by the subversion command line tools.
  3. Create an initial blank repository called “svn_repos” by launching the command prompt window and running:
    svnadmin create c:\svn_repos
  4. Configure apache to use the subversion module
    • Stop the Apache server
    • Copy the apache module “c:\bin\svn-win32-1.4.6\bin\” into the apache modules directory “C:\xampp\apache\modules”. Go ahead and overwrite the existing “” file as it is from an older version of subversion.
    • Open up the apache config file “C:\xampp\apache\conf\httpd.conf”
    • Enable the subversion module by adding “LoadModule dav_svn_module modules/” anywhere after the existing “LoadModule dav_module modules/” line. The best thing would be to add it as the last LoadModule line.
    • At the end, add a URL location (what you would enter into the browser or your subversion client) for your repository:
      <Location /repos>
          DAV svn
          SVNPath c:/svn_repos
    • Start the Apache server
    • You can access the repository using the URL “http://localhost/repos”. You should see a “Revision 0” header with no other data. If you get an error, check the “C:\xampp\apache\logs\error.log” file for details on the problem.
    • Note that you will need to add a location block like the above for each repository that you create with “svnadmin create”. (You shouldn’t need to do this because a repository can contain as many projects as you want.)
    • Note: we have not secured the repository so anyone can read or write to it. To secure subversion, see my followup post.
  5. Import an existing project (source code directory) into the “svn_repos” repository
    • If you have source code in a project directory like “c:\oldprojects\myoldproject”, you can import the contents of “myoldproject” into the subversion “svn_repos” repository by running this command:
      svn import c:\oldprojects\myoldproject http://localhost/repos/myproject -m "Initial import"
    • The comment “-m “Initial import”” is optional. If you don’t input it, the default subversion editor (“notepad.exe”) will appear. Add your import comment and save the file. If you close the file without making any changes, you will need to input “c” into the command prompt window to continue the import.
    • Browse to “http://localhost/repos/myproject” and you should see “Revision 1” header with the list of folders and files that have been imported.
  6. You can create a new empty project by creating an empty folder and importing it (see above).
  7. Checkout the initial “myproject” project to create a local working copy
    • Open the command line and go to the “c:\projects” directory.
    • Check out “myproject” by issuing the following command:
      svn co http://localhost/repos/myproject myproject
    • You will see a “c:\projects\myproject” directory with your imported folders or files (if you did the import step above). If you didn’t import, you will see an empty directory except for a “.svn” subdirectory; don’t touch the “.svn” subdirectory as it is used by the subversion client for bookkeeping.
  8. Inside your local working copy “c:\projects\myproject”, you can issue the following common subversion commands:
    • To update your local working copy with the latest revision from the repository:
      svn update
    • To add a new file:
      svn add newfile.cpp
    • To remove a file:
      svn rm oldfile.cpp
    • To move and/or rename a file:
      svn mv oldfile.cpp subdir/newoldfile.cpp
    • List the changes (aka status) that you have made to your working copy:
      svn st
    • To commit (aka checkin) the local working changes to the repository:
      svn ci -m "my checkin comments"

      If you don’t input the comment using the “-m” flag, the default editor (“notepad.exe”) will open to allow you to input the comment.

  9. To ignore certain subdirectories or files that you do not wish to check into subversion
    • Go to the directory containing the subdirectories or files to be ignored and run this command:
      svn propedit svn:ignore .
    • The default editor (“notepad.exe”) will open. Input the subdirectory and file names, one per line.
    • Instead of putting the exact filename, you can use a file pattern like “*.obj”.
    • Save and close the file.
    • To make this change permanent, issue a “svn ci” command.
    • You can also create a text file “ignore.txt” containing the subdirectory, filenames, and file patterns that you wish subversion to ignore, and apply it recursively to the current and all subfolders by running:
      svn propset -R svn:ignore . -F ignore.txt

Some info above derive from Ned Batchelder: Subversion on Windows quick start.


Setting Up an Apache, MySQL, PHP Development Environment with XAMPP

Windows Development 2 Comments

Rather than installing Apache, MySQL, and PHP individually, XAMPP is an integrated development enironment that combines all three (and more) into one easy installation.

  • Download XAMPP and install it into the default “c:\xampp” directory. Set apache and mysql to start as services.
  • Start XAMPP and browse to “http://localhost/” and you will see a welcome message.
  • If you don’t want to use the default “c:\xampp\htdocs” directory as your document root, you can update the DocumentRoot “C:/xampp/htdocs” property and <Directory “C:/xampp/htdocs”> element in the “c:\xampp\apache\conf\httpd.conf” file. The result should look like:
    DocumentRoot "c:/projects"
    <Directory />
    ... do not change this / default root block...
    <Directory "c:/projects">
  • Likewise, if you use SSL, update DocumentRoot “C:/xampp/htdocs”
    in “c:\xampp\apache\conf\extra\http-ssl.conf”.
  • Note: XAMPP uses the “c:\xampp\apache\bin\php.ini” when running PHP. There is a second “c:\xampp\php\php.ini” which is used if you call “c:\xampp\apache\bin\php.exe” from the command line.
  • Edit “c:\xampp\apache\bin\php.ini” to enable logging by setting the following properties:
    error_reporting = E_ALL
    log_errors = On
    error_log = "C:\xampp\apache\logs\phperror.log"
  • To enable access to the original XAMPP htdocs directory, we can create a subpath redirect to it using the alias function.
    1. Edit “c:\xampp\apache\conf\httpd.conf” and locate the <Directory “C:/projects”> block (or whatever path you had selected as document root).
    2. Immediately after the whole <Directory> block above (look for the matching end tag </Directory>), add the following text:
      # Allow access to the original xampp htdocs
      Alias /htdocs C:/xampp/htdocs
      <Directory "C:/xampp/htdocs">
          Options Indexes FollowSymLinks Includes ExecCGI
          AllowOverride All
          Order allow,deny
          Allow from all
    3. Adjust the htdocs files to account for the base URL change:
      • Edit “c:\xampp\htdocs\index.php”, locate header(‘Location: ‘.$uri.’/xampp/’);, and change that to be header(‘Location: ‘.$uri.’/htdocs/xampp/’);.
      • Repeat the above for “c:\xampp\htdocs\xammp\index.php” and “c:\xampp\htdocs\xampp\lang.php”.
      • Edit “c:\xampp\htdocs\xampp\splash.php”, locate
        <a href=”/xampp/lang.php?’.$key.'”>
        , and change that to be <a href=”/htdocs/xampp/lang.php?’.$key.'”>.
    4. Start XAMPP, open your browser to “http://localhost/htdocs” and you will see the original xampp htdocs directory.
  • If you attempt to access Apache from another machine in your network and your brower returns an access error, you may need to adjust your Windows Firewall. The latest version of Windows Firewall forces you to manually open up ports for services.
    1. Go to Start, Control Panel, Windows Firewall and click on the Advanced tab.
    2. Make sure that “Local Area Connection” is checked and hit the Settings button to the right of it.
    3. Under Services tab, make sure that “Web Server (HTTP)” is checked.

« Previous Entries