Übersicht

Wie es auch bei den meisten Anwendungen und Entwicklertools der Fall ist, ist es gewöhnlich am besten mit einem einfachen "Hello World!"-Beispiel zu starten. Die übliche Java Hello World Anwendung startet, gibt "Hello World" aus und beendet sich dann. Es ist nicht sehr interessant, ein Tool für das Ausführen und Überwachen von Diensten besonders anzupreisen. Im Falle des Java Service Wrappers wird ein Beispiel benötigt, welches installiert und dann als Windows-Dienst oder UNIX-Daemon kontinuierlich läuft.

Diese Seite beschreibt unser "Hello World Server"-Anwendungsbeispiel und hilft Ihnen durch die Vorgehensweise, dieses zu erstellen. Die Seite Wie kann ich meine Java-Anwendung als Windows-Dienst ausführen? nutzt dieses Beispiel, um Sie durch den Ablauf der schnellen Konfiguration und Installation dieses Beispiels zu führen, ausgeführt als ein Windows Dienst mittels des Java Service Wrappers.

Dieses Beispiel, die Hello-World-Anwendung startet einen Daemon-Thread, der auf dem Port 9000 für einfache textbasierte Clients lauscht, die sich via Telnet verbinden. Es wird dann einfach jede Eingabe ausgeben bis es die Eingabe exit anfindet, an dessen Punkt dann die spezifische Verbindung beendet wird.

Während dies ein wenig komplizierter als ein herkömmliches Hello-World-Beispiel ist, ermöglicht es Ihnen eine einfache Server-Anwendung auszuführen, die imstande ist, mit einem Client-Programm zu kommunizieren, dem grundlegenden Server-Client-Design-Modell folgend.

Beispiel Quellcode

Um unser Beispiel fehlerfrei zu halten und damit es problemlos mit unseren Beispielen funktioniert, beginnen Sie bitte mit einem leeren Verzeichnis am Ort Ihrer Wahl, welches wir %HELLO_HOME% nennen werden. Erstellen Sie bitte die Verzeichnisse lib\classes und src\java innerhalb von %HELLO_HOME%. Sie sollten Folgendes erhalten:

Verzeichnisstruktur
%HELLO_HOME%\
  lib\
    classes\
  src\
    java\

Als nächsten Schritt erstellen Sie bitte eine einzelne Datei im src\java Verzeichnis, genannt HelloWorldServer.java und öffnen Sie diese in einem Editor-Programm. Kopieren Sie den folgenden Quellcode in die Datei und speichern Sie diese.

HelloWorldServer.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class HelloWorldServer
    implements Runnable
{
    private final Socket m_socket;
    private final int m_num;

    HelloWorldServer( Socket socket, int num )
    {
        m_socket = socket;
        m_num = num;
        
        Thread handler = new Thread( this, "handler-" + m_num );
        handler.start();
    }
    
    public void run()
    {
        try
        {
            try
            {
                System.out.println( m_num + " Connected." );
                BufferedReader in = new BufferedReader( new InputStreamReader( m_socket.getInputStream() ) );
                OutputStreamWriter out = new OutputStreamWriter( m_socket.getOutputStream() );
                out.write( "Welcome connection #" + m_num + "\n\r" );
                out.flush();
                
                while ( true )
                {
                    String line = in.readLine();
                    if ( line == null )
                    {
                        System.out.println( m_num + " Closed." );
                        return;
                    }
                    else
                    {
                        System.out.println( m_num + " Read: " + line );
                        if ( line.equals( "exit" ) )
                        {
                            System.out.println( m_num + " Closing Connection." );
                            return;
                        }
                        //else if ( line.equals( "crash" ) )
                        //{
                        //    System.out.println( m_num + " Simulating a crash of the Server..." );
                        //    Runtime.getRuntime().halt(0);
                        //}
                        else
                        {
                            System.out.println( m_num + " Write: echo " + line );
                            out.write( "echo " + line + "\n\r" );
                            out.flush();
                        }
                    }
                }
            }
            finally
            {
                m_socket.close();
            }
        }
        catch ( IOException e )
        {
            System.out.println( m_num + " Error: " + e.toString() );
        }
    }
    
    public static void main( String[] args )
        throws Exception
    {
        int port = 9000;
        if ( args.length > 0 )
        {
            port = Integer.parseInt( args[0] );
        }
        System.out.println( "Accepting connections on port: " + port );
        int nextNum = 1;
        ServerSocket serverSocket = new ServerSocket( port );
        while ( true )
        {
            Socket socket = serverSocket.accept();
            HelloWorldServer hw = new HelloWorldServer( socket, nextNum++ );
        }
    }
}

Die Anwendung startet und beginnt auf dem Port 9000 bezüglich Remote-Verbindungen von jedweder Quelle zu lauschen. Da jede neue Verbindung akzeptiert wird, wird ein dedizierter Handler-Thread erstellt, der sich um jedwede Kommunikation mit dieser Verbindung kümmert bis diese geschlossen wird.

Der Handler-Thread liest und gibt dann jede Textzeile an den Client zurück. Wenn eine Textzeile, die nur das Wort exit enthält, empfangen wird, dann wird die Client-Verbindung geschlossen.

Beispiel erstellen

Das Erstellen eines Beispiels ist eine einfache Aufgabe. Beginnen Sie bitte, indem Sie eine Kommandozeile oder eine Shell unter UNIX öffnen und gehen Sie in das %HELLO_HOME% Verzeichnis, welches wir oben mittels des cd-Befehls erstellt haben.

Das Beispiel kann nun durch folgenden Befehl kompiliert werden:

Kompilieren des Beispiels:
javac -d lib\classes src\java\HelloWorldServer.java

Wenn Sie einen Fehler erhalten, dass der javac Befehl nicht gefunden werden konnte, stellen Sie bitte sicher, dass Sie eine Java SDK auf Ihrem System installiert haben. Wenn alles korrekt verlaufen ist, dann sollten Sie nach Abschluss des Kompilierens die Eingabeaufforderung ohne zusätzliche Ausgabeinformationen zurückerhalten.

Bitte stellen Sie sicher, dass beim Ausführen die class-Datei erstellt wurde:

Prüfen der Klassen-Datei:
dir lib\classes

Glückwunsch, Sie haben erfolgreich das HelloWorldServer-Beispiel erstellt.

Ausführen des Beispiels

Das Ausführen des Beispiels kann durch das Ausführen des folgenden Befehls von innerhalb des %HELLO_HOME% Verzeichnisses erledigt werden.

Ausführen des Beispiels:
java -classpath lib\classes HelloWorldServer

Wenn alles gut verläuft, sollten Sie Folgendes sehen:

Beispielausgabe:
Accepting connections on port: 9000

Sich als ein Client verbinden

Lassen Sie uns nun versuchen, einen Client zu unserem Server zu verbinden und sehen, was passiert. Beginnen Sie, indem Sie eine zweite Eingabeaufforderung starten und sich via Telnet verbinden:

Verbindung via Telnet:
telnet localhost 9000

Sobald Sie verbunden sind, sollten Sie eine Antwort erhalten, die Ihre Verbindungsnummer anzeigt. Darauf wird jedweder Text, den Sie gefolgt vom Drücken der Enter-Taste eingeben, Ihnen wiedergegeben.

Beispiel Telnet-Sitzung:
Welcome connection #1
Test
echo Test
Hello there world!
echo Hello there world!

Sobald Sie die Nachrichtenübertragung mit einem Server beendet haben, können Sie Ihre Verbindung durch Eingeben von exit beenden.

Unser Beispielserver ist auch imstande, Telnet-Verbindungen von jedem Computer, welcher den Server sehen kann, zu akzeptieren. Wenn Sie beim Verbinden Probleme haben sollten, stellen Sie bitte zuerst sicher, dass es zwischendrin keine aktiven Firewalls gibt.

Den Server zum Absturz bringen

Das obengenannte Beispiel passt ausgezeichnet auf einen einfachen Standalone Java Server. Aber wir möchten Ihnen zeigen, wie der Java Service Wrapper imstande ist, es versteht, einen kleinen Beispielserver viel stabiler zu machen, damit Ihr Unternehmen anfangen kann, sich auf diesen für betriebskritische Systeme zu verlassen.

Zu Anfang möchten wir ein crash-Befehl hinzufügen, so dass wir es für einen verbundenen Client ermöglichen können, die JVM zum Absturz zu bringen. Während es möglich ist, einen tatsächlichen Crash mittels verschiedener bekannter Bugs in the JVM zu verursachen, funktionieren viele dieser nur auf gewissen Platformen oder mit spezifischen Java-Versionen. Für dieses Beispiel simulieren wir einen Absturz durch Aufruf von Runtime.getRuntime().halt(0), um die JVM sofort zu beenden, ohne diese fehlerfrei herunterzufahren.

Bitte öffnen Sie die HelloWorldServer.java Quelldatei im Editor und aktualisieren Sie den Programmcode wie folgt:

HelloWorldServer.java
    ...
    System.out.println( m_num + " Read: " + line );
    if ( line.equals( "exit" ) )
    {
        System.out.println( m_num + " Closing Connection." );
        return;
    }
    else if ( line.equals( "crash" ) )
    {
        System.out.println( m_num + " Simulating a crash of the Server..." );
        Runtime.getRuntime().halt(0);
    }
    else
    {
        System.out.println( m_num + " Write: echo " + line );
        out.write( "echo " + line + "\n\r" );
        out.flush();
    }
    ...

Das Beispiel kann nun rekompiliert und mittels der gleichen Befehle wie oben ausgeführt.

Versuchen Sie sich nun mit dem Server zu verbinden und folgenden Befehl abzusenden: crash. Unser einfacher, kleiner Beispielserver wird zum Absturz gebracht und wir sind nicht länger in der Lage, uns mit diesem via Telnet zu verbinden, diesen zu nutzen. Es ist offensichtlich, dass wenn dies ein betriebskritischer Server wäre, würde der Systemadministrator einen Telefonanruf erhalten, sobald es einem User Unannehmlichkeiten bereiten würde.

Um dieses Problem zu lösen, sehen Sie bitte auf der Seite Wie kann ich meine Java-Anwendung als Windows-Dienst ausführen? für Anweisungen bezüglich, wie dieser Beispielserver in einen Windows Dienst oder UNIX Daemon umgewandelt werden kann, der in der Lage ist, sich automatisch von unserem Beispielabsturz wie von einer Zahl anderer Probleme wiederherzustellen.