PDA

View Full Version : Java-Applikation als Server-Dienst



Seiten : [1] 2

KM
19-01-07, 10:27
Hallo,

wir haben derzeit einen Java-Server-Job auf unserer iSeries laufen. Dieser lauscht einfach auf einer DTAQ, verarbeitet bei Bedarf die Daten und gibt die Ergebnisse wieder an eine DTAQ zurück. Da wir auch einen Windows-Server hier rumstehen haben, der ziemlich unausgelastet ist, überlege ich gerade, ob es möglich wäre diesen Server-Job von der iSeries auf diesen Windows-Server zu verlagern und dort als Dienst laufen zu lassen. Evtl. könnten auch mehrere Jobs dazukommen. Und ich möchte damit die iSeries entlasten.

Ich habe jetzt mal folgendes versucht. Ich habe die Java-Applikation mit EXE-Wrappern (Launch4J und JSmooth) in EXE-Dateien konvertiert. Die Java-Applikation wird dabei aber nur "gekapselt" und es wird weiterhin eine JRE auf dem Server benötigt. Diese EXE-Datei funktioniert auch. Wenn ich sie allerdings als Windows-Dienst laufen lasse (z.B. mit RunAsSvc), wird bei Beendigung des Dienstes die JVM wohl nicht sauber beendet bzw. gar nicht beendet. Deshalb ist diese Lösung nicht so toll.

Jetzt versuche ich gerade mit dem Tool "JavaNativeCompiler" und "GCJ" aus der Java-Applikation eine native EXE-Datei zu erstellen. Allerdings scheint dies nicht so zu funktionieren. Die Compilierung hat Stunden gedauert und ist mit einem Fehler abgebrochen.

Wie würdet Ihr so etwas lösen ? Hat jemand von Euch Erfahrung mit JavaNativeCompiler und GCJ bzw. mit anderen (kostenlosen) Tools, um so etwas zu realisieren ? Oder ist dies der völlig falsche Weg und wäre anders viel leichter zu lösen ?

Gruß,
KM

BenderD
19-01-07, 11:40
Hallo,

warum zur exe machen? TomCat lässt sich als Java Applikation auch als Dienst installieren und hatte bei älteren Versionen auch keine .EXE als Launcher, wenn ich mich da recht erinnere.

mfg

Dieter Bender


Hallo,

wir haben derzeit einen Java-Server-Job auf unserer iSeries laufen. Dieser lauscht einfach auf einer DTAQ, verarbeitet bei Bedarf die Daten und gibt die Ergebnisse wieder an eine DTAQ zurück. Da wir auch einen Windows-Server hier rumstehen haben, der ziemlich unausgelastet ist, überlege ich gerade, ob es möglich wäre diesen Server-Job von der iSeries auf diesen Windows-Server zu verlagern und dort als Dienst laufen zu lassen. Evtl. könnten auch mehrere Jobs dazukommen. Und ich möchte damit die iSeries entlasten.

Ich habe jetzt mal folgendes versucht. Ich habe die Java-Applikation mit EXE-Wrappern (Launch4J und JSmooth) in EXE-Dateien konvertiert. Die Java-Applikation wird dabei aber nur "gekapselt" und es wird weiterhin eine JRE auf dem Server benötigt. Diese EXE-Datei funktioniert auch. Wenn ich sie allerdings als Windows-Dienst laufen lasse (z.B. mit RunAsSvc), wird bei Beendigung des Dienstes die JVM wohl nicht sauber beendet bzw. gar nicht beendet. Deshalb ist diese Lösung nicht so toll.

Jetzt versuche ich gerade mit dem Tool "JavaNativeCompiler" und "GCJ" aus der Java-Applikation eine native EXE-Datei zu erstellen. Allerdings scheint dies nicht so zu funktionieren. Die Compilierung hat Stunden gedauert und ist mit einem Fehler abgebrochen.

Wie würdet Ihr so etwas lösen ? Hat jemand von Euch Erfahrung mit JavaNativeCompiler und GCJ bzw. mit anderen (kostenlosen) Tools, um so etwas zu realisieren ? Oder ist dies der völlig falsche Weg und wäre anders viel leichter zu lösen ?

Gruß,
KM

KM
19-01-07, 13:36
Danke für den Hinweis. Bis jetzt habe ich aber noch überhaupt keine Erfahrung mit Application Servern. Wenn ich das nun richtig verstanden habe, ist Tomcat doch ein Application Server für Servlets und JSP. Ich habe aber weder ein Servlet noch JSP, sondern eine ganz normale Java-Applikation (class), die eine DTAQ verarbeitet.

Kann mir jemand einen Tip geben wie ich diese Applikation da "installieren" muß ? Den Tomcat-Server habe ich bereits installiert. Aber viel weiter komme ich jetzt nicht.

Gruß,
KM

BenderD
19-01-07, 14:01
Hi,

das könnte man zwar auch unter Tomcat, oder JBoss laufen lassen, aber ich meinte nur, dass die keine Exe drechseln. Habe mal gegoogelt, schau dier mal folgenden Link an:
http://www.tom-henne.de/Wiki.jsp?page=JavaProgrammeAlsWindowsServiceStarte n
die Windoof Software kriegst du dann auch hier:
http://www.ppedv.de/software/tool.aspx

Ansonsten das mit dem Serverdienst und dem auslagern, das geht schon in die richtige Richtung. Aber wieso eigentlich mehrere? Da reicht doch einer, der für jeden Request einen Thread startet und die Anforderungen unterscheiden kann und entsprechend verzweigt.

mfg

Dieter Bender


Danke für den Hinweis. Bis jetzt habe ich aber noch überhaupt keine Erfahrung mit Application Servern. Wenn ich das nun richtig verstanden habe, ist Tomcat doch ein Application Server für Servlets und JSP. Ich habe aber weder ein Servlet noch JSP, sondern eine ganz normale Java-Applikation (class), die eine DTAQ verarbeitet.

Kann mir jemand einen Tip geben wie ich diese Applikation da "installieren" muß ? Den Tomcat-Server habe ich bereits installiert. Aber viel weiter komme ich jetzt nicht.

Gruß,
KM

KM
19-01-07, 14:31
Danke für die Links. Ich werde das mal ausprobieren.

Wenn Du aber auch einen Hinweis für mich hast, wie ich das unter Tomcat laufen lassen kann (ohne eine EXE zu erstellen), wäre ich Dir auch sehr dankbar. Wenn das ohne EXE ginge, wäre es mir sogar lieber als die Variante mit dem Windows-Dienst.

Gruß,
KM

BenderD
19-01-07, 15:41
Hallo,

also exe braucht man da so oder so keine, man kann die java.exe als Service eintragen und der als Parameter deine Java Klasse mit main mitgeben; Anleitung in dem vorher angegebenen Link. Wenn dieser Service Autostart ist, dann fährt das automatisch hoch mit Windows.

Unter Tomcat geht das auch, dann installiert man den Tomcat als automatisch zu startenden Dienst, legt da eine Web Applikation an, oder missbraucht eine vorhandene kleine Demoanwendung dazu. In der web.xml dieser Anwendung kann man Servlets eintragen, die beim Start des Containers geladen werden; der Eintrag sieht dann so aus:

<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.kcole.mypackage.MyServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

In solch einem Servlet überschreibt man die init Methode und startet dort seinen eigenen Dienst (nicht die main aufrufen, sondern mit new MyService().run() , wobei die run Methode jetzt das enthält, was aus der main gestartet wird.

mfg

Dieter Bender


Danke für die Links. Ich werde das mal ausprobieren.

Wenn Du aber auch einen Hinweis für mich hast, wie ich das unter Tomcat laufen lassen kann (ohne eine EXE zu erstellen), wäre ich Dir auch sehr dankbar. Wenn das ohne EXE ginge, wäre es mir sogar lieber als die Variante mit dem Windows-Dienst.

Gruß,
KM

RobertPic
22-01-07, 14:27
Wenn Du aber auch einen Hinweis für mich hast, wie ich das unter Tomcat laufen lassen kann (ohne eine EXE zu erstellen), wäre ich Dir auch sehr dankbar. Wenn das ohne EXE ginge, wäre es mir sogar lieber als die Variante mit dem Windows-Dienst.

Ich noch meine Erfahrungen zu den einzelnen Varianten - auch ich bevorzuge die Tomcat-Variante.


zum GCJ:

habe ich getestet und stufe das als Projekt im Betastadium ein. Vor allem wenn man viele fremde JAR's einbindet kann es mühsam werden.
Weiters benötigt man eine Linuxumgebung unter Windows (z.B. cygwin oder miniGW) damit gcj auch funktioniert. Bei cygwin muss man dann noch ein DLL mitgeben.
Selbst wenn man ein Exe hinbekommt, ist es nicht sicher, dass die Sache auch funkioniert.
Schneller ist nur das Startverhalten, der Rest ist langsamer als normales Java.
Das exe braucht zur Laufzeit aber weniger Hauptspeicher, als eine JVM.--> zuviel "gefrickel"

zu den Exe-Wrappern:
Von den exe-Wrappern verwende ich auch JSmooth.
Vorteile:
eigenes Programmsymbol
eigener Programmname in Taskmanager (nicht javaw)
kein Zip-Programm welche sich auf einmal die jar-Endung schnappt un den Start verhindert
--> verwende ich allerdings nur für kleine GUI Programme, nicht für Dienste

zu den Java Service Wrappern:
Hier habe ich den Open Source "Java Service Wrapper" getestet. http://sourceforge.net/projects/wrapper/
Hat prinzipiell funktioniert, aber die Vorteile von Tomcat (Stichwort: Wartung über Web) zogen doch "besser"zum Tomcat:

Ich verwende hier Tomcat 5.5, mit der JRE 1.5 Vorteile:
Statusabfrage, Start/Stop - alles über Web (Standardport 8080) machbar
Auch das Deployen ist über Web machbar (war-Datei über den Manager der Weboberfläche hochladen und installieren)
kein extra Aufwand für das Verpacken (wie bei JSmooth oder den Service Wrapper) - einfach in Eclipse ein war-File exportieren
in meiner Firmenumgebung: Javadienste im Tomcat sind überall (Windows, Linux) gleich zu starten bzw. zu beenden
Mit Webprogrammierung auch Log und Konfiguration der Applikation über Web möglich.Kleiner Crashkurs für Tomcat/Web

Zur Installation:
Ab der Version 5.5 bringt Tomcat einen eigenen Compiler mit. Damit reicht eine Java Runtime (ab JRE 1.5) aus. Das Installfile vom Tomcat hat gerade mal 5.5 MB und ist auch schnell installiert. Im Setupprogramm kann man dann auch sagen, ob Tomcat als Dienst laufen soll.

Wenn der Tomcat gestartet ist, geht es über die Weboberfläche weiter:

http://localhost:8080/ oder die http://ip-adresse:8080/ von einem anderen PC

Dort klickt man auf den Manager, und man muss ein Passwort eingeben (Standard ist glaube ich manager/manager oder tomcat/tomcat).

Installation der Applikation:
Unter:
Lokale WAR Datei zur Installation hochladen

auf dursuchen und das lokale war-File auf den Server uploaden und anschließend mit "Installieren" beenden --> das war es in vielen Fällen schon.

War-File mit Eclipse (inkl. WST) erzeugen
Wenn man neues Webprojekt erzeugt, wird automatisch die ganze Struktur angelegt. Die Javasourcen liegen wie gewohnt unter src.

Im Verzeichnis Web-Content/WEB-INF liegt die Datei web.xml. Dort muss jetzt dein Startprogramm eingetragen werden. Entweder so, wie es von Dieter beschrieben wurde, oder auch als Listener - was ich persönlich bevorzuge, da man hier auch das Ende mitbekommt:

in die web.xml einfügen:


<listener>
<listener-class>com.at.od.web.ehkat.DbStarter</listener-class>
</listener>

Die Klasse schaut dann so aus:



public class DbStarter implements ServletContextListener {

public void contextInitialized(ServletContextEvent servletContextEvent) {
// Hier den Dienst als Thread starten
}

public void contextDestroyed(ServletContextEvent servletContextEvent) {
// Hier den Thread wieder beenden
}
}

Für zusätzlich benötige fremde Jar-Bibliotheken gibt es 2 Möglichkeiten:
1.) Die Jar-Dateien in die Bibliothek WEB-INF/lib kopieren (die Dateien aus dem Explorer in das Verzeichnis WEB-INB/lib in der Eclipse-Umgebung kopieren.

2.) Häufig gemeinsame Bibliotheken kann man auch im tomcat unter:
...Tomcat 5.5\shared\lib ablegen. Damit stehen diese jars allen Applikationen zur Verfügung.

Beim Export gibt es unter "Web" die Auswahl War-File. Das damit erstellte war-File kann man dann wie oben beschrieben auf den Tomcatserver deployen.

Start/Stop/Entfernen und neu Installieren läuft alles über die Weboberfläche des Managers.

KM
22-01-07, 16:44
Vielen Dank für die ausführlichen Antworten !

Ich habe inzwischen den Tomcat 5.5 und die JRE 1.5 installiert. Der Tomcat-Server läuft auch ohne Probleme. Jetzt hapert's nur noch am Servlet. Da es mein erstes Servlet wird, ist mir noch nicht so ganz klar wo ich was machen muß. Habe ich das nun richtig verstanden, dass die service()-Methode nicht benötigt wird und ich meinen ganzen Programmcode in die init() schreiben muß ? Oder was ist mit "new MyService().run()" gemeint ?

Gruß,
KM

BenderD
22-01-07, 22:08
Hallo,

du kannst entweder die Variante von Robert nehmen, dann schreibst du halt einen ServletContextListener und überschreibts dort die contextInitialized. Oder du schreibst eine Klasse
class MyClass extends HttpServlet
und überschreibst dort die init.
In diesem oder jenem Fall packst du dann die Logik, die jetzt in deiner main Methode steht darein.

mfg

Dieter Bender


Vielen Dank für die ausführlichen Antworten !

Ich habe inzwischen den Tomcat 5.5 und die JRE 1.5 installiert. Der Tomcat-Server läuft auch ohne Probleme. Jetzt hapert's nur noch am Servlet. Da es mein erstes Servlet wird, ist mir noch nicht so ganz klar wo ich was machen muß. Habe ich das nun richtig verstanden, dass die service()-Methode nicht benötigt wird und ich meinen ganzen Programmcode in die init() schreiben muß ? Oder was ist mit "new MyService().run()" gemeint ?

Gruß,
KM

KM
24-01-07, 09:45
...mühsam ernährt sich das Eichhörnchen...

Jetzt hab ich beide Varianten mal ausprobiert und habe noch folgende Fragen/Probleme:

Ich bekomme sowohl die Servlet- als auch die Listener-Variante zum Laufen und sie funktionieren sogar. Das ist schon mal das Positive.

Problem 1: Wenn einer dieser Dienste allerdings läuft, komme ich nicht mehr auf die Manager-Oberfläche (http://localhost:8080). Der Browser bleibt ewig hängen. Sobald der Dienst beendet ist, komme ich wieder drauf. Woran kann das liegen ?

Problem 2: Wie bereits erwähnt, lauscht dieser Dienst auf einer DTAQ. Wenn ich diese DTAQ so beschicke, dass der Dienst beendet wird, wird automatisch auch der komplette Tomcat-Server beendet. Ist das normal ?

Problem 3: Wenn ich den Tomcat-Server beende, solange der Dienst noch aktiv ist, erhalte ich "Systemfehler 109. Die Pipe wurde beendet". Ich vermute mal das liegt daran, dass der DTAQ-Job unsauber beendet wird, oder ?

Problem 4: Wenn ich den Listener in das Verzeichnis "classes" stelle und in der web.xml dann nur den Klassennamen (MeinListener) angebe im <listener-class> Tag, dann funktioniert das. Wenn ich aber die Klasse ins Verzeichnis "classes\listener" stelle und in der web.xml die Klasse mit "listener.MeinListener" anspreche, dann erhalte ich einen Fehler beim Starten (...ClassNotFound... wrong name...). Was muß ich ändern, damit das auch funktioniert. Ich wollte eigentlich nicht alle Klassen ins Verzeichnis classes stellen.

Problem 5: Gibt es eine Möglichkeit Dienste auch anders zu starten/beenden als über die Manager-Oberfläche ?

Vielen Dank schon mal im Voraus.

KM