Stefano Sanna Mobile WebServices JMDF Second Meeting - Presentation Transcript
Java Mobile Developers Forum
http://jmdf.java2me.org
L
o
Web Services e dispositivi Java ME
Stefano Sanna
http://www.gerdavax.it
Stefano Sanna, Web Services e dispositivi Java ME
1
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Parliamo di...
Web Services su dispositivi mobili: ora si può!
●
Web Services API for J2ME
●
JAXP: decodificare XML
–
JAX-RPC: invocare metodi remoti
–
Dalla teoria alla pratica...
●
Conclusioni
●
Stefano Sanna, Web Services e dispositivi Java ME
2
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Web Services API for J2ME
Il Java Community Process ha definito la specifica
●
JSR 172, che porta nel mondo Java ME:
Un subset di JAXP 1.2
–
Un subset di JAX-RPC 1.1
–
Stefano Sanna, Web Services e dispositivi Java ME
3
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Caratteristiche principali
Footprint estremamente ridotto
●
~35KB per JAXP e ~25KB per JAX-RPC
–
Performance ottimizzate per dispositivi low-end
●
Supporto a tutti i profili basati su CLDC 1.0/1.1 e
●
CDC
Interfaccia RPC (SPI) indipendente dalla
●
particolare implementazione della libreria
Stefano Sanna, Web Services e dispositivi Java ME
4
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Architettura
MIDlet
Stub
WSA Service Provider
Interface
JAXP JAX-RPC
MIDP/PP
CLDC/CDC
Stefano Sanna, Web Services e dispositivi Java ME
5
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
JAXP 1.2 subset
E' l'API per il parsing di documenti XML
●
Caratteristiche:
●
Requisiti minimi: CLDC 1.0 e 35KB footprint!
–
Sottoinsieme della specifica JAXP 1.2
–
Supporto all'interfaccia SAX 2.0
–
Supporto agli XML namespaces
–
Supporto codifiche UTF-8 e UTF-16
–
L'eventuale validazione con DTD e' opzionale
–
(piuttosto improbabile...)
Stefano Sanna, Web Services e dispositivi Java ME
6
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
JAXP
javax.xml.parsers
●
contiene il SAX parser, la relativa factory e le classi
–
delle eccezioni
org.xml.sax
●
contiene il core delle API SAX (Attribute, Locator,
–
InputSource...)
org.xml.sax.helpers
●
contiene la classe DefaultHandler per la gestione
–
degli eventi di parsing
Stefano Sanna, Web Services e dispositivi Java ME
7
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Limitazioni JAXP
Nessun supporto SAX 1.0 (vedi SAX 2.0)
●
Nessun supporto XSLT
●
Nessun supporto DOM 1.0 e 2.0
●
Validazione opzionale
●
Stefano Sanna, Web Services e dispositivi Java ME
8
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
JAX-RPC 1.1 subset
E' l'API per l'invocazione remota di metodi
●
attraverso documenti XML
Caratteristiche:
●
Supporta WSDL 1.1
–
Supporta SOAP 1.1 (1.2 in futuro)
–
Supporto XML 1.0 e XML Schema
–
Binding su SOAP e trasporto HTTP (con supporto
–
autenticazione base)
Conforme al WS-I Basic Profile 1.0
–
Stefano Sanna, Web Services e dispositivi Java ME
9
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
JAX-RPC
javax.xml.rpc
●
contiene l'interfaccia Stub
–
javax.microedition.xml.rpc
●
contiene classi e interfacce della SPI
–
javax.xml.namespace
●
contiene la classe QName
–
java.rmi
●
contiene l'interfaccia Remote, da cui dipende Stub
–
Stefano Sanna, Web Services e dispositivi Java ME
10
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
WSDL-Java Mapping
xsd:long long java.lang.Long
xsd:int int java.lang.Integer
xsd:short short java.lang.Short
xsd:byte byte java.lang.Byte
xsd:float float java.lang.Float
xsd:double double java.lang.Double
xsd:string String
String su dispositivi
xsd:base64Binary byte[]
CLDC 1.0
xsd:hexBinary byte[]
xsd:complexType sequenza di classi e primitivi
vettory di primitivi e tipi complessi, secondo XML array
Stefano Sanna, Web Services e dispositivi Java ME
11
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Limitazioni JAX-RPC
Non sono supportati messaggi SOAP con
●
attachment né message handlers
Non è gestita la rappresentazione encoded di
●
messaggi SOAP (esclusivamente literal)
UDDI non supportato in questa versione
●
Non è prevista l'implementazione di endpoint
●
(nessun web service provider su telefonino!)
Stefano Sanna, Web Services e dispositivi Java ME
12
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
JAX-RPC: invocare metodi remoti
Utilizzare le routine di invocazione remota
●
all'interno di un mobile web service consumer è
estremamente semplice. Occorre:
Recuperare il WSDL del servizio di interesse e
–
verificare la compatibilita' WS-I
Generare lo stub a partire dal WSDL
–
Invocare i metodi dello stub dalla MIDlet
–
Stefano Sanna, Web Services e dispositivi Java ME
13
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
JAX-RPC: invocare metodi remoti
MIDlet
REQUEST
Web Service Stub
RESPONSE
WSDL
Stub Generator
Stefano Sanna, Web Services e dispositivi Java ME
14
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Stub
La creazione dello stub (interfaccia e
●
implementazione) viene effettuata
automaticamente attraverso opportuni
strumenti (Stub Generator)
Lo stub è indipendente dalla particolare
●
implementazione della WSA
Lo stub invoca i metodi delle classi della Service
●
Provider Interface
Stefano Sanna, Web Services e dispositivi Java ME
15
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Strumenti di sviluppo
Attualmente la WSA è supportata, tra gli altri, da:
●
Sun J2ME Wireless Toolkit 2.2 o superiore
–
Nokia Developer's Suite 2.2 o superiore
–
SonyEricsson SDK 2.2.2 for Java ME Platform
–
IBM WebSphere Studio Device Developer
–
Apache Mirae Project
–
Stefano Sanna, Web Services e dispositivi Java ME
16
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Web Service d'esempio
GlobalWeather: fornisce informazioni meteo
●
aggiornate su numerose citta' del mondo
Recensito su: http://www.xmethods.com
●
WSDL:
●
http://www.webservicex.com/globalweather.asmx?WSDL
I test sono stati eseguiti su Windows XP, Linux Mandrake e Mac OS X Tiger
Stefano Sanna, Web Services e dispositivi Java ME
17
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Utilizziamo il Wireless Toolkit
Stefano Sanna, Web Services e dispositivi Java ME
18
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Stub Generator
Stefano Sanna, Web Services e dispositivi Java ME
19
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Lo stub è pronto all'uso
Lo Stub Generator
●
ha creato:
L'interfaccia
●
Lo stub vero e proprio
●
Classi di supporto per
●
ciascun metodo
invocato
e relativa risposta
Stefano Sanna, Web Services e dispositivi Java ME
20
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
L'interfaccia dello stub
import java.rmi.Remote;
public interface GlobalWeatherSoap extends Remote {
public String getWeather(String cityName, String
countryName) throws java.rmi.RemoteException;
public String getCitiesByCountry(String countryName)
throws java.rmi.RemoteException;
}
Stefano Sanna, Web Services e dispositivi Java ME
21
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Lo stub /1
Lo stub fa riferimento alla Service Provider
●
Interface:
import javax.xml.rpc.JAXRPCException;
import javax.xml.namespace.QName;
import javax.microedition.xml.rpc.Operation;
import javax.microedition.xml.rpc.Type;
import javax.microedition.xml.rpc.ComplexType;
import javax.microedition.xml.rpc.Element;
Stefano Sanna, Web Services e dispositivi Java ME
22
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Lo stub /2
public class GlobalWeatherSoap_Stub implements
jipday.weather.GlobalWeatherSoap, javax.xml.rpc.Stub {
private String[] _propertyNames;
private Object[] _propertyValues;
public GlobalWeatherSoap_Stub() {
_propertyNames = new String[] {ENDPOINT_ADDRESS_PROPERTY};
_propertyValues = new Object[]
{"http://www.webservicex.com/globalweather.asmx"};
}
Stefano Sanna, Web Services e dispositivi Java ME
23
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Property dello Stub
Attraverso il metodo _setProperty() è possibile
●
impostare la configurazione dello stub:
ENDPOINT_ADDRESS_PROPERTY
–
SESSION_MAINTAIN_PROPERTY
–
USERNAME_PROPERTY
–
PASSWORD_PROPERTY
–
Il Wireless Toolkit imposta l'indirizzo di default
●
dell'endpoint
Stefano Sanna, Web Services e dispositivi Java ME
24
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Stefano Sanna, Web Services e dispositivi Java ME
25
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
MobileGlobalWeather
Scriviamo una MIDlet che utilizza lo Stub appena
●
generato per visualizzare informazioni meteo su
una città italiana (indicata attraverso un TextField)
Visto il lavoro svolto dallo Stub Generator, sarà
●
sufficiente istanziare lo Stub e invocarne i
metodi
Stefano Sanna, Web Services e dispositivi Java ME
26
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Il “telaio” della MIDlet
public class MobileGlobalWeather extends MIDlet implements
CommandListener, Runnable {
private Display display;
private Form cityForm;
private TextField cityField;
private Command queryCommand;
private Command backCommand;
private TextBox cityResult;
private Form loadingDialog;
private GlobalWeatherSoap_Stub stub;
public MobileGlobalWeather() { init(); }
Stefano Sanna, Web Services e dispositivi Java ME
27
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Inizializzazione
private void init() {
// creazione della GUI...
display = Display.getDisplay(this);
cityForm = new Form("MobileGlobalWeather");
cityForm.setCommandListener(this);
...
stub = new GlobalWeatherSoap_Stub();
}
Stefano Sanna, Web Services e dispositivi Java ME
28
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Gestione degli eventi
public void commandAction(Command c, Displayable d) {
if (c == queryCommand) {
display.setCurrent(loadingDialog);
new Thread(this).start();
}
else if (c == backCommand) {
display.setCurrent(cityForm);
}
}
Stefano Sanna, Web Services e dispositivi Java ME
29
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Invocazione remota
public void run() {
try {
String result = stub.getWeather(cityField.getString(),
"Italy");
cityResult.insert(result, 0);
}
catch(RemoteException re) {
cityResult.insert("Errore invocazione remota!”, 0);
}
finally { display.setCurrent(cityResult); }
}
Stefano Sanna, Web Services e dispositivi Java ME
30
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Che tempo fa...
Stefano Sanna, Web Services e dispositivi Java ME
31
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Sorpresa! :-)
Stefano Sanna, Web Services e dispositivi Java ME
32
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
La response è XML!
<?xml version="1.0" encoding="utf-16"?>
<CurrentWeather>
<Location>Cagliari/Elmas, Italy 39-15N 009-04E 5M</Location>
<Time>Sep 29, 2005 - 04:45 PM EDT / 2005.09.29 2045 UTC</Time>
<Wind> from the NW (310 degrees) at 10 MPH (9 KT):0</Wind>
<Visibility> greater than 7 mile(s):0</Visibility>
<SkyConditions> mostly cloudy</SkyConditions>
<Temperature> 68 F (20 C)</Temperature>
<DewPoint> 62 F (17 C)</DewPoint>
<RelativeHumidity> 82%</RelativeHumidity>
<Pressure> 30.12 in. Hg (1020 hPa)</Pressure>
<Status>Success</Status>
</CurrentWeather>
Stefano Sanna, Web Services e dispositivi Java ME
33
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Invocazioni sincrone
WSA genera chiamate sincrone: assicurarsi che
●
queste siano gestite all'interno di Thread
separati dalle routine di gestione della GUI
Non tutti gli esempi reperibili in rete (o generati
●
automaticamente dai tool...) tengono in
considerazione questo aspetto...
Stefano Sanna, Web Services e dispositivi Java ME
34
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Invocazioni sincrone
Senza Thread:
●
if (c == invokeCommand) {
stub.startEngine();
}
La chiamata a startEngine() è bloccante e può
●
condurre ad un deadlock dell'applicazione
Stefano Sanna, Web Services e dispositivi Java ME
35
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Invocazioni su Thread separato
class StartEngineTask implements Runnable {
public void run() {
stub.startEngine();
}
}
if (c == invokeCommand) {
new Thread(startEngineTask).start();
}
Stefano Sanna, Web Services e dispositivi Java ME
36
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
I dispositivi compatibili...
Stefano Sanna, Web Services e dispositivi Java ME
37
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
... sono sempre più numerosi!
Stefano Sanna, Web Services e dispositivi Java ME
38
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
WSA “custom” sui dispositivi?
... la WSA introduce i
●
package java.*,
javax.* di dominio dei
namespace protetti: la
VM del dispositivo ne
permette l'uso solo se i
package sono
contenuti all'interno
del runtime del
dispositivo!
Occorre una soluzione
●
alternativa...
Stefano Sanna, Web Services e dispositivi Java ME
39
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Uso delle librerie di un SDK
Come soluzione temporanea, si può:
●
Prendere il jar file relativo alla implementazione
–
della WSA di un emulatore/SDK (ad esempio, j2me-
ws.jar all'interno della directory lib/ del Wireless
Toolkit)
Disabilitare il supporto Web Services all'interno
–
dell'ambiente di sviluppo
Importare il file jar come libreria esterna (da
–
includere nel jar di deployment)
Utilizzare un obfuscator per eliminare i nomi dei
–
package riservati
IMPORTANTE: questa tecnica può essere
●
utilizza a scopo di test, in quando il riuso di
porzioni degli SDK non è consentito.
Stefano Sanna, Web Services e dispositivi Java ME
40
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Mirae: un aiuto da Apache
Mirae è una implementazione open source della
●
JSR 172 appartenente all'Apache Web Services
Project
Sorgente e documentazione sono disponibili:
●
Sito ufficiale:
–
http://ws.apache.org/mirae/
Repository sorgente:
–
https://svn.apache.org/repos/asf/webservices/mirae
Utilizzando Mirae è possibile includere la WSA
●
all'interno di device non aggiornati
Stefano Sanna, Web Services e dispositivi Java ME
41
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Mirae: piccoli ritocchi...
Per poter utilizzare Mirae all'interno di una
●
applicazione Java ME è necessario:
Includere il sorgente in un progetto (vedi filesystem)
–
Attivare la compatibilità CLDC 1.1
–
Cancellare le classi MailAgent e OperationMail dal
–
package org.apache.mirae.ws
Aggiungere alla classe NamespaceConstants del
–
package javax.xml.rpc il field:
public static final String NSPREFIX_SOAP_ENCODING = "soapenc";
Nota: non è supportato l'encoding UTF-16, per cui il
●
servizio GlobalWeather non è accessibile
Stefano Sanna, Web Services e dispositivi Java ME
42
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Un semplice web service di test
Per testare questa WSA artigianale è stato
●
predisposto un semplice web service d'esempio,
pubblicato su un server domestico ed è
raggiungibile all'indirizzo:
http://gerdavax.dyndns.org:8080/axis/services/ciao
Ringrazio Nicola Mura per il supporto... all'inseguimento dell'encoding!
Stefano Sanna, Web Services e dispositivi Java ME
43
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
L'interfaccia dello stub
package org.jugsardegna.mobile.ws.hello.stub;
import java.rmi.*;
public interface Ciao extends Remote {
public String saluto(String nome) throws
RemoteException;
}
Stefano Sanna, Web Services e dispositivi Java ME
44
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
HelloWSWorld: il “telaio”
public class HelloWSWorld extends MIDlet implements
CommandListener, Runnable {
private Display display;
private Form gui;
private TextField nameField;
private Command sayHelloCommand;
private Ciao stub;
public HelloWSWorld() { init(); }
Stefano Sanna, Web Services e dispositivi Java ME
45
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Inizializzazione
private void init() {
display = Display.getDisplay(this);
gui = new Form("HelloWSWorld!");
nameField = new TextField("Name:", "", 20,
TextField.ANY); gui.append(nameField);
gui.addCommand(sayHelloCommand);
gui.setCommandListener(this);
stub = new Ciao_Stub();
}
Stefano Sanna, Web Services e dispositivi Java ME
46
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Gestione degli eventi
public void commandAction(Command c, Displayable d)
{
if (c == sayHelloCommand) {
new Thread(this).start();
}
}
Stefano Sanna, Web Services e dispositivi Java ME
47
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Invocazione remota
public void run() {
String result = "";
AlertType type = AlertType.INFO;
try {
result = stub.saluto(nameField.getString());
} catch(RemoteException re) {
result = "Errore invocazione remota!";
type = AlertType.ERROR;
}
finally {
Alert pop = new Alert("Result", result, null, type);
pop.setTimeout(Alert.FOREVER);
display.setCurrent(pop, gui);
}
}
Stefano Sanna, Web Services e dispositivi Java ME
48
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Nota sulla codifica
La codifica document/literal può introdurre
●
ambiguità nei messaggi di invocazione dei metodi
remoti
E' importante, quando possibile, indicare
●
esplicitamente i tipi coinvolti nell'invocazione del
metodo
Stefano Sanna, Web Services e dispositivi Java ME
49
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
WSDD
<deployment
xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="ciao" provider="java:RPC" style="document"
use="literal">
<parameter name="className" value="io.me.Ciao"/>
<parameter name="allowedMethods" value="saluto"/>
<parameter name="scope" value="Request"/>
</service>
</deployment>
Stefano Sanna, Web Services e dispositivi Java ME
50
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Dopo la WSA
Il Java Community Process prosegue:
●
JSR 279: Service Connection API for JavaME
–
● Introduce maggiore astrazione rispetto al server
provider vero e proprio, includendo le interfacce
all'interno del Generic Connection Framework
JSR 280: XML API for Java ME
–
● API completa per la gestione di documenti XML
JSR 239-240: Mobile Service Architecture for CLDC
●
and CDC (web services per tutti?)
Stefano Sanna, Web Services e dispositivi Java ME
52
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Conclusioni
La Web Services API introduce nel mondo Java ME
●
una interfaccia standard per l'elaborazione di
documenti XML e l'invocazione remota di
procedure attraverso infrastruttura web services
Il supporto a WS-I Basic Profile limita
●
l'interoperabilità con molti servizi esistenti ma
garantisce compatibilità e riusabilità con quelli
futuri
I dispositivi WSA-compatibili sono ormai arrivati!
●
Per quelli meno recenti è possibile utilizzare Mirae
e scrivere servizi con codifica UTF-8
Stefano Sanna, Web Services e dispositivi Java ME
53
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Bibliografia
Un esempio dell'uso di JAXP è contenuto nel
●
seminario del JIP 2005 ed è reperibile sul sito di
Java Italian Portal (http://www.javaportal.it)
JSR 172: J2ME Web Services Specification
●
Java Community Process
–
http://jcp.org/en/jsr/detail?id=172
Web Services APIs for J2ME
●
C. Enrique Ortiz, IBM DeveloperWorks
http://www-128.ibm.com/developerworks/library/wi-
–
jsr e successivi
Stefano Sanna, Web Services e dispositivi Java ME
54
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Bibliografia
La piattaforma J2ME e i Web Services
●
Massimo Carli
–
Mokabyte n. 94 e 96
http://www.mokabyte.it
La Web Services API di J2ME
●
Emanuela De Vita, Stefano Sanna
–
Speciale Programmazione Mobile
Computer Programming 150, G.E. Infomedia
Stefano Sanna, Web Services e dispositivi Java ME
55
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Grazie per l'attenzione :-)
Farmer Clem meets the 21st C by lumix2004
http://www.sxc.hu/browse.phtml?f=profile&l=lumix2004
Stefano Sanna, Web Services e dispositivi Java ME
56
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
Web Services e dispositivi Java ME
(Versione 1.1)
(C) 2005 Stefano Sanna (gerdavax@tiscali.it)
è garantito il permesso di copiare, distribuire e/o modificare questo documento seguendo i
termini della Licenza per Documentazione Libera GNU, Versione 1.1 o ogni versione
successiva pubblicata dalla Free Software Foundation. Una copia della licenza in lingua
italiana è disponibile presso: http://www.softwarelibero.it/gnudoc/fdl.it.html
Realizzato in ambiente Linux con OpenOffice 2.0
Tutti i marchi commerciali sono di proprietà dei rispettivi titolari e sono stati citati in questa presentazione
a solo scopo illustrativo.
Stefano Sanna, Web Services e dispositivi Java ME
57
2' Meeting Java Mobile Developers Forum, Roma, 02 Dicembre 2005
0 comments
Post a comment