Installer GlassFish v3 1. Télécharger et installer le package Eclipse/GlassFish [http://download.java.net/glassfish/eclipse/] (choisir Windows, no JDK 1.6 bundled ) 2. Créer un raccourci Eclipse sur le bureau et configurer le lien vers la JDK : D:\GTB1.2-1\eclipse.exe -vm "C:\Program Files\Java\jdk1.6.0_16\bin" 3. Démarrer Eclipse, valider le workspace, passer la phase d'enregistrement Sun, débloquer le firewall.
Par la suite, on supposera que le workspace choisi est situé dans D:/GTB1.2-1/ Configuration du serveur 1. Installer le connecteur de base de données dans le dossier lib/ext du domaine du workspace (pour MySQL 5.1 [http://dev.mysql.com/downloads/connector/j/]) D:\ws_gtb-1\.metadata\.plugins\com.sun.enterprise.jst.server.sunappsrv92\domain1\lib\ext Ne pas confondre avec le dossier lib/ext du glassfish tools bundle situé dans D:\GTB1.2-1\glassfishv3\glassfish\domains\domain1\lib\ext 2. Démarrer le serveur
Si vous obtenez Command start-domain failed, vérifier qu'un port n'est pas déjà utilisé (voir le server.log dans la console). Par exemple : GRAVE: Shutting down v3 due to startup exception : Address already in use: bind: 8084=com.sun.enterprise.v3.services.impl.monitor.MonitorableSel Vérifier les instances de java dans le gestionnaire des taches, un netstat dans une boite cmd pourrait aider. Un simple redémarrage d'eclipse peut suffire. L'objectif étant d'arriver à : Command start-domain executed successfully 3. Un server.log standard après démarrage du serveur (encore vierge de toute application) : 14 mai 2010 10:28:18 com.sun.enterprise.admin.launcher.gflauncherlogger info INFO: JVM invocation command line: C:\Program Files\Java\jdk1.6.0_16\bin\java.exe -cp D:/GTB1.2-1/glassfishv3/glassfish/modules/glassfish.jar -XX:+UnlockDiagnosticVMOptions -XX:MaxPermSize=192m -XX:NewRatio=2 -XX:+LogVMOutput -XX:LogFile=D:\ws_gtb-1\.metadata\.plugins\com.sun.enterprise.jst.server.sunappsrv92\domain1/logs/jvm.log -Xmx512m -client -javaagent:d:/gtb1.2-1/glassfishv3/glassfish/lib/monitor/btrace-agent.jar=unsafe=true,noserver=true -Dosgi.shell.telnet.maxconn=1 -Djdbc.drivers=org.apache.derby.jdbc.ClientDriver -Dfelix.fileinstall.dir=D:\GTB1.2-1\glassfishv3\glassfish/modules/autostart/ -Djavax.net.ssl.keyStore=D:\ws_gtb-1\.metadata\.plugins\com.sun.enterprise.jst.server.sunappsrv92\domain1/config/keystore.jks -Dosgi.shell.telnet.port=6666 -Djava.security.policy=D:\ws_gtb-1\.metadata\.plugins\com.sun.enterprise.jst.server.sunappsrv92\domain1/config/server.policy -Dfelix.fileinstall.poll=5000 -Dcom.sun.aas.instanceRoot=D:\ws_gtb-1\.metadata\.plugins\com.sun.enterprise.jst.server.sunappsrv92\domain1 -Dcom.sun.enterprise.config.config_environment_factory_class=com.sun.enterprise.config.serverbeans.AppserverConfigEnvironmentFactory -Dosgi.shell.telnet.ip=127.0.0.1 -Djava.endorsed.dirs=D:\GTB1.2-1\glassfishv3\glassfish/modules/endorsed;D:\GTB1.2-1\glassfishv3\glassfish/lib/endorsed -Dcom.sun.aas.installRoot=D:\GTB1.2-1\glassfishv3\glassfish -Djava.ext.dirs=C:\Program Files\Java\jdk1.6.0_16/lib/ext;C:\Program Files\Java\jdk1.6.0_16/jre/lib/ext;D:\ws_gtb-1\.metadata\.plugins\com.sun.e -Dfelix.fileinstall.bundles.new.start=true -Djavax.net.ssl.trustStore=D:\ws_gtb-1\.metadata\.plugins\com.sun.enterprise.jst.server.sunappsrv92\domain1/config/cacerts.jks -Dcom.sun.enterprise.security.httpsOutboundKeyAlias=s1as -Djava.security.auth.login.config=D:\ws_gtb-1\.metadata\.plugins\com.sun.enterprise.jst.server.sunappsrv92\domain1/config/login.conf -DANTLR_USE_DIRECT_CLASS_LOADING=true -Dfelix.fileinstall.debug=1 -Dorg.glassfish.web.rfc2109_cookie_names_enforced=false -Djava.library.path=D:/GTB1.2-1/glassfishv3/glassfish/lib;C:/Program Files/Java/jdk1.6.0_16/bin;D:/GTB1.2-1/glassfishv3/glassfish;C:/WINDOWS/Sun com.sun.enterprise.glassfish.bootstrap.asmain -domainname domain1 -asadmin-args start-domain,,,--domaindir,,,d:\ws_gtb-1\.metadata\.plugins\com.sun.enterprise.jst.server.sunappsrv92,,,--debug=false,,,--verbose=false,,,domain -instancename server -verbose false -debug false -asadmin-classpath D:/GTB1.2-1/glassfishv3/glassfish/modules/admin-cli.jar -asadmin-classname com.sun.enterprise.admin.cli.asadminmain -upgrade false -domaindir D:/ws_gtb-1/.metadata/.plugins/com.sun.enterprise.jst.server.sunappsrv92/domain1 -read-stdin true 14 mai 2010 10:28:18 com.sun.enterprise.admin.launcher.gflauncherlogger info
INFO: Successfully launched in 16 msec. INFO: Running GlassFish Version: GlassFish v3 (build 74.2) INFO: Perform lazy SSL initialization for the listener 'http-listener-2' INFO: Starting Grizzly Framework 1.9.18-k - Fri May 14 10:28:22 CEST 2010 INFO: Starting Grizzly Framework 1.9.18-k - Fri May 14 10:28:22 CEST 2010 INFO: Grizzly Framework 1.9.18-k started in: 31ms listening on port 7676 INFO: Grizzly Framework 1.9.18-k started in: 156ms listening on port 8181 INFO: Grizzly Framework 1.9.18-k started in: 125ms listening on port 4860 INFO: Grizzly Framework 1.9.18-k started in: 219ms listening on port 8084 INFO: Grizzly Framework 1.9.18-k started in: 110ms listening on port 3700 INFO: GlassFish v3 (74.2) startup time : Felix(2703ms) startup services(1063ms) total(3766ms) INFO: javassist.util.proxy.proxyfactory.classloaderprovider = org.glassfish.weld.weldactivator$glassfishclassloaderprovider@2c06b2 INFO: Binding RMI port to *:8686 INFO: JMXStartupService: Started JMXConnector, JMXService URL = service:jmx:rmi://olivier:8686/jndi/rmi://olivier:8686/jmxrmi INFO: Using com.sun.enterprise.transaction.jts.javaeetransactionmanagerjtsdelegate as the delegate INFO: [Thread[GlassFish Kernel Main Thread,5,main]] started INFO: {felix.fileinstall.poll (ms) = 5000, felix.fileinstall.dir = D:\GTB1.2-1\glassfishv3\glassfish\modules\autostart, felix.fileinstall.debug INFO: Installed D:\GTB1.2-1\glassfishv3\glassfish\modules\autostart\org.apache.felix.fileinstall-autodeploy-bundles.cfg INFO: {felix.fileinstall.poll (ms) = 5000, felix.fileinstall.dir = D:\ws_gtb-1\.metadata\.plugins\com.sun.enterprise.jst.server.sunappsrv92\doma INFO: Installed D:\GTB1.2-1\glassfishv3\glassfish\modules\autostart\osgi-web-container.jar INFO: Installed D:\GTB1.2-1\glassfishv3\glassfish\modules\autostart\org.apache.felix.scr.jar INFO: Started bundle: file:/d:/gtb1.2-1/glassfishv3/glassfish/modules/autostart/osgi-web-container.jar INFO: Started bundle: file:/d:/gtb1.2-1/glassfishv3/glassfish/modules/autostart/org.apache.felix.scr.jar INFO: Total number of available updates : 0 En analysant ce log, on peut voir que : 1. 2. Le domaine est géré dans votre workspace : Domain location: D:\ws_gtb-1\.metadata\.plugins \com.sun.enterprise.jst.server.sunappsrv92\domain1 L'instance du serveur glassfish est démarrée à partir d'un jar du Tools Bundle glassfish.jar (et non via une commande asadmin). Il est inutile d'essayer d'utiliser l'utilitaire asdadmin présent dans le dossier d'installation de Glassfish pour lister les domaines démarrés, il ne trouvera rien. 1. Les jars signés le sont par le keystore présent dans D:\ws_gtb-1\.metadata\.plugins \com.sun.enterprise.jst.server.sunappsrv92\domain1/config/keystore.jks 2. Les polices de sécurité dans D:\ws_gtb-1\.metadata\.plugins\com.sun.enterprise.jst.server.sunappsrv92 \domain1/config/server.policy 3. Le truststore dans D:\ws_gtb-1\.metadata\.plugins\com.sun.enterprise.jst.server.sunappsrv92 \domain1/config/cacerts.jks 4. L'utilitaire asadmin est lancé par D:/GTB1.2-1/glassfishv3/glassfish/modules/admin-cli.jar 4. Ouvrir la console d'administration du serveur 5. Configurer le pool de la base de données MySQL
Après avoir fait Next, supprimer toutes les propriétés par défaut et ne garder que les 4 suivantes, à moins que vous n'ayiez de configuration bien particulière de votre serveur de bases de données. Les laisser peut impliquer que le pool ne fonctionne pas. Dans databasename, fournir le nom du schema par défaut SQL ; dans servername fournir l'adresse IP du serveur ; configurer l'utilisateur avec user et password. Faire un ping pour tester la connexion. En cas d'échec vérifiez vos paramètres et que vous avez bien installé le connecteur comme décrit plus haut ; redémarrez le serveur, lisez le server.log pour plus de détails, il est censé se mettre à jour dans la console Eclipse. Saisir la ressource (DataSource) qui va se connecter sur votre pool. Noter le nom JNDI qu'on va réutiliser dans le fichier de configuration persistence.xml :
Création du projet Hello World 1. File > New > Enterprise Application Project 2. Next > New Module
3. Finish Et voilà, comme diraient les anglais :
Configurer le module de persistance 4.1. Propriétés du projet EJB > Project Facets > Ajouter le support de la persistance. On désactive EclipseLink dans Eclipse, car on veut utiliser JPA 2.0 fourni par le serveur GlassFish. Eclipse ne propose que la version EclipseLink 1.0.
4.2. Further configuration required > JPA Implementation > Disable Library configuration 4.3. Ouvrir et configurer le fichier persistence.xml La source doit ressembler à cela : <?xml version="1.0" encoding="utf-8"?> <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocati <persistence-unit name="exempleup" transaction-type="jta"> <provider>org.eclipse.persistence.jpa.persistenceprovider</provider> <jta-data-source>jdbc/exempleds</jta-data-source> <properties> <property name="eclipselink.logging.level" value="finest"/> <property name="eclipselink.ddl-generation" value="create"/> <property name="eclipselink.ddl-generation.output-mode" value="database" /> </properties> </persistence-unit> </persistence> Le nom jdbc/exempleds doit être le même que celui configuré dans la Ressource JDBC précédemment. Ecriture des entités 1. Créer un nouveau package, une nouvelle classe entité User
User.java package fr.societe.hellow.entites; import java.io.serializable; import javax.persistence.entity; import javax.persistence.generatedvalue; import javax.persistence.generationtype; import javax.persistence.id; import javax.persistence.namedqueries; import javax.persistence.namedquery; import javax.persistence.table; /** * Entité représentant un User. * @author olivier.chorier@crosstalk.fr * @date 14 mai 2010 @Entity @Table(name="NetUser") @NamedQueries({ @NamedQuery(name="findAllUsers", query = "SELECT u from User u"), @NamedQuery(name="findUserById", query = "SELECT u from User u WHERE u.id = :id"), @NamedQuery(name="findUserByEmail", query = "SELECT u FROM User u WHERE u.email LIKE :email"), @NamedQuery(name="identifyUser", query = "SELECT u FROM User u WHERE u.email LIKE :email AND u.password = :password") ) public class User implements Serializable {
private static final long serialversionuid = 1L; private int id; private String firstname; private String lastname; private String email; private String password; private String address; private String zipcode; private String city; private String country; private boolean active; private int level; @Id @GeneratedValue(strategy=GenerationType.IDENTITY) public int getid() { return id; public void setid(int newid) { this.id = newid; public String getfirstname() { return firstname; public void setfirstname(string newfirstname) { this.firstname = newfirstname; public String getlastname() { return lastname; public void setlastname(string newlastname) { this.lastname = newlastname; public String getemail() { return email; public void setemail(string newemail) { this.email = newemail; public String getpassword() { return password; public void setpassword(string newpassword) { this.password = newpassword; public String getaddress() { return address; public void setaddress(string newaddress) { this.address = newaddress; public String getzipcode() { return zipcode; public void setzipcode(string newzipcode) { this.zipcode = newzipcode; public String getcity() { return city; public void setcity(string newcity) { this.city = newcity; public String getcountry() { return country; public void setcountry(string newcountry) { this.country = newcountry; public boolean isactive() { return active; public void setactive(boolean newactive) { this.active = newactive; public int getlevel() { return level; public void setlevel(int newlevel) { this.level = newlevel; public int hashcode() { int hash = 0; Integer id = Integer.valueOf(getId()); hash += (id!= null? id.hashcode() : 0); return hash; public boolean equals(object o) {
Integer id = Integer.valueOf(this.getId()); if (o == null!this.getclass().equals(o.getclass())) return false; User other = (User) o; if (this.getid()!= other.getid() && (id ==null!id.equals(other.getid()))) return false; return true; @Override public String tostring() { return "" + getfirstname(); Ecriture des EJB 1. Créer un nouveau package, une nouvelle classe session UserEJB et les interfaces Remote et Local UserEJB.java package fr.societe.hellow.ejb; import java.util.collection; import javax.ejb.localbean; import javax.ejb.stateless; import javax.persistence.entitymanager; import javax.persistence.persistencecontext; import javax.persistence.query; import fr.societe.hellow.entites.user;
/** * Session Bean implementation class AdminService * @author olivier.chorier@societe.fr * @date 14 mai 2010 @LocalBean @Stateless public class UserEJB implements UserEJBRemote, UserEJBLocal { @PersistenceContext(unitName = "ExempleUP") private EntityManager em; /* * CRUD sur User public User adduser(user user) { em.persist(user); return user; public User updateuser(user user) { em.merge(user); return user; public void deleteuser(int id) { em.remove(finduserbyid(id)); @SuppressWarnings("unchecked") public Collection<User> findallusers() { Query query = em.createquery("select user FROM User AS user"); return query.getresultlist(); public User finduserbyid(integer id) { return em.find(user.class, id); Le nom ExempleUP est celui configuré dans persistence.xml UserEJBLocal package fr.societe.hellow.ejb; import java.util.collection; import javax.ejb.local; import fr.societe.hellow.entites.user; /** * Interface d'accès local sur l'ejb UserEJB * @author olivier.chorier@societe.fr * @date 14 mai 2010 @Local public interface UserEJBLocal { /* * CRUD sur User public User adduser(user user); public User updateuser(user user); public void deleteuser(int id); public Collection<User> findallusers(); public User finduserbyid(integer id); UserEJBRemote.java package fr.societe.hellow.ejb; import java.util.collection; import javax.ejb.remote; import fr.societe.hellow.entites.user; /** * Interface d'accès distant (par Swing) sur l'ejb UserEJB * @author olivier.chorier@societe.fr * @date 14 mai 2010 @Remote public interface UserEJBRemote { /* * CRUD sur User public User adduser(user user); public User updateuser(user user); public void deleteuser(int id); public Collection<User> findallusers(); public User finduserbyid(integer id); Le Project Explorer doit ressembler à cela :
Ecriture de l'application Java Web Start 1. On est joueur : supprimer le Main.java généré automatiquement, créer un package et une nouvelle classe de démarrage qui appelle une IHM de gestion des utilisateurs. On commence simple, l'ihm ne contient qu'un label Hello World. Run.java package fr.societe.hellow.swing; import javax.swing.jframe; import javax.swing.swingutilities; import fr.societe.hellow.swing.users.gestionnaireusers; /** * Classe de démarrage de l'application lourde. * @author olivier.chorier@societe.fr public class Run { public static void main(string... args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { JFrame frame = new JFrame("Gestion Utilisateurs"); frame.setcontentpane(new GestionnaireUsers()); frame.setdefaultcloseoperation(jframe.dispose_on_close); frame.pack(); frame.setlocationrelativeto(null); frame.setvisible(true); ); GestionnaireUsers.java package fr.societe.hellow.swing.users; import java.awt.color; import java.awt.dimension; import java.awt.gridbagconstraints; import java.awt.gridbaglayout; import javax.swing.jlabel; import javax.swing.jpanel; /** * IHM de gestion des utilisateurs * @author olivier.chorier@societe.fr public class GestionnaireUsers extends JPanel { private static final long serialversionuid = 1L; private JLabel lblhelloworld; public GestionnaireUsers() { super(); setopaque(true); setbackground(color.white); setpreferredsize(new Dimension(640, 480)); setlayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints(); c.gridx=0; c.gridy=0; add(getlblhelloworld(), c); private JLabel getlblhelloworld() { if (lblhelloworld == null) { lblhelloworld = new JLabel("HelloWorld!"); lblhelloworld.setopaque(false); lblhelloworld.setfont(lblhelloworld.getfont().derivefont(18f)); return lblhelloworld; 2. Penser à mettre à jour le MANIFEST.MF dans le dossier META-INF pour pointer vers la nouvelle Main-Class. Manifest-Version: 1.0 Main-Class: fr.societe.hellow.swing.run Le Project Explorer doit ressembler à cela : Déployer l'application 1. Projet HelloWorld > Run > Run on server ; sélectionner le serveur GlassFish 2. Next > La zone configured contient HelloWorld avec les deux projets HelloWorldClient et HelloWorldEJB. 3. Finish Le server.log ne devrait pas relever d'erreurs (aucune ligne ne commençant par GRAVE). Vérifier l'absence d'erreur, la dernière ligne doit ressembler à INFO: HelloWorld was successfully deployed in 1 062 milliseconds. 4. Tester le client swing en Java Web Start : http://localhost:8084/helloworld/helloworldclient/ [http://localhost:8084/helloworld /HelloWorldClient/] Essayez le port 8080, mais chez moi c'est le 8084 qui fonctionne. Regardez quels sont les http-listeners qui ont été créés au moment de démarrer le serveur (fichier de log).