MokaByte
Numero 13 - Novembre 1997
|
|||
|
|
||
Giovanni Puliti |
Analisi della piattaforma Java rilasciata da Microsoft alla scoperta di cosa c'è di vero nelle accuse che Sun sta lanciando contro la casa di Redmond | ||
Introduzione
Nel numero scorso
di MB abbiamo annunciato della nascita della battaglia legale che è
nata fra Sun e Microsoft, e che sembra monopolizzare l’attenzione di tutti
gli addetti del settore. Per coloro che avessero perso le prime battute
della storia, facciamo un breve sunto dell’accaduto.
Dopo che Microsoft
ha rilasciato le ultime versioni del suo software per Java(Virtual Machine,
librerie contenute nell’SDK e tool di sviluppo), Sun ha scoperto che in
realtà tali prodotti non rispecchiano completamente lo standard
100%Pure Java. Questo fatto è secondo la casa madre un gravissima
inadempienza agli accordi presi, dato che l’obiettivo principale di Java
è quello di avere un unico standard per permettere il famoso Write
Once Run Evrywhere.
In base ai test
e dall’analisi delle librerie effettuati da Sun, Microsoft avrebbe
violato gli accordi commerciali e le specifiche tecniche in due modi:
da un lato introducendo classi aggiuntive non presenti nei package Java
core, e dall’altro modificando leggermente quelle presenti.
Queste due operazioni
compromettono pesantemente la portabilità di una applicazione Java,
dato che nel primo caso, facendo riferimento alle classi estranee, essa
non potrà essere eseguita su una VM non Microsoft, mentre al contrario,
nel secondo caso, una applicazione 100%Pure Java non potrà girare
su una macchina MS (anche se alla luce dell’analisi delle modifiche effettuate,
questa seconda possibilità sembra essere meno probabile).
In aggiunta,
oltre alle differenze dovute alle modifiche effettuate, Microsoft ha affermato
che non intende supportare ne adesso ne intende farlo in futuro,
la tecnologia RMI ed il supporto per il CORBA.
A tal proposito,
non è il fatto che attualmente tali tecnologie non siano supportate,
a stupire, nemmeno Netscape è in grado di offrire la totale copertura
del JDK 1.1, ma piuttosto che tale mancanza non sia dovuta
a carenze di sviluppo, ma sia voluta, e che non vi verrà posto rimedio
né ora né in futuro.
Alla luce di
tutto ciò vediamo di far luce su quello che effettivamente è
una reale mancanza da parte di MS, e su cosa invece sia semplicemente frutto
di guerra commerciale.
Analisi
delle differenze
Sulla base del
confronto delle classi contenute nell’ultima versione dell’SDK, la 2.0
(per capirsi quella su cui si basa l’Internet Explorer 4.0), si può
certamente affermare che in effetti Microsoft ha rilasciato una versione
non esattamente conforme a quella ufficiale di Sun. Il problema principale
è che è necessario stabilire quanto sia grande la differenza,
e soprattutto, se tali discrepanze siano tali da compromettere la tanto
leggendaria portabilità di Java. Secondo il comunicato ufficiale
del portavoce di Sun, l’operato del concorrente è sicuramente grave,
dato che sono state modificate profondamente le classi appartenenti ai
package fondamentali del core-Java; in aggiunta, Sun ha rincarato la dose
dicendo che tale iniziativa è ancora più grave in quanto
non completamente documentata, ma smascherabile solo dopo accurate
analisi delle varie librerie con appositi tool decompilatori (il javap
del JDK o il ClassView di MS).
Come prima cosa
ci chiediamo quali possano essere state le modifiche eseguite e quale peso
possano avere prese singolarmente. Ovviamente la cosa più
immediata che si può immaginare comprometta lo standard sia la modifica
della firma dei metodi o del tipo di alcune variabili di base, come la
modifica del nome di alcune classi. Un tale tipo di operazione però
è molto forte, quindi facilmente smascherabile, e non
necessaria per introdurre un po’ di incompatibilità, ed è
per questo che è stata eseguita con moderazione, modificando
alcune interfacce.
Al contrario
è molto meno intrusivo, ma altrettanto efficace, introdurre del
materiale aggiuntivo non compatibile con lo standard 100% Pure Java, in
modo da vincolare le applicazioni che ne fanno uso alla sola piattaforma
Java di Microsoft.
Questo tipo
di alterazione è stata quella maggiormente operata da Microsoft:
in particolare sono state aggiunte nuove classi, nuovi metodi e nuove
variabili, più tutto il package ms.com, che offre la strada più
breve per rendere un programma Java non portabile.
Un ultimo tipo
di operazione eseguita è stata quella di eliminare certi metodi
rinominandoli con una firma completamente diversa.
Si potrebbe
infine effettuare una comparazione delle differenze comportamentali fra
il software di Sun e quello di MS, ma questa non è una valutazione
comprovante delle effettive differenze fra le due piattaforme.
Sulla base delle
prove effettuare si può affermare che la maggior parte dei problemi
è stata riscontrata nei package java.lang(nuovi metodi, nuove variabili),
java.io(metodi eliminati), java.awt(nuove classi), java.util(nuovi metodi,
nuove variabili) e java.security(interfacce modificate), praticamente tutti
i più importanti:
Classi,
metodi e variabili aggiunte
La prima modifica
rappresenta le classi introdotte nei package di sistema, quelli che formano
il core Java API: un package di sistema è qualcosa che inizia per
Java.* nella sua denominazione completa.
Nell’insieme
delle classi aggiuntive, 16 appartengono alla AWT (il set dei componenti
grafici):
Le nuove classi di Microsoft per i componenti AWT peers | |||
---|---|---|---|
WButtonPeer | WCheckboxMenuItemPeer | WCheckboxPeer | WChoicePeer |
WLabelPeer | WListPeer | WMenuBarPeer | WMenuItemPeer |
WMenuPeer | WPopupMenuPeer | WScrollbarPeer | WScrollPanePeer |
WTextAreaPeer | WTextComponentPeer | WTextFieldPeer | WUIPeer |
Ad eccezione
dell’ultima, tutte le classi sono componenti peer (un peer component è
un oggetto grafico il cui aspetto e comportamento è fortemente dipendente
dalla piattaforma del sistema operativo sottostante). Normalmente tali
classi dovrebbero trovarsi in pacchetti diversi, come ad esempio sun.awt.windows
o sun.awt.motif, in modo da evitarne l’uso se non strettamente necessario.
Per quanto riguarda
i metodi, si deve dire che il metodo più frequentemente aggiunto
è il getBaseName(): fortunatamente è anch’esso privato
relativamente al package, per cui non si dovrebbero incontrare grossi problemi.
Altri cambiamenti
come ad esempio la trasformazione del classloader LoadClassinternal()
in metodo privato piuttosto che in package private, sono dovute a differenze
di implementazione interne, e non dovrebbero comportare effetti sullo
sviluppatore.
Non si intende
con questo minimizzare il problema, ma fintanto che lo sviluppatore non
debba andare ad interagire con queste classi in profondità nella
VM, non dovrebbero insorgere problemi di incompatibilità.
A tal proposito
si ricordi che, in base alle regole del 100%PJ (VEDI MB XXX), tali operazioni
sono da evitare nella maniera più assoluta, se si vuole mantenere
il proprio software portabile secondo la filosofia Java.
I veri problemi
sorgono con i metodi pubblici introdotti da MS:
Metodi pubblici aggiunti nelle libreirie fondamentali | |
---|---|
Class | New Method(s) |
java.awt.EventQueue | _postEvent (AWTEvent) |
java.awt.Font | getNativeData() |
java.awt.image.ColorModel | finalize() [was protected] |
java.awt.image.DirectColorModel | getToolkitData() |
java.awt.image.IndexColorModel | getOpaque()
getToolkitData() |
java.awt.SystemColor | getWin32Index() |
java.lang.Class | getInterface(String)
getMethods(int[]) getMethodFromSignature(String,String) getDeclaredMethodFromSignature(String,String) |
java.lang.Runtime | getNativeServices() |
java.lang.SecurityManager | checkFileDialog()
checkMultimedia() checkRegistry(int,String) checkSystemStreams(int) |
java.lang.VerifyError | getAuditDetails()
getAuditIdentifier() getClassName() getMethodName() getPC() getViolationCode() getViolationDescription() |
java.lang.reflect.Method | getDescriptor()
getParameterCount() |
java.util.Locale | Locale(String,
String, String, int, int)
getCodePage() getDefaultLocaleList() getLCID() [was private] getLocaleFromLCID(int) |
java.util.ResourceBundle | getMenu
(String)
getMenuBar(String) |
Si devono evitare
tutti i metodi della tabella precedente se non si vuole che le proprie
applicazioni siano eseguibili solo su piattaforma MS.
Inoltre sono
disponibili tre nuove variabili e una serie di Locale per l’internazionalizzazione.
Variabili aggiunte nelle Java API | |||
---|---|---|---|
Class | New Variable | ||
java.awt.Font | pData | ||
java.awt.SystemColor | appWorkspace | ||
java.lang.reflect.Member | PUBLIC_DECLARED | ||
java.util.Locale |
|
PUBLIC_DECLARED
è una nuova variabile di Member, così come appWorkSpace lo
è per SystemColor, mentre pdata da privata diviene pubblica. Si
evitino assolutamente.
Un commento
particolare deve essere fatto in merito all’introduzione dei nuovi valori
per Locale: tale operazione sembra il frutto della mania di grandezza
di Microsoft, che la porta di tanto in tanto senza volerlo (complici
i bug) a definire nuovi standard nazionali, continentali, mondiali, intergalattici
(si ricordi l’errato cambiamento nell’ora solare dell’anno scorso di Win
95). In questo caso sembra infatti che gli adepti della casa, al contrario
dei colleghi della setta del Dio Sole (Sun) siano capaci di comprendere
nuovi linguaggi, e per questo sentono il bisogno di estendere tali
capacità a tutta la comunità mondiale. Anche se l’intenzione
è senza dubbio onorevole, questa iniziativa può portare a
problemi senza che ce ne sia effettivamente il bisogno. In ogni caso per
evitare di incappare in tali trappole, è sufficiente
che definiate le vostre istanze di Locale con i dovuti parametri
standard, invece di fare affidamento a quelle ufficiali MS che in alcuni
casi non sono disponibili.
Veniamo infine
alle interfacce: tale elemento può essere considerata come uno
schema (incompleto) dal quale una classe deve partire e dalla quale
evolversi successivamente. Ebbene per quanto riguarda gli schemi (interfacce)
legati alla sicurezza sono state modificate alcuni dettagli, che
sebbene siano piccoli, sono sufficienti per impedire ad applicazioni che
fanno riferimento ai vecchi modelli di funzionare. Infatti, dato che tali
modifiche consistono nell’aggiunta di metodi, e dato che, il processo
di derivazione da una interfaccia prevede la riscrittura di tutti
i metodi, l’introduzione di elementi nuovi, rende di fatto errata
la derivazione di quelle classi che fanno riferimento alla vecchia versione
delle interfacce, quella senza intrusi. In tabella 4 sono riportati I corpi
del reato:
Metodi aggiuntivi nelle interfacce sulla sicurezza | |
---|---|
Interface | New Methods |
java.security.interfaces.DSAPrivateKey | getAlgorithm()
getEncoded() getFormat() getParams() |
java.security.interfaces.DSAPublicKey | getAlgorithm()
getEncoded() getFormat() getParams() |
Il
package com.ms
Questo pacchetto
rappresenta un set di classi rilasciate da Microsoft per l’utilizzazione
in ambiente Java, e che sono ovviamente inaccessibili da altre Virtual
Machine (come ad esempio quella di Netscape Comunicator): l’utilizzazione
di una qualsiasi di queste classi equivale ad intraprendere la via più
breve per uscire fuori dallo standard Java e della portabilità.
Un esempio tipico
di come si possa cadere facilmente in tali situazioni è dato dall’utilizzazione
di Fontmetrics dalla classe Toolkit (per mezzo del metodo getFontMetrics()):
infatti mentre la firma è la stessa (public FontMetrics getFontMetrics())
quello che si riceve indietro è una istanza di com.ms.awt.FontMetricsX.
Se considerate tale oggetto come FontMetricsX, allora l’applicazione
non sarà eseguibile fuori da una VM Microsoft. Se invece si
utilizza un FontMetrics si mantiene la portabilità.
Un eccezione
a questo inconveniente è rappresentata dalle Application Foundation
Classes (AFC) contenute nel package ms.com.ui, che essendo scritte
in java possono essere utilizzate senza problemi.
Cosa
manca nell’SDK
Fra tutte le
classi ed i package in analisi, sembra in definitiva che manchi un solo
metodo: si tratta del toString() della classe ByteArrayOutputStream,
ed anche se si tratta di un solo metodo, il tipo e la frequenza del suo
utilizzo fa dubitare della casualità della scelta.
Stessa
famiglia, ma comportamento diverso
Oltre alle differenze
nel codice fra le due versioni del JavaSoftware, vediamo quali sono
le differenze comportamentali dei due mondi: a tal proposito si tenga presente
che in generale, versioni differenti di software, anche se compatibili
dal punto di vista teorico, portano sempre a delle differenze, proprio
a causa delle differenze implementative; per questo motivo forse questo
tipo di confronto, fra tutti quelli possibili, è quello meno giustificato.
In aggiunta
a tale considerazione, si tenga presente che MS offre il suo Java versione
1.1, mentre Sun è arrivata alla versione 1.1.4. le sotto versioni
1.1.xx sono in realtà dei bug fix, per cui potrebbe sorgere il dubbio
che la versione di MS sia arretrata e per questo meno solida. Questo dubbio
per quanto plausibile non trova completa giustificazione, dato che le due
case non sono allineate temporalmente per il rilascio delle VM, e quindi
non è detto che la versione della casa di Redmond sia necessariamente
più scadente (si potrebbe calcolare che la MS VM 1.1 sia equivalente
ad una di Sun targata 1.1.2).
Forse verrebe
da obiettare che essendo Sun la casa che ha inventato Java, e che è
quella che attualmente che sta investendo maggiori risorse, si dovrebbe
adottare come standard universalmente riconosciuto quello introdotto da
Sun, ma ovviamente in questo caso si introducono esigenze legali e politiche.
Tralasciando
questi particolari tecnici e di marketing, differenze di comportamento
sussistono, ed in genere portano la VM di Ms ad essere meno rigorosa. Ad
esempio si è potuto osservare che utilizzando la classe java.util.BorderLayout,
ed immettendo un oggetto in un panel senza il quadrant-name,
con il JDK o JRE l’oggetto finisce per disporsi automaticamente al centro
dello schermo, mentre se invece lo si aggiunge con un nome illegale di
quadrante come ad esempio “TOP “ , viene generata una eccezione del tipo
IllegalArgumentException.
Nel caso in
cui si utilizzi invece la VM di Microsoft in entrambi i casi l’oggetto
non viene visualizzato ma non vengono generate eccezioni.
Altra differenza
è che la classe Dialog accetta sotto Microsoft parent=null, mentre
in tal caso il JDK genera una eccezione.
Conclusioni
Senza dubbio
possiamo dire che Microsoft ha volontariamente effettuato delle modifiche
alle classi base di JDK, e anche se le modifiche in certi casi sono minime,
o trasparenti si trattano pur sempre di modifiche.
Se tali
variazioni siano legali o meno, e se la causa ingiunta da Sun sia giustificata,
solo le aule dei tribunali ed il tempo potranno darci risposta. Per il
momento possiamo dire che se non si effettuano attenti controlli sul tipo
di operazioni effettuate, si rischia di cadere in situazioni pericolose
fortemente legate alla piattaforma MS e quindi in totale contrapposizione
con la filosofia principale di Java.
Vediamo di fare
una sintesi di quello che è emerso alla fine dell’analisi fatta:
Mancanza del supporto per RMI e JNI: nel caso in cui tali strumenti diventino necessari si dovrà ricorrere a soluzioni alternative (non MS come JRE o direttamente il JDK) o ricorrere a soluzioni antecedenti (come ad esempio all’utilizzazione di protocolli proprietari per invocare servizi di un server remoto al posto di RMI). Anche se una applet offre innegabili vantaggi rispetto all’applicazione, in certi casi questa seconda opzione diviene l’unica possibile se si è scelto di utilizzare MS.
Aggiunta di classi, metodi e variabili: se si desidera sviluppare applicazioni 100% PJ si dovrà assolutamente evitare tali elementi. Anche se il compito di evitare tali ostacoli non è difficile, non è presente nessun meccanismo del tipo @deprecated come con i metodi obsoleti.
Aggiunta di metodi ad interfacce: questo punto è uno dei più insidiosi di tutta l’operato di MS: infatti se una vecchia applicazione (o una costruita secondo 1000%PJ) viene fatta eseguire sulla nuova VM non funzionerà correttamente o affatto fino a che tutti i metodi delle interfacce saranno aggiunti (ovviamente vuoti dato che non erano previsti). Questa rimessa a modello dovrebbe creare applicazioni nuovamente 100% PJ.
Mancanza del metodo ByteArrayOutputStream: anche se si tratta di un solo metodo è forse una delle mancanze più gravi, ed anche se può essere aggirata facilmente obbliga a modifiche e ricompilazioni e sarebbero potute essere facilmente evitate.
Il package com.ms: differentemente da quanto avviene per le altre modifiche in questo caso, che uno dei più radicali contro la portabilità, non è altrettanto rischiosa dato che il pacchetto non è pubblicamente accessibile dall’esterno.
Differenze comportamentali:
anche se le varie modifiche sono state fatte cercando poi di mantenere
lo stesso tipo di comportamento delle classi, questo a volte non avviene.
Come detto precedentemente, dato l’alto numero di variabili in gioco, tali
divergenze sono comprensibili indipendentemente dal fatto che MS abbia
seguito una strada sua.
A prescindere
dalle effettive incompatibilità tecniche, sembra che nuovamente
stia nascendo un antagonismo a due fra giganti dell’informatica, come già
in passato è avvenuto per la guerra IBM e Apple: anche se in genere
le agitazioni portano dopo un primo periodo di scompiglio, a nuovi scenari,
in genere più interessanti, per il momento siamo in piena randomizzazione,
e non penso che si possa adesso fruire positivamente della cosa.
Anche se da
un certo punto di vista adesso le cose sono più chiare (si sono
finalmente gettate le maschere, e si sono mostrate le vere intenzioni),
credo che tale situazione non si esaurisca brevemente, ed anzi porti ad
un periodo pericolosamente lungo di stagnazione.
|
||
|
||
MokaByte ricerca
nuovi collaboratori
|
||
|