Wildfly è il nuovo application server di RedHat. Ha in comune con il suo predecessore molte importanti caratteristiche, per esempio il meccanismo di classloading che lo rende molto performante; in più recepisce le specifiche introdotte con Java 7 e introduce alcune interessanti novità. In questo articolo vengono introdotti alcuni aspetti di Wildfly, la sua struttura, il classloading e i principali files di configurazione.
Installare Wildfly
La versione di Wildfly trattata in questo articolo è la 8.0.0.Final ed è stata rilasciata lo scorso 11 febbraio. La versione 8.0.0.Final è scaricabile dal sito ufficiale di Wildfly [1].
Per eseguire il server è necessario aver installato JDK 1.7 e aver creato e valorizzato le variabili d’ambiente JAVA_HOME e JBOSS_HOME in modo opportuno. Una volta scaricato il pacchetto compresso ed estratti i files in una directory di vostra scelta (d’ora in poi nella directory JBOSS_HOME), si può lanciare Wildfly tramite il comando:
C:UsersFrancescowildfly-8.0.0.Final in>standalone.bat
Ecco di seguito l’output prodotto:
Calling "C:UsersFrancescowildfly-8.0.0.Final instandalone.conf.bat" Setting JAVA property to "c:glassfish4jdk7 injava" =========================================================================== JBoss Bootstrap Environment JBOSS_HOME: "c:UsersFrancescowildfly-8.0.0.Final" JAVA: "c:glassfish4jdk7 injava" JAVA_OPTS: "-XX:+UseCompressedOops -Dprogram.name=standalone.bat -Xms64M -Xmx512M -XX:MaxPermSize=256M -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs =org.jboss.byteman -agentlib:jdwp=transport=dt_socket,address=8787,server=y,suspend=n" ===========================================================================
Le novità e le caratteristiche
Wildfly presenta un’architettura modulare estremamente flessibile. I vari moduli caricati all’avvio dell’application server sono quelli indicati nella sua configurazione. Gli altri moduli vengono caricati in memoria solo se richiesti dalle applicazioni in esecuzione o da altri moduli eseguiti.
Un’istanza di Wildfly può essere facilmente configurata con un setup che preveda l’impiego delle sole features richieste, tramite l’impiego dei soli moduli che le implementano. Questa flessibilità permette di avere server Wildfly configurati in modo puntuale, ottimizzando l’impiego delle risorse.
Widlfly introduce importanti novità: una piattaforma Java EE 7 full profile, un nuovo web server, la possibilità di gestire profili di tipo amministrativo in modo più puntuale. Wildfly offre una piattaforma di sviluppo Java EE 7. Questo significa poter impiegare tecnologie come WebSocket, CDI 1.1, JAX-RS 2.0 per dirne solo alcune.
Undertow è il nuovo web container di Wildfly, leggero e flessibile, interamente scritto in Java: supporta Java EE servlet 3.1 e WebSocket. Una sua feature interessante è la capacità di implementare multiplexing di vari protocolli over HTTP. Ad esempio, è possibile sfruttare la porta 8080 per eseguire un lookup JNDI.
Come nella precedente versione, Wildfly presenta due modalità di esecuzione: standalone e multidomain. Le due modalità sono attivate rispettivamente tramite gli script di esecuzione JBOSS_HOME/bin/standalone.sh e JBOSS_HOME/bin/domain.sh.
Dipendenze esplicite e implicite
Wildfly presenta una strategia di classloading basata su JBossModule [4]. Questo permette a Wildfly di sfruttare le architetture multicore e razionalizzare la quantità di codice da caricare in memoria.
Questa architettura modulare è già stata introdotta in JBoss 7. La discutiamo di nuovo a beneficio di chi si avvicina a Wildfly con un’esperienza basata sulle versioni JBoss 6 o precendenti, dove questo tipo classloader non era stato ancora introdotto.
Ogni modulo ha il proprio classloader, quindi le dipendenze tra moduli devono essere indicate esplicitamente perchè le classi definite in un modulo possano avere la visibilità delle classi definite nell’altro.
Le dipendenze sono indicate tramite dichiarazione esplicita nel file MANIFEST.MF oppure jboss-deployment-structure.xml. Le stesse applicazioni deployate sul server sono moduli e possono essere indicate come dipendenze specificando il loro nome preceduto da deployment. Ad esempio:
Dependencies: deployment.nomedelfilewar
se stiamo utilizzando il file MANIFEST.MF.
Oppure,
se stiamo usando il file jboss-deployment-structure.xml. In quest’ultimo esempio, si ipotizza uno scenario in cui le classi che si vogliono usare appartengano ad un .jar a sua volta contenuto in un file .ear. Quindi, il nome del file .jar è preceduto dal nome del file .ear che lo contiene.
Wildfly ammette delle dipendenze implicite, ovvero, permette l’impiego di classi appartenenti a determinati moduli senza che ne venga fatta esplicita richiesta: è il caso di Weld [3]. Le dipendenze implicite possono essere escluse tramite jboss-deployment-structure.
Dipendenza ai moduli
Wildfly ha i propri moduli nella directory JBOSS_HOME/modules. Per dichiarare la dipendenza ad uno di questi moduli è sufficiente indicarne il nome costituito dal path del modulo a partire dalla directory suddetta. Ad esempio, per poter impiegare le classi che appartengono al modulo
JBOSS_HOME/modules/system/layers/base/org/apache/httpcomponents/main
è necessario indicare il nome del modulo org.apache.httpcomponents nel file MANIFEST.MF o in alternativa editare il file jboss-deployment-structure.xml. Per convenzione, se non viene diversamente specificato, il modulo caricato di default consiste nel .jar contenuto nella directory /main.
Conflitti di classloading
I conflitti di classloading sono risolti tramite precedenza. Il classloader di Wildfly aggiunge le dipendenze in base a un ordine specifico di seguito riportato, dal primo all’ultimo in ordine di priorità in fase di caricamento:
- dipendenze implicite, aggiunte automaticamente dal sistema;
- dipendenze indicate dall’utente nei file MANIFEST.MF o jboss-deployment-structure;
- dipendenze da moduli contenuti nel modulo applicazione stesso, ad esempio le classi contenute in WEB-INF/classes o i moduli contenuti in WEB-INF/lib;
- dipendenze tra moduli deployati.
Visibilità
In Wildfly, le classi dei moduli deployati all’interno di un file .ear non hanno visibilità reciproca. Le classi contenute nei moduli della /lib del modulo .ear stesso invece sono visibili alle altre. Questo è il comportamento di default che può essere disabilitato tramite la seguente configurazione:
false ...
così si permette alle varie classi di avere visibilità di tutte le classi appartenenti ad ogni modulo contenuto nel pacchetto .ear.
Non tutte le dipendenze implicite sono aggiunte automaticamente: alcune sono aggiunte in fase di deploy da Wildfly solo se si verificano determinate condizioni. Ad esempio, la dependency al modulo org.jboss.weld.core è aggiunta automaticamente se il modulo deployato presenta il file beans.xml nella sua directory WEB-INF o META-INF.
Struttura delle directory
Wildfly riprende la struttura delle directory di JBoss 7:
Figura 1 – JBOSS_HOME di Wildfly.
Di seguito, diamo una breve spiegazione della struttura:
- appclient: come nella precedente versione, contiene i file di configurazione per il container appclient;
- bin: in questa directory risiedono tutti gli script di lancio e di amministrazione di Wildfly; nella sottodirectory /client sono presenti i file .jar per lo sviluppo dei client;
- docs: contiene le due sottodirectory /examples, dove sono presenti esempi di configurazione di Wildfly, e /schema, dove sono riportati i file .xsd utilizzati per la validazione dei vari .xml;
- domain: contiene i file di configurazione, la directory di deploy e tutto quello che serve a Wildfly per poter essere eseguito e utilizzato in modalità domain;
- modules: contiene i moduli di Wildfly; qui possono essere aggiunti nuovi moduli. Ad esempio, i driver JDBC di un database;
- standalone: contiene i file di configurazione, la directory di deploy e tutto quello che serve a Wildfly per poter essere eseguito e utilizzato in modalità standalone;
- welcome-content: contiene la pagina di benvenuto di Wildfly.
Rispetto alla precedente versione, non compare la directory bundles. I bundles possono essere copiati direttamente nella directory standalone/deployments o domain/deployments. Un bundle è di fatto un modulo per Wildfly. Nei file di configurazione standalone.xml e domain.xml, però, non è presente di default un subsystem di configurazione per OSGi. Per approfondire, si rimanda il lettore alle pagine di documentazione del progetto JBOSGi [4].
La directory bin
La directory bin contiene tutti gli script di esecuzione e amministrazione di Wildfly, sia per Windows sia per Linux/Unix, e i relativi file di configurazione. Come nella versione precedente, tra questi file appare anche jboss-cli.bat/jboss-cli.sh, il quale permette di eseguire la consolle di amministrazione di Wildfly da shell, la famosa CLI (command-line interface). All’esecuzione del comando jboss-cli, appare il prompt dove viene richiesta la connessione alla CLI.
C:UsersFrancescowildfly-8.0.0.Final in>jboss-cli.bat You are disconnected at the moment. Type ‘connect' to connect to the server or ‘help' for the list of supported commands. [disconnected /] connect [standalone@localhost:9990 /]
Da notare che la CLI è associata all’interfaccia indicata come localhost:9990. Da questa interfaccia non è richiesta autenticazione. Invece, provando l’interfaccia web, appare il classico popup che chiede di inserire username e password: a tal proposito nella directory bin appare anche il file add-user.properties, che contiene la configurazione degli utenti. All’interno di questo file è possibile definire alcune regole, per esempio sulla password, che dovranno essere soddisfatte al momento della creazione di un nuovo utente
Standalone mode e la sua directory
Standalone è una delle due modalità di funzionamento di Wildfly: quando eseguito in questa modalità, si comporta come un singolo processo indipendente implementando una singola e unica istanza dell’application server.
La directory standalone si articola nelle seguenti sottodirectory :
- configuration: in questa directory risiedono i file di configurazione e gestione di Wildfly nella modalità di esecuzione standalone;
- data: directory di servizio dove Wildfly salva alcune informazioni prima di uno shutdown o restart; ad esempio, informazioni per il corretto funzionamento di HornetQ o dei timer;
- deployments: la directory dove copiare le applicazioni e i moduli;
- lib/ext: questa directory ha lo scopo di mantenere compatibilità con le applicazioni che utilizzano le Java extension-list; questo comportamento è sconsigliato dalla documentazione di Wildfly;
- log: contiene i file di log relativi al funzionamento in modalità standalone;
- tmp: contiene i file temporanei prodotti da Wildfly nel suo funzionamento.
Domain mode e la sua directory
Domain è l’altra modalità di esecuzione la quale permette di gestire in modo uniforme più istanze dell’application server: di fatto un domain è una collezione di server-group, dove ciascun server-group è una collezione di istanze di Wildfly. Tra tutte le istanze viene eletto un DomainController, il gestore della configurazione di quel domain, e uno o più HostController. Ciascun HostController ha il compito di coordinare un insieme di istanze di Wildfly con un DomainController.
Figura 2 – Configurazione di Domain.
Per eseguire Wildfly in modalità domain è necessario eseguire lo script
JBOSS_HOME/bin/domain.sh, oppure, JBOSS_HOME/bin/domain.bat
La directory domain si articola nelle seguenti sottocartelle:
- configuration: questa directory contiene tutti i file di configurazione per l’esecuzione di Wildfly in modalità domain;
- data: come per la modalità standalone, contiene i dati necessari al corretto funzionamento di Wildfly dopo un riavvio; ad esempio, contiene le informazioni relative ai timer;
- tmp: contiene i file prodotti da Wildfly durante il suo funzionamento.
Struttura dei files standalone.xml e domain.xml
Questi due file permettono di definire il comportamento di Wildfly nelle sue modalità di funzionamento. Ciascun file di configurazione è un file XML: vediamo gli elementi che li compongono.
Il tag
All’interno di questo tag sono indicati tutti i moduli di Wildfly che estendono le sue funzionalità base. Questi moduli sono disponibili senza indicarne la dipendenza esplicita.
Il tag
Questo tag incorpora tutte le propietà di sistema. I suoi elementi figli sono vere e proprie properties e possono essere impiegate nelle nostre applicazioni. Semplicemente:
System.getProperty("nome-della-system-property");
Il tag
Il tag contiene uno o più insiemi di configurazioni definite tramite , uno per ciascun aspetto che si desideri gestire. Ad esempio, il tag:
...
definisce il comportamento del servizio di logging.
Il definisce tutti i datasource che Wildfly rende disponibili tramite il loro nome JNDI.
enabled="true" use-java-context="true"> jdbc:postgresql://localhost:5432/test org.postgresql.Driver postgresql-jdbc4 2 20 true usr pwd SELECT 1 …
Nell’esempio qui sopra è riportata la definizione di un datasource per connettersi a un popolare database.
Il tag e il tag
Gli elementi del tag hanno lo scopo di definire i servizi messi a disposizione da Wildfly. Ciascun elemento di questo tag associa una porta logica a un identificativo del servizio.
Nel tag sono definite le interfacce offerte da Wildfly. Un’interfaccia è identificata tramite un nome logico. Associata a una risorsa, indica il modo in cui Wildfly permette di usufruire di quest’ultima. Ad esempio, l’elemento
indica che l’interfaccia denominata public è fruibile all’indirizzo IP indicato. Ad esempio, l’interfaccia nominata come public può essere associata ai socket. In questo modo viene stabilito come sia possibile fruire dei servizi corrispondenti.
Il tag
Il tag contiene elementi relativi alla configurazione e gestione di servizi e interfacce di Wildfly. Il tag prevede un contenuto diverso, in base alla modalità di impiego di Wildfly, standalone o domain. Nel caso di modalità domain, il contenuto può cambiare in base al ruolo che dev’essere svolto, tra quello di semplice host e quello di host avente funzioni di controller.
Il tag
Il tag è una collezione di elementi . Come visto in precedenza, un tag definisce una collezione di risorse e servizi. Mentre nel file JBOSS_HOME/standalone/conf/standalone.xml è presente un solo tag , la modalità domain prevede la definizione di più . In questo modo Wildfly permette di associare diverse configurazioni di servizi e risorse ai diversi gruppi di host che compongono quel domain.
Il tag
Nella modalità di esecuzione di tipo domain, ogni elemento contenuto in definisce un associazione tra un elemento e un elemento . In questo modo è possibile associare un profilo e delle risorse ad un gruppo di host. Ad esempio, nel file domain.xml,
sono definiti due server-group. A ciascun gruppo sono associate delle risorse, in questo caso indicate dai tag e , e un profilo.
Conclusioni
Wildfly permette agli sviluppatori di fruire di una piattaforma Java 7 full profile. In questo articolo abbiamo introdotto alcuni concetti relativi al suo funzionamento e alla sua configurazione. Abbiamo mostrato alcune novità e caratteristiche principali, come la struttura, i moduli offerti, le configurazioni di lancio. Prossimamente approfondiremo alcuni aspetti di Wildfly già trattati in questo articolo e introdurremo altre features.
Riferimenti
[1] Wildfly
[2] Hibernate
[3] Weld
[4] JBOSGi
https://docs.jboss.org/author/display/JBOSGI/Application+Server+Integration