Java: s tre typer av portabilitet

Java har genererat mycket spänning i programmeringsgemenskapen eftersom det lovar bärbara applikationer och applets. Faktum är att Java tillhandahåller tre olika typer av portabilitet: källkodsportabilitet, CPU-arkitekturportabilitet och OS / GUI-portabilitet. Det faktum att det finns tre olika typer av portabilitet är avgörande, eftersom bara en av dessa typer är ett hot mot Microsoft. Microsoft kan förväntas undergräva den ena typen av bärbarhet samtidigt som de omfamnar de andra två - samtidigt som de hävdar att de stöder Java. Att förstå de tre typerna av portabilitet och hur de fungerar tillsammans är avgörande för att förstå hotet mot Microsoft och Microsofts möjliga svar.

Innan vi hoppar in i detaljer om var och en av dessa tre typer av portabilitet, låt oss dock granska några grundläggande termer.

Definierar några termer

Följande termer används i den här artikeln:

Endianism
Endianism hänvisar till lagringsordningen för byte i en multibyte-kvantitet i en given CPU. Till exempel kräver den osignerade korta 256 (decimal) två byte lagring: en 0x01 och 0x00. Dessa två byte kan lagras i endera ordningen: 0x01, 0x00eller 0x00, 0x01. Endianism bestämmer i vilken ordning de två byten lagras. Av praktiska syften betyder endianism vanligtvis bara när processorer med olika endianism måste dela data.
Java
Java är flera olika tekniker förpackade tillsammans - Java-programmeringsspråket, Java Virtual Machine (JVM) och klassbiblioteken som är associerade med språket. Denna artikel diskuterar alla dessa aspekter.
Java virtual machine (JVM)

JVM är en imaginär CPU som de flesta Java-kompilatorer släpper ut kod för. Stöd för denna imaginära CPU är det som gör att Java-program kan köras utan att kompileras på olika processorer. Ingenting i Java-programmeringsspråket kräver att Java-källkod sammanställs till kod för JVM istället för till ursprunglig objektkod.

Faktum är att Asymetrix och Microsoft har meddelat Java-kompilatorer som avger inbyggda Microsoft Windows-applikationer. (Se avsnittet Resurser i den här artikeln för ytterligare information.)

J-kod
J-kod är den utdata som de flesta Java-kompilatorer sänder ut till klassfilerna. J-kod kan ses som objektkod för den virtuella Java-maskinen.
Bärbarhet
Portabilitet avser möjligheten att köra ett program på olika maskiner. Att köra ett visst program på olika maskiner kan kräva olika mängder arbete (till exempel inget arbete alls, kompilering eller små ändringar i källkoden). När människor hänvisar till Java-applikationer och -appletter som bärbara, menar de vanligtvis att applikationer och applikationer körs på olika typer av maskiner utan ändringar (t.ex. omkompilering eller justeringar av källkoden).

Nu när vi har täckt några väsentliga termer förklarar vi var och en av de tre typerna av Java-portabilitet.

Java som språk: källkodsportabilitet

Som programmeringsspråk tillhandahåller Java den enklaste och mest bekanta formen av portabilitet - källkodsportabilitet. Ett givet Java-program bordeproducera identiska resultat oavsett underliggande CPU, operativsystem eller Java-kompilator. Denna idé är inte ny; språk som C och C ++ har gett möjlighet till denna portabilitetsnivå under många år. C och C ++ ger dock också många möjligheter att skapa icke-bärbar kod. Om inte program skrivna i C och C ++ är utformade för att vara bärbara från början är förmågan att flytta till olika maskiner mer teoretisk än praktisk. C och C ++ lämnar odefinierade detaljer, såsom storleken och endianismen av atomiska datatyper, beteendet hos matematik med flytande punkter, värdet på oinitialiserade variabler och beteendet när man får tillgång till fritt minne.

Kort sagt, även om syntaxen för C och C ++ är väl definierad, är inte semantiken det. Denna semantiska lösthet gör att ett enda block av C- eller C ++ -källkod kan kompileras för program som ger olika resultat när de körs på olika CPU: er, operativsystem, kompilatorer och till och med på en enda kompilator / CPU / OS-kombination, beroende på olika kompilatorinställningar. (Se sidofältet Syntax kontra semantik för en diskussion om skillnaderna mellan semantik och syntax.)

Java är annorlunda. Java ger mycket strängare semantik och lämnar mindre upp till implementatören. Till skillnad från C och C ++ har Java definierade storlekar och endianism för atomtyperna, samt definierat flytande punktbeteende.

Dessutom definierar Java mer beteende än C och C ++. I Java blir minnet inte frigjort förrän det inte längre kan nås och språket har inga oinitialiserade variabler. Alla dessa funktioner hjälper till att begränsa variationen i beteendet hos ett Java-program från plattform till plattform och implementering till implementering. Även utan JVM kan program som skrivs på Java-språket förväntas portas (efter omkompilering) till olika processorer och operativsystem mycket bättre än motsvarande C- eller C ++ - program.

Tyvärr har funktionerna som gör Java så bärbara en nackdel. Java antar en 32-bitars maskin med 8-bitars byte och IEEE754 flytande matematik. Maskiner som inte passar den här modellen, inklusive 8-bitars mikrokontroller och Cray-superdatorer, kan inte köra Java effektivt. Av denna anledning bör vi förvänta oss att C och C ++ används på fler plattformar än Java-språket. Vi borde också förvänta oss att Java-program hamnar lättare än C eller C ++ mellan de plattformar som stöder båda.

Java som en virtuell maskin: CPU-portabilitet

De flesta kompilatorer producerar objektkod som körs på en CPU-familj (till exempel Intel x86-familjen). Även kompilatorer som producerar objektkod för flera olika CPU-familjer (till exempel x86, MIPS och SPARC) producerar bara objektkod för en CPU-typ åt gången; om du behöver objektkod för tre olika familjer av CPU, måste du kompilera din källkod tre gånger.

De nuvarande Java-kompilatorerna är olika. I stället för att producera utdata för varje CPU-familj som Java-programmet är avsett att producera, producerar nuvarande Java-kompilatorer objektkod (kallad J-kod) för en CPU som ännu inte finns.

(Sun har meddelat en CPU som kommer att köra J-kod direkt, men indikerar att de första proverna av Java-chips inte kommer att visas förrän under andra halvåret i år. Full produktion av sådana chips kommer att börja nästa år. Sun Microelectronics picoJavaI-kärnteknik kommer att vara kärnan i Suns egen microJava-processorlinje, som riktar sig mot nätverksdatorer. Licensinnehavare som LG Semicon, Toshiba Corp. och Rockwell Collins Inc. planerar också att producera Java-chips baserat på picoJavaI-kärnan.)

För varje riktig CPU som Java-program är avsedda att köras, "kör" en Java-tolk eller virtuell maskin J-koden. Denna obefintliga CPU tillåter att samma objektkod körs på vilken processor som helst som en Java-tolk finns.

Att producera produktion för en imaginär CPU är inte nytt med Java: UCSD (University of California i San Diego) Pascal-kompilatorer producerade P-kod för flera år sedan; Limbo, ett nytt programmeringsspråk under utveckling hos Lucent Technologies, producerar objektkod för en imaginär CPU; och Perl skapar en mellanliggande programrepresentation och kör denna mellanrepresentation istället för att skapa inbyggd körbar kod. Den internetkunniga JVM skiljer sig från dessa andra virtuella CPU-implementeringar genom att avsiktligt utformas för att möjliggöra generering av bevisligen säker, virusfri kod. Innan Internet fanns det inget behov av virtuella maskiner för att bevisa att programmen är säkra och virusfria. Denna säkerhetsfunktion i kombination med en mycket bättre förståelse för hur man snabbt kör program för imaginära processorer har lett till snabb,omfattande acceptans av JVM. Idag har de flesta större operativsystem, inklusive OS / 2, MacOS, Windows 95 / NT och Novell Netware, antingen eller förväntas ha inbyggt stöd för J-kodsprogram.

JVM, som i huvudsak är en imaginär CPU, är oberoende av källkodsspråket. Java-språket kan producera J-kod. Men det kan Ada95 också. Faktum är att J-kodhostade tolkar har skrivits på flera språk, inklusive BASIC, Forth, Lisp och Scheme, och det är nästan säkert att implementeringar av andra språk kommer att avge J-kod i framtiden. När källkoden har konverterats till J-kod kan Java-tolk inte berätta vilket programmeringsspråk som skapade J-koden den kör. Resultatet: bärbarhet mellan olika processorer.

Fördelen med att kompilera program (på vilket språk som helst) till J-kod är att samma kod körs på olika familjer av processorer. Nackdelen är att J-kod inte körs lika snabbt som inbyggd kod. För de flesta applikationer spelar detta ingen roll, men för de högsta av avancerade program - de som behöver varje sista procent av processorn - kommer prestandakostnaden för J-kod inte att accepteras.

Java som ett virtuellt operativsystem och GUI: OS-portabilitet

De flesta Microsoft Windows-program skrivna i C eller C ++ hamnar inte enkelt till Macintosh- eller Unix-miljöer, inte ens efter kompileringen. Även om programmerarna tar extra hand om att hantera de semantiska svagheterna i C eller C ++, är porten svår. Denna svårighet uppstår även när porten till operativsystemet som inte är Windows äger rum utan att byta CPU. Varför svårigheten?

Efter att ha eliminerat de semantiska problemen i C och C ++ och CPU-portningsproblemen måste programmerare fortfarande hantera olika operativsystem och olika GUI API-samtal.

Windows-program ringer väldigt olika samtal till operativsystemet än Macintosh- och Unix-program. Dessa samtal är avgörande för att skriva icke-triviala program, så tills detta problem med portabilitet åtgärdas kommer portning att förbli svårt.

Java löser detta problem genom att tillhandahålla en uppsättning av biblioteksfunktioner (som finns i java-levererade bibliotek såsom awt, util, och lang) som prata med en imaginär OS och imaginära GUI. Precis som JVM presenterar en virtuell CPU presenterar Java-biblioteken ett virtuellt OS / GUI. Varje Java-implementering ger bibliotek som implementerar detta virtuella OS / GUI. Java-program som använder dessa bibliotek för att tillhandahålla nödvändig OS- och GUI-funktionalitetsport ganska enkelt.

Att använda ett portabilitetsbibliotek istället för inbyggda OS / GUI-samtal är inte en ny idé. Produkter som Visix Softwares Galaxy och Protools Software's Zink ger denna möjlighet för C och C ++. Ett annat tillvägagångssätt, som inte följs av Java, är att välja ett enda OS / GUI som master och tillhandahålla omslagsbibliotek som stöder detta master OS / GUI på alla maskiner som du vill porta till. Problemet med master OS / GUI-metoden är att de portade applikationerna ofta ser främmande ut på de andra maskinerna. Macintosh-användare klagade till exempel på en ny version av Microsoft Word för Macintosh eftersom den såg ut och beter sig som ett Windows-program, inte som ett Macintosh-program. Tyvärr har det tillvägagångssätt som Java har tagit också problem.

Java har tillhandahållit en funktion med minst gemensam nämnare i sina OS / GUI-bibliotek. Funktioner som är tillgängliga på endast ett OS / GUI, till exempel flikdialogrutor, utelämnades. Fördelen med detta tillvägagångssätt är att kartläggning av den gemensamma funktionaliteten till det inbyggda operativsystemet / GUI är ganska enkelt och med omsorg kan tillhandahålla applikationer som fungerar som förväntat på de flesta OS / GUI. Nackdelen är att det kommer att finnas funktionalitet tillgänglig för native-mode-applikationer som inte är tillgängliga för Java-applikationer. Ibland kommer utvecklare att kunna kringgå detta genom att utöka AWT; andra gånger kommer de inte. I de fall där önskad funktionalitet inte kan uppnås med lösningar väljer utvecklare troligen att skriva icke-bärbar kod.

Vem bryr sig om bärbarhet?

Tre huvudkretsar bryr sig om portabilitet: utvecklare, slutanvändare och MIS-avdelningar.

Utvecklare: Möjligheter och hot är stora

Utvecklare har ett intresse av att skapa bärbar programvara. På den övre sidan, bärbar programvara tillåter dem att stödja fler plattformar, vilket leder till en större bas av potentiella kunder. Samma portabilitet som gör det möjligt för utvecklare att rikta sig mot nya marknader gör det också möjligt för konkurrenter att rikta sig mot sin marknad.

I ett nötskal driver Java-portabilitet applikationsprogramvarumarknaden bort från segregerade marknader baserat på olika operativsystem och GUI och mot en stor marknad. På den aktuella programvarumarknaden är Microsoft till exempel en kraft att räkna med på applikationsmarknaden för Windows och Macintosh, men har nästan ingen närvaro på OS / 2 och Unix-marknaderna. Denna partitionering gör det möjligt för företag på OS / 2 och Unix-marknaderna att bortse från Microsoft som en konkurrent. Java gör det lättare för dessa företag att konkurrera på Windows-marknaden, men gör det också lättare för Microsoft att komma in på OS / 2 och Unix-marknaden.

Användare: De indirekta mottagarna av bärbarhet

Användarna bryr sig i sig inte om bärbarhet. Om bärbarhet gör deras liv enklare och trevligare, är de allt för det; om inte är de inte. Bärbarhet har vissa positiva effekter för användarna, men dessa är något indirekta. De positiva effekterna: