Publish a Kotlin lib with gradle Kotlin DSL

I wanted to play more with Kotlin and I wanted to publish KGeoGson lib to a remote maven repo.

I was following gradle guide to build my kotlin project with Kotlin DSL.

Bootstrap Kotlin project

Create project directory with files of your library you want to build and publish. You may have a directory structure like the following:

project
├── build.gradle.kts
├── settings.gradle.kts
└── my-kotlin-library
├── build.gradle.kts
└── src
├── main
│   └── kotlin
│   └── org
│   └── example
│   └── MyLibrary.kt
└── test
└── kotlin
└── org
└── example
└── MyLibraryTest.kt

Setup

Root build.gradle.kts

plugins {
`build-scan`
}

buildScan {
termsOfServiceUrl = "https://gradle.com/terms-of-service"
termsOfServiceAgree = "yes"

publishAlways()
}

val clean by tasks.creating(Delete::class) {
delete(rootProject.buildDir)
}

In this file, « build-scan » plugin is activated and a clean task is added. That’s all for it

settings.gradle.kts

include("lib")

In this file, we define our modules

lib/build.gradle.kts

First we are adding some plugins

plugins {
// Add Kotlin plugin to build our Kotlin lib
kotlin("jvm") version "1.3.21"
// Get version from git tags
id("fr.coppernic.versioning") version "3.1.2"
// Documentation for our code
id("org.jetbrains.dokka") version "0.9.17"
// Publication to bintray
id("com.jfrog.bintray") version "1.8.4"
// Maven publication
`maven-publish`
}

Then we are defining dependencies and their repositories for our code

repositories {
jcenter()
mavenCentral()
}

dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7")
implementation("com.google.code.gson:gson:2.8.5")

testCompile("junit:junit:4.12")
}

We need some more tasks to add sources and javadoc to our lib. We are starting by configuring dokka task:

tasks {
dokka {
outputFormat = "html"
outputDirectory = "$buildDir/javadoc"
moduleName = rootProject.name
}
}

We can then bundle documentation into a jar

val dokkaJar by tasks.creating(Jar::class) {
group = JavaBasePlugin.DOCUMENTATION_GROUP
description
= "Assembles Kotlin docs with Dokka"
archiveClassifier.set("javadoc")
from(tasks.dokka)
dependsOn(tasks.dokka)
}

We are creating another jar containing sources

val sourcesJar by tasks.creating(Jar::class) {
archiveClassifier.set("sources")
from(sourceSets.getByName("main").allSource)
}

At this stage, you are able to compile your lib. The most important part of this article begins. Let’s see how publication is working. It is very important to configure pom.xml file of maven artifact in a right manner. Otherwise you will not be able to submit your library into JCenter repo.

Let’s start configuring base of maven publish plugin

val artifactName = "libname"
val artifactGroup = "org.example"

publishing {
publications {
create<MavenPublication>("lib") {
groupId = artifactGroup
artifactId = artifactName
// version is gotten from an external plugin
version = project.versioning.info.display
  // This is the main artifact
from(components["java"])
// We are adding documentation artifact
artifact(dokkaJar)
// And sources
artifact(sourcesJar)
  }
}
}

Now we need to add information about package in pom.xml file. You can edit pom.xml with pom.withXml {code


val pomUrl = "..."
val pomScmUrl = "..."
val pomIssueUrl = "..."
val pomDesc = "..."
val pomScmConnection = ""..."
val pomScmDevConnection = "..."

val githubRepo = "..."
val githubReadme = "..."

val pomLicenseName = "The Apache Software License, Version 2.0"
val pomLicenseUrl = "http://www.apache.org/licenses/LICENSE-2.0.txt"
val pomLicenseDist = "repo"

val pomDeveloperId = "..."
val pomDeveloperName = "..."


publishing {
publications {
create<MavenPublication>("lib") {
[...]

pom.withXml {
asNode().apply {
appendNode("description", pomDesc)
appendNode("name", rootProject.name)
appendNode("url", pomUrl)
appendNode("licenses").appendNode("license").apply {
appendNode("name", pomLicenseName)
appendNode("url", pomLicenseUrl)
appendNode("distribution", pomLicenseDist)
}
appendNode("developers").appendNode("developer").apply {
appendNode("id", pomDeveloperId)
appendNode("name", pomDeveloperName)
}
appendNode("scm").apply {
appendNode("url", pomScmUrl)
appendNode("connection", pomScmConnection)
}
}
}
}
}
}

Now that your maven publication is well configured, you can configure bintray plugin

bintray {
  // Getting bintray user and key from properties file or command line
user = if (project.hasProperty("bintray_user")) project.property("bintray_user") as String else ""
key = if (project.hasProperty("bintray_key")) project.property("bintray_key") as String else ""

// Automatic publication enabled
publish = true

// Set maven publication onto bintray plugin
setPublications("lib")

// Configure package
pkg.apply {
repo = "maven"
name = rootProject.name
setLicenses("Apache-2.0")
setLabels("Gson", "json", "GeoJson", "GPS", "Kotlin")
vcsUrl = pomScmUrl
websiteUrl = pomUrl
issueTrackerUrl = pomIssueUrl
githubRepo = githubRepo
githubReleaseNotesFile
= githubReadme

// Configure version
version.apply {
name = project.versioning.info.display
desc
= pomDesc
released = Date().toString()
vcsTag = project.versioning.info.tag
}
}
}

Here we is ! Happy publication !

Use Dagger Provider with Android Material Stepper

On an Android project, I am using android-material-stepper from StepStone. I am also using dependency injection with dagger.

I was facing the following problem : How to properly inject Fragments without the need to create a DaggerComponent for each of them ?

Providers are here to help. This is how I am doing

class StepFragmentBL @Inject constructor() :
Fragment(), Step, BlView {

@Inject
lateinit var blPresenter: BlPresenter

...
}

This is one of the Fragment I am creating. We can see the @Inject constructor with @Inject lateinit var that shows that this object is injectable by dagger. It is also implementing Step to be used by StepperLayout and implements another interface.

class BlPresenter @Inject constructor

BlPresenter is a simple injectable class

@Singleton
@Component(modules = [(DeliveryModule::class)])
interface DeliveryComponents {

fun inject(deliveryActivity: DeliveryActivity)
}

This is the component injecting my Activity

@Module
class DeliveryModule(private val activity: DeliveryActivity) {

@Named("Activity")
@Provides
internal fun providesContext(): Context {
return activity
}

@Provides
fun providesFragmentManager(): FragmentManager {
return activity.supportFragmentManager
}
}
class DeliveryActivity : AppCompatActivity() {

@Inject
lateinit var deliveryPresenter: DeliveryPresenter

private lateinit var deliveryComponents: DeliveryComponents

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_home)

di()
ui()
}

private fun di() {
deliveryComponents = DaggerDeliveryComponents.builder()
.deliveryModule(DeliveryModule(this))
.build()
deliveryComponents.inject(this)
}

private fun ui() {
Timber.v(Info.getMethodName())
stepperLayout.adapter = deliveryPresenter.stepperAdapter
    
}
}

We are creating the component into the Activity here. Then, presenter for this activity is also injected

class DeliveryPresenter @Inject constructor() {

@Inject
lateinit var stepperAdapter: PickingStepperAdapter

}

We are arriving to a StepperAdapter instance, also injected

private const val NB_FRAG = 2

class PickingStepperAdapter @Inject constructor(
fm: FragmentManager,
@Named("Activity") context: Context) :
AbstractFragmentStepAdapter(fm, context) {

/**
* Provider for Fragment
*/
@Inject
lateinit var blFragmentProvider: Provider<StepFragmentBL>

/**
* Provider for Fragment
*/
@Inject
lateinit var pdtFragmentProvider: Provider<StepFragmentPdt>

override fun getCount(): Int {
return NB_FRAG
}

override fun createStep(position: Int): Step {
Timber.v("${Info.getMethodName()} $position")

return when (position) {
0 -> blFragmentProvider.get()
else -> pdtFragmentProvider.get()
}
}
}

Here, we are just using

@Inject
lateinit var blFragmentProvider: Provider<StepFragmentBL>

to tell dagger to create the code that will provide an instance of fragment each time blFragmentProvider.get() will be called. Indeed, this is called here

return when (position) {
0 -> blFragmentProvider.get()
else -> pdtFragmentProvider.get()
}

Like this, dagger is injecting fragment for us, and we don’t have to care about objects creation

Android : Créer un fichier keystore (jks) à partir d’une clé (.pk8) et d’un certificat (.pem)

  • Extraire la clé contenue dans le fichier pk8 et la mettre en clair dans un fichier pem
openssl pkcs8 -inform DER -nocrypt -in key.pk8 -out key.pem
  • Regrouper la clé et le certificat dans un fichier p12 temporaire
openssl pkcs12 -export -in certificate.pem -inkey key.pem -out platform.p12 -password pass:android -name AndroidDebugKey
  • Générer le fichier jks à partir du p12 (keytool est un outil du framework android)
keytool -importkeystore -deststorepass android -destkeystore platform.jks -srckeystore platform.p12 -srcstoretype PKCS12 -srcstorepass android
  • Vérifier le fichier
keytool -list -v -keystore platform.jks

Assert Statique

L’utilisation d’un assert statique peut être utile dans le cas ou une condition doit être testée au moment de la compilation. Par exemple la taille d’un tableau. Le principe est d’utiliser une macro pour définir une expression. Si le test est valide alors l’expression générée l’est aussi, sinon elle résulte en une erreur de compilation.

#define STATIC_ASSERT(cond)    typedef int ERROR_##__LINE__[(cond) ? 1 : -1]

Ici, on utilise typedef pour définir un type tableau. Si la condition est valide alors la taille du tableau est positive. Sinon elle est négative ce qui résulte en une erreur de compilation.

Exemple d’utilisation :

STATIC_ASSERT(sizeof(object1) == sizeof(object2));

Protéger les classes contre la copie ou l’assignation en C++

Pour protéger les classes contre la copie, il suffit de déclarer le constructeurs de copie en private. Une macro peut être définie car le principe est le même pour toutes les classes.

#define DECLARE_NO_COPY_CLASS(classname)  \
    private:                              \
        classname(const classname&);
#endif

De même pour les protéger contre l’assignation, on peut déclarer la surcharge de l’opérateur « = » comme étant private.

#define DECLARE_NO_ASSIGN_CLASS(classname)  \
    private:                                \
        classname& operator=(const classname&);
#endif

Mutex Locker

Préambule

Le mutex locker fait partie du concept de RAII. Cette acronyme vient de l’anglais Resource Acquisition Is Initialization. C’est une technique de programmation qui permet de s’assurer que la ressource acquise sera bien libérée à la fin de la vie d’un objet.

Principe

Appliqué au mutex, ce principe consiste à bloquer un mutex lors de la création d’un objet et de le libérer lors de sa destruction. On peut imaginer la création d’un objet spécifique : le MutexLocker.  Il faudrait qu’il puisse prendre un mutex lors de sa création et le libérer lors de sa destruction. Son constructeur va donc prendre le mutex et son destructeur le détruire.

class MutexLocker {
    public :
        MutexLocker(Mutex& mutex): m_mutex(mutex) {
            m_mutex.Lock();
        }
        virtual ~MutexLocker(){
            m_mutex.Unlock();
        }

    private:
        Mutex& m_mutex;
};

Son utilisation procède comme suit :

{
    Mutex mutex;

    MutexLocker locker(mutex);

    /* Maintenant le mutex est pris. Le code critique peut être exécuté. */
}

Conclusion

Son utilisation est justifié quand des exceptions peuvent arriver à tout moment. A ce moment, le mutex est assuré d’être libéré à la fin de la portée du code lorsque le locker est détruit. D’une manière générale, il est bon de l’utiliser tout le temps pour éviter de tomber dans des cas d’erreur difficiles à détecter.

Singleton

Présentation

Le singleton est un patron de conception (design pattern) dont le but est de restreindre l’instanciation  d’une classe à un nombre défini d’objets. Il est utilisé lorsque l’on a besoin que d’un seul objet pour coordonner des actions dans un système. Par exemple, le singleton va être utilisé comme gestionnaire de fenêtre, gestionnaire de systèmes de fichiers ou d’imprimantes. Le singleton va être disponible de manière globale dans un package et sera utilisé comme étant un point d’accès.

Le singleton est une classe qui va s’instancier elle-même. Ses constructeurs seront donc définis comme étant privés. Elle met à disposition une méthode statique pour récupérer son instance. Cette méthode vérifie qu’une seule instance existe ou en crée une si elle n’existe pas encore.

Une attention particulière sera donnée dans les environnements multi-threadés. Si deux thread essaient d’accéder à l’objet, un seul devra l’instancier tandis que le deuxième obtiendra une référence sur l’objet nouvellement créé.

Implémentation en C++

template <typename T> class Singleton
{
    public:
        static T* Get() {
            if(null == m_intance) {
                m_instance = new T;
            }
            return m_instance;
        }

    protected:
        Singleton(){};
        virtual ~Singleton(){};

    private :
        static T* m_instance;
};

Les classes peuvent ensuite hériter de Singleton. Elles seront instanciées par la méthode héritée Get().

class Eur : public Singleton<Eur>
{
    friend class Singleton<Eur>;
};

func(){
    Eur* obj = Eur::Get();
};

Multi-Threading

Dans un environnement multi-tâche,  il est important de protéger le code d’instanciation pour éviter d’avoir plusieurs références vers le Singleton lorsque celui-ci est appelé depuis plusieurs threads différents.

La solution peut être comme suit :

template <typename T> class Singleton
{
    public:
        static T* Get() {
            m_mutex.Lock();
            if(null == m_intance) {
                m_instance = new T;
            }
            m_mutex.unlock();
            return m_instance;
        }

    protected:
        Singleton(){};
        virtual ~Singleton(){};

    private :
        static T* m_instance;
        static Mutex m_mutex;
};

Ici Mutex est une classe qui initialise le mutex dans son constructeur par défaut et présente les méthodes Lock() et Unlock() pour locker et délocker le mutex.

Le problème de cette solution est que le mutex est locké à chaque appel de Get(). Ceci peut être coûteux en nombre d’instruction en comparaison avec un simple test pour savoir si m_instance existe. D’autant plus que le Singleton n’est instancié qu’une seule fois pendant la durée de vie du programme.

Une proposition d’optimisation serait de tester une première fois si l’instance existe sans locker le mutex puis de tester une seconde fois sous protection dans le cas ou l’instance n’existe pas. Ceci ajoute un test dans le cas ou l’instance n’existe pas, mais enlève tout appel au mutex dans le cas ou elle existe.

template <typename T> class Singleton
{
    public:
        static T* Get() {
            if(null == instance)
            {
                m_mutex.Lock();
                if(null == m_intance) {
                    m_instance = new T;
                }
                m_mutex.unlock();
            }
            return m_instance;
        }

    protected:
        Singleton(){};
        virtual ~Singleton(){};

    private :
        static T* m_instance;
        static Mutex m_mutex;
};

Cette solution est valide car les accès concurrents en lecture ne sont pas pénalisant. En effet, le Singleton est le même pour tous les threads.

The TUN/TAP interface on Linux

Recently, I had to work with the tun interface on Linux. There is not a lot of documentation on this subject so here is a little presentation.

TUN/TAP is like a physical Ethernet port but for user space program. Instead of receiving data from a physical device, it receives it from a user space program and instead of sending data through a wire, sends it to a user space program.

This interface corresponds to a file situated in /dev/net/tun or /dev/tun. When a program opens this file, an interface is created. The name of this interface can be set by the program or automatically set by the tun driver as tunXX, tapXX or bnepXX where XX can be 0, 1, 2… This interface can be manipulated by ifconfig such as eth0.

More information can be found here

Now, i describe in the following some steps to open and use a tun interface.

Opening the file :

int tap = open(tunname[i], O_RDWR);
if (tap < 0) {
fprintf(stderr, "TAP: failed to open TUN interface\n");
return -1;
}

Configuring the interface :


struct ifreq ifr;

memset(&ifr, 0, sizeof(ifr));

/* Flags: IFF_TUN - TUN device (no Ethernet headers)
* IFF_TAP - TAP device
*
* IFF_NO_PI - Do not provide packet information
*/
ifr.ifr_flags = IFF_TAP|IFF_NO_PI;
strcpy(ifr.ifr_name, "bnep");

if( ioctl(tap, TUNSETIFF, (void *) &ifr) < 0 ) {
fprintf(stderr, "TAP: failed to set BNEP name\n");
close(tap);
tap = -1;
return -1;
}

Then we are setting the mac address :

struct sockaddr sap;
sap.sa_family = ARPHRD_ETHER;
((char*)sap.sa_data)[0]=0x00;
((char*)sap.sa_data)[1]=0x11;
((char*)sap.sa_data)[2]=0x22;
((char*)sap.sa_data)[3]=0x33;
((char*)sap.sa_data)[4]=0x44;
((char*)sap.sa_data)[5]=0x55;

memcpy((char *) &ifr.ifr_hwaddr, (char *) &sap, sizeof(struct sockaddr));

if (ioctl(tap, SIOCSIFHWADDR, &ifr) < 0) { fprintf(stderr, "TAP: failed to set MAC address\n"); }

The interface is configured. We can now start to listen :

uint8_t* buffer = (uint8_t *)malloc(1500); //size of an ethernet frame
assert(buffer != NULL);

while (tap >=0) {
struct timeval tv={ 1, 0};
fd_set rfd;
FD_ZERO(&rfd);
FD_SET(tap, &rfd);

// We are waiting for data coming to the file
if (select(tap+1, &rfd, NULL, NULL, &tv)<0) { fprintf(stderr, "bnep_sender: select failed\n"); break; } // If data to be read if (FD_ISSET(tap, &rfd)) { n = read(tap, buffer, BNEP_BUFFER_SIZE); if (n < 0 && errno != EINTR) { printf("\nERROR\n\n, thread killed \n\n"); break; } if (n==0){ printf("We read nothing\n"); } if (n > 0 ) {
//do some stuff with the data
}
}
}
if (buffer != NULL) free(buffer);
if (tap >= 0) close(tap);

return 0;

On the same way, we can write data to the file using 'write'. Don't forget the Ethernet header !

How to disable warnings

When we are using a third party library in software development, we may encounter a lot of warning during the compilation. It is possible to disable warnings using compiler flags. This will disable warnings for all codes, it is thus useless when we want the higher warning level in our code.

I have encountered some « unused variable » warning in adding source code in my project. I have disabled these warnings in adding this line just after the variable declaration : __attribute__ ((unused))

I have found the documentation here.

How to use diff in svn folder

The diff program is used to find differences between files. To know more about diff : http://www.google.com/search?hl=fr&q=man+diff

But, if we use diff in svn folder, it can find a difference between files inside .svn. Here is the line of code I’m using :
cd /where/is/my/svn/folder
diff -r -x .svn /folder/source /folder/dest > file

With these parameters, diff doesn’t look into .svn folder.