Solved – error while loading shared libraries: libpangox-1.0.so.0: Anydesk on Ubuntu 22.04 LTS

Resolve the “libpangox-1.0.so.0” Anydesk shared library error on Ubuntu 22.04 LTS with this easy step-by-step fix and download instructions.

After successfully upgrading from Ubuntu 20.04 LTS to 22.04 LTS, most of the applications are working perfectly. But, some of the applications behave unusually. Such as, I tried to run the Anydesk application, but it doesn’t launch/start. when I checked the status service, the AnyDesk service was failed and the reason for failing is mentioned in the below error message,

anydesk: error while loading shared libraries: libpangox-1.0.so.0: cannot open shared object file: No such file or directory

What is libpangox library?

libpangox-1.0.so.0 is a anydesk shared library used for text layout and rendering the text. Most of the work on Pango-1.0 was done using the GTK+ widget toolkit as a test platform.

Install the library

So, I ran the command to install it using the apt as follows,

sudo apt install libpangox-1.0-0

But, it gives me the following error,

Package libpangox-1.0-0 is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or is only available from another source

So, from this error we can understand that, libpangox-1.0.so.0 can’t be installed from apt or apt-get. We need to install it manually.

Use the following steps to install libpangox-1.0.so.0 manually,

Step 1. Download the libpangox-1.0 package

You need to manually download the .deb file using wget command. This package is available to many package libraries. I have downloaded it from Debian Package Library.

wget http://ftp.us.debian.org/debian/pool/main/p/pangox-compat/libpangox-1.0-0_0.0.2-5.1_amd64.deb

Step2: Install the package using apt

Install the downloaded .deb file using apt command as follows,

sudo apt install ./libpangox-1.0-0_0.0.2-5.1_amd64.deb

Step3: Restart the AnyDesk service

After successful installation, restart the anydesk service.

sudo service anydesk restart

After these steps, if you check the AnyDesk service status, it will show active (running).

Advanced Error Handling in PHP (Part 2)

Explore advanced techniques for error handling in PHP including exceptions, custom error handlers, and best practices in Part 2 of this series.

In this second part of our series, we’ll dive deeper into error handling in PHP. We’ll cover how to read, process, and present your error logs so you can monitor and debug more effectively. If you haven’t gone through Part 1 (logging errors), it’s a good idea to start there first.

Reading Error Logs Programmatically

Once you have error logs being generated, the next step is to read them in a usable way. The goal is to convert the log file into a structured format, so you can display recent errors first, filter entries, etc to make error handling easy.

Here is a sample PHP method that reads an error log file:

public function errorLogs($filePath = 'error.log') {

        $fileContent = file($filePath);

        $errorsArray = array();
        if(sizeof($fileContent) == 0) {
            return false;
        }

        foreach($fileContent as $row) {
            $errors = explode(":  ", $row);

            if(empty($errors[1])) continue;
            $errorsArray[] = $errors;
        }

        return array_reverse($errorsArray, true);
}

Explanation:

$fileContent = file($filePath);

This line of code will read the file line by line from the provided file path.

if(sizeof($fileContent) == 0) {
    return false;
}

Checks whether the file is empty; if yes, returns false to indicate there’s nothing to process.

foreach($fileContent as $row) {
      $errors = explode(":  ", $row);

      if(empty($errors[1])) continue;
      $errorsArray[] = $errors;
}

This part of the function will loop through the log contents row by row.

explode(": ", $row)

Splits each line at the pattern ": " — usually separating a timestamp from the error message.

if (empty($errors[1])) continue;

Skips any lines that don’t have an error message portion after splitting.

$errorsArray[] = $errors;

Adds the parsed pieces to an array.

return array_reverse($errorsArray, true);

Reverses the order, so the newest log entries appear first in whatever display you build.

Why You’d Do This

Prioritize recent errors: By reversing the array, newer errors show up first so you don’t have to scroll through older logs.

Filter out noise: Skipping lines with missing data helps prevent malformed entries from causing trouble.

Make things display-friendly: Once you have structured data (e.g. timestamp + message), you can feed this into UI tables or dashboards.

Beginner’s Guide to Error Handling in PHP – Part 1

Learn the basics of error handling in PHP. Understand production safety and developer insights with logging errors using error_reporting.

Effective error handling in PHP is essential for developers—it helps identify issues while keeping your production environment secure and user-friendly.

Balancing Error Display vs. Security

On a production server, showing PHP errors directly on the screen poses security risks, as they may reveal sensitive file paths or internal logic. Hence, many developers suppress error display using:

ini_set('error_reporting', 0);
error_reporting(0);

ini_set('display_errors', FALSE);

However, completely hiding errors without logging them makes debugging nearly impossible.

Capturing and Logging Errors Safely

A more practical approach is to keep errors hidden from users but log them for developers to review, like below:

ini_set('error_reporting', E_ALL);
error_reporting(E_ALL);

ini_set('log_errors', TRUE);
ini_set('html_errors', FALSE);
ini_set('error_log', LOG_PATH.'error.log');

ini_set('display_errors', FALSE);

Explanation:

  • Enable reporting for all errors (E_ALL), ensuring nothing is missed.
  • Direct errors to logs, turning off HTML formatting (html_errors = FALSE) for cleaner log formatting.
  • Specify a custom log file path (via LOG_PATH . 'error.log'), enabling modular logging for different parts of your application.
  • Disable display of errors to protect end users from seeing raw error output.

Benefits of This Approach

  • Production safety: Users can’t see system internals or error details.
  • Developer insight: All error information will be logged in centralized log files.
  • Modular logging: You can segregate logs per module for quicker diagnostics.

Would you like to learn advanced error handling techniques in PHP like exceptions, custom handlers, or reading log files? Just let me know—happy to continue!

Setup and use a virtual python environment in Ubuntu

With virtualenvwrapper (user-friendly wrappers for the functionality of virtualenv)

Install virtualenv

Install virtualenv with

sudo apt-get install virtualenv

(for Ubuntu 14.04 (trusty) install python-virtualenv)

Install virtualenvwrapper

The reason we are also installing virtualenvwrapper is that it offers nice and simple commands to manage your virtual environments. There are two ways to install virtualenvwrapper:

As Ubuntu package (from Ubuntu 16.04)

Run sudo apt install virtualenvwrapper then run echo "source /usr/share/virtualenvwrapper/virtualenvwrapper.sh" >> ~/.bashrc

Using pip

  1. Install and/or update pip

    Install pip for Python 2 with
    sudo apt-get install python-pip

    or for Python 3
    sudo apt-get install python3-pip

    (if you use Python 3, you may need to use pip3 instead of pip in the rest of this guide).

    Optional (but recommended): 
    Turn on bash autocomplete for pip Run
    pip completion --bash >> ~/.bashrc

    and run 

    source ~/.bashrc 

    to enable.
  2. Install virtualenvwrapper Because we want to avoid sudo pip we install virtualenvwrapper locally (by default under ~/.local) with:
    pip install --user virtualenvwrapper

    and

    echo "export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3" >> ~/.bashrc
  3. Source virtualenvwrapper in .bashrc

    echo "source ~/.local/bin/virtualenvwrapper.sh" >> ~/.bashrc

Setup virtualenv and virtualenvwrapper:

First, we export the WORKON_HOME variable which contains the directory in which our virtual environments are to be stored. Let’s make this ~/.virtualenvs

export WORKON_HOME=~/.virtualenvs

now also create this directory

mkdir $WORKON_HOME

and put this export in our ~/.bashrc file so this variable gets automatically defined

echo "export WORKON_HOME=$WORKON_HOME" >> ~/.bashrc

We can also add some extra tricks like the following, which makes sure that if pip creates an extra virtual environment, it is also placed in our WORKON_HOME directory:

echo "export PIP_VIRTUALENV_BASE=$WORKON_HOME" >> ~/.bashrc

Source ~/.bashrc to load the changes

source ~/.bashrc

Test if it works

Now we create our first virtual environment. The -p argument is optional, it is used to set the Python version to use; it can also be python3 for example.

mkvirtualenv -p python2.7 test

You will see that the environment will be set up, and your prompt now includes the name of your active environment in parentheses. Also if you now run

python -c "import sys; print sys.path"

you should see a lot of /home/user/.virtualenv/... because it now doesn’t use your system site packages.

You can deactivate your environment by running

deactivate

and if you want to work on it again, simply type

workon test

Finally, if you want to delete your environment, type

rmvirtualenv test

Enjoy!

How to Autostart GlassFish Server on Ubuntu Startup

Learn how to configure GlassFish Server to start automatically on system boot in Ubuntu. Step-by-step guide using systemd service scripts.

If you want GlassFish Server to launch automatically when your Ubuntu system boots, you can easily achieve that by creating an init script. This allows you to manage GlassFish’s start, stop, and restart actions seamlessly.

In this article, we learn to create the init script for GlassFish server and how to configure it in Ubuntu systems to control GlassFish server.

Step 1: Create the Init Script

The init script file for GlassFish Server is to be created at /etc/init.d/.

For managing all GlassFish Server startup events, it ships with the asadmin tool. Use this tool in the startup script as follows,

Create GlassFish init file using the following command:

sudo nano /etc/init.d/glassfish

Paste the following lines in the file

#!/bin/sh
# Prevent potential issues by defining Java path
export AS_JAVA=/usr/lib/jvm/jdk1.8.0
GLASSFISHPATH=/home/glassfish/bin

case "$1" in
  start)
    echo "Starting GlassFish from $GLASSFISHPATH"
    sudo -u glassfish $GLASSFISHPATH/asadmin start-domain domain1
    ;;
  stop)
    echo "Stopping GlassFish from $GLASSFISHPATH"
    sudo -u glassfish $GLASSFISHPATH/asadmin stop-domain domain1
    ;;
  restart)
    $0 stop
    $0 start
    ;;
  *)
    echo "Usage: $0 {start|stop|restart}"
    exit 3
    ;;
esac

This script uses asadmin to control the domain named domain1, running it as a dedicated glassfish user for security and proper permissions.

Step 2: Make the Script Executable

Now, glassfish startup script is created. We need to add this file in startup to make Glassfish Server autostart during Ubuntu startup.

Set the appropriate permissions so the system can run it at boot:

sudo chmod a+x /etc/init.d/glassfish

Step 3: Register the Script to Run at Startup

Link it into Ubuntu’s init system to execute during startup:

sudo update-rc.d glassfish defaults

This ensures the script will be triggered automatically during system boot.

Step 4: Validate the Setup

Now, restart Ubuntu and check if it really autostart the Glassfish Server.

Step 5: Validate Manual Commands

You can also manage Glassfish Server startup events as follows,

sudo /etc/init.d/glassfish start  # Start the server
sudo /etc/init.d/glassfish stop   # Stop the server
sudo /etc/init.d/glassfish restart  # Restart the server

Conclusion

Setting up GlassFish to start automatically on boot ensures that your applications and services are always available after a system reboot—without requiring manual intervention. By creating a simple init script and registering it with Ubuntu’s startup sequence, you can streamline your server management and reduce downtime. This method is especially useful for production environments where stability and automation are critical.

If you’re using a newer Ubuntu version that defaults to systemd, consider switching to a systemd service file for even better control and logging.