PlugIns

Der D1-Kernel ist relativ klein und besteht lediglich aus den nötigen Services für das lokale Messaging. Alle weiteren Inhalte werden über PlugIns bereitgestellt.

Das PlugIn-System ist einfach gehalten. Dennoch können PlugIns vollständig am Messaging teilhaben.

PlugIn-Interface

PlugIns sind JAR-Dateien, welche eine Klasse besitzen, die das Interface IPlugIn implementieren. Hier folgt exemplarisch die Klasse für das Monitor-PlugIn:

package de.softdevel.d1.monitor.impl;

import java.net.URL;
import java.net.URLClassLoader;

import de.softdevel.d1.exception.CException;
import de.softdevel.d1.kernel.IKernel;
import de.softdevel.d1.plugin.IPlugIn;

public final class CModule implements IPlugIn
{
    private CMonitorFrame mFrame = null;

    @Override
    public void startPlugin(final URL aUrl,
                            final URLClassLoader aClassLoader,
                            final IKernel aKernel) throws CException
    {
        if (mFrame == null)
        {
            mFrame = new CMonitorFrame(aKernel);
        }
    }

}

Die Klasse ist super einfach gehalten. Wie man sieht, wird lediglich der Kernel benötigt, um den Monitor an das Messaging zu binden. Es wird hier lediglich ein Swing-Frame erstellt, und diesem zwecks Anbindung der Kernel überreicht.

Diese Einfachheit ist auch der Grund, warum wir Programme, die devel.one benutzen, einfach als PlugIn ausführen. PlugIns können leicht von einem System zu einem anderen kopiert werden. Zudem laufen sie nicht alleine, denn das System kann durch Hinzufügen von anderen PlugIns leicht durch weitere Funktionalität erweitert werden. Alle PlugIns werden schließlich innerhalb der selben Programm-Instanz ausgeführt. Es ist zudem problemlos möglich, GUI-Programme als PlugIn zu starten.

PlugIn-Manifest

Damit der Kernel die richtige PlugIn-Klasse findet, muss sie im JAR-Manifest angegeben werden. Technisch geht das mit vielen Build-Systemen. Wir benutzen Gradle:

apply plugin: 'java'
apply plugin: 'checkstyle'

version = '1.0'

repositories {
    jcenter()
}

dependencies {
    compile project(':D1Kernel')
    compile project(':D1MonitorAPIPlugIn')

    compile 'org.slf4j:slf4j-api:1.7.21'

    testCompile 'junit:junit:4.12'
}

jar {
    manifest {
        attributes(["Manifest-Version": "1.0"])
        attributes(["Implementation-Title": "D1 Monitor PlugIn"])
        attributes(["Implementation-Vendor": "softdevel GmbH, Hohenwestedt, Germany"])
        attributes(["Implementation-URL": "www.softdevel.de"])
        attributes(["Implementation-Version": version])
        attributes(["PlugIn-Class": "de.softdevel.d1.monitor.impl.CModule"], "devel.one")
    }
}

Dabei ist die letzte Zeile des Manifest-Eintrags wichtig (PlugIn-Class). Hier wird die vollständige Klassenbezeichnung eingetragen.

Lade-Reihenfolge

Dabei kann das PlugIn auch von anderen PlugIns abhängig sein. Die Reihenfolge des Ladevorgangs wird in der Datei plugins.txt im Konfigurationsverzeichnis festgelegt:

D1NetworkPlugIn
D1TcpPlugIn
D1LogCatcherPlugIn
D1MonitorAPIPlugIn
D1MonitorPlugIn
D1MonitorLogPlugIn
D1MonitorSequencePlugIn
D1TestPlugIn
D1GateKeeperPlugIn
D1Application
D1PrivateOnlineTestPlugIn

Da das PlugIn D1MonitorPlugIn vom PlugIn D1MonitorAPIPlugIn abhängig ist, wird letzteres zuerst geladen.

Die obige PlugIn-Steuerungsdatei ist auch aus anderem Grund nützlich. Alle PlugIns deiner Systeme können zentral auf einem Server liegen. Es werden nur die PlugIns geladen, die auch in der Steuerungsdatei eingetragen sind. Das erleichtert die Arbeit bei System-Updates vieler D1-Systeme und steuert dem Versions-Wildwuchs entgegen.