Wednesday, April 18, 2018

Create a Fragment App with Android Studio 3.1

This is a follow up from my previous Android Fragments in an Activity.

This example, demonstrates how Fragments are created and loaded by an Activity class. Android Studio 3.1.1 is the IDE with Java 1.8.0 and an emulator is created with API 23. All this is running on Centos 7.

Step 1: Create an Empty project with vertical orientation

Open Android Studio and create a new project.
Application name: My Fragment
Click Next

Click Checked for Phone and Tablet
Minimum SDK: choose API 23:Android 6.0 (Marshmallow)
Click Next

Choose "Basic Activity"
Click Next

Activity Name: MainActivity
Layout Name: activity_main
Title: MainActivity

Click checked Use a Fragment

Click "Finish"

This will provide a template to quickly create the rest of Fragments to be used with this Activity.

A total of 23 files are created in the app/src/main folder. By the time all steps are completed, there should be 29 files created in app/src/main folder.
=== Listing of 25 files at start of the project===
app/src/main/res/drawable/ic_launcher_background.xml
app/src/main/res/values/colors.xml
app/src/main/res/values/strings.xml
app/src/main/res/values/dimens.xml
app/src/main/res/values/styles.xml
app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
app/src/main/res/drawable-v24/ic_launcher_foreground.xml
app/src/main/res/mipmap-hdpi/ic_launcher_round.png
app/src/main/res/mipmap-hdpi/ic_launcher.png
app/src/main/res/mipmap-mdpi/ic_launcher_round.png
app/src/main/res/mipmap-mdpi/ic_launcher.png
app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
app/src/main/res/mipmap-xhdpi/ic_launcher.png
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
app/src/main/res/mipmap-xxhdpi/ic_launcher.png
app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
app/src/main/res/layout/content_main.xml
app/src/main/res/layout/activity_main.xml
app/src/main/res/menu/menu_main.xml
app/src/main/java/com/example/nicholas/myfragment/MainActivity.java
app/src/main/AndroidManifest.xml
===
Project Structure of application - Newly create project




A default project contains the following layouts
activity_main.xml
  • CoordinatorLayout
    • AppBarLayout
    • Toolbar
    • an include layout tag
    • FloatingActionButton
content_main.xml
  • ConstraintLayout 
  • TextView.
Edit the layout/activity_main.xml
In the CoordinatorLayout tag, insert following line before tools:context

tools:orientation="vertical"

Step 2: Add the buttons

Edit the file values/strings.xml and add within the <resources> tag

<string name="digital">Digital</string>
<string name="analog">Analog</string>

<string name="textclock">Text Clock</string>

Edit content_main.xml and remove the whole TextView tag. Replace with 2 buttons where you can just drag and drop the buttons from the widget list. Add a FrameLayout where we will position our Fragment layouts. Edit the button code as follows

<Button
        android:id="@+id/button_analog"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/analog"
        />
<Button
        android:id="@+id/button_digital"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="@string/digital"
        app:layout_constraintTop_toBottomOf="@+id/button_analog"
        />

<Button
        android:id="@+id/button_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="@string/textclock"
        app:layout_constraintTop_toBottomOf="@+id/button_digital"
        />

<FrameLayout
        android:id="@+id/fragment_container"
        android:layout_width="280dp"
        android:layout_height="495dp"
        android:layout_marginStart="8dp"
        app:layout_constraintStart_toEndOf="@+id/button_analog"
>
    </FrameLayout>


Let build and run the project.

Click the Run App button (green play button) or press Shift+F10. I am using an API 23 emulator for my test applications. Create the Android emulator if it is not done yet.




Step 3: Create Analog Fragment

Click File ->New ->Fragment ->Fragment (Blank). Fill following values
Fragment Name: AnalogFragment
Fragment Layout Name: fragment_analog

Leave all other options checked.
Click Finish

In AnalogFragment.java, replace import android.support.v4.app.Fragment with

import android.app.Fragment;

I plan to provide support only to Android API 23 and above.

Lets explore the Design editor.
Edit layout/fragment_analog.xml and click the tab Design. Notice that the default is FrameLayout.



On the left is the Palette, in the middle is the screen design + blueprint, on the right is the Attributes list. In the Design area, click the menu to choose API 23. Right click any where on the design and choose Convert FrameLayout to ConstraintLayout. Click "Ok".

Delete the default TextView in the design.


From the Palette, notice there is no AnalogClock which means it will have to be manually added. Click the Text tab and insert the following

<AnalogClock
        android:id="@+id/analogClock"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"

        app:layout_constraintTop_toTopOf="parent"
         />


Step 4: Connect MainActivity with Analog Fragment

I have broken down the steps further in this step. Edit MainActivity class.

1. Add following member variables

Button analogButton;

2. Edit protected void onCreate(Bundle savedInstanceState), add after the line setSupportActionBar(toolbar)

analogButton = (Button) findViewById(R.id.button_analog);
analogButton.setOnClickListener(this);


There should be a wriggly red line at the text "this", click once then press Alt+Enter. Choose "Make MainActivityFragment implement android,view.View.OnClickListener". Choose "onClick(v:View):void" and press "OK".

3. Add onClick(View v) method
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
if(v==analogButton){
        f = new AnalogFragment();
}
transaction.replace(R.id.fragment_container, f);

transaction.commit();

4. Edit the class declaration with the AnalogFragment

public class MainActivity extends AppCompatActivity implements View.OnClickListener,
        AnalogFragment.OnFragmentInteractionListener  {


Implement AnalogFragment's OnFragmentInteractionListener, add the method near the end of the class.

public void onFragmentInteraction(Uri uri) {
        //
}



Compile and run.

Step 5: Create Digital Fragment

Repeat steps 3 and 4 above but change the Analog to Digital. Below is the code to display a digital clock

<DigitalClock
    android:id="@+id/analogClock"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginEnd="8dp"
    android:layout_marginStart="8dp"
    android:layout_marginTop="8dp"
    android:background="#9a0"
    android:padding="24dp"
    android:textColor="#eff"
    android:textSize="25sp"
    android:textStyle="bold"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"

    app:layout_constraintTop_toTopOf="parent"
    />




Step 6: Create TextClock Fragment

Repeat steps 3 and 4 above but change the Analog to TextClock. Below is the code to display a digital clock

<TextClock
    android:id="@+id/analogClock"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginEnd="8dp"
    android:layout_marginStart="8dp"
    android:layout_marginTop="8dp"
    android:background="#9a0"
    android:padding="24dp"
    android:textColor="#eff"
    android:textSize="25sp"
    android:textStyle="bold"
    android:format12Hour="HH:MM:ss EEEE"
    android:format24Hour="EE H:mm:ss"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"

    app:layout_constraintTop_toTopOf="parent" 
    />


Here is the complete source code for MainActvity.java

1:  package com.example.nicholas.myfragment;  
2:  import android.app.Fragment;  
3:  import android.app.FragmentManager;  
4:  import android.app.FragmentTransaction;  
5:  import android.net.Uri;  
6:  import android.os.Bundle;  
7:  import android.support.design.widget.FloatingActionButton;  
8:  import android.support.design.widget.Snackbar;  
9:  import android.support.v7.app.AppCompatActivity;  
10:  import android.support.v7.widget.Toolbar;  
11:  import android.view.View;  
12:  import android.view.Menu;  
13:  import android.view.MenuItem;  
14:  import android.widget.Button;  
15:  public class MainActivity extends AppCompatActivity implements View.OnClickListener,  
16:      AnalogFragment.OnFragmentInteractionListener, DigitalFragment.OnFragmentInteractionListener,  
17:      TextClockFragment.OnFragmentInteractionListener {  
18:    Button analogButton, digitalButton, textClockButton;  
19:    Fragment f;  
20:    @Override  
21:    protected void onCreate(Bundle savedInstanceState) {  
22:      super.onCreate(savedInstanceState);  
23:      setContentView(R.layout.activity_main);  
24:      Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);  
25:      setSupportActionBar(toolbar);  
26:      analogButton = (Button) findViewById(R.id.button_analog);  
27:      analogButton.setOnClickListener(this);  
28:      digitalButton = (Button) findViewById(R.id.button_digital);  
29:      digitalButton.setOnClickListener(this);  
30:      textClockButton = (Button) findViewById(R.id.button_textclock);  
31:      textClockButton.setOnClickListener(this);  
32:      FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);  
33:      fab.setOnClickListener(new View.OnClickListener() {  
34:        @Override  
35:        public void onClick(View view) {  
36:          Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)  
37:              .setAction("Action", null).show();  
38:        }  
39:      });  
40:    }  
41:    @Override  
42:    public boolean onCreateOptionsMenu(Menu menu) {  
43:      // Inflate the menu; this adds items to the action bar if it is present.  
44:      getMenuInflater().inflate(R.menu.menu_main, menu);  
45:      return true;  
46:    }  
47:    @Override  
48:    public boolean onOptionsItemSelected(MenuItem item) {  
49:      // Handle action bar item clicks here. The action bar will  
50:      // automatically handle clicks on the Home/Up button, so long  
51:      // as you specify a parent activity in AndroidManifest.xml.  
52:      int id = item.getItemId();  
53:      //noinspection SimplifiableIfStatement  
54:      if (id == R.id.action_settings) {  
55:        return true;  
56:      }  
57:      return super.onOptionsItemSelected(item);  
58:    }  
59:    @Override  
60:    public void onClick(View v) {  
61:      FragmentManager manager = getFragmentManager();  
62:      FragmentTransaction transaction = manager.beginTransaction();  
63:      if(v==analogButton){  
64:        f = new AnalogFragment();  
65:      } else if (v==digitalButton){  
66:        f = new DigitalFragment();  
67:      } else if (v==textClockButton) {  
68:        f = new TextClockFragment();  
69:      }  
70:      transaction.replace(R.id.fragment_container, f);  
71:      transaction.commit();  
72:    }  
73:    @Override  
74:    public void onFragmentInteraction(Uri uri) {  
75:      //  
76:    }  
77:  }  

Done.

Tuesday, April 17, 2018

Upgrade Android Studio to 3.1

New in Android Studio v3.1.1 on Stable channel are
  • For those who use C++, there is a CPU performance profiler that troubleshoot codes with the  simpleperf tool. 
  • Better lint support to check quality of codes for Kotlin (an alternative JAVA language). From the command line, lint can be accessed with the tool gradlew lint.
  • Improved  SQLite's and Room's table query and creation.
  • The default compiler uses D8 dexer which have the capability to make codes much smaller and more accurate step debugging.
  • Improved build output window to trace errors in a tree view.
  • Upgrade to the IntelliJ Idea 3.3 platform. This is the base platform of which Android Studio IDE is built.
  • Improved network profiler to trace network request on multi-threaded traffic.
The new version patch size is 456MB. Can hardly spot any difference from previous versions but its running much more smoother.

Android Studio 3.1.1 Workspace


Here is the current PC setup
  • Android Studio version: 3.0.1 (build 171.4443003) 
  • Centos 7.4 (64 bits) Linux 3.10.0 x86_64 amd64
  • OpenJDK 64-bit v1.8.0_161
  • Gradle 4.3.1
  • Apache Ant 1.9.6

This is how I upgraded to Android Studio 3.1.1

Check for updates


Canary or Stable channels can be check with the following steps.
Open Android Studio menu and click File ->Settings ->Preferences. On left panel choose Appearance & Behavoir ->System Setting ->Updates. Choose the Stable Channel from Automatically check updates for.

Click Check Now. This should retrieve latest update on the Stable Channel.

Step 1: Update Android Studio

Choose to update from the popup window when Android Studio is open.


Do the steps above if you have not retrieved the updates information. Click Update and Restart.


Alternatively, at the bottom of the Android Studio start page, click "Check" if you do not find the update option.

Once update starts, this will begin with download of the required files.

Step 2: Configuration

After it has installed the update, choose to import my settings from a previous version (keep existing configuration) from the window Import Studio Settings from: choose the option below and click "Ok"

Previous version (~/.AndroidStudio3.0/config)

Step 3: Update Plugin and other components

Close all emulators then open an existing project. This will have the usual build checks, once the gradle has started processing, the following window will appear.


Click Update to update Android Gradle Plugin to version 3.1.1 and Gradle to version 4.4. Wait until the Gradle project sync in progress... is completed.

At the window IDE and Plugin Updates, click "update". To update currently installed SDK and it tools, click "Update now".


Once completed download, click Finish. In my case it took 1.5GB of downloads.


Next up: Will write on creating a Fragment type application with Android Studio 3.1.
Done.

Friday, April 13, 2018

Howto Install Evernote on Linux Mint


One of the tools to capture my notes on a PC and Android mobile device is Evernote. Searching online today, it is clear that Evernote is not available on Linux (Mint), however it has been implied that their API is sufficient for anyone to develop a version of Evernote (Evernote on Linux). This means no Evernote application on Linux. Good news for the Linux community as the API documentations are available at https://dev.evernote.com/

Nixnote by baumgarr provides you access to Evernote on Linux Mint along with a user manual in PDF. Download the version suitable for you at https://sourceforge.net/projects/nevernote/files

Nixnote2 on Linux Mint


My set up (inxi -S)
Kernel: 4.10.0-38-generic x86_64 (64 bit)
Distro: Linux Mint 18.3 Sylvia
Desktop: Cinnamon 3.6.7



Step 1: Download nixnote

Locate the file online from Sourceforge and download. The file I downloaded to my Download folder is

nixnote2-2.0.2_amd64.deb

Step 2: Install from command prompt


$ cd ~/Download
$ sudo apt install ./nixnote2-2.0.2_amd64.deb
$ apt install libcurl3 libcurl3-nss

This installed the dependency packages libcurl3, libpoppler-qt5-1 and tidy.

Troubleshoot: Error

QSqlDatabase: QSQLITE driver not loaded
QSqlDatabase: available drivers:
ERROR 2018-04-13 00:50:37.788 ( sql/databaseconnection.cpp @ 44 ) Error opening database:  QSqlError(-1, "Driver not loaded", "Driver not loaded")


Solution: At CLI type

$ apt install lua5.2-sql-sqlite3
$ apt install libqt4-sql-sqlite

Step 3: Run Nixnote

At the Desktop Menu ->Internet ->Nixnote2

Troubleshoot: Nothing appears after click Nixnote2.

At CLI the error shows:

nixnote2: error while loading shared libraries: libpoppler-qt4.so.4: cannot open shared object file: No such file or directory

Solution: Open CLI and type


$ apt install libpoppler-qt4-4
$ nixnote2

Usage

Once its started, Click in the menu File ->Add another user. Key in your new user name.
Click File ->User Account Maintenance. Choose the new user.
Click Tools ->Synchronised

Wait for it to download from Evernote.

Friday, March 16, 2018

VNC Troubleshoot Cannot access vdagent virtio channel /dev/virtio-ports/

On Centos 7, the vncserver started for each service is able to launch and users can login remotely. Within 1 minute, this service crashes and the usual command (see below) to start the vncserver fails.

$ sudo systemctl start vncserver@:1

The reason for this failure is capture in the command;

$ sudo systemctl status vncserver@:1

There were 2 items to take note,
  1. Users were launching the vncviewer almost immediately upon the server boot up.
  2. The following error appears "Cannot access vdagent virtio channel /dev/virtio-ports/" upon checking the status.

Whats on the Linux?

Centos Linux version 7.4.1708 (Core)
Tigervnc version 1.8.0

Spice [reference Fedora]

Spice aims to provide a complete open source solution for interaction with virtualized desktop.  The Simple Protocol for Independent Computing Environments (SPICE) is used for client-server communication. Spice adds a QXL display device to QEMU and provides drivers for this device for both X and Windows. It also provides a Spice server and VDAgent to handle connections and transmit the information via the SPICE protocol to clients. The Spice project provides a Linux, Windows, and HTML5 client. There are experimental Mac OS X and Android clients as well.

This /dev/virtio-ports is created in this feature that modifies the current single-port virtio-console device to guests running on top of qemu and kvm. It exposes multiple ports to the guest in the form of simple char devices for simple IO between the guest and host userspaces. It also allows for multiple such devices to be exposed, lifting the current single device restriction.

Somehow, these were installed on the server.

$ rpm -qa \*spice\*
spice-vdagent-0.14.0-14.el7.x86_64
spice-server-0.12.8-2.el7.1.x86_64
spice-gtk3-0.33-6.el7_4.1.x86_64
spice-glib-0.33-6.el7_4.1.x86_64

The RPM documentation on spice-vdagent states
"* Client mouse mode (no need to grab mouse by client, no mouse lag)
this is handled by the daemon by feeding mouse events into the kernel via uinput. This will only work if the active X-session is running a spice-vdagent process so that its resolution can be determined.
* Automatic adjustment of the X-session resolution to the client resolution
* Support of copy and paste (text and images) between the active X-session and the client"

I make an assumption that if no virtualisations are needed on the server, its a matter of deleting these packages. However, I have an Android Emulator that have dependency on the virtio-ports. Its still a question mark if VNC depends on spice-vdagent.

Solution

Step 1. Start SPICE agent.

At the command line on the host server, start the spice agent.
$ sudo systemctl start spice-vdagentd.service

Check and ensure that this service runs at boot up.
$ sudo systemctl show spice-vdagentd |grep enable
UnitFileState=enabled
UnitFilePreset=enabled

Step 2. Give host server time

Allow the Linux server to fully boot up all processed before attempting to start a VNC client session.


Done

Monday, March 12, 2018

Laravel 5 and Error key was too long

The server was running PHP applications without any fuss, everyone is happy on this 12th March 2018. Laravel 5 came in that one day and a simple application was launched to show the default Laravel welcome screen. The next step was to create a CRUD application with storage to the local database.

A Model is created of a simple Task object. The room fell silence after the command, php artisan migrate

SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table users add unique users_email_uniq(email))


What was wrong? Never mind that, lets see whats on the server!

  • Centos version 7.4.1708
  • Apache httpd  version Apache/2.4.6 (CentOS)
  • Mariadb (MySQL fork) version 5.5.56-MariaDB
  • PHP version 7.2.2 (cli) with Zend Engine v3.2.0
  • Laravel 5.6.7
  • Composer versioon 1.6.3
  • npm version 3.10.10

All of above are tested and working on its own. Going back to analyse the error, its database related. The respective tables of migrate, users were generated in the database, but the new model "task" isn't.The related code is in the file <laravel5>/database/migrations/2014_10_12_000000_create_users_table.php


On the database side, changed Collation to utf8mb4_unicode_ci but the error is still there. This is a 4-byte UTF-8 Unicode Encoding and as described in MySQL 5.5, it is
  1. In UTF8 it uses 3 bytes per character, containing only BMP characters. Utf8mb4 supports maximum 4 bytes per character and includes supplementary characters. 
  2. Utf8mb4 is a superset of Utf8.
  3. To save space, utf8mb4 is to use VARCHAR instead of CHAR type for BMP characters. 
 Changing a table from utf8 to utf8mb4 can be done with
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

e.g.
ALTER TABLE `users` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Solution

Make the whole Laravel application and the database server utf8mb4 aware.

Step 1. Edit file  <laravel5>/config/database.php

'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'engine' => 'InnoDB ROW_FORMAT=DYNAMIC',
DYNAMIC allows to store of long key indexes.

Step 2.  Edit file /etc/my.cnf


[mysqld]
# default character set and collation
collation-server = utf8mb4_unicode_ci
character-set-server = utf8mb4

# utf8mb4 long key index
innodb_large_prefix = 1
innodb_file_format = barracuda
innodb_file_format_max = barracuda
innodb_file_per_table = 1

 Step 3. Edit file /etc/my.cnf.d/client.cnf


[mysql]
default-character-set=utf8mb4

Step 4. Restart database server

Stop then start the database server with

$ sudo systemctl stop mysqld
$ sudo systemctl start mysqld

Done.

Points to note

The error states maximum key length is 767 bytes for the email field. In Laravel 5 the migration file for "Users" declared a string that gets created in the Mariadb database. Problem in question is adding the "unique" string that get generated in the database "Users" for field "email" with type VARCHAR(255) and collation utf8mb4. MySQL has to actually index the whole value to complete the operation. This calculates to give maximum size of

255 characters x 4 bytes = 1,020 bytes (MAXIMUM BYTES)

This looks like sufficient space, but why the error?
When Laravel writes/reads data to MySQL, it utilises a call to the local MySQL client/server that takes this as default of uf8 which is having maximum 3 bytes per character (due to the mysql default client/server settings). A little bit of calculation gives

255 characters x 3 bytes = 765 bytes (MAXIMUM BYTES)

In the above solution, there is access to modify the database configurations. What if you do not have such an access? The solution is to reduce the default string length sent by Laravel. Taking 191 as maximum characters, we get

191 characters x 4 bytes = 764 bytes

Edit file <laravel5>/app/Providers/AppServiceProvider.php

Add after the "use .... \ServiceProvider;"
use Illuminate\Support\Facades\Schema;

Add in the "public function boot( )"
Schema::defaultStringLength(191);

Save and from the project's main folder, run migration
$ php artisan migrate

OR
Alternatively, changed the field "email" that was declared unique to collation "utf8". It worked for me, but some people have mentioned it didn't work for them.

Done

Monday, February 26, 2018

Installing Nodejs and NPM

Nodejs provides JavaScript with a way to optimise single threaded and single CPU core processing. 
NPM is a package manager to deliver applications. Its like yum on Centos linux.

In this case, I am installing Cordova for Android development on Centos 7.4 and it required nodejs along with npm. Hence, this article came along the way.

Step 1: Install Epel repository

$ sudo yum install epel-release  
$ sudo yum info nodejs
It shows nodejs version 6.12.3


Step 2: Install nodejs

Install the development environment then nodejs. This will install together the npm (version 3.10.10)
$ sudo yum --setopt=group_package_types=mandatory,default,optional groupinstall "Development Tools"
$ sudo yum install nodejs

Check installed version
$ node -v
$ npm -v

Step 3: Run Hello World

Create this script and name it as helloworld.js to test on a command line and the web browser.

var http = require('http');

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.end('<p>This is <b>Hello World</b></p>');
}).listen(8080);
console.log('This example is my world!');


At a command line, type
$ node helloworld.js

This should display the output on the command line.
Next, open a web browser and type the following url

localhost:8080

Continue with Cordova installation from previous article.

Remove Defunct or Zombie processes

On Linux systems (Centos, Fedora, Ubuntu, Mint, Puppy), a running application is identified by one or more processes. Example when running a document with LibreOffice Writer, the process thats related is oosplash and soffice.bin as can be seen below.

tboxmy  5262  0.3  0.0 299672  3272 ?        Sl   10:17   0:00 /usr/lib64/libreoffice/program/oosplash --writer
tboxmy  5277  3.1  1.1 1273804 89564 ?       Sl   10:17   0:01 /usr/lib64/libreoffice/program/soffice.bin --writer --splash-pipe=5

Shown in bold, the unique process identification (id) are 5262 and 5277 for the two processes. Upon using the command ps xl, it can be seen that process 5277 is spawned by process 5262. Making 5262 a parent to 5277.


What is a defunct process?

A "defunct" processes is referred as a dead process that still hogs memory resources. Its not much a problem having a defunct process, but when the system starts to have more defunct processes, the system can slow down and affect applications.

This defunct or dead process that still lingers on the system is also known as zombie process. Most appropriate, like in a horror flick! You can't kill a zombie that is already dead, so what can you do? Watch the next zombie show and try figuring that out. Luckily, on Linux systems, a zombie doesn't go around attacking or destroying resources. It only lingers on, hogging on to resources once given to it when it was a live process, at one time.

What brings about this zombie? On Linux its mostly due to bad programming that lead to errors and bugs that are not handled by the application itself.


Dealing with defunct process

Don't attempt to bring back to live a zombie process. Seek out the zombie and terminate from the system. Here are commands to handle an example zombie processes (defunct) with process id 5277.

Where are the zombie processes?
$ ps ef |grep defunct
5277 ?        Z      0:01 [example-app] <defunct>

Notice the word "defunct" and status as Z (for zombie) for the process 5277. That, is our zombie. Did you find any zombie's in your system?

The command kill is used to terminate any process and free system resources such a memory (RAM). The problem with zombie processes is that, they are dead, and can't be killed (not most of the time). What is done however, is to identify the parent process (the one responsible for creating the zombie) and terminate that process.

Identify the parent process id (5262) and terminate it.
$ ps -o ppid 5277
 PPID
 5262

$ kill -9 5262
$ ps ef |grep defunct

That is the end of the zombie. In some cases, a zombie might be holding on to a resource and it will take sometime for it to detach (give it a bit of a wait).

There are other methods to look for zombies. E.g. the ps command provides a method of displaying the parent hierarchy as follows;
$ ps xlf |grep defunct

Or in the command top, look at the second line for number of zombie processes.

What if the zombie keeps appearing on a daily basis for the same process? 

This is a problem, but sometimes its not apparent as zombie's live among the running processes without bothering anyone. Let me know if you have other than the suggestions I have list below.
  • See if there is a newer version of the application or an alternative (such as different architecture, from a different source) and install. 
  • It is possible that the application itself is not the problem. Identify any other related applications or module that is causing this zombie. Then update or find an alternative application to use.
  • Report to the application project team for a solution.

Friday, February 23, 2018

Cannot open display Error when using VNC

After opening VNC Viewer on MS Windows 10 and connecting to the Centos 7, the desktop appears as planned. However, there is an error when running some apps such as system-config-printer. The error is

Gtk-WARNING **: cannot open display:1

Good to note that the VNC server was providing the session at display 1 on port 5901. If you are running the display on another port, it wouldn't matter.

Solution:

At the user's terminal (AND as that user NOT sudo or root), add localhost to the xhost permission. Type

$ xhost +localhost

And this allows system-config-printer to run.


Wednesday, February 14, 2018

Cordova: Accepting user input

What would be the first thing in programming? A simple use of variable and user text input comes to mind. Following the previous post (link here), the Cordova programming environment is set up for Android. The existing files will be edited to do the following;

The HelloWorldApp when started, will prompt the user to enter a city name.






The user enters a city name and press "OK" button. The city name will be displayed on the app.






Step 1. Position the text to display user response.

Using a text editor, open the file index.html in HelloWorld/www and replace the previous <p> tag with the text "Hello World" with;

<div id="answer"></div>

Save the file.

Step 2. Prompt user at apps startup and display the reply.

Open the file index.js in HelloWorld/www/js

Add our function called getAnswer to the end of the file;
function getAnswer() {
    var ans = prompt("Name your city");
    if (ans.length > 0) {      
        document.getElementById('answer').innerHTML = "";      
        document.getElementById('answer').innerHTML = ans + " is a great place.";
    } else {      
        getAnswer();
    }
}


Activate the getAnswer function in the initialize:function( )by adding after document.addEventListener(...);

getAnswer( );

Step 3. Build and launch the app.

At the command line interface (CLI) or the command terminal, type

$ cordova build android
$ cordova run android

This will launch the default emulator.

In order to test the app, at any time after editing to the source files, just follow this Step 3.

Troubleshooting

Android emulator error: 
The connection to the server was unsuccessful. (file:///android_assets/www/index.html)

Edit the file config.xml in HelloWorld folder. Add the following line after the </platform> tag.

<preference name="loadUrlTimeoutValue" value="700000" />

Build and launch the app.

Tuesday, February 13, 2018

How to Install Cordova for Android Development

One challenge in developing a mobile application is in choosing a mobile environment. Apache Cordova allows building of an application through the use of Java for Android, AngularJS, SCSS to create reusable code across platforms. I suggest that some study is done on those languages in order to fast track learning. Cordova supports several development platforms, for this article, its focus is on Android platform.

Cordova Installation

Here are the steps to get started on a command line with installation of Cordova and launching the Android emulator on MS Windows 10 (version 10.0.16299). All the versions mentioned here are those that I am using for this article.

1.Install Base Environment

Cordova relies on well known development tools to generate the latest mobile application. Install Java Development Kit (version 8 or newer), Android studio, Node.js and git. Ensure all these are working.
  1. Java Development Kit. This should be version 8 or newer and configure JAVA_HOME.
  2. Android Studio (This article is version 2.3.3). Install the required SDK platform (I choose Android 7.1.1 Nougat), SDK Tools comprising of Android SDK Tools (version 26.1.1), Android SDK Platform-tools (version 27.0.1) and Android Support Repository (version 47.0.0). In SDK Tools, install Android Emulator. On MS Windows platform, also install HAXM (I have version 6.2.1).
  3. Node.js. This article is version 6.9.1 with npm 3.10.8. 
  4. Optional: GIT (version 2.8.1.windows.1)
Ensure environment variables are configured for JAVA_HOME and ANDROID_HOME

Then at the command prompt type (do not type the dollar sign);
$ npm install -g cordova

On linux
$ sudo npm install -g cordova

2. Creating Hello World App.

We will create a Cordova project in a folder HelloWorld. This will be in io.cordova.project with the app title of HelloWorldApp.
$ cordova create HelloWorld io.cordova.project HelloWorldApp
$ cd HelloWorld

Here is the syntax to create any project
cordova create [project_name] [package_name] [apk_name]

Open the folder platforms, notice it is empty.
Cordova Project folder for HelloWorld


Open and identify the codes in index.html located at
HelloWorld\www


In HelloWorld\www edit index.html to display Hello World. At end of the app tag, add 1 line
<div class="app">


<p>Hello World</p>
</div>

3. Install Android Platform.

When it is the first time creating a project, the target platform has to be added. Here its created in a folder CordovaProject.
$ cordova platform add android

Have a look at the Android source files are located at MainActivity.java in

HelloWorld\platforms\android\app\src\main\java\io\cordova\project

Default MainActivity.java file

Each time the apps code is modified, the project is compiled and run in an emulator OR on a mobile device. Compile and build the project for the Android platform.
$ cordova build android

Start the apps in an emulator. The default emulator manager is by Genymotion and the default emulator is Pixel with Android API 25.
$ cordova emulate android.


If you intend to plug in your Android device to run the app, or  start the apps in an external device, type
$ cordova run android



4. Tips

List existing platform installed and what platform is available.
$ cordova platform ls

Wednesday, January 10, 2018

Apache not sending emails on Centos 7

Applications on Apache webserver that are working fine but can't send out emails is a real headache. Especially if everything was working on the development server. Example of error encountered;

Could not execute: /usr/sbin/sendmail

In Wordpress, it refuses to send email. Once such instance is the Forget password window and you see the message
The e-mail could not be sent.
Possible reason: your host may have disabled the mail() function.

This is ONE possibly most common situation. 

On most Development servers, the SELinux is probable turned OFF or in permissive mode. However on the Production servers, they are almost always set to ON. In the web server document directory, check if the following SELinux status;

$ getsebool httpd_can_sendmail

It should be in status OFF. Change the status to ON and restart Apache with the command

$ setsebool -P httpd_can_sendmail on
$ systemctl restart  httpd.service

Second common situation

Still not receiving emails from apache or Wordpress? It is possible Postfix SMTP server is using values that the email relay SMTP is not accepting. Check the maillog for any errors such as this;

said: 450 4.1.8 <apache@production.localdomain>: Sender address rejected: Domain not found (in reply to RCPT TO command))  

Or

sendmail[2450]: NOQUEUE: SYSERR(apache): /etc/mail/sendmail.cf: line 0: cannot open: Permission denied

This is a story for another time.

Wednesday, December 20, 2017

Install Linux on Samsung NP150 Plus netbook - Part 1

Installation of Linux Mint 18.3 (Sylvia) Xfce 64-bit on Samsung NP150 Plus netbook. This is how I installed a dual boot of Linux Mint 18 on existing MS Windows 10 Home (Upgraded from MS Windows 7 Starter).

This little netbook runs on  1.66-GHz Intel Atom N450 processor with 1Gb of RAM and an x64-based processor. I am giving it a shot to see if its possible to install Mint and usability as a school student's laptop. Linux Mint is a project spun off from Ubuntu with a large library of applications. Version 18.3 is based on Linux kernel 4.4 with Ubuntu package on 16.04 and will receive security updates until 2021. Xfce is an open source software to provide a light weight desktop for low processor computers. See Whats new for more details.

Linux Mint Xfce vs (Cinnamon

Minimum requirement:
9Gb (20Gb) Disk space
1024x767 resolution (lower resolution require press Alt drag windows with mouse to fit monitor)
512Mb (2Gb) RAM


Linux Mint 18.3 with Xfce desktop

Installation

Linux Mint can be downloaded from linuxmint.com. Download then create a bootable Linux Mint on the USB disk. I used Rufus version 2.18.1213 (See error below when using Win32diskimager version 1.0.1) to extract the ISO file into the USB disk. File system on Rufus MUST be set to FAT (Default) with cluster size 64 kilobytes (Default).

(A) This netbook comes with MS Windows 10 Home Windows 7 Starter and a small capacity hard disk. Firstly create free space by using the apps in MS Windows.
  1. Open MS Windows Explorer. Right click "This PC" -> Manage.
  2. Choose Storage ->Disk Management
  3. Choose the unused disk partition and resize to 50Gb of free space. More would be better.
Choose "Manage" to access the Partition tools.


On some disk, it will need to "optimise disk" to reclaim more free space.

(B) Boot from USB disk
  1. Shutdown netbook. Plugin the Mint on USB disk into the netbook. 
  2. Boot netbook and press F2 to enter BIOS 
  3. Choose to boot USB HDD before the AHCI HDD
  4. Save and reboot.
Samsung N150 Plus BIOS screen to boot from USB Disk.

Note: Win32diskimager 1.0.0 to create USB Disk.
The Linux Mint boot up screen appears at first boot but ended up with following message.

32-bit relocation outside of kernel!
-- System halted

This is solved by formating the USB disk as FAT, then run Win32diskimager.

Note: Hangs after boot screen. 
Reboot then at the Linux mint boot screen, Choose first option "Linux Mint" and press TAB. Remove the text "quick splash" and press Enter. This reveals the error;

Uncompression Error
-- System halted

This is resolved by using a larger capacity USB disk. Initially it was a 2Gb USB stick then changed to a 4 Gb USB disk.

Its booting! Will continue with further post next time.



Linux Mint 18.3 Installed on N150 Plus


For now, the partition table plan as follows;

/  -  20000MB
swap  -  2
/home  -  Remainder space



Friday, November 17, 2017

What's new in Firefox Quantum (screens)



Firefox 57, also known as Quantum is a major upgrade for Firefox web browser. Here are initial screens of this new web browser compared to previous version of Firefox 56.






Tools menu






Toolbar


Preferences
 

Speedtest



Speedtest Ranking



Friday, November 10, 2017

Laravel and using custom CSS file

Laravel 5 supports CSS and JavaScript preprocessors through Elixir and Gulp. Elixir is a node.js tool that helps gulp in the use of less, sass and coffee methods. Gulp assist programmers by automating repeated task like copying files, testing, minify codes.

If all that sounds confusing, dig deeper and you will find that Laravel framework assist developers to build and test application faster through tools like Elixir and Gulp.

There will be cases where an existing and proven CSS file should be used within a Laravel 5 project. In this example, there is a CSS file name beautiful.css that provides a box when used in the DIV CLASS code of the php application as shown below;

<DIV class="beautiful-tip">
 <P>Hello World</P>
</DIV>

We will use an existing working Laravel 5 application that is installed at the folder named <project>. In the gulpfile.js, the mix.sass contains 'app.scss' where instructions to use the CSS will be recorded.

Step 1: Copy the CSS file to Project's node_modules folder

Create the folder "example" in <project>/node_modules
Copy beautiful.css into the folder <project>/node_modules/example and make sure the folder and its contents are readable by the web server service.

Step 2: Include the CSS file when gulp compiles SASS files.

Edit <project>/resources/assets/sass/app.scss

At the last row, add the command (name of CSS file without its extension) and save.
@import "node_modules/example/beautiful";

Step 3: Run gulp.

At a command prompt in the project folder, type
# gulp

Done

Friday, November 3, 2017

Can anyone use OSS in their product?

Use of open source (OSS) licensed software have gained widespread acceptance. Its no longer just for hobbyist and academic studies. R&D takes place much rapidly with these open knowledge available to masses but its very different from just copying the software when corporations and industry adopts OSS in their product.

Ever wonder why anyone would allow their codes formed from sweat and sleepless nights to be made available to everyone? Broadcom for example, provide their source codes and its become such a powerful references. Something to ponder, but lots of articles are around to help one understand.

If you intend to use OSS as part of a product that is sold (not the services) or distributed freely, there is the GPL and LGPL type of licensing type of OSS. A brief if not too broad explanation on the differences.

Products bundled with GPL type licensed OSS components and codes must distribute with the source code made available to the product recipient. Lets say, you develop a smart desktop suite called P99SmartDS that incorporates modified Mozilla Thunderbird to handle smtp and pop messaging to the desktop. Thunderbird expects you to ship the P99SmartDS with working source code and be licensed not more restrictive than that GPL licensed.

Products bundled with LGPL type licensed OSS component and codes must distribute with the license and library of that specific OSS component. Lets say, you develop a wireless driver interface and application to simplify configuration and its using a LGPL licensed OSS library. This application does not have to be OSS licensed.

Selling a product base on OSS is not just about submitting bugs or chats in forums. It sharing of knowledge gain via successful products. The OSS licensed is the guardian to ensure continuity of the freedom of choices and knowledge. Play your part to safe guard this freedom.

Wednesday, November 1, 2017

Laravel 5 and OpenSSL

Notes on updating Apache 2.4, Laravel 5.5 with PHP 5, to PHP 7.1. 


Currently, the openssl key on my Apache server is serving encryption with AES 128. Information here is for development server environment only.

Default new Laravel applications are generated with use of encryption key type AES 256 as found in <Laravelproject>/config/app.php

The cipher key in app.php can be changed, or just generate the new required AES 256 keys.

Steps to generate the OpenSSL public and private keys;

$ openssl genrsa -aes256 -out mysitename.key 2048
$ openssl rsa -in mysitename.key -out mysitename-decrypted.key
$ openssl req -x509 -nodes -new -sha256 -key mysitename-decrypted.key -out mysitename.crt


When restarting Apache on MS Windows 10, this error appears.
"Init: SSLPassPhraseDialog builtin is not supported on Win32"

Solution is to remove the pass phrase in private key (See). In this example, the public and private ssl certs are both stored in <Apache directory>/conf/ssl/
Step 1:
Copy private key mysitename.key to secure.key

Step 2: Remove pass phrase from private key in use.
In CLI of the folder for ssl type

$ openssl rsa -in secure.key -out mysitename.key

Step 3: Open <Apache directory>/conf/extra/httpd-ssl.conf and comment out the line
# SSLPassPhraseDialog  builtin

Step 4: Restart Apache

In the event the following error appears, it means the openssl module is not loaded. Find another compatible Apache server to be installed that can load the openssl in directory extension.

PHP Startup: Unable to load dynamic library
or
Undefined method openssl_cipher_iv_length( )

Laravel non-existent script error

Recently updated to PHP 7.1 and all the existing PHP projects are working fine.

However, this error appeared when I am trying to create a new Laravel 5 project,

You made a reference to a non-existent script @php -r "file_exists('.env') || copy('.env.example', '.env');"
Loading composer repositories with package information
. . .

You made a reference to a non-existent script @php artisan key:generate

Lets fix this in one step;

Step 1: Update the composer,

$ composer self-update

Updating to version 1.5.2 (stable channel).
    Downloading: 100%
Use composer self-update --rollback to return to version 1.2.2

Run the command used to create the new project,

$ composer create-project laravel/laravel myapps

Blog Archive