BEA WebLogic Server è uno degli Application Server più utilizzati tra quelli compatibili con la piattaforma J2EE. Nell'articolo vedremo l'installazione dell'Application Server per poi passare allo sviluppo e l'installazione di una semplicissima applicazione web che ci aiuterà a prendere confidenza con le funzionalità messe a disposizione. Infine affronteremo anche il problema dell'installazione e dell'utilizzo di un EJB di tipo Session Stateless.
Installazione di BEA WebLogic Server su Windows XP
È possibile scaricare una licenza trial di BEA WebLogic Server dal sito ufficiale (la versione corrente di WebLogic Server è la 10).
Si consiglia di installare esclusivamente WebLogic Server, escludendo il componente Workshop che non è argomento di questo articolo e necessita, tra l'altro, di molto spazio su disco.
Configurazione di un Dominio
Prima operazione fondamentale successiva all'istallazione dell'Application Server è la creazione di un Dominio. Si tratta di un gruppo di istanze di WebLogic Server che condividono trà loro diversi settaggi quali i ruoli, gli utenti e le politiche di sicurezza.
Un Dominio è costituito da almeno un'istanza di WebLogic Server chiamata Administration Server che viene creata automaticamente in fase di creazione del Dominio. Tutte le altre istanze sono chiamate Managed Server.
Ciascun Dominio può essere di due tipi:
- Development: riservata agli sviluppatori in quanto utilizza delle politiche di sicurezza meno complesse e quindi leggermente più veloce. Permette l'auto-deploy delle applicazioni che velocizza il processo di sviluppo delle applicazioni.
- Production: riservata alle applicazioni ormai collaudate e funzionanti che necessitano di complesse politiche di sicurezza. Risulta più lenta ma più efficiente da un punto di vista di sicurezza. Durante la creazione di un nuovo Dominio bisogna specificare le credenziali di accesso che saranno utilizzate dall'amministratore per accedere al pannello di amministrazione.
Start dell'Application Server
Avviare l'Application Server equivale ad avviare un Dominio. Nella directory BEA_HOMEuser_projectsdomains vengono memorizzate le informazioni sui Domini. Ciascun Dominio creato avrà una sottodirectory che conterrà il file startWebLogic.cmd. Per avviare il Dominio è necessario lanciare questo file. WebLogic Server utilizza di default la porta 7001 quindi tutte le Web Application che vengono installate sono raggiungibili dal link http://localhost:7001/ContextRoot
.
La prima applicazione su Bea WebLogic Server
La struttura di un'applicazione web compatibile con WebLogic Server deve rispettare tutti gli standard di una Web Application generica. È necessaria la creazione di un ulteriore file di configurazione specifico per WebLogic Server, il weblogic.xml, mediante il quale è possibile configurare alcuni parametri, come ad esempio il ContextPath dell'applicazione e le politiche di sicurezza.
Come esempio, verrà creata una semplicissima Web Application utile per contare il numero di accessi ad una pagina web. La nostra Web Application sarà costituita da una Servlet (CounterServlet.java) che gestirà il contatore, una JSP per la visualizzazione del contatore (counter.jsp) e dai due file di configurazione, il web.xml e il weblogic.xml.
Listato 1. Servlet che gestisce il contatore
package servlets;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CounterServlet extends HttpServlet{
private static final long serialVersionUID = 0L;
private int counter = 0;
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException{
this.counter++;
request.setAttribute("counter", new Integer(counter));
RequestDispatcher dispatch = request.getRequestDispatcher("counter.jsp");
dispatch.forward( request, response);
}
}
La Servlet dispone di una variabile intera (counter) il cui valore rappresenta il numero di volte che la Servlet
viene richiamata. Ogni volta che la Servlet viene chiamata la variabile intera counter viene incrementata di
un'unità e il suo valore viene reso disponibile sulla request per la lettura da parte della JSP.
Poiché l'Application Server gestisce un'unica istanza della servlet, il valore del counter corrisponde al numero
di volte che gli utenti richiamano la pagina JSP.
Listato 2. Pagina JSP per la visualizzazione del contatore
<%
int counter = 0;
if (request.getAttribute("counter") != null)
counter = ((Integer)request.getAttribute("counter")).intValue();
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Counter Application</title>
</head>
<body>
Valore del contatore: <%= counter %>
<hr />
<a href="Counter">Refresh</a>
</body>
</html>
La pagina JSP non fa altro che leggere dalla request il valore del counter e stamparlo a video.
Listato 3. Web.xml - primo file di configurazione
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Counter Application</display-name>
<servlet>
<servlet-name>CounterServlet</servlet-name>
<servlet-class>servlets.CounterServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CounterServlet</servlet-name>
<url-pattern>/Counter</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>/Counter</welcome-file>
</welcome-file-list>
</web-app>
Nel file web.xml viene definita la CounterServlet raggiungibile all'interno dell'applicazione con il nome logico Counter. Inoltre viene definita la pagina di default che viene richiamata qualora venisse richiesta la web application senza esplicitare la risorsa richiesta. Nel nostro caso viene richiamata la CounterServlet che provvede ad effettuare le redirezione alla JSP.
Listato 4. Weblogic.xml - secondo file di configurazione
<!DOCTYPE weblogic-web-app PUBLIC
"-//BEA Systems, Inc.//DTD Web Application 8.1//EN"
"http://www.bea.com/servers/wls810/dtd/weblogic810-web-jar.dtd">
<weblogic-web-app>
<context-root>WLS_Test_1</context-root>
</weblogic-web-app>
Il file weblogic.xml contiene il nome logico con il quale la nostra applicazione sarà disponibile.
La struttura della nostra Web Application sarà quindi la seguente:
Una volta sviluppata l'applicazione web consigliamo di impacchettarla in un archivio WAR.
Deploy dell'applicazione web
Per fare il deploy dell'applicazione occorre accedere al pannello di amministrazione del Dominio (http://localhost:7001/console) e loggarsi utilizzando le credenziali di accesso settate durante la fase di creazione del Dominio.
Cliccando sulla voce di menù Deployments si accede all'elenco di tutti i moduli J2EE installati sull'AS (Web Application, EJB...)
Inizialmente il tasto Intall è disabilitato, ciò è dovuto al fatto che quando si accede per la prima volta al pannello di amministrazione si hanno diritti di sola lettura. Per poter effettuare il deploy di un'applicazione occorrono i permessi di scrittura. Quindi clicchiamo sul tasto in alto a sinistra Lock & Edit.
Adesso il tasto Install è disponibile. Cliccando su di esso inizia la procedura di installazione dell'Applicazione WEB. L'operazione può essere riassunta in tre step:
- Selezionare la directory che contiene i file della nostra Web Application oppure semplicemente il file WAR corrispondente, selezionarla e cliccare sul tasto Next. Come si può notare WebLogic riconosce durante l'esplorazione delle risorse le directory che potrebbero contenere un modulo J2EE (solo i modulo J2EE risultano selezionabili) oppure i file WAR/EAR.
- selezionare "installare la web application come nuova applicazione" e andare avanti.
- Il nome che verrà visualizzato nel pannello di amministrazione (questo non è il nome del ContexRoot che viene definito nel file weblogic.xml).
- La politica di sicurezza che si desidera utilizzare, si consiglia di selezionare la DD Only
- Come i file sorgenti saranno accessibili; si consiglia "Use the defaults defined by the deployment's targets" poiché nel nostro caso l'Application Server e l'ambiente di sviluppo con i relativi sorgenti risiedono sulla stessa macchina.
- Clicchiamo su Finish per terminare l'installazione.
verranno richieste alcune informazioni sull'Applicazione come:
Se tutta la procedura andrà a buon fine verrà visualizzata la schermata di sintesi. A questo punto rendiamo attive le modifiche cliccando sul bottone Activate Changes.
Ritornando sulla pagina di Deployment adesso è possibile visualizzare l'applicazione installata. Lo stato è
Prepared, ovvero l'applicazione è installata ma non ancora attiva. Per attivarla è necessario selezionarla e
cliccare su Start Servicing all request.
NOTA: Qualora il Dominio sul quale installare la web application è di tipo Development è possibile
installare la web application semplicemente spostando la directory o il file war corrispondente all'interno
della directory BEA_HOMEuser_projectsdomainsnome_dominioautodeploy
.
Il link per testare l'applicazione è http://localhost:7001/WLS_Test_1
Il primo EJB su Bea WebLogic Server
Così come una Web application, anche un EJB compatibile con WebLogic Server deve rispettare le specifiche standard degli EJB. WebLogic Server necessita di un ulteriore file di configurazione nel quale vengono definite alcune informazioni sull'EJB: il file weblogic-ejb-jar.xml.
Come esempio modificheremo la nostra Web Application precedentemente creata. La Servlet delegherà la gestione del contatore ad un EJB di tipo Session Stateless.
Web Application ed EJB verranno installati sullo stesso Application Server quindi per comodità ed efficienza utilizzeremo un EJB con interfaccia locale.
Un EJB di tipo Session Stateless Local è caratterizzato dai seguenti componenti:
- Interfaccia home
- Interfaccia locale
- Implementazione
Listato 5. Interfaccia home
package ejb;
import javax.ejb.CreateException;
import javax.ejb.EJBLocalHome;
public interface ICounterHome extends EJBLocalHome {
public abstract ICounterSession create() throws CreateException;
}
L'interfaccia home è costituita da un unico metodo mediante il quale il client ottiene il riferimento all'interfaccia locale.
Listato 6. Interfaccia locale
package ejb;
import javax.ejb.EJBLocalObject;
public interface ICounterSession extends EJBLocalObject {
public int getCounter();
}
L'interfaccia locale contiene i metodi che l'EJB mette a disposizione del client. Nel nostro caso è previsto un unico metodo che restituisce il valore del contatore.
Listato 7. Implementazione
package ejb;
import java.rmi.RemoteException;
import javax.ejb.EJBException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import singleton.CounterSingleton;
public class CounterEJB implements SessionBean {
private static final long serialVersionUID = 1L;
private SessionContext sessionContext;
public void ejbCreate() {
}
public void ejbActivate() throws EJBException, RemoteException {
}
public void ejbPassivate() throws EJBException, RemoteException {
}
public void ejbRemove() throws EJBException, RemoteException {
}
public void setSessionContext(SessionContext sc) throws EJBException, RemoteException {
this.sessionContext = sc;
}
public int getCounter() {
return CounterSingleton.getInstance().getCounter();
}
}
L'implementazione contiene, oltre a tutti i metodi specifici di un EJB di tipo Session, il metodo getCounter
che ci restituisce il valore del contatore.
Il contatore è gestito da una classe Singleton il cui scopo è quello di assicurare che una qualsiasi classe abbia una sola istanza all'interno del sistema.
Listato 8. File ejb-jar.xml - Specifica le classi che implementano interfaccia home
<!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN'
'http://java.sun.com/dtd/ejb-jar_2_0.dtd'>
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>CounterEJB</ejb-name>
<local-home>ejb.ICounterHome</local-home>
<local>ejb.ICounterSession</local>
<ejb-class>ejb.CounterEJB</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>CounterEJB</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute>Supports</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
Nel file ejb-jar.xml vengono specificate le classi che implementano interfaccia home, interfaccia locale e implementazione dell'EJB.
Listato 9. File weblogic-ejb-jar.xml - imposta il nome JNDI
<!DOCTYPE weblogic-ejb-jar PUBLIC '-//BEA Systems, Inc.//DTD WebLogic 8.1.0 EJB//EN' 'http://www.bea.com/servers/wls810/dtd/weblogic-ejb-jar.dtd'>
<weblogic-ejb-jar>
<description>EJB che gestisce il contatore di accessi</description>
<weblogic-enterprise-bean>
<ejb-name>CounterEJB</ejb-name>
<stateless-session-descriptor>
<pool>
<max-beans-in-free-pool>10</max-beans-in-free-pool>
</pool>
</stateless-session-descriptor>
<local-jndi-name>html/ejb/CounterEJB</local-jndi-name>
</weblogic-enterprise-bean>
</weblogic-ejb-jar>
Nel file weblocic-ejb-jar impostiamo il nome JNDI con il quale il client potrà richiamare i metodi dell'EJB.
È possibile definire per ciascun EJB la politica di sicurezza da utilizzare. La Servlet rappresenta, in questo caso, il Client che richiama l'EJB. Nel nostro esempio Client ed EJB sono in esecuzione sulla stessa JVM e condividono lo stesso ambiente quindi è sufficiente richimare il contesto della JVM.
package servlets;
Listato 10. Richiama il contesto della JVM
import java.io.IOException;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import ejb.ICounterHome;
import ejb.ICounterSession;
public class CounterServlet extends HttpServlet {
private static final long serialVersionUID = 0L;
protected void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
int counter = 0;
InitialContext ctx = null;
try {
ctx = new InitialContext();
} catch (NamingException e) {
e.getStackTrace();
}
try {
Object objref = ctx.lookup("html/ejb/CounterEJB");
ICounterHome home = (ICounterHome) objref;
ICounterSession bean = home.create();
counter = bean.getCounter();
} catch (Exception e) {
e.printStackTrace();
}
request.setAttribute("counter", new Integer(counter));
RequestDispatcher dispatch = request.getRequestDispatcher("counter.jsp");
dispatch.forward(request, response);
}
}
Nel caso di EJB Remoto, richiamato da un client in esecuzione su altra JVM, il client deve acquisire il Contesto
della JVM sulla quale l'EJB è in esecuzione.
Listato 11. Contesto richiamato da remoto
try {
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL, "t3://localhost:7001");
env.put(Context.SECURITY_PRINCIPAL, "weblogic");
env.put(Context.SECURITY_CREDENTIALS, "weblogic");
ctx = new InitialContext(env);
} catch (NamingException e) {
e.getStackTrace();
}
try {
Object obj = ctx.lookup("html/ejb/CounterEJB_R");
ICounterHome home = (ICounterHome)PortableRemoteObject.narrow(obj, ICounterHome.class);
ICounterSession bean = home.create();
counter = bean.getCounter();
} catch (Exception e) {
e.printStackTrace();
}
Una volta sviluppata l'applicazione web e l'EJB è necessario creare il file EAR. Il deploy di un EJB è identico a quello di una web application. Basta seguire la procedura di installazione di una Web Application descritta in precedenza. WebLogic Server riconoscerà all'interno del file EAR la presenza dei due moduli, la web application e l'EJB.
Terminata la procedura di installazione è possibile visualizzare le risorse JNDI direttamente dalla console di amministrazione. Accedete alle informazioni del Server (menu Environment, Server) e cliccate sul tasto View JNDI Tree. Il link per testare l'applicazione è http://localhost:7001/WLS_Test_2
Conclusione
In questo articolo sono stati affrontati alcuni concetti basilari di BEA WebLogic Server necessari ad uno sviluppatore di medio-alto livello per iniziare a prendere confidenza con questo application server.