Friday 5 October 2018

Correctly restarting syslog on Mac OS X

For some experimentation, I was recently looking at restarting syslog daemon. I expected it to be as simple as Linux system daemons. The init system of Mac appeared to be more like systemd in my initial searches. A few blogs instructed unload followed by load operation which sounded strange to me.

In systemd parlance, I expected unload operation to disable the daemon from starting up during initial booting. If you try to follow the process suggested in these blogs, you end up with an error stating "Operation not permitted while System Integrity Protection is engaged". This leaves two options:

  1. Disable System Integrity Protection
  2. Restart the system for every change in config
Of course, the answer is far too simple and none of these complexities need to handled. The right way of restarting the syslog daemon is as follows (using stop and start operations instead of unload and load):

sudo launchctl stop /System/Library/LaunchDaemons/com.apple.syslogd.plist
sudo launchctl start /System/Library/LaunchDaemons/com.apple.syslogd.plist

Tuesday 25 September 2018

Hello OSGi

I found existing guides for OSGi to be a bit outdated. So, it is probably better to document the basic setup.

The plan is to first create a consumable bundle, i.e. a service bundle followed by a consumer bundle that uses the former.

I am also using maven for creating the projects so that the maven toolchain can be used for proper packaging.

For the consumable bundle, we start with defining an interface that exposes functionality of the bundle.

package main.java.interfaces;

public interface TestService {
    void hello();
}


We then implement it.

package main.java.impls;



import main.java.interfaces.TestService;



public class TestServiceImpl implements TestService {

    @Override

    public void hello() {

        System.out.println("Hello Duniya");
    }
}

We then add the activation logic for the bundle.

package main.java.provider;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;

import main.java.interfaces.TestService;
import main.java.impls.TestServiceImpl;

public class ServiceActivator implements BundleActivator {
    private ServiceRegistration registration;

    @Override
    public void start(BundleContext bundleContext) throws Exception {
        registration = bundleContext.registerService(
                TestService.class.getName(),
                new TestServiceImpl(),
                null);
        System.out.println("ServiceActivator started");
    }

    @Override
    public void stop(BundleContext bundleContext) throws Exception {
        registration.unregister();
    }
}



We complete this bundle by adding a POM for building it.




<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>felix_test</groupId>
    <artifactId>felix_test</artifactId>
    <version>1.0</version>
    <packaging>bundle</packaging>

    <dependencies>
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>org.osgi.core</artifactId>
            <version>6.0.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Bundle-SymbolicName>felix_test</Bundle-SymbolicName>
                        <Export-Package>main.java.interfaces</Export-Package>
                        <Bundle-Activator>main.java.provider.ServiceActivator</Bundle-Activator>
                        <Bundle-Vendor>Amitav Mohanty</Bundle-Vendor>
                    </instructions>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>


The package of interfaces that are to be exposed are called out along with the activator so that the maven toolchain can build our bundle properly.

We move on to create the consumer bundle next. We start with the bundle activator.

package main.java.consumer;

import main.java.interfaces.TestService;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;

public class FelixTestActivator implements BundleActivator {
    @Override
    public void start(BundleContext bundleContext) throws Exception {
        ServiceReference reference = bundleContext.getServiceReference(TestService.class.getName());
        consumer = new TestConsumer((TestService)bundleContext.getService(reference));
        consumer.startTimer();
    }

    @Override
    public void stop(BundleContext bundleContext) throws Exception {
        consumer.stopTimer();
    }

    private TestConsumer consumer;
}

We then add the consumer.


package main.java.consumer;

import main.java.interfaces.TestService;

import javax.swing.Timer;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class TestConsumer implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
        service.hello();
    }

    public TestConsumer(TestService service){
        super();
        this.service = service;
        timer = new Timer(1000, this);
    }

    public void startTimer(){
        timer.start();
    }

    public void stopTimer(){
        timer.stop();
    }

    private final TestService service;
    private final Timer timer;

}


The initiation of the consumer happens when the bundle is started.

The POM for building the consumer bundle is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>consumer</groupId>
    <artifactId>consumer</artifactId>
    <version>1.0</version>
    <packaging>bundle</packaging>

    <dependencies>
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>org.osgi.core</artifactId>
            <version>6.0.0</version>
        </dependency>

        <dependency>
            <groupId>felix_test</groupId>
            <artifactId>felix_test</artifactId>
            <version>1.0</version>
            <scope>system</scope>
            <systemPath>${basedir}/../target/felix_test-1.0.jar</systemPath>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Bundle-SymbolicName>consumer</Bundle-SymbolicName>
                        <Bundle-Activator>main.java.consumer.FelixTestActivator</Bundle-Activator>
                        <Bundle-Vendor>Amitav Mohanty</Bundle-Vendor>
                    </instructions>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

The dependency on the other bundle is called out.

The "packaging" node in the POMs is essential for creating OSGi bundles.

Wednesday 9 May 2018

Backward compatibility in user experience

Gmail recently launched a new design. I tried it out of curiousity. The first thing I noticed was that my muscle memory started failing me. Every time a new design comes, people focus on the look and feel of the design, its intuitiveness and other such factors but its compatibility with old design is not taken into account ever.

Power users tend to build muscle memory even for UIs. I tend to move my mouse to a particular location on the screen for the delete button for example.

With a product that has so many existing users, I think GMail should pay attention to these details as well when planning a new design. So, should other companies with similar products. An epic failure in the same lines is removal of start button by Microsoft. Of course a button position is not as critical; but the point is to have this criterion included in the design process.

Wednesday 31 January 2018

Testing filebeat

For testing codecs like multiline, the recommendation is to try the Go playground website. However, before making a config live, it can be tested locally also; using input from stdin and printing output to the console. The following config can be used as skeleton.

filebeat.prospectors:
- input_type: stdin

output:
  console:
    pretty: true

Friday 12 January 2018

Ola does not support Amex

As per their FAQs, Ola claims to support Amex cards.



However, when an attempt is made to add an Amex card, an error is shown as following.



The explanation provided by Ola is as follows.



I don't understand why is this clarity is not provided in the FAQ.

Tuesday 2 January 2018

KActivityManager blocking unmounting

While un-mounting a partition to safely remove the external hard drive, I got an error about the device being busy. Both Dolphin and the command line said the same thing.

umount /run/media/myuser/New\ Volume/
umount: /run/media/myuser/New Volume: target is busy.


It seems kactivitymanagerd was using it.


[root@clown myuser]# fuser -vm /run/media/myuser/New\ Volume/
                    USER        PID ACCESS COMMAND
/run/media/myuser/New Volume:
                     myuser     612 ..c.. kactivitymanage


I tried to stop the daemon but I got the following error.

root@clown myuser]# /usr/bin/kactivitymanagerd
QStandardPaths: wrong ownership on runtime directory /run/user/1000, 1000 instead of 0


After some discussion on Freenode, I got to know that when graphical apps are run with escalated priviledges, similar error is found. I guessed I was getting the error because I was trying to stop the daemon as root user. I tried changing back to my regular user and stopping the daemon. It worked  and I was able to unmount the drive after that.

/usr/bin/kactivitymanagerd stop
Service stopped
Cleaning up...