Inhalt
Installation JBoss/Eclipse
Eclipse und WebTools-Plugin konfigurieren:
JBoss-KnowHow:
Installation JBoss/Eclipse
Benötigte Komponenten
Eclipse und WebTools-Plugin konfigurieren
WildFly 18.0.x
In "Window" -> "Preferences..." gehen und links in der Übersicht den Punkt "Server" -> "Runtime Environments" wählen.
Über "Add..." einen neuen Server zufügen.
Im Bereich "JBoss Community" wählen einen Server vom Typ "WildFly 18.x Runtime"" aus.
Im nächsten Schritt als Runtime JRE ein Execution Environment "JavaSE-1.8" auswählen (sollte standardmäßig verfügbar sein, wenn Java 1.8 auf dem Rechner installiert ist)
und als "Home directory" das Wurzel-Verzeichnis des JBoss auswählen.
Eclipse-Tuning
Folgende Einstellungen empfehle ich, um Eclipse schneller und Resourcenschonender einzustellen:
Automatischen Build ausschalten
Die Option "Build Automatically" im Menü "Project" wird ausgeschaltet:
Das bedeutet dass man das Compilieren vor einem Deploy per Hand durch "Build Project" bzw. "Build All" anstoßen muss.
Rechtschreibprüfung abschalten
Die integrierte Rechtschreibprüfung (per Default sowieso nur englisches Wörterbuch) wird abgeschaltet da dies sehr viele Resources kostet:
Eclipse-Codeformatter
Damit der Quellcode zumindest innerhalb einer Projektgruppe bei allen gleich aussieht empfehle
ich die Codeformatierungs-Optionen von Eclipse zu vereinheitlichen. Dies geschieht über "Window" ->
"Preferences" -> "Java" -> "Code Style" -> "Formatter", wo man ein neues Profile zufügt.
Im folgenden die in meinen Beispielen verwendeten Einstellungen:
Eine Mischung aus Tabs und Leerzeichen sieht in einem anderen Editor meistens müllig aus,
deshalb nur Leerzeichen für Einrückung verwenden. Und mit nur 2 Leerzeichen sparen wir Platz.
Ich bevorzuge öffnende Klammern auf der gleichen Spalte wie die schließende Klammer, also
viele Zeilenumbrüche.
Passend zu den Zeilenumbrüchen vor öffnenden Klammern mag ich sie auch nach schließenden Klammern.
Die maximale Zeilenlänge bis zu einem vom CodeFormatter erzwungenen Zeilenumbruch würde
steht in neueren Eclipse-Versionen schon auf einem sinnvollen Default-Wert von "120":
Angewendet werden diese Einstellungen automatisch beim Tippen. Man kann aber auch nachträglich eine Datei formatieren,
indem man sie öffnet und im Editor-Contextmenü den Punkt "Source" - "Format" wählt:
Für die Formatierung von HTML-/JSP-Seiten finden wir die Formatierungseinstellungen unter "Window" -> "Preferences" ->
"Web" -> "HTML" -> "Editor". Auch hier werden Tabs abgeschaltet sowie die Zeilenlänge auf 120 Zeichen hochgedreht.
Javadoc
In den Preferences werden die JavaDoc-Warnungen eingeschaltet:
Projektstruktur
Die Struktur eines Projekts (im Beispiel das Stateless-Beispiel mit EJB-Projekt, Webprojekt
und ApplicationClient) sieht auf Festplatte so aus (Screenshot aus einer älteren Eclipse-Version und auf dem Stand von JavaEE5, grundlegend
gilt das aber alles noch):
- Im Verzeichnis "StatelessClient\appClientModule" finden wir die Java-Quelldateien und im
Unterverzeichnis "META-INF" die Deskriptoren. In "StatelessClient\build\classes"
werden beim Build des Projekts die compilierten "class"-Dateien sowie benötigte Deployment-Deskriptoren
abgelegt.
- Dito für "StatelessEJB\ejbModule": hier liegen die Java-Quelldateien. Im
Unterverzeichnis könnten "META-INF" Deployment-Deskriptoren liegen. In "StatelessEJB\build\classes"
laden beim Build die "class"-Dateien und die Deployment-Deskriptoren.
- Beim Webprojekt liegen die Java-Dateien im Unterverzeichnis "JavaSource", während die Deskriptoren
und die JSP-Dateien im Verzeichnis "WebContent" liegen. In "StatelessWeb\build\classes"
werden beim Build des Projekts die compilierten "class"-Dateien erstellt (hier werden allerdings keine
Dateien aus WEB-INF kopiert).
- In "Stateless\EarContent" liegen die Deployment-Deskriptoren der EAR-Anwendung (falls vorhanden).
Debugging
Zum Debuggen dürfen wir den JBoss nicht "normal" starten sondern im Debug-Modus (Rechtsklick auf den Server, "Debug"
wählen).
Im folgenden beziehe ich mich auf Klassen aus dem ersten Beispiel, "Stateless".
Wir setzen einen Breakpoint in der Methode doPost
des GeometricModelServlet
. Anschließend im Browser zu dieser URL navigieren:
http://localhost:8080/StatelessWeb/servlet/GeometricModelServlet.
Wenn wir alles richtig gemacht haben schiebt sich Eclipse in den Vordergrund, und wir werden gefragt ob wir
in die Debug-Perspective wechseln wollen (machen wir natürlich).
In der Toolbar können wir jetzt Einzelschritte ausführen, in Funktionen springen oder aus einzelnen Funktionen hinausspringen. Über die Schaltfläche "Resume"
können wir die Verarbeitung bis zum nächsten Breakpoint weiterlaufen lassen.
Auf diese Weise können wir auch JSP-Seiten debuggen.
JBoss-Knowhow
Doku: https://docs.jboss.org/author/display/AS71/Documentation
Für JBoss 8 - WildFly: https://docs.jboss.org/author/display/WFLY8
Dort findet sich z.B. ein "Getting Started Guide".
Anmerkung: der Serverversions-Teil der URL ("AS71" für "Application Server 7.1") könnte sich ändern.
So gibt es aktuell auch eine "AS72"-Variante. Diese sollte eigentlich neuer sein, aber scheinbar wurden in dem "AS71"-Zweig
seit dem Split der 7.2-Version noch Änderungen in der Doku gemacht, die nicht im "AS72"-Zweig ankamen.
Verzeichnisstruktur
Ein WildFly 8.x-Paket besteht (unter anderem) aus diesen Verzeichnissen:
- "bin": enthält wichtige Scripte zum Serverstart und zur Administration. Beispiel:
- "standalone.bat": startet einen Server im Standalone-Modus. Über diese Datei müssten wir JBoss immer starten, wenn Eclipse
und das nicht abnehmen würde. Das Gegenstück zu dieser Datei ist "domain.bat": sie startet einen Server im Domain-Modus.
- "jboss-cli.bat": startet das "Command Line Interface" von JBoss, also die konsolenbasierte Administrations-"oberfläche".
- "appclient.bat": startet einen JavaEE-Application Client (jar-Datei innerhalb einer ear-Datei), siehe
Stateless-Beispiel.
Dazu wird ein Mini-JBoss-Umfeld gestartet, dessen Arbeitsbereich (Logdateien, Config, Temp-Verzeichnis) im
Verzeichnis "%JBOSS_HOME%\appclient" liegt
- "add-user.bat": kann Server-Benutzer anlegen - siehe weiter unten.
- "docs": enthält primär die XSD- und DTD-Dateien zu den von JBoss verwendeten Configdateien, darunter auch die XSDs des JavaEE-Umfelds.
- "standalone": enthält das Umfeld für einen JBoss im Standalone-Modus (für Details siehe nächster Abschnitt).
- "domain": enthält das Umfeld für einen JBoss im Domain-Modus. Für uns nicht relevant.
- "modules": enthält im Prinzip alle Jar-Dateien, die JBoss benötigt: jede Jar-Datei liegt in einer Verzeichnisstruktur, die ihrem Package
entspricht. Jeder Package-Trenner wird zu einem Verzeichnis-Trenner. Ab JBoss 8 ist diese Verzeichnisstruktur
erweitert worden: "modules\system\layers\base"
Standalone/Domain
Siehe hier: https://docs.jboss.org/author/display/AS7/Operating+modes
Stark vereinfacht: Im Domain-Modus gibt es einen zentralen Server ("Domain Controller"), bei dem sich weitere Server registrieren. Die Konfiguration
für alle Server wird über den Domain Controller gesteuert und abgeglichen. Dies ist nicht zu verwechseln mit einem Cluster, in dem mehrere Server
die gleiche Anwendungs-Funktionalität anbieten und Clientanfragen an unterschiedliche Server verteilt werden - dies ist in Domain- und Standalone-Modus
möglich.
Im Rahmen dieser Dokumentationen konzentrieren wir uns auf einen Standalone-Server.
Dieser befindet sich im Verzeichnis "%JBOSS_HOME%\standalone" und hat folgende Unterverzeichnisse:
- "configuration": Hier findet sich die Server-Konfiguration ("standalone.xml" ist der Default, die anderen "standalone-xx.xml"-Dateien
biete andere Konfigurationsprofile und müssen explizit beim Serverstart angegeben werden, um genutzt zu werden.
Die Dateien "mgmt-users.properties" und "application-users.properties" enthalten Benutzer, die mittels "%JBOSS_HOME%\add-user.bat" angelegt wurden.
- "data": enthält Laufzeitdaten des Servers, z.B. Transaktionen oder Timer
- "deployments": hier können im Standalone-Server Anwendungen abgelegt werden, die in den Server eingespielt werden sollen.
Im Domain-Modus gibt es dieses Verzeichnis nicht. Mehr zum Deploy von Anwendungen weiter unten.
- "log": Protokolldateien des Servers. "boot.log" wird beim Serverstart geschrieben, "server.log" enthält genau die Ausgaben, die wir auch
in der Konsole sehen.
- "tmp": enthält die temporären Dateien des Servers. Im Verzeichnis "vfs" (Virtual File System) finden sich in Unterverzeichnissen z.B. Dateien, die als Archiv
ins "deployments"-Verzeichnis kopiert wurden und im "vfs"-Verzeichnis entpackt wurden. In "work" finden sich Daten des integrierten Webservers, siehe unten.
JBoss starten/stoppen
Ganz trivial:
Starten: "%JBOSS_HOME%\bin\standalone.bat" ausführen (startet Server im Standalone-Modus)
Stoppen: In dem beim Start aufgehenden Konsolenfenster "Strg+C" drücken. Man kann den Server auch über die diversen Verwaltungskonsolen
stoppen, siehe weiter unten.
Ab WildFly 9 wird der bevorzugte Weg für das Server-Starten ein Powershell-Script sein: https://issues.jboss.org/browse/WFCORE-25
Command Line Interface (CLI)
Das "Command Line Interface" (kurz: CLI) ist eine der Verwaltungsmöglichkeiten für einen JBoss-Server.
Siehe https://community.jboss.org/wiki/CommandLineInterface
Man startet es durch Ausführen von %JBOSS_HOME%\bin\jboss-cli.bat. Es bietet sich folgenden Ausgabe:
Mittels des Befehls "connect" (bzw. "connect localhost:9999" als Beispiel für die Angabe von Server und Port - das sind auch die Defaults)
baut man eine Verbindung zum JBoss-Server auf:
ACHTUNG:
Mit JBoss 8 - WildFly hat sich der Port geändert, das ist jetzt die Nummer "9990". Also sieht der Befehl zum Verbinden so aus: "connect localhost:9990".
Mehr Beispiele für die Anwendung der CLI kommen später.
Hier nur soviel:
- "quit" beendet die laufende Sitzung.
- "shutdown" stoppt den JBoss-Server
Hinweis: an sehr vielen Stellen wird Tab Completion unterstützt. Nicht nur Befehle sind erweiterbar, sondern auch für die Argumente gibt
es die Vorschläge und Vervollständigung.
Es gibt auch eine GUI-Variante der Konsole (siehe
https://community.jboss.org/wiki/AGUIForTheCommandLineInterface)
Diese wird gestartet mittels "jboss-cli.bat --gui":
Web-Console
Eine zweite Verwaltungsmöglichkeit ist die Webkonsole. Diese erreicht man über http://localhost:8080 (dort
auf den Link "Administration Console" klicken) bzw. direkt über http://localhost:9990/console
Beim ersten Aufruf wird einen nur eine Seite begrüßen, die einen darauf hinweist, dass man noch keinen Benutzer angelegt hatte:
Also folgt man der Anleitung auf dieser Seite:
- Man ruft das Script %JBOSS_HOME%\bin\add-user.bat" auf
- Man wählt Option "a) Management User (mgmt-users.properties)"
- Im nächsten Schritt wird automatisch das Realm als "ManagementRealm" vorbelegt (JBoss 7.x und frühere WildFly 8.x-Versionen fragten hier nach)
- Jetzt gibt man einen Usernamen an. Hier kommen Warnungen, wenn der Username zu einfach ist. Für einen lokalen JBoss mag das aber OK sein.
- Im nächsten Schritt ist ein Passwort gefragt. Hier gibt es ziemlich strenge Validierungsregeln, die ein zu einfaches Passwort
verbieten. Ohne Anspruch auf Vollständigkeit: das Passwort muss mind. 8 Zeichen lang sein. Es muss mindestens ein nicht-alphanumerisches
Symbol enthalten.
Wichtig: dieses Passwort irgendwo notieren - wir werden es später noch benötigen!
- Bei der Frage "What groups do you want this user to belong to?" (neu in WildFly 8.2) geben wir nichts an.
- Danach wird man gefragt, ob dieser Benutzer auch dazu verwendet werden soll, um von einem JBoss-Prozess aus eine Verbindung zu einem
anderen JBoss-Prozess aufzubauen. Das können wir mit "no" verneinen.
Jetzt haben wir es geschafft. Hier alle Schritte als Screenshot:
Der User wurde (wie man schon dem Screenshot entnehmen kann) der Datei "%JBOSS_HOME%\standalone\configuration\mgmt-users.properties" zugefügt.
Das Passwort ist verschlüsselt.
In WildFly 19 gibt es einen vorkonfigurierten, aber deaktivierten User "admin" - siehe "mgmt-users.properties" (den Eintrag gibt es auch schon in früheren Versionen,
aber die Meldung ist mir erst mit dieser Version aufgefallen).
Gibt man hier den Usernamen "admin" an, kommt eine Abfrage "User 'admin' already exists and is disabled, would you like to...".
Die Option "Enable the existing user" entfällt, da ich das Default-Passwort nicht kenne und der Kommentar in der Properties-Datei danach klingt, als wäre das kein "echtes" Passwort.
Also wählt man Option a) und muss ihn dann genauso weiterverarbeiten wie oben beschrieben.
Jetzt endlich können wir uns in der Webkonsole anmelden:
Unten rechts findet sich im Aufklappmenü unter "Tools" der Punkt "Management Model".
Hier sehen wir in einer Baumstruktur die Konfiguration aus "standalone.xml" sowie Informationen über aktuell deployte Anwendungen.
(das Bild ist nachbearbeitet - die Liste der Attribute ist ein Stück nach unten gescrollt, um ein paar relevante Informationen zu zeigen).
Im Beispiel ist der Bereich aufgeklappt, der die Datenbankverbindungen enthält. Auf der rechten Seite sieht man
drei Karteireiter, darunter eine Liste der Attribute und Operationen, die dieses Objekt bietet und die man per CLI abrufen kann.
Der Screenshot zeigt den Karteireiter "Data", auf dem die aktuellen Property-Werte dieses Objekts ausgegeben werden.
Auf die Attribute kann man auch per CLI zugreifen. Beispiel: Auslesen des Attributs "connection-url":
[standalone@localhost:9990 /] /subsystem=datasources/data-source=ExampleDS:read-attribute(name=connection-url)
{
"outcome" => "success",
"result" => "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE"
}
Und hier ein Screenshot, der eine deployte Anwendung (das Stateless-Beispiel) zeigt:
Viel mehr als den "Logout"-Button rechts unten zu nutzen können wir allerdings bisher nicht tun - mehr später ;-)
Deploy
Für das Deployen einer Anwendung gibt es mehrere Möglichkeiten:
Deploy ins "deployments"-Verzeichnis
Diese Variante ist nur in einen standalone-JBoss verfügbar. Der "domain"-Server bietet diese Möglichkeit nicht.
Die einfachste Art des Deployments ist es, ein Archiv (Ear, war, jar) in dieses Verzeichnis zu kopieren. JBoss
wird die Datei erkennen und automatisch deployen. Umgekehrt führt ein Löschen zu einem Undeploy, und ein Überschreiben durch
eine neuere Version zu einem Redeploy.
Wenn man ein "Exploded Deployment" durchführen will (also statt einer Archivdatei die entpackte Verzeichnisstruktur, wobei das
oberste Verzeichnis exakt so benannt ist wie eine Archivdatei, z.B. "Stateless.ear" als Verzeichnis!), dann führt JBoss kein automatisches
Deploy durch (Grund ist: der Server kann nicht erkennen, wann das hinkopieren der Daten abgeschlossen ist, und würde eventuell
eine halbe Anwendung deployen). Stattdessen muss man das Deployment über "Marker files" anstoßen. Diese haben den gleichen Namen
wie die zu deployende Anwendung (inklusive ear/war/jar-Zusatz), über ihre Endung wird die durchzuführende Aktion gesteuert.
Siehe https://docs.jboss.org/author/display/AS7/Application+deployment
oder auch die "README.txt" im "deployments"-Verzeichnis.
Beispiel: "Stateless.ear.dodeploy" startet das Deploy der Anwendung "Stateless.ear" (die natürlich schon vorher im "deployments"-Verzeichnis liegen muss).
Der Server löscht diese Datei, sobald das Deploy gestartet wurde, und schreibt während des Vorgangs diverse Status-Dateien:
"Stateless.ear.isdeploying" ist das Kennzeichen für "Deployment läuft gerade". Im Erfolgsfall wird diese Datei durch "Stateless.ear.deployed"
ersetzt. Löscht man diese Datei, erfolgt automatisch ein Undeploy. Im Fehlerfall entsteht "Stateless.ear.failed", die außerdem
eine Deployment-Fehlermeldung enthält. Löscht man diese Datei, erfolgt ebenfalls ein Undeploy.
Über eine Datei "Stateless.ear.skipdeploy" kann man das Deploy der Anwendung unterdrücken.
Deploy über CLI
Das Deploy einer Anwendung erfolgt so:
[standalone@localhost:9999 /] deploy c:\temp\Stateless.ear
Hinweis: auch bei Eingabe des Pfads hat man mittels "Tab" eine Komplettierung der Eingabe zur Verfügung, wie von Windows- oder Linux-Kommandozeile
bekannt.
Die deployte Anwendung findet sich auf dem Server wieder in einem Verzeichnis "%JBOSS_HOME%\standalone\tmp\vfs\deployment<zufallswert>"
Außerdem trägt JBoss die Anwendung in "standalone.xml" ein:
<deployments>
<deployment name="Stateless.ear" runtime-name="Stateless.ear">
<content sha1="2a62e331dff5c46922429a1269da21f185f9d7b8"/>
</deployment>
</deployments>
Der Wert "content" führt vermutlich zu dem eigentlichen Pfad von "Stateless.ear", allerdings gehasht.
Die originale EAR-Datei scheint in "%JBOSS_HOME%\standalone\tmp\vfs\temp<zufallswert>\content-<zufallswert>"
zu liegen. In diesem Verzeichnis gibt es eine Datei "content" - dies ist die umbenannte Datei "Stateless.ear".
Aus diesem Verzeichnis wird die Anwendung bei einem Server-Neustart geholt und die Inhalte in ein neues "...tmp\vfs\deployment..." gelegt.
Das Undeploy erfolgt so:
[standalone@localhost:9999 /] undeploy Stateless.ear
Hier wird nur der Name der Anwendung angegeben, ohne Pfad.
Deploy über Webconsole
Es gibt zwei Wege zum Deployment: auf der "Home"-Seite gibt es im Bereich "Common Tasks" die Gruppe "Deploy an application", dort klickt
man auf "Create Deployment". Alternativ kann man oben auf den Karteireiter "Deployments" klicken.
Auf der Seite "Deployments" klickt man im rechten Bereich auf "Add":
Es öffnet sich ein Assistent, in dem man die Datei auswählt. Im nächsten Schritt (Name der Anwendung) kann man alles auf den Defaults belassen.
Jetzt ist die Anwendung zwar auf dem Server deployed, allerdings noch nicht gestartet (erkennbar an dem "verboten"-Icon rechts neben dem Namen).
Deshalb klickt man auf "En/Disable" und bestätigt die Abfrage.
Generierte JSP-Java-Klassen
Zu JSP-Seiten generiert der in den JBoss integrierte Webserver (bis: JBoss 7.2: basierend auf Tomcat 7.0, ab WildFly 8: der Undertow-Webserver, eine
JBoss-Eigenentwicklung) Java-Dateien, diese wiederum werden ganz normal compiliert. Die generierten Java-Dateien findet man hier:
Bis JBoss 7.2: "%JBOSS_HOME%\standalone\tmp\work\jboss.web\default-host\(name der Web-Applikation)\org\apache\jsp"
Ab WildFly 8: "WILDFLY_HOME%\standalone\tmp\(name der Web-Applikation)\org\apache\jsp"
Ein Blick in diese Dateien ist bei Compilefehlern in der JSP-Seite eventuell nötig, wobei in den meisten Fällen die fehlerhaften Zeile
der JSP-Datei angegeben wird. Nur bei sehr schweren Syntax-Fehlern kann es nötig sein, einen Blick in die generierte Java-Datei zu werden.
JNDIView
Die JNDIView listet alle Einträge im Server-JNDI auf, darunter finden sich auch unsere eigenen Beans.
Webconsole
Über die Webconsole ist die "JNDIView" simpel zu erreichen (Anleitung ist auf dem Stand von WildFly 19): über den Karteireiter "Runtime" findet man links
eine Liste der Server. Hier steht im Falle eines Standalone-Servers natürlich nur ein Eintrag. Diesen klickt man an. Danach öffnet sich in einer
zweiten Spalte eine Liste der Subsysteme. Dort wählt man "JNDI" aus und klickt auf "View":
Auf der neuen Seite finden sich die JNDI-Einträge - im Beispiel für das Stateless-Beispiel:
CLI
Der benötigte Befehl ist:
[standalone@localhost:9999 /] /subsystem=naming:jndi-view
Das Ergebnis ist relativ unübersichtlich, enthält aber die gleichen Informationen wie die Webconsole:
JNDI-Namen
Der JaveEE6-Standard (http://docs.oracle.com/cd/E19798-01/821-1841/girgn/index.html)
definiert, wie JNDI-Namen aufgebaut sind. Anmerkung: in früheren JavaEE-Versionen war es dem jeweiligen Implementierer überlassen,
wie ein Name auszusehen hat. Mit JavaEE6 wurde dies standardisiert.
Es gibt drei Bereiche ("JNDI Namespaces"), in denen JNDI-Einträge gebunden werden können:
- Global: beginnt ein JNDI-Name mit "java:global", dann liegt dieser Eintrag global im Server vor und kann von allen Komponenten (die auf dem
Server laufen oder auch von außen darauf zugreifen) abgerufen werden. Die Syntax ist:
java:global[/application name]/module name/enterprise bean name[/interface name]
Der optionale "application name" (und der "/" davor) ist nötig, wenn die deployte Anwendung Teil eines EAR ist. Ansonsten wird dieser Teil weggelassen.
Der "interface name" ist ebenfalls optional: will man auf eine EJB über ein Local oder Remote Interface zugreifen, steckt hier der Name
des Interfaces. Bei WildFly8 ist der per Default der volle Name des Interfaces ("Package.Interface"). Im Falle einer "no interface view"
wird dieser Teil weggelassen (siehe Abschnitt im Stateful-Beispiel).
- Modul: beginnt ein JNDI-Name mit "java:module", dann liegt dieser Eintrag nur innerhalb des Moduls (z.B. ein EJB-JAR oder ein Web-Modul) vor
und kann von allen Komponenten in diesem Modul abgerufen werden, aber nicht von Komponenten außerhalb. Die Syntax ist:
java:module/enterprise bean name/[interface name]
Bei einem Webmodul erlaubt dies nur Zugriff auf EJBs, die in der Webanwendung definiert sind. Ist das Webmodul Teil einer EAR-Datei, dann könnte
man nicht auf EJBs zugreifen, die in einem separaten EJB-JAR liegen.
- Anwendung: beginnt ein JNDI-Name mit "java:app", dann liegt dieser Eintrag nur innerhalb der Anwendung (also einer EAR-Datei) vor
und kann von allen Modulen in dieser Anwendung abgerufen werden, aber nicht von Komponenten außerhalb. Die Syntax ist:
java:app[/module name]/enterprise bean name[/interface name]
Hier kann eine Webmodul auf EJBs zugreifen, die in einer EJB-JAR liegen, sofern beide Module in einer EAR-Datei gebündelt sind.
- Komponente: jede Komponente kann außerdem einen privaten Namespace definieren. Ein Beispiel hierfür ist die Deklaration einer EJB-Referenz in "web.xml" oder
"application-client.xml", die an einen JNDI-Eintrag gebunden ist. Was eine Komponente ist, ist unterschiedlich:
Eine Webanwendung oder ein Application Client
zählen als eine einzige Komponente, so dass alle im Deploymentdeskriptor deklarieren "java:comp"-Einträge allen Klassen im Modul zur Verfügung stehen.
In den Deployment Deskriptoren sind die Elemente "ejb-ref" und "ejb-local-ref" globale Elemente.
In einem EJB-JAR zählt jede EJB als Komponente und hat deshalb ihren eigenen "java:comp"-Namespace. Die Elemente "ejb-ref" und "ejb-local-ref"
sind deshalb Kinder des "enterprise-beans/session"-Elements.
Siehe http://stackoverflow.com/questions/7458114/what-is-the-relationship-between-javacomp-env-and-javaglobal
In der Verwendung wird beim Lookup immer dieser JNDI Context vor den Namen gestellt: "java:comp/env/".
In der Deklaration darf man "java:comp/env/" allerdings nicht angeben, da er implizit gilt.
- JBoss-Erweiterung: "java:jboss/exported": in diesem Namespace werden Remote Interfaces gebunden, auf die über Non-JavaEE-Anwendungen
über das Verfahren "jboss-remote-naming" zugegriffen wird, siehe Zugriff auf Stateless Session Bean aus Java-Anwendung-
Beispiel.
- JBoss-Erweiterung: "ejb:": in diesem Namespace werden Remote Interfaces gebunden, auf die über Non-JavaEE-Anwendungen
über das Verfahren "JBoss EJB client" zugegriffen wird, siehe Zugriff auf Stateless Session Bean aus Java-Anwendung-
Beispiel. Dieser Namespace gilt wohl nur in EJB-Clients.
- JBoss-Erweiterung: "java:jboss": diesen Namespace habe ich nur in der Server-Konfiguration vorgefunden: hier werden z.B.
DataSources gebunden ("java:jboss/datasources/ExampleDS", für die Verwendung in der Anwendung siehe
Kuchen-Beispiel)
Deployen wir eine Anwendung, sehen wir, dass JBoss JNDI-Bindings für alle Bereiche erzeugt (im folgenden für das Stateless-Beispiel):
java:global/Stateless/StatelessEJB/GeometricModelBean!de.fhw.komponentenarchitekturen.knauf.stateless.GeometricModelLocal
java:app/StatelessEJB/GeometricModelBean!de.fhw.komponentenarchitekturen.knauf.stateless.GeometricModelLocal
java:module/GeometricModelBean!de.fhw.komponentenarchitekturen.knauf.stateless.GeometricModelLocal
java:global/Stateless/StatelessEJB/GeometricModelBean!de.fhw.komponentenarchitekturen.knauf.stateless.GeometricModelRemote
java:app/StatelessEJB/GeometricModelBean!de.fhw.komponentenarchitekturen.knauf.stateless.GeometricModelRemote
java:module/GeometricModelBean!de.fhw.komponentenarchitekturen.knauf.stateless.GeometricModelRemote
java:jboss/exported/Stateless/StatelessEJB/GeometricModelBean!de.fhw.komponentenarchitekturen.knauf.stateless.GeometricModelRemote
Entsprechend können wir im Stateless-Beispiel in der JSP "GeometricModel.jsp" einen Lookup auf die Einträge in "java:global" und in "java:app" durchführen,
aber nicht auf "java:module".
Logging
In allen Beispielen wird das Logging mittels der Klassen des Packages java.util.logging
verwendet. Im Code sieht das so aus:
Auf Klassenebene wird ein Logger deklariert (Codefragmente aus dem Stateless-Beispiel):
protected static final Logger logger = Logger.getLogger(GeometricModelBean.class.getName());
Die Logausgabe erfolgt so:
logger.info("computeCuboidVolume mit a = " + a + ", b = " + b + ", c = " + c);
JBoss ist in Sachen Logging die eierlegende Wollmilchsau und unterstützt über den "JBoss Log Manager" so ziemlich alle relevanten
Logging-Frameworks:
Quelle: https://access.redhat.com/knowledge/docs/en-US/JBoss_Enterprise_Application_Platform/6/html/Development_Guide/chap-Logging_for_Developers.html
Hier ein paar Links zur Logging-Konfiguration:
https://docs.jboss.org/author/display/AS72/Logging+Configuration
https://docs.jboss.org/author/display/AS72/How+To
Logging wird konfiguriert über die Datei "%JBOSS_HOME%\standalone\configuration\standalone.xml". Diese enthält einen Abschnitt "subsystem xmlns="urn:jboss:domain:logging:1.2"
(Version 1.2 ist wohl für JBoss 7.2/8.0 - in früheren Versionen kann das 1.0 oder 1.1 sein - zum Check prüfen, welche XSD in "%JBOSS_HOME%\docs\schema"
herumliegt: "jboss-as-logging_1_2.xsd" wäre ein Zeichen, dass man oben die Subsystem-Version 1.2 nutzen kann).
Für mein Stateless-Beispiel sieht die Config so aus:
<subsystem xmlns="urn:jboss:domain:logging:1.2">
<console-handler name="CONSOLE">
<level name="INFO"/>
<formatter>
<pattern-formatter pattern="%K{level}%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
</formatter>
</console-handler>
<periodic-rotating-file-handler name="FILE" autoflush="true">
<formatter>
<pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
</formatter>
<file relative-to="jboss.server.log.dir" path="server.log"/>
<suffix value=".yyyy-MM-dd"/>
<append value="true"/>
</periodic-rotating-file-handler>
<file-handler name="StatelessFILE" autoflush="true">
<formatter>
<pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
</formatter>
<file relative-to="jboss.server.log.dir" path="stateless.log"/>
<append value="true"/>
</file-handler>
<logger category="com.arjuna">
<level name="WARN"/>
</logger>
<logger category="org.apache.tomcat.util.modeler">
<level name="WARN"/>
</logger>
<logger category="org.jboss.as.config">
<level name="DEBUG"/>
</logger>
<logger category="sun.rmi">
<level name="WARN"/>
</logger>
<logger category="jacorb">
<level name="WARN"/>
</logger>
<logger category="jacorb.config">
<level name="ERROR"/>
</logger>
<logger category="de.fhw.komponentenarchitekturen.knauf.stateless" use-parent-handlers="false">
<level name="INFO"/>
<handlers>
<handler name="StatelessFILE"/>
</handlers>
</logger>
<root-logger>
<level name="INFO"/>
<handlers>
<handler name="CONSOLE"/>
<handler name="FILE"/>
</handlers>
</root-logger>
</subsystem>
Fett markiert sind hier die beiden Abschnitten, die für das Stateless-Beispiel relevant sind:
- Zuerst wird ein Handler deklariert. Dieser kümmert sich darum, was mit Logeinträgen passiert.
Ein "console-handler" gibt sie auf der Konsole aus.
Ein "periodic-rotating-file-handler" schreibt sie in eine Datei, deren Name sich nach einem
bestimmten Muster aus dem aktuellen Datum aufbaut und entsprechend bei jedem Datumswechsel in eine neue Datei geschrieben wird.
Genauer: die aktuellen Logausgaben landen immer in der gleichen Datei (hier: "server.log"), beim Datumswechsel wird diese
Datei umbenannt in eine Datei mit Datumsstempel.
Und der von mir benutzte "file-handler" ist die vereinfachte Variante: hier wird in eine Datei festen Namens geschrieben.
- Teil 2 der Konfiguration ist eine Filterung der Logeinträge, die im Log-Manager ankommen. Dies geschieht über das
Element "logger". Das Element "category" gibt ein Package an: dieser Logger verarbeitet nur Logeinträge, die von Methoden
dieses Packages geschrieben wurden.
Ein Logger kann außerdem "handler" referenzieren: seine Logausgaben landen werden alle auf diesem Handler geschrieben.
Dadurch kann loggt obiges Beispiel alle Einträge des Package "de.fhw.komponentenarchitekturen.knauf.stateless" in eine separate
Logdatei.
Außerdem laufen alle Logeinträge über den "root-logger". D.h. meine Stateless-Logeinträge würde auch auf die Serverkonsole und in
"server.log" geschrieben. Will man diese verhindern, dann setzt man im "logger" das Element "use-parent-handlers" auf "false" - dadurch
werden Logeinträge, die in den Filter dieses Logger fallen, nicht an den "root-logger" weitergereicht.
Logger per CLI konfigurieren
Dies basiert auf https://docs.jboss.org/author/display/AS72/How+To:
Zuerst wird der Handler definiert:
[standalone@localhost:9999 /] /subsystem=logging/file-handler=StatelessFILE:add(file={"relative-to"=>"jboss.server.log.dir", "path"=>"stateless.log"}, formatter="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"
{"outcome" => "success"}
Die zweite Zeile gibt das zu erwartende Ergebnis an.
Der Ausdruck wirkt "schrecklich", aber dank Tab-Completion kommt man meistens ziemlich gut zurecht.
Im zweiten Schritt wird der Logger deklariert:
[standalone@localhost:9999 /] /subsystem=logging/logger=de.fhw.komponentenarchitekturen.knauf.stateless:add(use-parent-handlers=false,handlers=\["StatelessFILE"\],level=INFO)
{"outcome" => "success"}
Das Löschen des Loggers geht analog:
[standalone@localhost:9999 /] /subsystem=logging/file-handler=StatelessFILE:remove
{"outcome" => "success"}
[standalone@localhost:9999 /] /subsystem=logging/logger=de.fhw.komponentenarchitekturen.knauf.stateless:remove
{"outcome" => "success"}
Stand 25.04.2020
Historie:
19.03.2013: Erstellt auf Basis der Doku von 2009, angepasst an Eclipse 4.2, JBoss 7.1 etc.
02.04.2013: Link zur allgemeinen JBoss-Doku
10.06.2013: Anpassungen für JBoss 8 - WildFly
27.08.2013: Eclipse 4.3, JBossTools 4.1
26.03.2014: WebConsole: "Management Model"
12.05.2014: Abschnitt "JNDI-Namen"
07.08.2014: Eclipse 4.4, JBossTools 4.2
12.02.2015: WildFly 8.2.0 (Webkonsole), JBossTools 4.2.2
02.11.2015: Eclipse 4.5, JBossTools 4.3
05.10.2017: Eclipse 4.7, JBossTools 4.5, Link zu WildFly-Snapshots geändert
08.01.2020: Eclipse 2019-12, WildFly 18, JBossTools 4.13
25.04.2020: JNDIView und WebConsole: Screenshots auf WildFly 19 aktualisiert, "add-user.bat": Hinweis auf Default-User "admin" in WildFly 19.