Introduction▲
Cet article explique :
- Le couplage des langages Java EE et PHP
- L'installation et configuration du serveur GlassFish responsable du couplage
- Le développement d'une application Java EE 6 / PHP
Ce qu'il faut savoir :
- Les bases du langage de programmation PHP
- Les bases du langage de programmation Java
- La maîtrise de projets Java EE
- Des notions d'infrastructures Web pour la mise en place du serveur
La principale architecture Open Source actuelle pour le développement d'applications Internet de grande envergure est Java EE 6 avec ses API comme : Servlets, JavaServer Pages, JavaServer Faces, Enterprise JavaBean, Java Persitence API et son serveur standardisé : GlassFish. Le concurrent largement utilisé sur le Web est le langage PHP et le serveur Apache.
Les entreprises développent des projets de toutes tailles à l'aide de ces deux architectures et acquièrent de facto des connaissances approfondies dans l'une ou l'autre des technologies. Les développeurs travaillent avec des IDE évolués et utilisent en production le serveur Apache pour l'architecture LAMP et GlassFish pour l'architecture Java EE. Cependant, le serveur GlassFish permet, par l'intermédiaire d'une librairie, de coupler la puissance de Java EE et PHP pour le développement d'applications Internet.
I. GlassFish, le serveur Java EE de référence▲
GlassFish (http://glassfish.org) est le nom du nouveau serveur v3 d'applications Open Source Java EE 6 développé par la société Sun MicroSystems. Le serveur GlassFish est gratuit, libre et distribué sous licence CDDL et GNU GPL. Le mot d'ordre de ce serveur est rapidité et performance. La version 3.0 date de décembre 2009 et propose la gestion de Web Services, des EJB3.1, l'implémentation en standard du moteur de persistance Java Persistence API et plusieurs autres outils. Actuellement, GlassFish est le seul serveur totalement compatible Java EE 6, il est d'ailleurs utilisé comme serveur de référence par plusieurs sociétés comme la SNCF et RTL.
Depuis quelques années, les serveurs d'applications sont devenus de plus en plus complexes et offrent un nombre croissant de services. Les fonctionnalités et services proposés ont augmenté en même temps que le coût des serveurs. Le serveur Sun GlassFish propose un logiciel serveur pour les applications Web et un développement rapide pour un coût moindre. La dernière version de GlassFish v3 implémente en standard la dernière plate-forme Java EE 6, mais en plus, le serveur GlassFish fournit une plate-forme complète de type LAMP/SAMP (Sun Apache MySQL PHP) avec le support multi-langages (PHP, Java ou Ruby). Le serveur GlassFish est également compatible et permet un fonctionnement avec le serveur Apache en frontal (mod_jk).
L'administration de GlassFish est basée sur le concept de domaines gérés par un Domain Administration Server (DAS) et des noeuds agents (node agent) exécutés sur une machine. Le DAS permet de gérer le système central contenant les applications déployées. Les communications entre le DAS, les noeuds agents et les instances sont sécurisées et l'API Java Management Extensions (JMX) est disponible pour gérer le serveur et changer sa configuration. À la suite de l'installation du serveur, nous utiliserons le domaine installé par défaut (domain1).
Le serveur est livré en standard avec deux outils de gestion et d'administration. L'interface graphique disponible par défaut sur le port 4848 (http://localhost:4848) permet de gérer, à partir d'un navigateur Web, le serveur et ses applications. L'interface en ligne de commande nommée asadmin permet de réaliser les mêmes opérations.
II. Installation du serveur GlassFish▲
Le couplage Java EE 6 / PHP utilise le serveur GlassFish v3 (sges-v3.zip) qui peut être installé à partir d'une archive ZIP, d'un script pour les systèmes Linux, MacOs X et Solaris ou d'un exécutable Windows.
Le serveur est téléchargé sur le site officiel du projet GlassFish : https://glassfish.dev.java.net/public/downloadsindex.html.
Remarque : Le serveur GlassFish Java EE est développé en Java et nécessite l'installation d'un kit de développement Java JDK 1.6 ou supérieur.
L'installation du serveur est simple et peut être réalisée à partir de l'archive multi plateformes au format ZIP.
-
Copier l'archive du serveur GlassFish précédemment téléchargée dans le répertoire des sources.
#cp sges-v3.zip /usr/local/src -
Se déplacer dans le répertoire des sources.
#cd /usr/local/src -
Décompresser l'archive du serveur GlassFish.
#unzip sges-v3.zip -
Déplacer l'archive décompressée du serveur GlassFish dans le répertoire des logiciels.
#mv glassfishv3 /usr/local
Sous Windows l'installation peut être réalisée également à l'aide de l'archive au format ZIP ou directement avec l'exécutable.
Le serveur GlassFish est maintenant correctement installé. Nous devons terminer la configuration en ajoutant la variable d'environnement GLASSFISH_HOME dans le fichier caché /root/.bashrc sous Linux en précisant le chemin absolu vers le répertoire d'installation du serveur.
export GLASSFISH _ HOME=/usr/local/glassfi shv3
export PATH=$JAVA _ HOME/bin:$GLASSFISH _HOME/bin:$PATH
Sous Windows le principe reste le même et il est conseillé d'ajouter la variable d'environnement GLASSFISH_HOME avec le panneau de configuration. Cette variable d'environnement permet de référencer directement les exécutables utilisés par le serveur.
Remarque : Avec l'installation par défaut du serveur GlassFish, nous utilisons le port 8080 pour le serveur Java EE, le port 4848 pour l'accès à l'interface d'administration, admin comme identifiant et adminadmin comme mot de passe.
L'arborescence de GlassFish est présentée dans la Figure 1 et montre les différents dossiers nécessaires pour l'exécution du serveur, la configuration ou la gestion des domaines.
L'installation du serveur étant terminée, nous pouvons tester son fonctionnement en lançant directement GlassFish à l'aide de la commande suivante dans un terminal ou une console Ms-DOS :
#asadmin start-domain
Le serveur est alors accessible à l'adresse suivante http://localhost:8080/ et l'interface d'administration à l'adresse http://localhost:4848 (Figure 2).
III. GlassFish et PHP avec Quercus▲
Il existe plusieurs approches pour exécuter du code PHP sur le serveur Java EE GlassFish.
La première consiste à installer un exécutable comme Quercus, capable d'interpréter du PHP avec la machine virtuelle Java.
La seconde consiste à installer un pont entre l'implémentation Java EE et PHP comme JavaBridge. Enfin, la dernière solution consiste à utiliser le serveur Web Apache en frontal et à exécuter les pages PHP avec le module d'Apache. Cette technique est utilisée pour le load balancing mais ne permet pas de coupler/mélanger le code Java avec PHP.
La première solution concerne l'utilisation d'un interpréteur comme Quercus permettant d'utiliser un seul serveur, et surtout de bénéficier du mélange Java / PHP dans les applications comme nous allons le voir ci-après.
Quercus est une technologie Caucho sous licence GPL utilisant Resin et développée en Java pour l'interprétation du langage PHP.
Quercus permet l'intégration de Java dans des services PHP ou scripts mais également une interaction entre le code Java et PHP.
Avec Quercus, les applications PHP peuvent ainsi manipuler les technologies Java comme les Enterprise JavaBeans, les frameworks, Java Message-Service et les JavaBeans. Ce concept est rendu possible grâce aux techniques suivantes (Figure 3) :
- Le code PHP est interprété et compilé dans le code Java.
- Quercus est entièrement écrit en Java et donc interprétable par un serveur Java.
- Quercus propose une API de communication Java vers PHP.
Quercus (version 4.0.3 pour cet ouvrage) est livré sous forme de fichier .war (Web Archive ou archive de type .tar) contenant l'interpréteur Quercus et les librairies PHP. Ce fichier .war peut être déployé sur n'importe quel serveur compatible Java comme GlassFish, Tomcat ou encore Jboss. La mise en place de Quercus commence par le téléchargement de la dernière version du fichier .war (http://quercus.caucho.com).
La suite consiste à installer la librairie Quercus. L'installation d'une librairie sous GlassFish peut être réalisée de deux façons :
- Pour l'ensemble des applications du domaine en copiant les fichiers .jar dans le répertoire /glassfishv3/glassfish/lib/.
- Pour un domaine particulier en copiant les archives .jar dans le répertoire /glassfishv3/glassfish/domains/domain1/lib/ext.
Nous utilisons la première solution et nous copions les archives téléchargées resin.jar et inject-16.jar dans le répertoire /glassfishv3/glassfish/lib.
Remarque : L'installation d'une nouvelle librairie nécessite un redémarrage du serveur GlassFish.
IV. Mise en place d'un premier projet Java EE / PHP▲
Nous allons créer un nouveau projet Java EE de type Dynamic Web Project nommé projetjavaeephp avec l'IDE Eclipse ou NetBeans. Nous allons ensuite créer un simple fichier PHP (Listing 1) dans le répertoire Web de notre projet avec le contenu suivant permettant de tester le fonctionnement de l'interpréteur.
<
html>
<
head>
<
title>
Premier projet Java EE
avec PHP<
/title
>
<?php
function
quercus_test()
{
return
function_exists("quercus_version"
);
}
?>
<
/head
>
<
body>
<
p>
Test de Quercus
<
/p
>
<?php
if
(quercus_test())
{
echo "Quercus fonctionne parfaitement"
;
}
?>
<
/body
>
<
/html
>
L'installation est presque terminée, il reste à préciser dans le fichier de déploiement (Listing 2) de l'application Java EE /WEB-INF/web.xml, l'exécution des fichiers portant l'extension .php par Quercus.
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns
:
xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns
=
"http://java.sun.com/xml/ns/javaee"
xmlns
:
web
=
"http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi
:
schemaLocation
=
"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id
=
"WebApp _ ID"
version
=
"2.5"
>
<display-name>
projetjavaeephp</display-name>
<servlet>
<servlet-name>
Quercus Servlet</servlet-name>
<servlet-class>
com.caucho.quercus.servlet.QuercusServlet</servletclass>
<init-param>
<param-name>
script-encoding</param-name>
<param-value>
UTF-8</param-value>
</init-param>
<init-param>
<param-name>
license-directory</param-name>
<param-value>
WEB-INF/licenses</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>
Quercus Servlet</servlet-name>
<url-pattern>
*.php</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>
index.jsp</welcome-file>
</welcome-file-list>
</web-app>
Nous pouvons tester notre application déployée avec GlassFish et déclencher le fichier PHP à l'URL suivante : http://localhost:8080/projetjavaeephp/php.php (Figure 4).
L'arborescence du projet à cette étape est présentée dans la Figure 5.
V. Utilisation de classes Java en PHP▲
Afin de présenter la puissance du couplage Java EE / PHP, nous allons créer une première classe simple JavaBean POJO nommée Personne avec des attributs et méthodes.
L'importation de classes Java dans un fichier PHP est réalisée avec l'opérateur import. L'appel de méthode Java en PHP respecte la notation pointée. Nous allons utiliser notre classe Java Personne (Listing 3) dans un fichier PHP personne.php (Listing 4).
package
com.gdawj;
public
class
Personne {
private
int
id;
private
String nom;
public
Personne
(
)
{
System.out.println
(
"Appel du constructeur"
);
}
public
String afficherPersonne
(
)
{
return
"Bonjour "
+
this
.id+
" "
+
this
.nom;
}
public
int
getId
(
) {
return
id;
}
public
void
setId
(
int
id) {
this
.id =
id;
}
public
String getNom
(
) {
return
nom;
}
public
void
setNom
(
String nom) {
this
.nom =
nom;
}
}
<?php
//importation du paquetage Java
import com.
gdawj.
Personne;
//instanciation de la classe
$pojo
=
new
Personne();
//declenchement de methodes
$pojo
->
setId(1
);
$pojo
->
setNom("Lafosse"
);
echo $pojo
->
afficherPersonne();
//importation
import java.
util.
Calendar;
//singleton
$calendar
=
Calendar::
getInstance();
//afficher la valeur
echo("<br/>"
.
$calendar
);
?>
L'appel de membres statiques et de Singleton est également possible avec PHP.
Le résultat de l'exécution est présenté avec la Figure 6.
GlassFish et Quercus permettent une intégration simple et performante de PHP avec Java. Les possibilités de PHP et Java sont multiples et permettent également d'utiliser les pools de connexions JNDI avec PHP pour les connexions aux bases de données, de réaliser des conversions de type PHP vers Java, de gérer les sessions ou autres.
VI. Ajouter de nouvelles fonctionnalités à PHP▲
Quercus permet également de déclencher des méthodes Java de classes statiques sans instancier d'objet. La classe Java statique BoiteOutils.java présentée dans le Listing 5, permet d'afficher la date courante du système.
package
com.gdawj;
import
java.util.Calendar;
public
class
BoiteOutils {
public
static
String afficherDate
(
){
Calendar calendar=
Calendar.getInstance
(
);
return
calendar.getTime
(
).toString
(
);
}
}
Cette classe est déclenchée en PHP avec la méthode java_class() permettant de charger des informations statiques.
<?php
$class
=
java_class("com.gdawj.BoiteOutils"
);
echo $class
->
afficherDate();
?>
Cette technique est très largement utilisée pour proposer de nouvelles fonctionnalités à PHP en profitant de la puissance du langage Java. Par exemple, la manipulation de flux d'octets est largement détaillée et documentée en Java. Elle pourra ainsi être utilisée à l'aide de PHP.
Remarque : Pour les exemples qui suivent nous utilisons les librairies Quercus installées dans le répertoire /WEBINF/lib de notre projet Java EE afin de pouvoir y faire référence et importer les classes.
VII. Utiliser des composants Java EE avec PHP▲
Les Enterprises JavaBeans (EJB) sont largement utilisés pour la gestion de la couche métier en Java EE et permettent de séparer la partie modèle du design pattern MVC de façon optimisée. Ce type de technologie n'existe pas en PHP mais il est tout à fait possible de profiter de la puissance des EJB Java en PHP. Les développeurs peuvent ainsi coder en Java EE et les intégrateurs en PHP.
Pour cet exemple, nous utilisons une classe EJB Java EE nommée ClientEJBBean (Listing 6) fournissant deux services simples.
package
com.gdawj.ejb;
import
java.util.Calendar;
import
javax.ejb.Stateless;
@Stateless
public
class
ClientEJBBean implements
ClientEJB{
Calendar calendar=
Calendar.getInstance
(
);
public
String infoClient
(
String param){
return
"Service réalisé par Client EJB : "
+
param.toUpperCase
(
)+
" !"
;
}
public
String infoDateClient
(
){
return
"Date depuis l'EJB : "
+
calendar.getInstance
(
).getTime
(
).toString
(
);
}
}
Dans un cas professionnel, ces services pourraient accéder à un SGBD ou un ERP. Ce code représente la couche Modèle du design pattern MVC.
Nous allons maintenant dans le Listing 7, présenter la couche Contrôleur avec une Servlet nommée ServletClientEJB. Cette Servlet invoque l'EJB à partir du paramètre entré dans la vue PHP.
package
com.gdawj.servlets;
import
java.io.IOException;
import
javax.ejb.EJB;
import
javax.servlet.ServletException;
import
javax.servlet.http.HttpServlet;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
import
com.gdawj.ejb.ClientEJB;
public
class
ServletClientEJB extends
HttpServlet
{
private
static
final
long
serialVersionUID =
1
L;
// utiliser l'EJB
@EJB
private
ClientEJB clientEJB;
public
void
doGet
(
HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException
{
// chargement de l'EJB Java et envoi à la vue PHP
if
(
request.getParameter
(
"saisie"
)!=
null
&&
!
request.getParameter
(
"saisie"
).equals
(
""
))
{
String infoEJB=
clientEJB.infoClient
(
request.getParameter
(
"saisie"
).toString
(
));
request.setAttribute
(
"infoEJB"
, infoEJB);
response.sendRedirect
(
"vuephp.php?infoEJB="
+
infoEJB);
return
;
}
// redirection vers la vue PHP
getServletContext
(
).getRequestDispatcher
(
"/vuephp.php"
).forward
(
request, response);
}
public
void
doPost
(
HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException
{
doGet
(
request, response);
}
}
Enfin, la dernière partie (Listing 8) est codée en PHP et représente la couche vue du modèle MVC.
<
html>
<
head>
<
title>
Premier projet Java EE avec PHP<
/title
>
<
/head
>
<
body>
<
p>
Utilisation de Java et des EJB en MVC avec PHP<
/p
>
<?php
// afficher les informations de l'EJB Java EE dans du PHP
$resultatClientEJB
=
$_REQUEST
[
"infoEJB"
];
if
(!
empty($resultatClientEJB
))
{
echo $resultatClientEJB
.
"<br/>"
;
}
// utiliser le client EJB directement
$clientEJB
=
jndi_lookup("java:global/projetjavaeephpEAR/projetjavaeephpEJB/ClientEJBBean"
);
echo $clientEJB
->
infoDateClient().
"<br/>"
;
?>
<
form name
=
"
formulaire
"
action
=
"
servlet
"
method
=
"
POST
"
>
Saisir les informations à
envoyer à
l'EJB<
br/
>
<
input type
=
"
text
"
name
=
"
saisie
"
id
=
"
saisie
"
/
>
<
input type
=
"
submit
"
value
=
"
Envoyer
"
/
>
<
/form
>
<
/body
>
<
/html
>
Cette page déclenche la Servlet et affiche le résultat de l'exécution de l'EJB Java en PHP.
Nous utilisons également JNDI pour appeler directement l'EJB depuis le code PHP.
Le résultat est présenté dans les Figures 7 et 8.
Remarque : L'API Java Naming and Directory Interface (JNDI) fournit un mécanisme de nommage de type annuaire pour l'accès aux ressources. Ces ressources peuvent être de différents types mais le but étant d'associer les objets à un nom (bind) et de retrouver ces objets (lookup) dans un annuaire de nommage semblable à LDAP, DNS ou NIS.
VIII. Profiter de la souplesse de PHP en Java▲
Le paragraphe précédent montre le principe d'utilisation de Java avec PHP mais il est également possible d'utiliser des techniques PHP avec Java. Par exemple, la librairie de graphisme GD est très simple à utiliser en PHP et peut être ajoutée à Java.
Nous allons dans cet exemple utiliser PHP et la librairie GD à l'aide d'une classe Java afin de générer une image à la volée.
Pour cela, nous allons créer une nouvelle classe Pojo Java nommée ImageMiniature.java (Listing 9) composée de ses attributs et accesseurs.
package
com.gdawj;
public
class
ImageMiniature {
private
String chemin;
private
int
largeur;
private
int
hauteur;
public
ImageMiniature
(
)
{
System.out.println
(
"Appel du constructeur ImageMiniature"
);
}
public
String getChemin
(
) {
return
chemin;
}
public
void
setChemin
(
String chemin) {
this
.chemin =
chemin;
}
public
int
getLargeur
(
) {
return
largeur;
}
public
void
setLargeur
(
int
largeur) {
this
.largeur =
largeur;
}
public
int
getHauteur
(
) {
return
hauteur;
}
public
void
setHauteur
(
int
hauteur) {
this
.hauteur =
hauteur;
}
}
La page PHP nommée image.php utilise le POJO Java pour les informations et génère une miniature de l'image source à l'aide de PHP / GD.
<?php
// importation du paquetage Java
import com.
gdawj.
ImageMiniature;
// instanciation de la classe Java
$pojo
=
new
ImageMiniature();
// declenchement de methodes
$pojo
->
setChemin("images/image.jpg"
);
// afficher l'image d'origine
echo "Image d'origine<br/><img src=
\"
"
.
$pojo
->
getChemin().
"
\"
/>"
;
// retailler l'image avec PHP GD
$pojo
->
setHauteur(150
);
$pojo
->
setLargeur(150
);
// recuperer la source avec Java
$source
=
imagecreatefromjpeg($pojo
->
getChemin());
// creer la vignette avec les infos du pojo
$destination
=
imagecreatetruecolor($pojo
->
getHauteur(),
$pojo
->
getLargeur());
// les fonctions imagesx et imagesy renvoient la largeur et la hauteur d'une image
$largeur_source
=
imagesx($source
);
$hauteur_source
=
imagesy($source
);
$largeur_destination
=
imagesx($destination
);
$hauteur_destination
=
imagesy($destination
);
// on cree la miniature
imagecopyresampled($destination
,
$source
,
0
,
0
,
0
,
0
,
$largeur_destination
,
$hauteur_destination
,
$largeur_source
,
$hauteur_source
);
// on enregistre la miniature sous le nom "miniature.jpg"
imagejpeg($destination
,
"miniature.jpg"
);
// afficher l'image miniature
echo "<br/>Image miniature<br/><img src=
\"
miniature.jpg
\"
/>"
;
?>
IX. Conclusion▲
La plate-forme Java EE 6 et le langage PHP ont actuellement le monopole pour les développements Internet Open Source, et il est courant de trouver des codeurs pro Java EE ou PHP.
Java EE est utilisé pour les grosses infrastructures et permet de gérer des pools de connexion, Enterprise JavaBean, Java Persistence API ou encore des WebServices évolués quand PHP permet un développement rapide de vues ou l'utilisation simplifiée de librairies pour la manipulation d'images par exemple.
Le serveur GlassFish Open-Source totalement compatible Java EE 6, permet de coupler la puissance de ces deux langages.
Un projet existant pourra par exemple migrer de PHP vers Java EE, ou conserver les meilleurs services de chaque langage afin d'optimiser le produit. Ainsi dans le cas d'une migration totale de PHP vers Java EE, le passage pourra être progressif et réalisé service par service. Enfin, dans le meilleur des cas, les services optimisés pour Java seront développés avec Java EE et les autres resteront en PHP. Plus rien ne nous empêche désormais de développer des projets en MVC I ou II avec Java EE pour les parties Contrôleur et Modèle et de conserver la couche Vue en PHP/XHTML.
Merci à Lyche pour sa relecture orthographique.