Un exercici amb el Framework Seam

Des de fa un temps que estic involucrat en el manteniment d’una aplicació desenvolupada sobre el framework Seam. Fins dates recents el manteniment s’ha limitat a modificacions menors, però fa poc ens ha entrat un canvi en profunditat.Ha estat l’oportunitat que estava esperant per a poder aprendre una mica més sobre aquest potent framework.

Primer de tot, què és Seam? La Viquipèdia ens dona una definició breu, senzilla i entenedora: “Seam és un Framework per a aplicacions Web desenvolupat per JBoss, una divisió de Red Hat.”

Hi han molts frameworks per a aplicacions web.  Un framework és  la sistematització de l’experiència acumulada en el desenvolupament de moltes aplicacions web. Aquesta sistematització pren la forma d’arquitectures, patrons, llibreries, bones pràctiques i eines de diferents tipus. En adoptar un framework per a desenvolupar una aplicació web el que estem fent, doncs, es manifestar la voluntat de “fer bé les coses”, repetint models coneguts que han funcionat.  De forma pràctica, l’adopció d’un framework es tradueix en l’ús de certes llibreries, metodologies i eines de desenvolupament

Spring ve a ser l’estàndar de facto de la indústria o, si més no, el framework java per a aplicacions web més popular. Si coneixem Spring, doncs, ja sabem que podem esperar de Seam.  Tanmateix, Seam té les seves pròpies característiques. En aquest enllaç podeu trobar una anàlisi comparativa entre els frameworks Seam i Spring.

Per aproximar-me a Seam provaré de fer “alguna cosa” amb el framework. Per exemple un gestor de biblioteca molt senzill.

El que vull fer és una aplicació web que em permeti donar d’alta i de baixa  llibres, classificar-los segons autor, temàtica i tipus de suport físic, i que em permeti saber a quin lloc de la casa paren.

Doncs bé, resulta que això puc fer-ho sense escriure una línia de codi java. Seam es capaç de generar una aplicació web de manteniment sense més que proporcionar-li un esquema de dades. La veritat és que és força espectacular. No cal dir que aquests superpoders no són pas els únics dels que disposa Seam, però per a una primera aproximació -res més pretenc en aquest post- és més que suficient.

Comencem: aplicacions. El framework Seam es pot fer servir amb qualsevol Servidor d’Aplicacions que suporti EJB3.0, ara bé, Seam és un producte de JBoss i, com es pot esperar s’integra fàcilment amb aquest servidor. El primer que faré, doncs, és descarregar les darreres versions de  JBoss AS i del Seam framework. Proveu els següents enllaços:

Seam 3.1.0 http://sourceforge.net/projects/jboss/files/Seam/3/3.1.0.Final/

jBoss AS 7.1.1 Final http://download.jboss.org/jbossas/7.1/jboss-as-7.1.1.Final/jboss-as-7.1.1.Final.zip

Ens caldrà una versió de JDK igual o superior a la 1.6 (feu un cop d’ull a http://www.oracle.com/technetwork/java/javase/downloads/index.html).

Si per alguna raó no poguéssim disposar almenys de JDK1.6, aleshores hauríem de fer servir versions anteriors de JBoss AS i de SEAM. Podria ser aquest el cas d’haver d’ocupar-nos del manteniment d’una aplicació legacy.

La següent configuració funciona amb JDK 1.5 (evidentment, funciona amb JDK superiors):

Seam 2.3.0 GA http://sourceforge.net/projects/jboss/files/JBoss%20Seam/2.3.0.Final/

JBoss AS 5.1.0.GA http://sourceforge.net/projects/jboss/files/JBoss/JBoss-5.1.0.GA

La instal·lació del servidor JBoss AS 1.7 i del Seam Framework 3.1.0 no presenta cap dificultat, es tracta, simplement de descomprimir el paquet zip corresponent. he creat una carpeta seam-jboss i els he descomprimit allà.

Si tinc versions diverses de JDK, puc modificar l’script d’arrencada de JBoss bin/standalone.sh per a indicar-hi explícitament quin JDK vull fer servir, només em cal donar un valor inicial a JAVA_HOME per a que apunti a la carpeta del JDK triat, per exemple:

JAVA_HOME=/home/albert/jdk1.6.0_30

El següent pas és crear les taules i relacions de la base de dades. Faré servir el servidor MySQL que em ve amb el XAMPP que tinc instal·lat de posts anteriors, i el phpMyAdmin com interfase de la base de dades.

Només vull fer una petita demostració, o sigui que no entraré en detalls: la idea és crear una petita bd de biblioteca. Tindré
– una taula per guardar els llibres (id, llibre, isbn, id_ubicació, id_format);
– una taula d’autors (id, autor);
– una taula de relació m-n entre llibres i autors (un autor pot haver escrit molts llibres, un llibre pot ser escrit per molts autors. Per tant: id, id_autor, id_llibre);
– una taula de relació m-n entre llibres i temàtiques (un llibre pot tractar diversos temes; un tema pot ser tractat per molts llibres. Per tant, id, id_llibre, id_tematica);
– lògicament, doncs, una taula de temàtiques (id, tematica).
– una taula d’ubicacions (id, lloc) ja que puc tenir llibres per uns quants llocs de la casa, a prestatges, o a DVDs (suposo que tinc els DVDs etiquetats, cosa que algun dia hauré de fer, però, en fi, això només pretén ser un exemple 😉
– una taula de formats: “paper”, “pdf”, “epub”, “cbr”… (id, format).

Dit i fet. Primer de tot creo la base de dades “prova_seam”, i les taules “llibre”, “autor”, “llibre_autor”, “llibre_tematica”, “ubicacio” i “format”.

A continuació, creo els índexos sobre totes les columnes que participaran en les relacions i, finalment, creo les relacions. Cal esmerçar-se en crear correctament els índexos i les relacions. És necessari per a que la màgia de Seam funcioni. Es tracta, simplement, de permetre que les eines de mapeig de model relacional a model d’objectes tinguin tota la informació necessària per a crear una capa de classes java que encapsulin l’accés a les dades.

Després d’una sessió de phpMyAdmin, obtinc un model de dades que m’agrada. L’esquema és el següent:


-- phpMyAdmin SQL Dump
-- version 3.4.5
-- http://www.phpmyadmin.net
--
-- Servidor: localhost
-- Tiempo de generación: 21-11-2012 a las 21:05:25
-- Versión del servidor: 5.5.16
-- Versión de PHP: 5.3.8

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;

--
-- Base de datos: `prova_seam`
--

-- --------------------------------------------------------

--
-- Estructura de tabla para la tabla `autor`
--

CREATE TABLE IF NOT EXISTS `autor` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `autor` varchar(100) COLLATE latin1_spanish_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci AUTO_INCREMENT=2 ;


-- --------------------------------------------------------

--
-- Estructura de tabla para la tabla `format`
--

CREATE TABLE IF NOT EXISTS `format` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `format` varchar(100) COLLATE latin1_spanish_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci AUTO_INCREMENT=2 ;


-- --------------------------------------------------------

--
-- Estructura de tabla para la tabla `llibre`
--

CREATE TABLE IF NOT EXISTS `llibre` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `llibre` varchar(200) COLLATE latin1_spanish_ci NOT NULL,
  `isbn` varchar(13) COLLATE latin1_spanish_ci NOT NULL,
  `id_ubicacio` int(11) NOT NULL,
  `id_format` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `id_ubicacio` (`id_ubicacio`),
  KEY `id_format` (`id_format`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci AUTO_INCREMENT=1 ;

-- --------------------------------------------------------

--
-- Estructura de tabla para la tabla `llibre_autor`
--

CREATE TABLE IF NOT EXISTS `llibre_autor` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `id_llibre` int(11) NOT NULL,
  `id_autor` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `id_llibre` (`id_llibre`),
  KEY `id_autor` (`id_autor`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci AUTO_INCREMENT=1 ;

-- --------------------------------------------------------

--
-- Estructura de tabla para la tabla `llibre_tematica`
--

CREATE TABLE IF NOT EXISTS `llibre_tematica` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `id_autor` int(11) NOT NULL,
  `id_tematica` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `id_autor` (`id_autor`),
  KEY `id_tematica` (`id_tematica`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci AUTO_INCREMENT=1 ;

-- --------------------------------------------------------

--
-- Estructura de tabla para la tabla `tematica`
--

CREATE TABLE IF NOT EXISTS `tematica` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `tematica` varchar(100) COLLATE latin1_spanish_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci AUTO_INCREMENT=1 ;

-- --------------------------------------------------------

--
-- Estructura de tabla para la tabla `ubicacio`
--

CREATE TABLE IF NOT EXISTS `ubicacio` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `ubicacio` varchar(100) COLLATE latin1_spanish_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci AUTO_INCREMENT=2 ;

--
-- Volcado de datos para la tabla `ubicacio`
--

INSERT INTO `ubicacio` (`id`, `ubicacio`) VALUES
(1, 'llibreria de l''escriptori');

--
-- Restricciones para tablas volcadas
--

--
-- Filtros para la tabla `llibre`
--
ALTER TABLE `llibre`
  ADD CONSTRAINT `llibre_ibfk_1` FOREIGN KEY (`id_ubicacio`) REFERENCES `ubicacio` (`id`),
  ADD CONSTRAINT `llibre_ibfk_2` FOREIGN KEY (`id_format`) REFERENCES `format` (`id`);

--
-- Filtros para la tabla `llibre_autor`
--
ALTER TABLE `llibre_autor`
  ADD CONSTRAINT `llibre_autor_ibfk_1` FOREIGN KEY (`id_llibre`) REFERENCES `llibre` (`id`),
  ADD CONSTRAINT `llibre_autor_ibfk_2` FOREIGN KEY (`id_autor`) REFERENCES `autor` (`id`);

--
-- Filtros para la tabla `llibre_tematica`
--
ALTER TABLE `llibre_tematica`
  ADD CONSTRAINT `llibre_tematica_ibfk_1` FOREIGN KEY (`id_autor`) REFERENCES `autor` (`id`),
  ADD CONSTRAINT `llibre_tematica_ibfk_2` FOREIGN KEY (`id_tematica`) REFERENCES `tematica` (`id`);

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;


En aquest punt, deixo el phpMyAdmin i me’n vaig a la carpeta on tinc el seam.

Estic fent servir la versió de Seam 3.2.0. Amb aquesta versió hi han les següents eines disponibles per al desenvolupament d’aplicacions web:
– el JBoss Developer Estudio. que només requereix registre per a poder-lo descarregar lliurement.
– Les JBoss Tools. Que són plugins per Eclipse. Les JBoss Tools permeten crear, directament, aplicacions per al Framework Seam 2.3.0 i, indirectament, a través del plugin de Seam Forge, per al Framework Seam 3.1.0.
Seam Forge. Es tracta d’una shell des de la que es poden crear aplicacions, deployar, crear objectes nous… Aquesta shell s’integra com a plugin a les JBoss Tools o al JBoss Developer Studio. El Seam Forge vindria a ser l’evolució de l’script seam-gen de la versió Seam Framework 2.3.0. A diferència de seam-gen, que formava part del paquet de distribució del Framework, el Seam Forge ha de descarregar-se com una aplicació separada.

Seam Forge es pot extendre amb plugins. A la pàgina de plugins en trobarem alguns que ens caldran per a poder fer l’enginyeria inversa de la base de dades i per automatitzar les tasques d’administració dels desplegaments al JBoss AS. Però n’hi han d’altres. Serà cosa de provar a veure què fan.

Com que el repte és “crear una aplicació sense escriure una línia de codi”, i tenint en compte les explicacions anteriors, descarrego el Seam Forge. És un paquet zip que desplego a la mateixa carpeta de seam-jboss on tinc les carpetes del JBoss AS i del Seam Framework. Em cal indicar-li el JDK que penso fer servir i quina és la seva carpeta home. Per a fer-ho vaig a la carpeta bin del Seam Forge i allà modifico l’script forge per a establir les variables JAVA_HOME i FORGE_HOME.

Seam Forge em permetrà generar (scaffold) una aplicació o, si més no, l’esquelet i alguns òrgans vitals, d’una aplicació web. Tot plegat d’una forma que recorda els Archetypes de Maven. pel que estic veient, Maven és una eina que es fa força imprescindible a l’hora de treballar amb projectes desenvolupats a partir de Forge. En general Maven és una eina molt potent que caldria tenir en compte (almenys considerar-ne l’ús) de forma habitual.

A més, em caldrà tenir a ma el driver jdbc del MySQL per a poder desplegar-lo al JBoss.

És el primer que faig. Per a desplegar el driver jdbc n’hi ha prou amb col·locar-lo a la carpeta JBOSS_HOME/standalone/deployments. Si tenim una finestra oberta amb els logs del servidor veurem com, efectivament, el desplega. A més, a la consola d’administració del JBoss també veurem el nou desplegament:

UN cop tinc el driver disponible al JBoss, passo a la construcció de l’aplicació amb el Forge.

Escric forge al terminal i accedeixo a la shell. Una advertència, no tanqueu la shell del Forge fins completar tots els passos del desplegament de l’aplicació:

Per a poder fer l’enginyeria inversa del model de dades al MySQL i generar les classes java per hibernate em cal, primer de tot, carregar els hibernate-tools. Aquesta part del post està basada en aquest link (http://www.mastertheboss.com/forge/reverse-engineer-your-db-schema-using-jboss-forge).


albert@athena:~/seam-jboss/forge-distribution-1.1.2.Final/bin$ forge
    _____                    
   |  ___|__  _ __ __ _  ___ 
   | |_ / _ \| `__/ _` |/ _ \  \\
   |  _| (_) | | | (_| |  __/  //
   |_|  \___/|_|  \__, |\___| 
                   |___/      

JBoss Forge, version [ 1.1.2.Final ] - JBoss, by Red Hat, Inc. [ http://jboss.org/forge ]
[no project] bin $
[no project] bin $ forge install-plugin hibernate-tools
***INFO*** Preparing to install plugin: hibernate-tools
***INFO*** Checking out plugin source files to [/tmp/forgetemp2102291278366764408/repo] via 'git'
***INFO*** Switching to branch/tag [refs/heads/master]
***INFO*** Invoking build with underlying build system.
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building hibernate-tools-plugin 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ hibernate-tools-plugin ---
[INFO] 
[INFO] --- maven-resources-plugin:2.4.3:resources (default-resources) @ hibernate-tools-plugin ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 3 resources
[INFO] 
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ hibernate-tools-plugin ---
[INFO] Compiling 9 source files to /tmp/forgetemp2102291278366764408/repo/target/classes
[INFO] 
[INFO] --- maven-resources-plugin:2.4.3:testResources (default-testResources) @ hibernate-tools-plugin ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 3 resources
[INFO] 
[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ hibernate-tools-plugin ---
[INFO] Not compiling test sources
[INFO] 
[INFO] --- maven-surefire-plugin:2.7.2:test (default-test) @ hibernate-tools-plugin ---
[INFO] Tests are skipped.
[INFO] 
[INFO] --- maven-jar-plugin:2.3.1:jar (default-jar) @ hibernate-tools-plugin ---
[INFO] Building jar: /tmp/forgetemp2102291278366764408/repo/target/hibernate-tools-plugin-1.0.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 22.651s
[INFO] Finished at: Sun Nov 18 14:29:57 CET 2012
[INFO] Final Memory: 33M/79M
[INFO] ------------------------------------------------------------------------
***INFO*** Installing plugin artifact.
***SUCCESS*** Installed from [https://github.com/forge/plugin-hibernate-tools.git] successfully.
Wrote /home/albert/.forge/httpsrawgithubcomforgepluginrepositorymasterrepositoryyaml.yaml
Wrote /home/albert/.forge/plugins/org/jboss/hibernate/forge/hibernate-tools-plugin/1.0.0-SNAPSHOT-311059c3-c505-46c1-915e-4a3af362ea9a
...

després d’escriure un munt de jars a la carpeta de plugins, finalment, tinc les hibernate tools disponibles al Forge:

Wrote /home/albert/.forge/plugins/org/jboss/hibernate/forge/hibernate-tools-plugin/1.0.0-SNAPSHOT-311059c3-c505-46c1-915e-4a3af362ea9a/slf4j-log4j12-1.5.10.jar
Wrote /home/albert/.forge/plugins/org/jboss/hibernate/forge/hibernate-tools-plugin/1.0.0-SNAPSHOT-311059c3-c505-46c1-915e-4a3af362ea9a/hibernate-tools-plugin.jar
Wrote /home/albert/.forge/plugins/org/jboss/hibernate/forge/hibernate-tools-plugin/1.0.0-SNAPSHOT-311059c3-c505-46c1-915e-4a3af362ea9a/module.xml
    _____                    
   |  ___|__  _ __ __ _  ___ 
   | |_ / _ \| `__/ _` |/ _ \  \\
   |  _| (_) | | | (_| |  __/  //
   |_|  \___/|_|  \__, |\___| 
                   |___/      

JBoss Forge, version [ 1.1.2.Final ] - JBoss, by Red Hat, Inc. [ http://jboss.org/forge ]

Ara creo el nou projecte:

[no project] bin $ new-project
 ? [named=The name of the new project (of type java.lang.String)]: provaseam
 ? Use [/home/albert/seam-jboss/forge-distribution-1.1.2.Final/bin/provaseam] as project directory? [Y/n] n

 ? Where would you like to create the project? [Press ENTER to use the current directory: bin] [ .../bin] /home/albert/workspace/wk-java/provaseam
***SUCCESS*** Created project [provaseam] in new working directory [/home/albert/workspace/wk-java/provaseam]
Wrote /home/albert/workspace/wk-java/provaseam
Wrote /home/albert/workspace/wk-java/provaseam/pom.xml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/java
Wrote /home/albert/workspace/wk-java/provaseam/src/test/java
Wrote /home/albert/workspace/wk-java/provaseam/src/main/resources
Wrote /home/albert/workspace/wk-java/provaseam/src/test/resources
Wrote /home/albert/workspace/wk-java/provaseam/src/main/java/com/example/provaseam
[provaseam] provaseam $

new-project ha creat un fitxer pom.xml (per a compilar i deployar amb maven) i una estructura de carpetes.

Ara cal omplir aquesta estructura de carpetes de contingut. A continuació, configuro paràmetres incials de persistència:

[provaseam] provaseam $ persistence setup
 ? [provider=ARG (of type org.jboss.forge.spec.javaee.jpa.api.JPAProvider)]: org.jboss.forge.spec.javaee.jpa.api.JPAProvider
[provider=ARG (of type org.jboss.forge.spec.javaee.jpa.api.JPAProvider)]: 

  1 - [HIBERNATE]
  2 - [OPENJPA]
  3 - [ECLIPSELINK]
  4 - [INFINISPAN]

 ? Choose an option by typing the number of the selection: 1
 ? [container=ARG (of type org.jboss.forge.spec.javaee.jpa.api.JPAContainer)]: org.jboss.forge.spec.javaee.jpa.api.JPAContainer
[container=ARG (of type org.jboss.forge.spec.javaee.jpa.api.JPAContainer)]: 

  1 - [JBOSS_AS6]
  2 - [JBOSS_AS7]
  3 - [JBOSS_EAP6]
  4 - [GLASSFISH_3]
  5 - [CUSTOM_JDBC]
  6 - [CUSTOM_JTA]
  7 - [CUSTOM_NON_JTA]

L’anterior es podia haver fet en una sola línia així si hagués afegit les opcions provider i container a persistence setup:

persistence setup --provider HIBERNATE --container JBOSS_AS7

Segueix:

 ? Choose an option by typing the number of the selection: 2
Use which version of 'jboss-javaee-6.0' ?

  1 - [org.jboss.spec:jboss-javaee-6.0:pom::1.0.0.Beta4]
  2 - [org.jboss.spec:jboss-javaee-6.0:pom::1.0.0.Beta5]
  3 - [org.jboss.spec:jboss-javaee-6.0:pom::1.0.0.Beta6]
  4 - [org.jboss.spec:jboss-javaee-6.0:pom::1.0.0.Beta7]
  5 - [org.jboss.spec:jboss-javaee-6.0:pom::1.0.0.CR1]
  6 - [org.jboss.spec:jboss-javaee-6.0:pom::1.0.0.Final]
  7 - [org.jboss.spec:jboss-javaee-6.0:pom::2.0.0.Beta1]
  8 - [org.jboss.spec:jboss-javaee-6.0:pom::2.0.0.CR1]
  9 - [org.jboss.spec:jboss-javaee-6.0:pom::2.0.0.Final]
  10 - [org.jboss.spec:jboss-javaee-6.0:pom::2.1.0.Beta1]
  11 - [org.jboss.spec:jboss-javaee-6.0:pom::3.0.0.Beta1]
  12 - [org.jboss.spec:jboss-javaee-6.0:pom::3.0.0.Final]
  13 - [org.jboss.spec:jboss-javaee-6.0:pom::3.0.1.Final]*

 ? Choose an option by typing the number of the selection [*-default]  [0] 
***SUCCESS*** Installed [forge.spec.jpa] successfully.
***INFO*** Setting transaction-type="JTA"
***INFO*** Using example data source [java:jboss/datasources/ExampleDS]
 ? Do you want to install a JPA 2 metamodel generator? [y/N] 
 ? The JPA provider [HIBERNATE], also supplies extended APIs. Install these as well? [y/N] 
***SUCCESS*** Persistence (JPA) is installed.
Wrote /home/albert/workspace/wk-java/provaseam/src/main/resources/META-INF/persistence.xml
Wrote /home/albert/workspace/wk-java/provaseam/pom.xml
[provaseam] provaseam $

Fixem-nos en aquesta línia:

***INFO*** Using example data source [java:jboss/datasources/ExampleDS]

S’ha creat un datasource de prova. El podem trobar a la carpeta /home/albert/workspace/wk-java/provaseam/src/main/resources/META-INF/

El persistence.xml generat:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="forge-default" transaction-type="JTA">
    <description>Forge Persistence Unit</description>
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
      <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
      <property name="hibernate.show_sql" value="true"/>
      <property name="hibernate.format_sql" value="true"/>
      <property name="hibernate.transaction.flush_before_completion" value="true"/>
    </properties>
  </persistence-unit>
</persistence>

El que faré serà canviar el persistence.xml que fa servir el datasource d’exemple per un persistence.xml que apunti al datasource que crearé ara.

Creo el datasource. Per això copio un fitxer datasource.xml amb el següent contingut a la carpeta de deployments (JBOSS_HOME/standalone/deployments).

<datasources xmlns="http://www.jboss.org/ironjacamar/schema">
<datasource jndi-name="java:jboss/datasources/mysqldev" pool-name="poolmysqldev">
    <connection-url>jdbc:mysql://localhost/prova_seam</connection-url>
    <driver>mysql-connector-java-5.1.22-bin.jar</driver>
    <pool>
        <max-pool-size>30</max-pool-size>
    </pool>
    <security>
        <user-name>root</user-name>
        <password></password>
    </security>
</datasource>
</datasources>

Com abans amb el driver, si tenim una consola oberta amb els logs de funcionament del JBoss veurem com fa el deploy del datasource. A la consola d’administració podrem vereu el datasource que tot just hem creat i en podrem provar la connexió amb la base de dades.

I ara canvio el persistence.xml per un persistence.xml que apunti al meu datasource. Fixem-nos que les properties canvien. Pot ser interessant consultar la següent taula de Hibernate Dialects. En general, no està de més fer-li un cop d’ull a la documentació d’Hibernate.

Vet aquí el persistence.xml que poso a /home/albert/workspace/wk-java/provaseam/src/main/resources/META-INF/

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
             version="2.0">

    <persistence-unit name="test">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <jta-data-source>java:jboss/datasources/mysqldev</jta-data-source>
        <properties>
            <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
            <property name="hibernate.connection.username" value="root"/>
            <property name="hibernate.connection.password" value=""/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
        </properties>
    </persistence-unit>  
</persistence>

I ara ja puc generar les classes amb les hibernate tools:

[provaseam] provaseam $ generate-entities
 ? Specify the URL for the JDBC connection. [jdbc:h2:tcp://localhost/sakila] jdbc:mysql://localhost/prova_seam
 ? Enter the user name for JDBC connection. [null] root
 ? Enter the password for JDBC connection. 
 ? Enter the dialect to use for the datasource. [org.hibernate.dialect.H2Dialect] org.hibernate.dialect.MySQLDialect
 ? Specify the class name for the JDBC driver for the datasource. [org.h2.Driver] com.mysql.jdbc.Driver
 ? Enter the path in the local file system to the jar file containing the JDBC driver. [null] /home/albert/jdbc-drivers/mysql.jar
 ? In which package you'd like to generate the entities, or enter for default: [com.example.provaseam.model] com.stsoftlliure.provaseam.model
Found 7 tables in datasource
Generated java at /home/albert/workspace/wk-java/provaseam/src/main/java/com/stsoftlliure/provaseam/model/LlibreAutor.java
Generated java at /home/albert/workspace/wk-java/provaseam/src/main/java/com/stsoftlliure/provaseam/model/LlibreTematica.java
Generated java at /home/albert/workspace/wk-java/provaseam/src/main/java/com/stsoftlliure/provaseam/model/Tematica.java
Generated java at /home/albert/workspace/wk-java/provaseam/src/main/java/com/stsoftlliure/provaseam/model/Autor.java
Generated java at /home/albert/workspace/wk-java/provaseam/src/main/java/com/stsoftlliure/provaseam/model/Llibre.java
Generated java at /home/albert/workspace/wk-java/provaseam/src/main/java/com/stsoftlliure/provaseam/model/Ubicacio.java
Generated java at /home/albert/workspace/wk-java/provaseam/src/main/java/com/stsoftlliure/provaseam/model/Format.java
Generated 7 java files.
[provaseam] provaseam $

Ara genero l’esquelet de l’aplicació web:

[provaseam] provaseam $ scaffold setup
 ? No scaffold type was selected, use default [JavaServer Faces]? [Y/n] 
 ? Scaffold provider [faces] is not installed. Install it? [Y/n] 
 ? Facet [forge.maven.WebResourceFacet] requires packaging type(s) [war], but is currently [jar]. Update packaging? (Note: this could deactivate other plugins in your project.) [Y/n] 
***SUCCESS*** Installed [forge.maven.WebResourceFacet] successfully.
***SUCCESS*** Installed [forge.spec.ejb] successfully.
***SUCCESS*** Installed [forge.spec.cdi] successfully.
***SUCCESS*** Installed [forge.spec.servlet] successfully.
***SUCCESS*** Installed [forge.spec.jsf.api] successfully.
***SUCCESS*** Installed [faces] successfully.
 ? Create scaffold in which sub-directory of web-root? (e.g. http://localhost:8080/provaseam/DIR) [/] 
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp
Wrote /home/albert/workspace/wk-java/provaseam/pom.xml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/WEB-INF/beans.xml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/WEB-INF/faces-config.xml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/favicon.ico
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/resources/scaffold/paginator.xhtml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/resources/scaffold/pageTemplate.xhtml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/index.html
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/index.xhtml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/error.xhtml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/resources/add.png
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/resources/bootstrap.css
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/resources/false.png
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/resources/favicon.ico
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/resources/forge-logo.png
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/resources/forge-style.css
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/resources/remove.png
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/resources/search.png
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/resources/true.png
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/resources/jboss-community.png
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/WEB-INF/web.xml
[provaseam] provaseam $

Genero les classes de l’aplicació bàsica, a partir del model. L’aplicació bàsica és del tipus CRUD (Create, Read, Update i Delete), és dir, les quatre opcions mínimes de tot manteniment de taules.

[provaseam] provaseam $ scaffold from-entity com.stsoftlliure.provaseam.model.* --overwrite
***INFO*** Using currently installed scaffold [faces]
***SUCCESS*** Generated UI for [com.stsoftlliure.provaseam.model.Autor]
***SUCCESS*** Generated UI for [com.stsoftlliure.provaseam.model.Format]
***SUCCESS*** Generated UI for [com.stsoftlliure.provaseam.model.Llibre]
***SUCCESS*** Generated UI for [com.stsoftlliure.provaseam.model.LlibreAutor]
***SUCCESS*** Generated UI for [com.stsoftlliure.provaseam.model.LlibreTematica]
***SUCCESS*** Generated UI for [com.stsoftlliure.provaseam.model.Tematica]
***SUCCESS*** Generated UI for [com.stsoftlliure.provaseam.model.Ubicacio]
Wrote /home/albert/workspace/wk-java/provaseam/src/main/java/com/example/provaseam/view/AutorBean.java
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/autor/create.xhtml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/autor/view.xhtml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/autor/search.xhtml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/resources/scaffold/pageTemplate.xhtml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/java/com/example/provaseam/view/ViewUtils.java
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/WEB-INF/classes/META-INF/forge.taglib.xml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/java/com/stsoftlliure/provaseam/model/Autor.java
Wrote /home/albert/workspace/wk-java/provaseam/src/main/java/com/example/provaseam/view/FormatBean.java
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/format/create.xhtml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/format/view.xhtml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/format/search.xhtml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/java/com/stsoftlliure/provaseam/model/Format.java
Wrote /home/albert/workspace/wk-java/provaseam/src/main/java/com/example/provaseam/view/LlibreBean.java
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/llibre/create.xhtml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/llibre/view.xhtml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/llibre/search.xhtml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/java/com/stsoftlliure/provaseam/model/Llibre.java
Wrote /home/albert/workspace/wk-java/provaseam/src/main/java/com/example/provaseam/view/LlibreAutorBean.java
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/llibreAutor/create.xhtml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/llibreAutor/view.xhtml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/llibreAutor/search.xhtml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/java/com/stsoftlliure/provaseam/model/LlibreAutor.java
Wrote /home/albert/workspace/wk-java/provaseam/src/main/java/com/example/provaseam/view/LlibreTematicaBean.java
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/llibreTematica/create.xhtml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/llibreTematica/view.xhtml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/llibreTematica/search.xhtml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/java/com/stsoftlliure/provaseam/model/LlibreTematica.java
Wrote /home/albert/workspace/wk-java/provaseam/src/main/java/com/example/provaseam/view/TematicaBean.java
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/tematica/create.xhtml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/tematica/view.xhtml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/tematica/search.xhtml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/java/com/stsoftlliure/provaseam/model/Tematica.java
Wrote /home/albert/workspace/wk-java/provaseam/src/main/java/com/example/provaseam/view/UbicacioBean.java
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/ubicacio/create.xhtml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/ubicacio/view.xhtml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/webapp/ubicacio/search.xhtml
Wrote /home/albert/workspace/wk-java/provaseam/src/main/java/com/stsoftlliure/provaseam/model/Ubicacio.java
[provaseam] provaseam $

Anem molt bé. En principi, la aplicació ja està llesta per compilar i desplegar. Però en realitat no. Si compilem i despleguem ara, obtindrem l’aplicació, però en provar a introduir valors a les taules obtindré errors. (si no us ho creieu simplement salteu-vos aquest pas i compileu i desplegueu ara). Com anuncia el link http://www.mastertheboss.com/forge/reverse-engineer-your-db-schema-using-jboss-forge alguna cosa no ha acabat d’anar a l’hora. Els errors que obtindreu si decidiu provar amb l’aplicació tal comestà deixen aquesta traça:

22:51:02,392 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/provaseam].[FacesServlet]] (http--127.0.0.1-8080-2) Servlet.service() for servlet FacesServlet threw exception: org.hibernate.TypeMismatchException: Provided id of the wrong type for class com.stsoftlliure.provaseam.model.Format. Expected: class java.lang.Integer, got class java.lang.Long

Els ID que ha generat el plugin de les hibernate-tools per a les entitats ha estat del tipus Integer; El codi al que em refereixo és aquest:

A la carpeta

src/main/java/com/stsoftlliure/provaseam/model/
    LlibreAutor.java
    LlibreTematica.java
    Tematica.java
    Autor.java
    Llibre.java
    Ubicacio.java
    Format.java

Però resulta que el codi que han generat el pas d’scaffolding (la línia “scaffold from-entity com.stsoftlliure.provaseam.model.* –overwrite”), que ha generat el següent codi java:

src/main/java/com/example/provaseam/view/
    ViewUtils.java
    AutorBean.java
    FormatBean.java
    LlibreBean.java
    LlibreAutorBean.java
    LlibreTematicaBean.java
    TematicaBean.java 
    UbicacioBean.java

Tenim que els ID que referencien els objectes són del tipus Long.

Per exemple, mirem les classes Autor i AutorBean

Autor

package com.stsoftlliure.provaseam.model;

// Generated 19/11/2012 23:16:54 by Hibernate Tools 3.4.0.CR1

import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

/**
 * Autor generated by hbm2java
 */
@Entity
@Table(name = "autor", catalog = "prova_seam")
public class Autor implements java.io.Serializable
{

   private Integer id;
   private String autor;
   private Set llibreAutors = new HashSet(0);
   private Set llibreTematicas = new HashSet(0);

   public Autor()
   {
   }

   public Autor(String autor)
   {
      this.autor = autor;
   }

   public Autor(String autor, Set llibreAutors, Set llibreTematicas)
   {
      this.autor = autor;
      this.llibreAutors = llibreAutors;
      this.llibreTematicas = llibreTematicas;
   }

   @Id
   @GeneratedValue(strategy = IDENTITY)
   @Column(name = "id", unique = true, nullable = false)
   public Integer getId()
   {
      return this.id;
   }

   public void setId(Integer id)
   {
      this.id = id;
   }

...

AutorBean

package com.example.provaseam.view;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.ejb.SessionContext;
import javax.ejb.Stateful;
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import com.stsoftlliure.provaseam.model.Autor;

/**
 * Backing bean for Autor entities.
 *
* This class provides CRUD functionality for all Autor entities. It focuses * purely on Java EE 6 standards (e.g. @ConversationScoped for * state management, PersistenceContext for persistence, * CriteriaBuilder for searches) rather than introducing a CRUD framework or * custom base class. */ @Named @Stateful @ConversationScoped public class AutorBean implements Serializable { private static final long serialVersionUID = 1L; /* * Support creating and retrieving Autor entities */ private Long id; public Long getId() { return this.id; } public void setId(Long id) { this.id = id; } ...

En principi, doncs, i atenent al missatge d’error, tenim dues possibilitats: o corregir les classes generades amb les hibernate tools (canviant integer per long), o corregir les generades amb l’scaffolding (canviant Long per Integer), ara bé, resulta que a les classes generadese amb l’scaffolding, les NomClasseBean, es fa servir l’Id del tipus Long en altres mètodes d’us intern, com el FindById. Per tant, és millor canviar les classes generades amb Hibernate-tools, on l’Id només apareix un cop.

Per tant, canvio Integer per Long a Autor. Així:


(- Ep! Un moment! havies dit que no caldria escriure ni una línia de codi!
– Bé, estrictament no estem escrivint cap línia de codi, només estic modificant-ne alguna…Sí, d’acord… és una mica lleig)

package com.stsoftlliure.provaseam.model;

// Generated 19/11/2012 23:16:54 by Hibernate Tools 3.4.0.CR1

import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

/**
 * Autor generated by hbm2java
 */
@Entity
@Table(name = "autor", catalog = "prova_seam")
public class Autor implements java.io.Serializable
{

   private Long id;
   private String autor;
   private Set llibreAutors = new HashSet(0);
   private Set llibreTematicas = new HashSet(0);

   public Autor()
   {
   }

   public Autor(String autor)
   {
      this.autor = autor;
   }

   public Autor(String autor, Set llibreAutors, Set llibreTematicas)
   {
      this.autor = autor;
      this.llibreAutors = llibreAutors;
      this.llibreTematicas = llibreTematicas;
   }

   @Id
   @GeneratedValue(strategy = IDENTITY)
   @Column(name = "id", unique = true, nullable = false)
   public Long getId()
   {
      return this.id;
   }

   public void setId(Long id)
   {
      this.id = id;
   }

...

Un cop he fet els canvis a les classes d’entitat (Autor.java, Format.java, Llibre.java, Tematica.java, Ubicacio.java, LlibreAutor.java i LlibreTematica.java), puc compilar i deployar.

Per a fer-ho, primer instal·laré al forge el plugin de control del JBoss AS 7.1:

[provaseam] provaseam $ forge install-plugin jboss-as-7
Connecting to remote repository [https://raw.github.com/forge/plugin-repository/master/repository.yaml]... connected!
***INFO*** Preparing to install plugin: jboss-as-7
***INFO*** Checking out plugin source files to [/tmp/forgetemp3143468914443124072/repo] via 'git'
***INFO*** Switching to branch/tag [refs/heads/1.0.5.Final]
***INFO*** Invoking build with underlying build system.
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building plugin-jboss-as7 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ plugin-jboss-as7 ---
[INFO] 
[INFO] --- maven-resources-plugin:2.4.3:resources (default-resources) @ plugin-jboss-as7 ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 2 resources
[INFO] 
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ plugin-jboss-as7 ---
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 23 source files to /tmp/forgetemp3143468914443124072/repo/target/classes
[INFO] 
[INFO] --- maven-resources-plugin:2.4.3:testResources (default-testResources) @ plugin-jboss-as7 ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory /tmp/forgetemp3143468914443124072/repo/src/test/resources
[INFO] 
[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ plugin-jboss-as7 ---
[INFO] Not compiling test sources
[INFO] 
[INFO] --- maven-surefire-plugin:2.7.2:test (default-test) @ plugin-jboss-as7 ---
[INFO] Tests are skipped.
[INFO] 
[INFO] --- maven-jar-plugin:2.3.1:jar (default-jar) @ plugin-jboss-as7 ---
[INFO] Building jar: /tmp/forgetemp3143468914443124072/repo/target/plugin-jboss-as7.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 10.310s
[INFO] Finished at: Sun Nov 18 16:25:25 CET 2012
[INFO] Final Memory: 47M/113M
[INFO] ------------------------------------------------------------------------
***INFO*** Installing plugin artifact.
***SUCCESS*** Installed from [https://github.com/forge/plugin-jboss-as.git] successfully.
Wrote /home/albert/.forge/httpsrawgithubcomforgepluginrepositorymasterrepositoryyaml.yaml

...

Wrote /home/albert/.forge/plugins/org/jboss/as/plugin-jboss-as7/dependencies/1.0.0-SNAPSHOT-b32f7bdd-fc1e-4d44-91ab-18119749258b/module.xml
    _____                    
   |  ___|__  _ __ __ _  ___ 
   | |_ / _ \| `__/ _` |/ _ \  \\
   |  _| (_) | | | (_| |  __/  //
   |_|  \___/|_|  \__, |\___| 
                   |___/      

JBoss Forge, version [ 1.1.2.Final ] - JBoss, by Red Hat, Inc. [ http://jboss.org/forge ]
The following plugins have been activated: [as7]
[provaseam] provaseam $

Compilo…

[provaseam] provaseam $ build
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building provaseam 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
Downloading: http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-war-plugin/2.1.1/maven-war-plugin-2.1.1.pom
Downloaded: http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-war-plugin/2.1.1/maven-war-plugin-2.1.1.pom (7 KB at 38.6 KB/sec)
Downloading: http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-war-plugin/2.1.1/maven-war-plugin-2.1.1.jar
Downloaded: http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-war-plugin/2.1.1/maven-war-plugin-2.1.1.jar (76 KB at 657.7 KB/sec)
Downloading: http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-install-plugin/2.3.1/maven-install-plugin-2.3.1.pom
Downloaded: http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-install-plugin/2.3.1/maven-install-plugin-2.3.1.pom (5 KB at 83.7 KB/sec)
Downloading: http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-install-plugin/2.3.1/maven-install-plugin-2.3.1.jar
Downloaded: http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-install-plugin/2.3.1/maven-install-plugin-2.3.1.jar (23 KB at 352.8 KB/sec)
[INFO] 
[INFO] --- maven-resources-plugin:2.4.3:resources (default-resources) @ provaseam ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 2 resources
[INFO] 
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ provaseam ---
[INFO] Compiling 15 source files to /home/albert/workspace/wk-java/provaseam/target/classes
[INFO] 
[INFO] --- maven-resources-plugin:2.4.3:testResources (default-testResources) @ provaseam ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ provaseam ---
[INFO] Not compiling test sources
[INFO] 
[INFO] --- maven-surefire-plugin:2.7.2:test (default-test) @ provaseam ---
[INFO] Tests are skipped.
[INFO] 
[INFO] --- maven-war-plugin:2.1.1:war (default-war) @ provaseam ---
Downloading: http://repo1.maven.org/maven2/org/codehaus/plexus/plexus-archiver/1.2/plexus-archiver-1.2.pom
Downloaded: http://repo1.maven.org/maven2/org/codehaus/plexus/plexus-archiver/1.2/plexus-archiver-1.2.pom (2 KB at 32.2 KB/sec)
Downloading: http://repo1.maven.org/maven2/org/codehaus/plexus/plexus-io/1.0.1/plexus-io-1.0.1.pom
Downloaded: http://repo1.maven.org/maven2/org/codehaus/plexus/plexus-io/1.0.1/plexus-io-1.0.1.pom (2 KB at 20.5 KB/sec)
Downloading: http://repo1.maven.org/maven2/com/thoughtworks/xstream/xstream/1.3.1/xstream-1.3.1.pom
Downloaded: http://repo1.maven.org/maven2/com/thoughtworks/xstream/xstream/1.3.1/xstream-1.3.1.pom (12 KB at 166.6 KB/sec)
Downloading: http://repo1.maven.org/maven2/com/thoughtworks/xstream/xstream-parent/1.3.1/xstream-parent-1.3.1.pom
Downloaded: http://repo1.maven.org/maven2/com/thoughtworks/xstream/xstream-parent/1.3.1/xstream-parent-1.3.1.pom (14 KB at 210.2 KB/sec)
Downloading: http://repo1.maven.org/maven2/xpp3/xpp3_min/1.1.4c/xpp3_min-1.1.4c.pom
Downloaded: http://repo1.maven.org/maven2/xpp3/xpp3_min/1.1.4c/xpp3_min-1.1.4c.pom (2 KB at 33.5 KB/sec)
Downloading: http://repo1.maven.org/maven2/org/apache/maven/shared/maven-filtering/1.0-beta-2/maven-filtering-1.0-beta-2.pom
Downloaded: http://repo1.maven.org/maven2/org/apache/maven/shared/maven-filtering/1.0-beta-2/maven-filtering-1.0-beta-2.pom (4 KB at 64.5 KB/sec)
Downloading: http://repo1.maven.org/maven2/org/apache/maven/shared/maven-shared-components/10/maven-shared-components-10.pom
Downloaded: http://repo1.maven.org/maven2/org/apache/maven/shared/maven-shared-components/10/maven-shared-components-10.pom (9 KB at 84.9 KB/sec)
Downloading: http://repo1.maven.org/maven2/org/apache/maven/maven-parent/9/maven-parent-9.pom
Downloaded: http://repo1.maven.org/maven2/org/apache/maven/maven-parent/9/maven-parent-9.pom (33 KB at 433.3 KB/sec)
Downloading: http://repo1.maven.org/maven2/org/codehaus/plexus/plexus-utils/1.5.6/plexus-utils-1.5.6.pom
Downloaded: http://repo1.maven.org/maven2/org/codehaus/plexus/plexus-utils/1.5.6/plexus-utils-1.5.6.pom (6 KB at 101.5 KB/sec)
Downloading: http://repo1.maven.org/maven2/org/codehaus/plexus/plexus/1.0.12/plexus-1.0.12.pom
Downloaded: http://repo1.maven.org/maven2/org/codehaus/plexus/plexus/1.0.12/plexus-1.0.12.pom (10 KB at 106.3 KB/sec)
Downloading: http://repo1.maven.org/maven2/org/codehaus/plexus/plexus-interpolation/1.6/plexus-interpolation-1.6.pom
Downloaded: http://repo1.maven.org/maven2/org/codehaus/plexus/plexus-interpolation/1.6/plexus-interpolation-1.6.pom (3 KB at 55.7 KB/sec)
Downloading: http://repo1.maven.org/maven2/org/codehaus/plexus/plexus-archiver/1.2/plexus-archiver-1.2.jar
Downloading: http://repo1.maven.org/maven2/org/codehaus/plexus/plexus-io/1.0.1/plexus-io-1.0.1.jar
Downloading: http://repo1.maven.org/maven2/com/thoughtworks/xstream/xstream/1.3.1/xstream-1.3.1.jar
Downloading: http://repo1.maven.org/maven2/xpp3/xpp3_min/1.1.4c/xpp3_min-1.1.4c.jar
Downloading: http://repo1.maven.org/maven2/org/apache/maven/shared/maven-filtering/1.0-beta-2/maven-filtering-1.0-beta-2.jar
Downloaded: http://repo1.maven.org/maven2/xpp3/xpp3_min/1.1.4c/xpp3_min-1.1.4c.jar (25 KB at 135.4 KB/sec)
Downloaded: http://repo1.maven.org/maven2/org/codehaus/plexus/plexus-io/1.0.1/plexus-io-1.0.1.jar (50 KB at 248.4 KB/sec)
Downloaded: http://repo1.maven.org/maven2/org/apache/maven/shared/maven-filtering/1.0-beta-2/maven-filtering-1.0-beta-2.jar (33 KB at 150.7 KB/sec)
Downloaded: http://repo1.maven.org/maven2/org/codehaus/plexus/plexus-archiver/1.2/plexus-archiver-1.2.jar (178 KB at 595.9 KB/sec)
Downloaded: http://repo1.maven.org/maven2/com/thoughtworks/xstream/xstream/1.3.1/xstream-1.3.1.jar (422 KB at 934.1 KB/sec)
[INFO] Packaging webapp
[INFO] Assembling webapp [provaseam] in [/home/albert/workspace/wk-java/provaseam/target/provaseam]
[INFO] Processing war project
[INFO] Copying webapp resources [/home/albert/workspace/wk-java/provaseam/src/main/webapp]
[INFO] Webapp assembled in [248 msecs]
[INFO] Building war: /home/albert/workspace/wk-java/provaseam/target/provaseam.war
[INFO] WEB-INF/web.xml already added, skipping
[INFO] 
[INFO] --- maven-install-plugin:2.3.1:install (default-install) @ provaseam ---
Downloading: http://repo1.maven.org/maven2/org/codehaus/plexus/plexus-digest/1.0/plexus-digest-1.0.pom
Downloaded: http://repo1.maven.org/maven2/org/codehaus/plexus/plexus-digest/1.0/plexus-digest-1.0.pom (2 KB at 19.5 KB/sec)
Downloading: http://repo1.maven.org/maven2/org/codehaus/plexus/plexus-components/1.1.7/plexus-components-1.1.7.pom
Downloaded: http://repo1.maven.org/maven2/org/codehaus/plexus/plexus-components/1.1.7/plexus-components-1.1.7.pom (5 KB at 71.4 KB/sec)
Downloading: http://repo1.maven.org/maven2/org/codehaus/plexus/plexus/1.0.8/plexus-1.0.8.pom
Downloaded: http://repo1.maven.org/maven2/org/codehaus/plexus/plexus/1.0.8/plexus-1.0.8.pom (8 KB at 117.7 KB/sec)
Downloading: http://repo1.maven.org/maven2/org/codehaus/plexus/plexus-container-default/1.0-alpha-8/plexus-container-default-1.0-alpha-8.pom
Downloaded: http://repo1.maven.org/maven2/org/codehaus/plexus/plexus-container-default/1.0-alpha-8/plexus-container-default-1.0-alpha-8.pom (8 KB at 150.9 KB/sec)
Downloading: http://repo1.maven.org/maven2/org/codehaus/plexus/plexus-digest/1.0/plexus-digest-1.0.jar
Downloaded: http://repo1.maven.org/maven2/org/codehaus/plexus/plexus-digest/1.0/plexus-digest-1.0.jar (12 KB at 160.8 KB/sec)
[INFO] Installing /home/albert/workspace/wk-java/provaseam/target/provaseam.war to /home/albert/.m2/repository/com/example/provaseam/provaseam/1.0.0-SNAPSHOT/provaseam-1.0.0-SNAPSHOT.war
[INFO] Installing /home/albert/workspace/wk-java/provaseam/pom.xml to /home/albert/.m2/repository/com/example/provaseam/provaseam/1.0.0-SNAPSHOT/provaseam-1.0.0-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 10.090s
[INFO] Finished at: Sun Nov 18 16:28:22 CET 2012
[INFO] Final Memory: 65M/155M
[INFO] ------------------------------------------------------------------------
[provaseam] provaseam $

Configuro el plugin per a fer-lo servir amb el meu JBoss local

[provaseam] provaseam $ as7 setup
 ? The Java Home '/home/albert/jdk1.6.0_30' is already set, would you like to override it? [y/N] 
 ? A default version of 7.1.1.Final is already set, would you like to override it? [y/N] 
 ? Enter path for JBoss AS or leave blank to download: /home/albert/jboss-as-7.1.1.Final
***SUCCESS*** Installed [AS7ServerFacet] successfully.
[provaseam] provaseam $

i, finalment, faig el deploy:

[provaseam] provaseam $ as7 deploy
The deployment operation (FORCE_DEPLOY) was successful.
[provaseam] provaseam $

I ja només em queda provar l’aplicació que acabo de deplegar. Per això apunto el navegador a http://localhost:8080/provaseam i, efectivament obtinc una senzilla aplicació de biblioteca. Basada en un manteniment de taules. Com he dit abans, el resultat és força espectacular. L’esforç ha estat en definir i crear correctament les taules, els índexos i les relacions entre les taules (i arreglar alguns petits desajustos que Seam Forge ha deixat).

A la consola d’administració del JBoss podem veure els desplegaments realitzats:

Vet aquí la pantalla inicial de l’aplicació:

Per cert, com a extra, des de la pantalla inicial es pot enviar un tuit (feu click al link Get Excited!) per anunciar al món que ja hem fet la nostra primera aplicació amb Seam 3 i Forge! No m’hi estic pas!

Les relacions entre taules es resolen amb camps desplegables. Entro alguns formats i ubicacions i creo un llibre:

format:

ubicacio:

vaig a crear un llibre:

El llibre creat:

Cal reconèixer que és força lletja la representació dels formats i les ubicacions. Caldria corregir les visualitzacions. En tot cas, podem seguir l’enllaç, per exemple, de les ubicacions per obtenir tots els llibres que estan al prestatge de l’estudi:

En resum, una generació força automatitzada d’una aplicació de manteniment de taules (un CRUD) feta amb l’eina Seam Forge, amb la versió de Framework Seam 3.1. desplegada sobre un JBoss 7.1.

Val a dir que després de provar això mateix amb el seam-gen del framework Seam 2.3.0 un es queda una mica decebut. Fa l’efecte com si s’hagués anat enrere. En realitat, sembla que la qüestió és que s’ha iniciat un camí nou amb el Forge. Encara més, a la mateixa definició de Seam3 que fan a la web www.seamframeworkorg/seam3 han fet desaparèixer la paraula framework per parlar de conjunt de mòduls i eines: “Seam3 is a collection of modules and developer tooling tailored for Java EE 6 application development, with CDI as the central piece.”i encara una mica després, referint-se a Forge el defineixen com “JBoss Forge is an incremental project enhancement API and shell.” De fet, la forma de treballar amb Forge té més a veure amb definir des del forge les entitats i les accions, que no pas fer una enginyeria inversa d’un model existent. O sigui que hem fet servir el Forge no de la forma com “estava prevista” (en canvio seam-gen de Seam2, sí que estava més pensat per a això).

La definició anterior de Seam, a més, feia aparèixer la sigla màgica CDI. CDI, Context and Dependency Injection. CDI i Java EE 6 (HTML | PDF). No és ara el moment per parlar-ne. Però caldrà fer-ho.

Al proper post faré de nou l’aplicació de Biblioteca amb el Seam 2 i el seam-gem. Tot i que es tracta de la versió anterior manté tot l’interès ja que, en cap cas, es pot considerar que Seam 2 sigui obsolet. De fet, com he comentat abans, per una qüestió de compatibilitat amb versions de JDK i Java EE podem ben bé trobar-nos amb que no es pugui fer servir la versió Seam 3, que demana últimes versions.

Smart City Expo World Congress 2012. Barcelona, del 13 al 15 de novembre.

Aquesta propera setmana, del 13 al 15 de novembre es celebrarà a Barcelona la Fira Smart City Expo World Congress.

Que a Barcelona es celebrin fires no és cap novetat. El que sí que pot sonar novedós, tot i que ja fa temps que se’n parla, és el concepte d’Smart City.

Què és una smart ciy? la smart city és la ciutat intel·ligent. La ciutat que aplica les tecnologies TIC per captar informació diversa amb els sensors adequats per prendre el pols a les constants vitals de la ciutat, i processar-ne aquesta informació amb l’objectiu de fer que la ciutat sigui  més eficient, més neta, més democràtica i, en definitiva, més habitable i respectuosa amb el medi ambient.

Podem  posar matisos a la definició anterior: per exemple, la pàgina http://smartcity-telefonica.com/ pren el subtítol “un primer paso hacia la Internet de las cosas”. És dir, la  Internet of Things, o  IoT, mireu http://www.iot-i.eu/public/front-page .

També podem consultar la web del projecte http://smartbarcelona.cat/ que compta amb el suport de la Unió Europa i de la Generalitat de Catalunya i que pretén “definir, dissenyar i desenvolupar un model de referència d’una plataforma de gestió de xarxa i dades sensorials per a Smart Cities, i finalment validar-lo en una ciutat important com és Barcelona, amb l’objectiu final que aquest model pugui ser adoptat per qualsevol altra ciutat arreu del món”. Val a dir, però,  que la web en qüestió em sembla excessivament estàtica i sembla abandonada (no hi ha cap notícia  en cap dels tres idiomes!).

De nou, podem consultar una altre web relacionada amb Telefónica: http://sociedadinformacion.fundacion.telefonica.com.En  aquesta web trobem l’article ¿Qué son las ‘Smart Cities’ o Ciudades Inteligentes? per José Manuel Hernández Muñoz de Telefónica I+D, que planteja de forma força entenedora què és una smart city, quins projectes hi han rel·lacionats , o quins avatanges aporta al ciutadà.

El matís ecològic és important i es parla també de les smart green cities. Aquesta passada setmana es va celebrara  Tarragona el I Congrés d’Eficiència Energètica i Smart Green Cities celebrat durant dos dies al Palau Firal. El congrés va comptar amb la participació de Jeremy Rifkin, autor  de “La era del acceso”, “El fin del trabajo” o “La economía del Hidrógeno”, entre d’altres, i assessor d’Al Gore i Bill Clinton. Amb aquest congrés es pretén llançar el projecte de convertir Tarragona en la smart green city de referència al Mediterrani i es vincula aquest projecte amb els Jocs del mediterrani que es celebraran a la ciutat el 2017. Estic buscant per alguna banda la “Declaració de Tarragona” que es va llegir al congrés per enllaçar-la aquí, però de moment, no l’he sabut trobar, o no està disponible per al públic.

El projecte Tarragoní ens recorda l’existència de projectes similars, per exemple http://www.smartcities.info/aim que involucra  ciutats de diversos països de la regió del mar del nord.

Finalment, les Smart Cities són objecte d’anàlisi i reflexió arreu del món. Podeu consultar les següents adreces

Universitat d’Stanford:  http://sprie.gsb.stanford.edu/research/smart_green_cities

Massachussets Institute of Technology – MIT: MIT Cities, http://cities.media.mit.edu/

Smart cities, doncs. Les TIC aplicades a fer ciutats més netes, eficients i, esperem, democràtiques. Una oportunitat de negoci? segurament sí. Però encara més important, una gran oportunitat per començar a canviar models.

Recordem: aquesta propera setmana, del 13 al 15 de novembre es celebrarà a Barcelona la Fira Smart City Expo World Congress. Feu un cop d’ull al programa. El preu de les acreditacions varia des dels 30€, passe de visitant d’un sol dia només per a l’exposició, fins al passe de tres dies, amb accés a totes les conferències i esdeveniments, per 700€.

En tot cas, sempre podrem esperar a que els diferents expositors i conferenciants publiquin els vídeos i presentacions de la seva participació. Com aquests vídeos corresponents a l’exposició de l’any passat

http://www.casadomo.com/

http://www.domonetio.com/

http://www.esmartcity.es/

LinuxCon Europe 2012. Del 5 al 9 de novembre a l’Hotel Fira Palace de Barcelona.

Durant la setmana del 5 al 9 de novembre es celebrarà a Barcelona, a l’hotel Fira Palace del carrer Lleida, la LinuxCon Europe 2012.

Per a més informació, podeu vistar la pàgina oficial de la LinuxCon.

La LinuxCon és una conferència en la que acostumen a participar alguns noms importants o populars del món Linux. Per exemple, en aquesta ocasió es comptarà amb Mark Shuttleworth, el fundador de Canonical, l’empresa que impulsa les distribucions Ubuntu. Però no només amb ell. També hi seran altres actors importants, com Red Hat, SuSE, Intel, o EverNote. A la conferència es presentaran els plans dels diferents actors pel que fa al futur de Linux.

Principals oradors:

Dave Engberg Dave Engberg
Evernote
Ralf Flaxa Ralf Flaxa
SUSE
Catarina Mota Catarina Mota
Open Materials
Marten Mickos Marten Mickos
Eucalyptus
Mark Shuttleworth Mark Shuttleworth
Canonical
Imad Sousou Imad Sousou
Intel
Brian Stevens Brian Stevens
Red Hat

De la pàgina oficial:

“LinuxCon Europe 2012

November 5 – 9, 2012 · Hotel Fira Palace · Barcelona, Spain

LinuxCon Europe will bring together the best and brightest that the Linux community has to offer, including community developers, system administrators, business executives and operations experts. LinuxCon Europe will deliver attendees top notch speaking talent (from across Europe and around the globe), innovative and abundant program content, and a wide variety of opportunities to connect with peers.

Who Should Attend:
Software Developers, Linux IT Professionals, Corporate End Users, Senior Business Executives, IT Operations Experts, System Administrators, Students, Media and anyone else with an interest in the Linux ecosystem.
Schedule of Events:

Monday, November 5th
LinuxCon Europe, ELCE, EFL Developer Day, Cloud Summit

Tuesday, November 6th
LinuxCon Europe, ELCE, Cloud Summit

Wednesday, November 7th
LinuxCon Europe, ELCE, Cloud Summit, KVM Forum, oVirt Workshop

Thursday, November 8th
Gluster Workshop, Yocto Developer Day, KVM Forum, oVirt Workshop, OpenSAF Symposium

Friday, November 9th
KVM Forum, oVirt Workshop, Wireless Summit”