Avoid XML Schema restrictions

I am back on XML Schema design and I do really like it !

One of the challenge that I am facing now is including or not the UBL metalanguage in my schemas (see some video on the oasis website), an Oasis standard, as you can deduce.

As you can see from this file:

http://docs.oasis-open.org/ubl/os-UBL-2.1/xsd/common/UBL-UnqualifiedDataTypes-2.1.xsd

UBL metalanguage has elements which are based on the UN/CEFACT elements, see:

http://docs.oasis-open.org/ubl/os-UBL-2.1/xsd/common/CCTS_CCT_SchemaModule-2.1.xsd

So as you can see UN/CEFACT has ComplexType which are extended by adding optional attributes, while the UBL elements are sometime restrictions  on the attributes (by making them required) and sometimes the elements are just extended giving a freedom in a later moment to choose what to add.

Independently from  the current problem, it happens that we might not need all the attributes or simply all the elements for our schema.

So either we add restrictions or we copy the elements that we need in our schema but simplified.

Adding restrictions can be possible in two ways:

1) Restrict on the patterns, like the max length of an element, they are so called facets, see: http://www.w3.org/TR/xmlschema-0/#SimpleTypeFacets

2) Restrict on the number of elements or attributes, in the case of the attributes  we need to make them prohibited

Conceptually both are restrictions based on an another type and this creates a problem in Object Oriented languages, like Java (hence the tittle of this post) which supports extensions (at the end a restriction is a sort of extension of a base object with some changes).

Jaxb is the official standard used for databinding XML elements to Java objects which relies on XJC for the conversion. Such standard adds Java annotations to associate XML elements to Java objects. Further, Jaxb relies on the validator of the marshaller by using the setSchema() method, see for example the post of Blaise Doughan, so in any moment you can validated your object against the schema to be sure before sending out your xml message.

For the facets, Jaxb doesn’t create annotations, there is still an open issue where 2 subgroups are working to solve it but still none of them are officially approved:

Other data bindings work on simple restrictions like enumerations (see Jibx) or numeric type and enumerations (see Xmlbeans, now archived).

You need also to consider that facets can change in the future (the max length could be extended from 100 characters to 200), so which impact has changing the xml schema? Since Jaxb doesn’t generate annotations for facets you don’t need to change the java objects but other databindings might be.

For the restriction on the the number of elements/attributes this CANNOT be reflected in a Object Oriented language because it is not possible to restrict an extended class on inherited properties. Therefore I suggest to copy simplified elements (by keep only those mandatory and removing the optionals), in this way:

  1. you have less dependency
  2. the developer has less method generated (just those needed)
  3. you keep compatibility at the minimum if you want to convert the copied object into the original objects

Therefore I would recommend to avoid restrictions if possible, you can keep them for the sake of validation but you need to think about the impact on the objects generated with the databinding libraries. Such recommandation is also expressed by the HP XML schema best practices (search for “restrictions for complex types”) and in Microsoft xml schema design pattern.

 

 

 

Webclient for SVN, Hudson e Artifactory

Salve a tutti, in questi giorni mi sono addentrato ancora nel mondo del continuous integration perchè sto lavorando su un progetto in Java, gestito in outsourcing, dove aiuto un gruppo di sviluppatori ad utilizzare strumenti di sviluppo che facilitano il lavoro quali un sistema di continuos integration.

Sono partito da un progetto con subversion installato su una macchina e so che nel progetto usano Jboss con JDK 1.5 (ancora non so perchè)

Su un’altra macchina remota vado e installo JDK 1.5.0.22, Ant 1.7.1, Maven 2.2.1 (fino ad ora (2 mesi di progetto) hanno usato solo Ant e vorrebbero passare a Maven), Jboss 5.1.0, Webclient for SVN 3.1.0 e Artifactory 2.1.2.

Piccola nota: volevo usare Sventon ma l’ultima versione aveva problemi con le librerie e le precedenti mi davano anch’esse problemi.

Non sapete cosa è Artifactory ??? Allora è possibile che siete ancora freschi su Maven (non è che io non lo sia :-) )

Artifactory è una applicazione web che permette di gestire repository Maven, sviluppata in Java e rilasciata con licenza LGPL 3.0. L’applicazione è realizzata da JFrog Ltd, una società privata isreliana.

Strutturalmente si poggia su Apache Jackrabbit per l’implemetazione delle specifiche JSR 170 per il cosiddetto Java Content Repository (anche altri content manager come Nuxeo si appoggiano su Jackrabbit).

Piccola nota: la JSR 170 (rilasciata nel 2005) è seguita dalla JSR 283 da poco rilasciata (25 Settempre 2009) ed entrambe sono condotte da David Nuescheler, CTO della società svizzera Day Software.

Inoltre Artifactory si basa su Apache Lucene per indicizzare i file e Apache Wicket per l’interfaccia utente.

Ora l’applicazione è rilasciata come standalone ma esiste la versione war che può essere deployata su un application server e quindi l’ho messa su Jboss insieme ad Hudson e Webclient for SVN (questi 2 li ho poi legati con il plugin di hudson per Polarion che permette di linkare la lista di file modificati ai file presenti sul webclient e si possono anche vedere le differenze con le versioni precedenti).

La struttura è basata anche su database, di default Apache Derby ma che può essere cambiato (vedi anche qui).

A parte il fatto che Artifactory permette di base una autenticazione LDAP, quello che lascia senza parole è la semplicità di uso (andrebbe confrontato con Nexus ma non ne ho tempo, di sicuro nella versione base manca LDAP (anche se ho scoperto di recente che esiste un plugin di terze parti) e di sicuro gli sviluppatori hanno realizzato una bella guida a maven e un plugin per Eclipse). Una volta andato su

http://localhost:8080/artifactory

e loggato, sono andato sul pannello amministrativo e nella sezione repository ho creato un repository locale dove fare il deploy dei propri jar file e un repository virtuale in cui aggiungo quello locale più tutti i remoti quali quello di Maven, Jboss ecc ecc. Fatto ! Ora potete generare anche la sezione del file settings.xml da aggiungere nel vostro progetto Maven.

Per una vecchia guida vi rimando qui. Per un confronto con Nexus e Archiva vi rimando a questo link (attenzione è scritto dallo stesso autore della guida su Artifactory ma sembra serio)

Buon maven a tutti !

Nota: Webclient for SVN si basa su Subversion 1.4 (con versioni successive ho avuto problemi perchè usa un SVNKit vecchio che non posso aggiornare perchè c’è una particolare classe non più presente nelle ultime versioni), potete trovare Subversion 1.4 qui:

http://downloads-guests.open.collab.net/servlets/ProjectDocumentList?folderID=6

Gestione fatture con Invoicex

Invoicex è un programma multipiattaforma grazie al fatto che è realizzato in Java quindi si puo’ installare per Win, Linux e Mac.

Invoicex è rilasciato con licenza GPL 2 dalla società TNX la quale, in collaborazione con Bios Informatica, ha realizzato ClientManager un software, non libero, per la gestione di interventi tecnici che si puo’ integrare con Invoicex.

Invoicex, tra l’altro, usa MySQL come database, infatti all’avvio dell’installazione, vi viene chiesto se volete usare il suo database interno o dargli un database remoto (che puo’ risiedere sul vostro pc), se non esiste il database verrà creato con una 50 di tabelle, io ho usato MySQL avviandolo da Xampp e ho lasciato creare il database.

Finita la fase di creazione del database vi vengono chiesti i dati dell’azienda: ragione sociale, partita iva, codice fiscale e recapito. I dati vengono salvati nella tabella dati_azienda del database.

Vi viene chiesto tra l’altro se volete che questi dati siano trasmessi a TNX per uso statistico, potete dire di no ovviamente.

Finito il tutto potete, tramite una interfaccia semplice e pulita (solo un menu e una barra orizzontale), gestire preventivi/ordini, ddt, fatture, clienti/fornitori e loro situazione, articoli, fatture acquisto.

La versione attuale del programma (1.7.7 del 28/01/2009) ha poi 5 plugin che, se abiltati sono gratuiti per 30 giorni, dopo di che devono essere acquistati, i plugin in questione sono:

  • Backup/Restore su server remoto TNX
  • Integrazione con Client Manager
  • Aggiornamento automatico del programma
  • Gestione ritenuta d’acconto
  • Ricerca globale

I report di preventivi/ordini, ddt, fatture, clienti/fornitori vengono di solito stampati/salvati in PDF, in particolare ho notato che quanto si stampano i preventivi/ordini viene usato JasperViewer mentre quando si stampa l’elenco degli articoli questo puo’ esser salvato in PDF, HTML e Excel.

JasperViewer viene usato anche quando si genera il report su Ordini/Bolle/Fatture dal menu Statistiche.

E’ possibile infine chiedere assistenza, a pagamento, annuale o per ticket.

Cliccando sul menu Aiuto -> Informazioni si scopre che il programma si basa sulle seguenti librerie:

Buona fatturazione !

Note su Hudson e CruiseControl

In uno dei recenti progetti sto valutando con un mio collega la possibilità di fornire come servizio l’uso di uno strumento di Continuous Integration.

Attualmente stiamo hostando diversi progetti Java (30), PHP (10), Python (6) e Javascript(6), C++ (4) più altri minimi progetti; di conseguenza ho cominciato a valutare strumenti Java tra cui Hudson, CruiseControl e Apache Continuum per poi vedere quale è il più indicato per progetti in PHP e Python.

Nota: Avevo già provato Apache Continuum ma non mi aveva dato una grande impressione.

Guardando sul sito JavaPowerTools , Wakkaleo, SOA World Magazine, Eclipse Community Survey 2009 e partecipando al Devoxx si nota come Hudson e CruiseControl sono i preferiti.

Se diamo uno sguardo a strumenti di continuous integration per PHP ritroviamo in pratica Xinc e PHPUnderControl, quest’ultimo si basa su CruiseControl e include strumenti come PHPUnit, PhpDocumentor e PHP_CodeSniffer.

Se quindi consideriamo CruiseControl + PHPUnderControl si copre una grossa percentuale di progetti. CruiseControl e Hudson hanno comunque il supporto a Phing per progetti in PHP ma PHPUnderControl è alettante.

Vediamo quali strumenti esistono per Python:

Development in Python

Link

Buildbot, a python continuous integration tool http://buildbot.net/trac
It explains how to integrate Hudson and Python (but an internal link explains the same thing with CruiseControl with PyUnit). For Hudson there is a plugin that uses Pylint http://redsolo.blogspot.com/2007/11/hudson-embraces-python.html
Python Ant task (Pydoc generation) http://www.rpstechnologies.net/PyAntTasks.html

http://www.ibm.com/developerworks/opensource/library/os-ecant/

Python Doxygen integration http://internetducttape.com/2007/03/20/automatic_documentation_python_doxygen/
Pylint (errors in python code – command line) http://www.logilab.org/857

It claims to be more advanced of PyChecker, also Netbeans Python Early Access seems to use it, see:

http://www.netbeans.org/kb/docs/python/temperature-converter.html#08

Also PyDev (Eclipse plugin) has a support for PyLint, see

http://pydev.sourceforge.net/pylint.html

Eric Python IDE has a plugin for Pylint, see:

http://eric-ide.python-projects.org/index.html

PyChecker (error in python code – command line) http://pychecker.sourceforge.net/

Used by Stani Python Editor, see:

http://pythonide.blogspot.com/

PyFlakes (error in python code – command line) http://divmod.org/trac/wiki/DivmodPyflakes
Figleaf (code coverage – command line) http://darcs.idyll.org/~t/projects/figleaf/doc
General notes http://www.doughellmann.com/articles/CompletelyDifferent-2008-03-linters/index.html

Sfortunatamente vediamo che esiste in pratica solo Buildbot che non puo’ essere integrato con CruiseControl o Hudson ma esiste un plugin, più per Hudson che per CruiseControl, che aiuta ad integrare Python con gli altri tools.

Dall’altro lato abbiamo un Python Ant Task e qualche strumento a linea di comando che possono essere usati con Ant e quindi una facile integrazione con CruiseControl e Hudson.

Riguardo Javascript al momento l’unico Javascript unit test che sembra integrabile con Ant per eseguire unit test è JsUnit.

Riguardo a C++ notiamo che in Hudson ci sono 2 plugin (CCCC e CppUnit) mentre su CruiseControl sembra che non ci sia niente (solo questo link). Tuttavia ho trovato un Ant task per C++ che permette di scegliere tra diversi compilatori.

Per quanto riguarda i generatori di documentazione ritroviamo:

Document generator

Link

Javadoc

http://java.sun.com/j2se/javadoc/

Doxygen

http://www.stack.nl/~dimitri/doxygen/

PhpDocumentor

http://www.phpdoc.org/

Pydoc

http://docs.python.org/library/pydo

JsDoc Toolkit

http://code.google.com/p/jsdoc-toolkit-ant-task

Per C++ di solito viene usato Doxygen. Per Javascript potete notare JsDoc Toolkit per cui esiste il rispettivo Ant task.

Sarebbe bene anche includere software che fanno analisi statica del codice per fare debug del codice tra questi ritroviamo dal sito JavaPowerTools:

Java Analyzer Code Style

Vote – Number of votes

Checkstyle

3,37/5 – 90

PMD

3,63/5 – 84

Findbugs

3,69/5 – 83

Dobbiamo dire che Doxygen e questi strumenti (più Cobertura) sono integrati come plugin su Hudson tuttavia essi sono disponibili come Ant task e quindi integrabili con CruiseControl:

Plugins

Link

Checkstyle

http://checkstyle.sourceforge.net/anttask.html

Findbugs

http://findbugs.sourceforge.net/manual/anttask.html

Cobertura

http://cobertura.sourceforge.net/anttaskreference.html

PMD

http://pmd.sourceforge.net/ant-task.html

Doxygen

http://ant-doxygen.blogspot.com/

Per C++ ho notato che esiste Cppcheck to do static code analysis. Qui ho trovato come usarlo, in pratica è un eseguibile (esiste exe e deb)  che si puo’ facilmente integrare.

Per Javascript ho notato che esiste Yasca strumento a linea di comando che si integra con diversi strumenti visti prima (tra questi Javascript Lint e CppCheck) e genera diversi report.

Ultime note:

  • abbiamo notato che Gforge AS (quindi non la nostra versione community), ha un plugin per CruiseControl.
  • Gforge ha poi un sistema di gestione delle richieste di supporto (ticket) non tanto carino e sarebbe possible rimpiazzarlo con Trac che ha tra i suoi plugin proprio il supporto per CruiseControl e Hudson.
  • Abbiamo notato che Jboss e Linkedin fanno uso di Hudson (stiamo parlando di soli progetti Java).
  • Quelli di Apache usano sia Hudson che Continuum :-)
  • Stefane Fermigier, CEO di Nuxeo, afferma di usare Hudson e Glassfish come application server.
  • Installando Hudson per prova si vede subito la possibilità di usarlo su più nodi per scalabilità o semplicemente perchè alcuni progetti richiedono sistemi operativi diversi mentre sembra per CruiseControl non esiste una perfetta integrazione. Entrambi comunque propongono JNLP come connessione.
  • Occorre considerare l’integrazione con LDAP. Per Hudson un post interessante è qui.
  • Trovata una tabella comparativa.
  • Trovato un documento comparativo pubblicato il 2 gennaio 2009

Ora credo ci sia da scegliere anche perchè ho notato in rete che la gente lamenta il fatto che CruiseControl vada opportunatamente configurato tramite file XML mentre Hudson tramire interfaccia grafica e gli sviluppatori migrano nel tempo a Hudson.

//

XML, Java e dintorni

Nel mio ultimo progetto ho lavorato molto con l’XML per via dei web services e dei relativi data-binding. Più che altro sono stato incuriosito da questo libro e cosi’ ho cominciato a spulciare in rete se ne vale l’acquisto, partendo dalle origini delle librerie JAVA per XML perchè dovete sapere che al di là di uno standard ci sono le sue implementazioni….

Per chi non lo sapesse in pratica esistono 2 famosi parser XML chiamati DOM (giunto alla versione 3 nell’Aprile 2004) e SAX (giunto alla versione 2.0.2 nello stesso mese), a cui si è aggiunto nel tempo STAX cercando di prendere i vantaggi da entrambi.

Per cercare di omogeneizzare l’XML estrapolato da DOM, SAX e STAX, quelli di SUN (principalmente Jeff Suttor, Norman Walsh) realizzano una serie di interfacce e classi  sotto il nome di JAXP 1.3, sorgente che viene donato nell’aprile 2005 (Neeraj Bajaj compare tra i nomi della documentazione java) a quelli di Apache.

Vediamo poi che JAXP 1.3 finisce il suo corso nel Febbraio 2008 a cui segue JAXP 1.4  per essere incluso in JAVA SE 6. Tuttavia JAXP 1.3 è ancora un punto di riferimento.

Affianco ai parser troviamo l’XSL che include:

  • XSLT per trasformare un documento XML in un altro che sia anche HTML o WML, ha bisogno di un processore XSLT che sappia interpretare il foglio di stile XSLT.
  • XPath che è un linguaggio usato da XSLT per accedere a parti di un documento XML
  • XSL-FO usato per formattare documenti XML la cui implementazione è realizzata dalle librerie Apache FOP ( il cui sito è davvero interessante) principalmente pensato per convertire il documento in PDF ma non solo.

Tornando alle librerie Java abbiamo:

  • Xalan 2.7.1 che è un XSLT processor il quale si basa su JAXP 1.3, XSLT 1.0 e XPATH 1.0
  • Xerces 1.4.4 che è un parser java basato su XML 1.0, DOM 1/2 e SAx 1/2

Tornando indietro nel tempo, il 23 gennaio 2007 al W3C i vari working group rilasciano diverse specifiche che coinvolgono XQuery 1.0, XPath 2.0 e XSLT 2.0. Nei working group vediamo principalmente IBM, SUN (ritroviamo Norman Walsh coinvolto) e Oracle.

XQuery nasce come linguaggio per fare query su database in XML, il linguaggio è, diciamo, più naturale del XSLT.

L’unico editor dell’ XSLT 2.0 è Michael Kay, il quale prima lavorava per Software AG e poi si mette in proprio per fondare Saxonica da cui Saxon l’XSLT processor.

Saxon è quindi l’unico ad implementare XSLT 2.0 (ci dovrebbe essere uno di Oracle) che rispetta le specifiche …del suo stesso autore :-) . Saxon, viene rilasciato nella versione Saxon-B come open source mentre la versione Saxon-SA rilasciato con licenza commerciale; solo che la versione open souce è veramente limitata.

Di conseguenza non credo per ora di prendere il libro anche se puo’ essere uno stimolo per studiare XSLT 1.0 almeno.

Note:

Web Services: stili, overloading e databinding

Nei precedenti post avevo già segnalato il fatto che per mantenere l’interoperabilità dei web services, partendo da un file wsdl, occorre rispettare il cosiddetto Basic Profile 1.1. Il Basic Profile non fa altro che far applicare delle restrizioni sulla scrittura del file wsdl in modo tale da garantire una certa interoperabilità.

L’interoperabilità non significa che tutto puo’ funzionare come vogliamo noi e difatti uno dei problemi di cui vi sto accennando nell’articolo è il problema dell’overloading dei metodi.

Occorre dire che ci sono principalmente 2 modi per descrivere un file wsdl compatibile con il Basic Profile e questi sono RPC/literal e Document/literal (per maggiori dettagli vedere il seguente articolo). Fatto sta che tra le 2 quella più usata è Document/literal in versione “wrapped”.

Questa versione è usata in pratica da .NET di default mentre la versione RPC no, tra l’altro Microsoft fa parte del consorzio WS-I, di consequenza scegliere per scegliere uno stile conviene adottare questo in modo da essere interoperabili con .NET (non me ne vogliano i puristi ma io lavoro con web services in java e questi devono comunicare in web services in .NET).

Secondo l’articolo che vi ho linkato un esempio di file wsdl in stile Document/literal wrapped è il seguente:

<types>
    <schema>
        <element name="myMethod">
            <complexType>
                <sequence>
                    <element name="x" type="xsd:int"/>
                    <element name="y" type="xsd:float"/>
                </sequence>
            </complexType>
        </element>
        <element name="myMethodResponse">
            <complexType/>
        </element>
    </schema>
</types>
<message name="myMethodRequest">
    <part name="parameters" element="myMethod"/>
</message>
<message name="empty">
    <part name="parameters" element="myMethodResponse"/>
</message>

<portType name="PT">
    <operation name="myMethod">
        <input message="myMethodRequest"/>
        <output message="empty"/>
    </operation>
</portType>

Come vedete la sezione message contiene solo una “part” per input/output. La parte che contiene l’input ha l’elemento myMethod, nome che deve essere uguale al nome dell’operazione. L’elemento myMethod è quindi un tipo complesso definito da una sequenza di elementi.

Uno dei problemi messi in evidenza è l’impossibilità di fare overloading dei metodi perchè se il metodo myMethod  con i 2 parametri corrisponde all’elemento myMethod non è possibile aggiungere in xml un secondo elemento dal nome myMethod con un solo parametro per via dell’XML stesso.

Tuttavia il problema diciamo non si pone poichè solo con file WSDL 1.1 è possibile l’overloading mentre con file WSDL 2.0 no anche se l’adozione di quest’ultimo non trova piena applicazione.

A riguardo l’uso dello stile wrapped vi suggerisco un articolo tratto dal blog di  Anne Thomas Annes, esperta in web services, che ha collaborato con WS-I ed una interessante spiegazione in questa mailling list (vedere ore 13:43)

Il tutto ovviamente si ricollega al databinding perchè, stile a parte,  occorre scegliere il databinding, e il fatto che ADB e Jibx supportano lo stile unwrapped e wrapped mentre Xmlbeans solo wrapped  (vedi articolo) viene meno se scegliamo lo stile wrapped.

Personalmente uso Xmlbeans per una serie di metodi utili forniti dall’interfaccia che ogni oggetto xml implementa. Per alcuni dettagli sulla storia e struttura di xmlbeans suggerisco questo articolo (oltre che il sito ufficiale) di David Bau uno dei creatori di Xmlbeans.

Nota a parte: ADB e Xmlbeans sono databinding della Apache foundation. Xmlbeans in particolare è stato donato da Bea System (nel settembre 2003), una delle società fondatrici della WS-I, da sempre coinvolta nel campo dei web services con il suo Esb, e di recente (aprile 2008) comprata da Oracle altra società fondatrice e leadership della WS-I.

Non penso di rompervi più con il Basic Profile :-)

JavaDay Roma Gennaio 2009

Sabato 24 Gennaio a Roma ci sarà il terzo convegno attorno al mondo java!!!

A partecipazione gratuita il convegno si prolunga per tutta la giornata e si distende in ben 5 sessioni parallele che vanno dal web 2.0 al mobile fino a spring quindi non c’è che da scegliere i talk che ritenete interessanti.

Il JavaDay è organizzato dal Jug di Roma in collaborazione con altri partner tra cui Java Italian Portal e vede anche sponsor del calibro di Red Hat, Sun, Spring e Accenture.

Durante il convegno c’è anche una pausa per consegnare i vostri curriculum.

Per ogni info: http://roma.javaday.it/roma/javaday2009-roma.htm

Osservazioni su esb, web service framework e application server

Attualmente sono coinvolto in un progetto dove si lavora con web services e bpel. Nel tempo ho scoperto che la proliferazione di software open source benchè sia una ottima cosa deve fare i conti con gli standard che sono quelli a cui bisogna attenersi se si vuole cercare di raggiungere una certà interoperabilità.

In un precedente articolo avevo già accennato ai problemi di interoperabilità per quanto riguarda i file wsdl e che il consorzio WS-I propone degli strumenti per ridurre i rischi di interoperabilità. La leadership di WS-I è guidata da Michael Bechauf vicepresidente di SAP AG e partecipante alla board di Eclipse. Tra le altre compagnie figurano Microsoft, Fujitsu, HP, Sun, IBM, Intel, Oracle.

Ma i web services si appoggiano ai Web services framework e normalmente sono instradati da Esb e poi avrete bisogno di application server. Quali scegliere ? La risposta a questa domanda fa perdere molto tempo ed una guida è di sicuro è capire quali standard esistono e quali sono i software che si attengono.

Nel campo java questi standard si ottengono dalle implementazioni delle JSR. Per quanto riguarda i web service framework la JSR più importante è la JSR 224 che descrive JAX-WS un modo per realizzare data binding tra file wsdl e le classi java che realizzano i servizi.

JAX-WS è adottato da Apache CXF e Metro di Sun. Axis2 ha il supporto ma è venuto dopo nel tempo.

Nel campo degli esb le JSR importanti sono JSR 208 e JSR 312 che esprimono il concetto di JBI. JBI è uno standard imposto poichè in un bus possono essere attaccati diversi software che usano ad esempio JMS, eventi BPEL ecc. In questo ambito ritroviamo praticamente Apache ServiceMix e OpenESB di Sun. In pratica si appoggiano alla JSR 208 inseguendo la 312 che apporta le migliorie allo standard JBI.

Apache Synapse per quello che ho capito sta stringendo una collaborazione con quelli di ServiceMix per essere aiutati a raggiungere lo standard JBI.

Nel panorama degli application server si nota che ServiceMix ha un ottima integrazione con Apache Geronimo (completamente aderente a Java EE 5) mentre OpenESb e Metro si integrano facilmente con Glassfish che ovviamente Sun publicizza.

Tomcat è un semplice servlet container che si presta anche ed ha il vantaggio che rispetto agli altri, per la sua semplicità, risulta più veloce. Spesse volte quelli di Netbeans spiegano come usare Tomcat alternativamente a Glassfish.

Merita un discorso a parte JBoss. Per quelli di Jboss il loro stack è rappresentato da Jboss Native, Metro e CXF quindi una combinazione dei precedenti. Tuttavia loro rilasciano il loro esb e il loro application server. Vi faccio notare che Hibernate è condotto da quelli di Jboss.

Quindi fino a qui abbiamo visto Apache, Sun e Jboss con un piccolo zampino di IBM che fornisce supporto ad Apache Geronimo e ad Eclipse (CXF ha qualche plugin per Eclipse). Manca il tassello di BPEL.

Lo standard BPEL è stato sottomesso all’OASIS ed è denominato WS-BPEL. I più attivi questo campo sono stati Microsoft, IBM e BEA e SAP. Da quelli di Apache la risposta è Apache ODE sul cui sito è spiegato come usarlo con Tomcat e un JBI container, a caso, ServiceMix anche se dicono di avere dei problemi con quest’ultimo in quanto non proprio aderente allo standard JBI.

Con software come Intalio che si appoggiano su Apache ODE potete progettare i processi BPEL. Faccio notare che quelli di Intalio mostrano nel loro sito la collaborazione con quelli di ServiceMix e Mule Esb un esb che può essere usato con un web container come Tomcat o un application server come Geronimo e fa uso di un application framework come Apache CXF (qui un articolo sull’integrazione).

Quelli di Sun invece inglobano il BPEL service engine direttamente nel loro esb OpenEsb e potete progettare i vostri processi BPEL direttamente da Netbeans.

Eclipse ha poi il suo plugin STP che permette di progettare BPEL.

In tutto questo panorama si scorge l’esb Petals che insieme ad OpenEsb è certificato dai tool TCK. Petals è sponsorizzato dal consorzio OW2 che vede tra i suoi membri strategici RedHat, Thales ma anche IONA e Linagora. Per il bpel c’è poi Orchestra che offre integrazione con Petals, guardacaso Orchestra è sponsorizzato dal consorzio OW2 e la sua guida è scritta da quelli di Bull che ne fanno parte.

Vi siete persi ? Spero di no, non vi posso suggerire qual è meglio quale no, vi faccio solo notare che ci sono degli standard e ci sono grosse aziende che forniscono un pò tutti questi prodotti.

A mio avviso siccome la struttura delle vostre applicazioni probabilmente spazierà tra application server, esb e web service framework soffermatevi sui software che fanno parte della stessa azienda perchè avrete sicuramente necessità di integrarli (e magari meno sono gli strumenti che usate e meglio è).

I riferimenti sono così tanti che non ho voglia di metterli vi consiglio di partire dalla pagina di wikipedia di JBI e quella di BPEL.

Axis2 e la gestione dei soap header

Come avete potuto notare attualmente sono focalizzato sui web services, in particolar modo sto lavorando con Axis2 che funziona non solo come container ma mette a disposizione strumenti per lo sviluppo come wsdl2java. Andiamo per ordine.

Un servizio web, come qualcuno di voi sa, non è altro che una serie di operazioni compiute da una applicazione (in questo caso scritta in java) che è raggiunta via web. In particolar modo queste operazioni si scambiano per lo più messaggi SOAP.

Questi messaggi SOAP sono sostanzialmente messaggi scritti in XML che viaggiano su protocollo HTTP e sono strutturati in un header e in un body.

La descrizione di questi messaggi, legati alle operazioni di cui fanno parte, è fatta dai file WSDL che appunto descrivono il web service. Talvolta, anzi spesso, questi file WSDL sono accompagnati da XML schema (file con estensione xsd) che descrivono la struttura degli elementi dei messaggi.

Molte volte avrete necessità di inserire questi elementi nel body ma puo’ capitare di voler metterli nell’header. Per far cio’ dovete specificare l’header come elemento soap:header all’interno della soap:operation (scusate se entro nel dettaglio, comunque potete vedere le specifiche WSDL)

Axis2 fornisce strumenti automatici che partono dal file WSDL e creano delle classi java, chiamate stub e skeleton, a cui si appoggieranno i vostri client e server (lo strumento è chiamato WSDL2Java ed puo’ essere incluso come plugin in Eclipse e in Netbeans) . Al momento della creazione avrete necessita’ di decidere quale parser utilizzare di solito a scelta tra ADB, Xmlbeans, Jibx. Questi parser trasformano gli elementi XML dichiarati nel file WSDL in oggetti java.

Se avete mai realizzato un web service con gli strumenti di Axis2 avrete notato, facendo anche la più semplice operazione, che normalmente gli elementi vengono incapsulati nel body. Ma se aggiungete un elemento header come accennato sopra cosa accade ?

Ebbene occorre purtroppo dire che lo stub permette di richiamare il servizio passando l’elemento che vogliamo aggiungere nell’header senza nessun problema mentre cio’ non accade con lo skeleton. In particolare lo skeleton viene richiamato da un’altra classe che è automaticamente generata ed il cui nome finisce in genere per MessageReceiverInOut. Questa classe ha un metodo che si chiama invokeBusinessLogic, essa recupera il messaggio in ricezione e invia il messaggio in uscita dal web service una volta richiamato lo skeleton.

Dovete sapere che Axis2 ha diversi stati o sessioni cioè strutture dati (classi java) che memorizzano, in breve, lo stato delle operazioni e dei messaggi. Ogni messaggio, in particolare è incapsulato nella classe MessageContext la quale sta a livello inferiore dell’OperationContext che è la classe che rappresenta lo stato della operazione. Ci sono stati di livello superiore per avere un dettaglio vederei riferimenti a fondo pagina.

Di conseguenza il metodo invokeBusinessLogic prende un MessageContext ingresso e restituisce un nuovo MessageContext in uscita. Succede pero’ che il metodo che dovrete implementare nello skeleton  restituisce solo un oggetto che viene messo in un messaggio SOAP creato sull’istante dal metodo invokeBusinessLogic.

Quindi a nulla vale aver creato nello skeleton il soap envelope (messaggio SOAP) con tanto di header perchè appunto nel metodo invokeBusinessLogic viene creato un nuovo messaggio SOAP (in cui andrà il risultato del metodo dello skeleton) non curandosi del messaggio creato nello skeleton.

Allo stato attuale quindi o dovete modificare a mano la classe MessageReceiverInOut oppure dovete pensare a soluzioni come quella di includere un header dentro al body. Dovete pensare che le classi generate non sono intoccabiliti semplicemente assistono chi vuole creare un servizio web quindi se volete modificatele pure.

Questo problema è stato verificato con Axi2 1.3 e Axis2 1.4 e con i parser ADB e Xmlbeans.

Riferimenti:

Web Services con Eclipse 3.4, Tomcat 6.0.16 e Axis2 1.4

Per un progetto in azienda sto lavorando con i web services, usiamo pero’ vecchie versioni di eclipse e axis2 poichè il progetto è iniziato con quelle versioni e non si può cambiare strumento durante lo sviluppo, come è giusto che sia. Per i fatti miei però ho sperimentato la generazione di web services dapprima con Netbeans 6.1 e poi con Eclipse 3.4.

Introduzione

Come da titolo dovete scaricare Eclipse, Tomcat e Axis2. Io ho scaricato Eclipse 3.4 per Java EE, Tomcat Core e Axis2 il file war ma anche la standard binary distributition perchè essa contiene dei comandi che il war file non ha.

Tomcat è un application server e dovrà lanciare Axis2 che funge da contenitore per i vostri web services e vi permette anche di gestirli. Con Eclipse dovrete creare le classi java per il client e il server.

Iniziamo

Una volta estratta la standard binary distribution, create la variabile di ambiente AXIS2_HOME in modo che punti ad essa e poi copiate il file war nella cartella /webapps di Tomcat. Ora, se volete, potete far partire tomcat lanciandolo dalla sua cartella /bin e con il vostro browser andare all’url:

http://localhost:8080

8080 è in genere la porta su cui Tomcat gira. Dovreste vedere la pagina di Tomcat, se cliccate a sinistra su Tomcat manager vedete la lista di applicazioni tra cui c’è Axis2. Cliccateci sopra e vi compare la pagina di Axis2. Come primo link c’è “Services” che indica gli attuali web services che stanno girando tra cui ci sarà anche il nostro.

Come vi ho già detto nella standard binary distribution ci sono dei comandi che nel war non sono presenti e sono java2wsdl e wsdl2java (vedere qui per tutti i parametri)

Se siete nuovi nel mondo dei web services dovete sapere che i file wsdl sono dei file xml che descrivono i web services percio’ prima di proseguire vi consiglio di studiarvi XML, i file xml schema e i file wsdl in generale (potete dare una occhiata al sito w3schools). Occorre saperlo perchè grazie al comando wsdl2java potete creare, a partire dal file wsdl, ciò che sta sotto la comunicazione tra client e webservice ovvero stub e skeleton.

Stub e skeleton sono delle classi java che fungono da proxy ovvero il vostro client chiamerà lo stub per la comunicazione mentre il webservice userà lo skeleton per ricevere, ed eventualmente trasmettere, i dati.

In un precedente articolo ho spiegato come potete validare i vostri file wsdl in modo da diminuire i rischi di interoperabilità, pensate ad esempio ad un client (stub) realizzato in java ed un web service (skeleton) realizzato sotto .NET.

Il comando java2wsdl potete immaginare cosa fa.

Questi comandi, come descritto nella reference di Axis2 sono molto semplici da usare ma una interfaccia grafica non dispiace.

Il servizio andrà poi impacchettato in un archivio axis (file aar) e deployato (in altre parole copiato e spacchettato, lasciatemi passare il termine) nella cartella di Axis2 sotto Tomcat.

Ho dapprima provato il plugin di Netbeans ma personalmente credo che andrebbe migliorato perchè è possibile selezionare poche cose e, inoltre, obbliga alla all’inserimento di parametri (-g) a linea di comando (da dentro l’interfaccia!) per la generazione del client, in quanto, in automatico, lui crea lo skeleton e l’unico modo per creare lo stub è aggiungere il parametro; per il resto il plugin si comporta bene. Il tutorial che ho seguito è questo. Tuttavia ho poi proseguito per Eclipse anche se poi ho scoperto che il plugin è buggato ma ho trovato rimedio.

I plugin di Axis2 sono a mio avviso più completi e si scaricano dal sito di Axis2 e precisamente sono il Service Archive Wizard 1.4 e il Code Generator Wizard 1.4 che come vedete nella tabella richiedono Axis 1.4.

Il primo serve per creare l’archivio axis da copiare in Tomcat il secondo come interfaccia per i comandi java2wsdl e wsdl2java.

Non dovete fare altro che scaricare i plugin ed estrarli nella cartella plugins di Eclipse e correggere qualche bug :-) .

In pratica nella cartella del Code Generator c’è un file che si chiama plugin.xml, in questo file sono descritte le librerie di cui il plugin si serve, tra queste notate che c’è l’archivio jar stax-api-1.0.1.jar ma questo non si trova nella cartella lib del plugin e dovete scaricarlo dalla rete (vedete qui). C’è poi un pacchetto che manca proprio e che è backport-util-concurrent-3.1.jar (lo trovate nella cartella /lib di Axis2) che dovete aggiungere nella cartella lib e nel file plugin.xml (in pratica tutto cio’ serve per risolvere l’eccezione java.lang.reflect.invocationTargetException che si manifesta all’ultimo passaggio del wizard).

Nel caso in futuro avete degli errori lanciate Eclipse in debug mode da console in questa maniera:

eclipse -clean -debug

L’opzione debug vi permette di vedere eventuali errori da console, clean pulisce una cache che Eclipse usa quando crea i vostri progetti (per altri parametri vedere qui). Se ancora avete problemi come ultima speranza rimuovete il plugin che vi da fastidio dalla cartella nascosta .metadata/.plugins che si trova nel vostro workspace.

Non fate partire ancora Eclipse perchè voglio segnalarvi un altro plugin che vi permette di lanciare/fermare Tomcat da Eclipse questo plugin lo trovate qui ed è semplice da installare come spiega il sito (in pratica va poi messo nella cartella dropins di Eclipse e occorre configurare il plugin indicando il path di tomcat).

Ok ora siete pronti per lanciare Eclipse, dovrete creare un progetto java e seguire questa guida suddivisa in 2 parti che vi spiega per filo e per segno tutto.

Durante la guida vi ritrovete a creare il codice java per lo stub dal file wsdl, il wizard vi chiede l’inclusione delle librerie del codegen ma questa non va e perciò dovrete farlo a mano agggiungendole direttamente nel vostro Build Path prendendole dalla cartella lib del plugin Codegen. Attenzione potrebbe essere un problema del Mac, ho notato che in debug mode, al momento della creazione del codice eclipse pensa di trovare il plugin nella cartella /eclipse/Contents/MacOS/plugins e non, come dovrebbe essere, in /eclipse/plugins, perciò se siete sotto Mac copiate i 2 plugin anche in quella cartella (da creare) e cosi al momento della generazione pesca correttemente i jar file della cartella lib.

Se non vedete il codige generato provate a fare un refresh del progetto. Volevo farvi notare che quando il wsdl viene caricato il plugin carica anche gli XML schema collegati (se ve ne sono) e quindi fa un controllo sulla validità, potete notare il caricamento se usate Eclipse in debug mode; tra l’altro una volta che avete creato il file wsdl potete validarlo selezionandolo e cliccando sulla voce di validazione dal menu contestuale aperto con il tasto destro del mouse.

Quando vi viene chiesto di compilare fatelo usando il file build.xml (tasto destro ed “esegui” dal menu contestuale) che viene automaticamente generato e conosce tutte le dipendenze.

Quando eseguirete il client avrete una eccezione riguardo il file jar woden API che è mancante questo perchè con Axis 2 1.4 questo package è richiesto; prendetelo dalla cartella lib di Axis2 e aggiungetelo al vostro build path. Ho semplicemente aggiunto solo il jar delle woden API.

Non vi preoccupate del warning su log4j è perchè non trova il suo file di configurazione.

Quando andate a generare lo skeleton che dovete riempire fate caso al fatto che i parametri in ingresso del metodo terminano con un numero.

Notate anche che quando generate lo stub questo ha come sottoclassi le richieste e le risposte mentre quando generate lo skeleton queste sono messe nei rispettivi file.

Nella parte 2 del tutorial vi verrà chiesto di usare il file services.xml che è stato generato nella cartella resources, ebbene in teoria dovreste poterlo selezionare in pratica dovrete inserire il suo path a mano.

Tra l’altro vi faccio notare che, sempre nella parte 2, il file wsdl viene generato nuovamente nella cartella resources, il file è pressocchè identico a quello di partenza anche se è questo che viene usato per la generazione del servizio con il Service Archiver.

Nella parte 2 vi viene chiesto di inserire la parte del client ebbene inserite il codice usato nella parte 1 e non quello proposto.

Se siete arrivati fino alla fine del tutorial complimenti! La strada per connettere e dare più funzionalità ai web services è lunga ma ora avete la basi per poterne creare.

Aggiornamento 1

Se avete avuto occasione di creare da zero wsdl, avete visto la comoda possibilità di includere XML schema dentro in modo da separare la descrizione del servizio dai tipi usati nei messaggi.

In questo ambito ho scoperto che il plugin Service Archiver ha un bug, semplicemente non include l’XML schema usato dal file WSDL dentro l’archivio aar creato e dovete purtroppo farlo a mano, a meno che c’è qualcuno che vuole modificare il codice (dovrebbe essere semplice ma non ho voglia, considerate che c’è la libreria WSDL4J che puo’ aiutarvi). Per modificarlo spacchettare il file aar (una volta rinominato in zip), aggiungete il file e rimpacchettate.

Aggiornamento 2 (uso di Xmlbeans su Eclipse 3.2, Tomcat 6 e Axis2 1.3, da verificare con Axis2 1.4)

Se durante la creazione del web service avete usato Xmlbeans come data binding ovete prestare attenzione a 2 cose in caso di errore:

-) La cartella resources contiene una cartella generata da Xmlbeans che si chiama schemaorg_apache_xmlbeans. Questa cartella contiene la cartella system la quale a sua volta contiene delle cartelle indicate da una combinazione di numeri. In una di queste si deve trovare il file TypeSystemHolder.class, questo file potrebbe esservi richiesto quando lanciate il client. Dovete quindi aggiungere la cartella resources come Class Folder tra le librerie del progetto e non come src folder.

-) In fase di creazione del web service con il Service Archiver Wizard potreste aver bisogno di aggiungere tra le librerie esterne quelle di di Xmlbeans ovvero il file Xbeans-packaged.jar che si trova nella cartella build/lib.

Alla prossima

P.S. Ho usato la java virtual machine 1.5.0_13