Microsoftu przygody z Javą
Zakładając chwilowo, że mam jakichkolwiek „stałych czytelników”, przypuszczam, że dość prędko dostrzegli oni, że nie przepadam za Javą. Jestem świadom tego, jaki problem usiłowała rozwiązać, twierdzę jednak, że boleśnie widocznym jest to, że cierpi ona na przypadłości pioniera: przed Javą nie istniało nic podobnego (a na pewno nie na taką skalę), zaoferowane rozwiązania były technicznie eleganckie i bezkonkurencyjne, lecz wciąż było to niejako pierwsze podejście. Mimo wielu nowych iteracji i niezwykle długiej drogi przebytej przez Javę, jej specyfika niezmiennie mnie denerwuje. Dostaję ciężkiej, plamistej cholery widząc ładowanie NetBeansa i Eclipse’a, notorycznie napotykam na małe, acz rozwścieczające niedoróbki (zwane „decyzjami projektowymi”), a przebywanie w tym samym pomieszczeniu z komputerem zawierającym jakiekolwiek oprogramowanie korzystające ze Swinga skraca mój lifespan o wiele miesięcy. Nie wspominając o pulpitowym JRE, które już niemal na pewno zostało stworzone przez bandę lobotomizowanych małp na cracku, nieumiejących napisać żadnej poprawnie działającej aplikacji, tworząc koszmar wdrożeniowca, zanieczyszczający dziewicze połacie świeżo zainstalowanych systemów lepkim szlamem absolutnie nieinstalowalnego oprogramowania.
Będąc dwukrotnie młodszym, niż obecnie, natknąłem się na cudo o nazwie C#. Było to jeszcze w czasach .NET Frameworka 1.1, ale natychmiast odkryłem, że jest to Java zrobiona poprawnie. Przeczytana w Linux+ recenzja, opisująca (przy okazji Mono) C# jako „nową, ulepszoną Javę i górę pieniędzy wydaną na marketing” jest oczywiście słuszna. Ponadto, C# do niedawna nie wywiązywał się ze swoich obietnic o wiele bardziej, niż Java: projektowa przenośność była marnowana brakiem implementacji wirtualnej maszyny na środowiska inne, niż Windows (zresztą nie wszystkie), a przyrośnięcie do technologii Microsoftu bywało straszną kulą u nogi. Nie pomagała certyfikacja ECMA.
Skąd w ogóle Microsoft wytrzasnął C#? Ten produkt jest zaskakująco dobry jak na myśl projektową owej firmy. Zdając się na nich w całości, oczekiwałbym raczej czegoś w stylu Visual Basic.NET, a tu taka niespodzianka. VB (zarówno .NET, jak i legendarne 6.0) poszło w odstawkę, a postawiono właśnie na C#. Czy taki wynalazek może wziąć się znikąd? Oczywiście, może. Można było zlecić stworzenie produktu od zera ludziom z zewnątrz, a następnie przejąć do niego wszystkie prawa (a autorów rozstrzelać). Ale Microsoft nie wymyślił C# w jedną noc. Wszak chodził wokół Javy od bardzo dawna. I mimo, że C# uchodzi za „Javę od Microsoftu”, w istocie istnieje prawdziwa Java od Microsftu i nie jest nią C#. Co więcej, takich „Jav” jest więcej. Ach, no i oczywiście jakimś cudem znowu doskonale to pamiętam.
Moja ukochana Java prędko urosła do rangi cudownego dziecka. W ogóle, w latach 90tych ludzie o wiele bardziej i o wiele łatwiej ekscytowali się oprogramowaniem. Netscape niemalże doprowadził do wytrenowania bojówek pseudokibiców, a Java zarażała swoją nazwą poboczne technologie, wedle powszechnego przekonania, że wszystko z Javą w nazwie jest skazane na sukces. Efektem tej urokliwej mentalności było nazwanie LiveScriptu – JavaScriptem. A ma on z Javą tyle wspólnego, co krzesło z krzesłem elektrycznym. Nie powinno być więc zaskoczeniem, że Javą zainteresował się również Microsoft. Należy w tym momencie pamiętać, że Microsoft z owych czasów dość bezkompromisowo stosował politykę „embrace-extend-extinguish ”, więc Java od Microsoftu nie mogła być taką po prostu zwykłą Javą.
Pod koniec grudnia 1996, pakiet Microsoft Visual Studio, „ostateczne” IDE dla Windows, wzbogaciło się o nowego kolegę. Na świat przyszedł Visual J++. Już sama nazwa sugeruje, co tu się dzieje. Programista początku lat 90tych miał następujący wybór: albo C++ albo jakiś horror, niemal zupełnie do niego niepodobny. Taki krajobraz sprzyjał przekonaniu, że Java to taki lepszy C++. Więc nazwa „J++” miała podkreślać, że oto połączono zalety Javy z wiarygodnością C++. To pierwsze znaczenie. Istnieje jednak drugie, bardziej niepokojące. Otóż rodzi się pytanie, na ile (i na jak długo), owa „lepsza Java” pozostanie zgodna z Javą prawdziwą. Pytanie wcale niepozbawione sensu, ponieważ migracja projektów była niemożliwa: kod Javy wymagał ręcznego przeniesienia klas, a wrzucenie kodu J++ w kierunku kompilatora javac skutkowało błędami już w pierwszych liniach. To wszystko nie był dobry znak.
Powierzchownie wszystko było w porządku: IDE umożliwiało stworzenie pliku wykonywalnego lub apletu, uruchamianego jako komponent dokumentu HTML. Wynika z tego, co jest cwanym zabiegiem, konieczność instalacji Internet Explorera. Oraz maszyny wirtualnej Javy. Od Microsoftu. Visual Studio mocno tego pilnował. Nawet, gdy nie instalowaliśmy żadnych komponentów J++, Internet Explorer lądował w systemie. Blokującym błędem był również brak maszyny wirtualnej Javy. Jej instalacja była obowiązkowa. Oczywiście, był to pierwszy krok do uniemożliwiania instalacji „prawdziwej Javy”, ten od Sun Microsystems. Skoro już wciskamy własną przeglądarkę, czemu nie wcisnąć własnego środowiska uruchomieniowego? Co nam pan zrobi?
Jak przeciągnąć programistów nauczonych Javy w stronę Microsoftu? Wiemy już, że trzeba stworzyć „prawie Javę”. Ale co to znaczy? Krok pierwszy to zaimplementować 80% referencyjnej biblioteki klas. To już jest dobry start. Kolejny krok to koniecznie zawrzeć w brakujących 20% jedną, ale całkiem istotną część konkurenta. Na przykład takie RMI. Po co komu RMI? Przecież mamy własny most do zdalnego wywoływania procedur, nazywa się DCOM. Się przeszkoli, sypnie przykładowym kodem i nikt za RMI nie będzie tęsknił, tylko grzecznie pisał kod z DCOM. Będziesz pan zadowolony. A jak ktoś będzie chciał odpalić program używający RMI? No cóż – potrzebuje Javy od Suna. Niezgodnej z maszyną od Microsoftu, która oczywiście nie może funkcjonować w systemie równolegle. Skutkiem ubocznym będzie utrata międzyplatformowości kodu, bo VM jest upośledzony i inny od tego np. na Uniksach, ale to nie problem. Windowsa sobie pan kupi i wszystko będzie OK. Macie serwery na procesorze Alpha? Nie szkodzi, zrobiliśmy Windows NT dla tej architektury. Obiecujemy całkowicie porzucić wsparcie dla tego systemu, jak tylko go kupicie!
Microsoft oczywiście miał szereg wymówek, dlaczego nie chce dołączać Javy do swojego systemu. Szczególnie zabawny, z perspektywy czasu, jest niezwykle arogancki ton przedstawicieli firmy, wyrażony słowami „good luck, it won’t work in Internet Explorer”. No ale to, wedle norm z 1996, jeszcze nie jest wystarczająco bezczelne. Należy podjąć kolejne kroki rozwalające zgodność z Javą, na innych polach. Dlatego też J++ oferował możliwość „odblokowania potencjału systemu Windows” poprzez możliwość odwoływania się do Win32. Przypominam, że cały sens JVM (i .NET, o którym za chwilę) polega na tym, że kod odwołuje się wyłącznie do wirtualnej maszyny. To maszyna martwi się, jak zaimplementować funkcjonalność języka w systemie. Kod ma być ten sam. Tymczasem J++ pozwalał stworzyć kod przenośny między platformami… aż do pierwszego wywołania Win32. Oczywście, dzięki temu często rozwiązywało się jakiś doraźny problem. Przekreślało to jednak przenośność kodu. O to właśnie chodziło Microsoftowi.
Ostatnim krokiem obrzydzania Sunowskiej Javy była… optymalizacja środowiska. To jest ciekawy detal, zaskakująco prędko zapomniany. Microsoft stworzył najszybszą maszynę wirtualną Javy na rynku. Stan ten utrzymywał się kilka lat – Sun nie umiał ich przegonić. Dlatego dużo interaktywnych stron Web (w praktyce serwujących aplet), aby utrzymać wysoką wydajność i dostępność, wybierało MSJVM. A skoro już serwują to na Windowsie, to można by użyć DCOM. A jakiś tam brak doimplementować wywołaniem WinAPI... i czarodziejsko lądowało się w kleszczach Visual Studio, tylko dlatego, że szyld na drzwiach wejściowych miał napisane „Java”.
Takie akcje oczywiście nie zawsze pozostają bezkarne. Sun prędko zorientował się, że nadchodzi katastrofa. Jeżeli soft pisany w Javie masowo „rozjedzie się” ze standardem i zacznie powoływać na jego cudzą, zbastardyzowaną wersję, Sun utraci kontrolę nad swoim produktem. Zalety Javy zmienią się w dodatku trampolinę dla popularności Windowsów. Sun zostanie bez oferty dla programistów, a wkrótce potem – dla całego rynku IT. Microsoft tylko udawał, że kocha Javę. W międzyczasie wszak dusił Netscape’a, który przypadkiem wygadał się, że chce stworzyć chmurowy pulpit niezależny od systemu, a Windows to nic ponad „zbiór kiepsko napisanych sterowników”. Słynne słowa o odcięciu dopływu powietrza Sun potraktował z pełną, i zasadną, powagą.
Dlatego trzeba było nacisnąć wielki czerwony przycisk z napisem „POZEW”. Swoją drogą i to jest zabawne. Obecnie właścicielem Javy jest Oracle. Oracle, jak powszechnie wiadomo, nie ma klientów. Oracle ma zakładników. I nie zatrudnia żadnych programistów, a jedynie armię prawników, zdolnych wywalczyć odszkodowania nawet, gdy Oracle przestanie oferować jakikolwiek produkt. Pozwy są plagą Javy i to, co rozpętano 20 lat temu, prawdopodobnie nie skończy się już nigdy.
Istotnie, rok po wydaniu J++ i kilka miesięcy po udostępnieniu przełomowego Internet Explorera 4.0, z wbudowanym MSJVM, Sun Microsystems pozwał Microsoft za niekompletną implementację standardu przy jednoczesnej sprzedaży produktu używającego zastrzeżonej i chronionej standardem nazwy „Java”. Pół roku później, zarzut żerowania na standardach celem osaczenia i wrogiego przejęcia klientów stał się jednym z najważniejszych na długiej liście aktów monopolistycznych, w głośnym procesie „Stany Zjednoczone versus Microsoft Corporation”.
Był to w praktyce pozew o przyszłość Javy. Długi, męczący, ciągnący się przez 4 lata i pełen wzajemnych nieuprzejmości zakończył się ugodą. Bardzo korzystną dla Sun Microsystems. Javę z MSJVM i przede wszystkim całą hecę z J++ uznano na niespełniającą standardów i celowo złośliwą implementację. Maszyna MSJVM miała zostać usunięta ze wszystkich produktów Microsoftu. A środowisko uruchomieniowe J++ nie mogło kopiować nowych funkcji, wprowadzanych do Javy przez Suna. Albo Microsoft stworzy maszynę Javy zgodną ze standardem albo J++ ma pozostać odrębnym, różnym od Javy językiem programowania. Microsoft musiał się zgodzić, bo alternatywą było przyznanie wprost „my wcale nie chcemy rozwijać J++, używamy go, żeby kraść wam klientów!”. Dzięki owej ugodzie rozwój J++ ustał. Ostatnią wersją był Visual J++ 6.0, należący do IDE98. Nowe Visual Studio nie nadchodziło, bo przeżywało przemianę w środowisko .NET, a tam miejsca na J++ nie będzie na pewno. Stąd też problem z rozjeżdżającym się standardem został zażegnany. Natomiast z maszyną MSJVM było trudniej. Teoretycznie, miała ona zniknąć z powierzchni Ziemi. I faktycznie, zniknęła z Centrum Pobierania bardzo szybko. Co więcej, zobowiązano się do niedodawania Javy do nowego Windows XP, a następnie wycofania z obiegu kilku wersji Microsoft Office, Internet Explorera oraz systemów Windows 98 i Windows Millennium Edition. Zastanawialiście się kiedyś, dlaczego na MSDN Imagine można pobrać MS‑DOS 6.22, ale nie Windows 98? No więc właśnie dlatego!
Microsoft był jednak ociężałą bryłą i często wydawało się, że jego niedopatrzenia to przejaw okrutnego poczucia humoru. Zainstalowane kopie Internet Explorera, napotykające aplet Javy na stronie internetowej, wyświetlały okno „Instalowanie na żądanie” z prośbą o doinstalowanie MSJVM. Wyrażenie zgody przeprowadzało skuteczną instalację owego oficjalnie uznanego za „nielegalne” oprogramowania. A miało to miejsce tylko na nowych instalacjach Windows XP. Przecież w użytku były miliony komputerów z już zainstalowanym MSJVM…
To jednak nie jest wystarczający trolling. Większą hecą był Service Pack 1 do Windows XP. Ponieważ Microsoft świadczył wsparcie techniczne (i aktualizacje zabezpieczeń) dla już istniejących kopii Javy, pakiety serwisowe aktualizowały w systemie również Javę, gdy była zainstalowana, ale tylko jako element systemu (samowolne instalacje się nie liczą). Trwała wtedy kiepsko udokumentowana wojenka, czy należy pozwalać ludziom instalować stare MSJVM na XP, czy może podrzucić im jej zaktualizowaną wersję, czy może zachować się po ludzku i wrzucić do Service Packa 1 wersję od Suna. Oryginalny Windows XP, ze względu na toczące się postępowanie, Javy nie miał. (Or did it? Moja kopia nie ma, ale podobno były takie, co miały… )
Zdecydowano się na wariant drugi, wzbogacając XP, wraz z Service Packiem 1, o antyczną Javę od Microsoftu, w wydaniu z poprawkami. Wtedy sąd apelacyjny powiedział, że taka akcja nie przejdzie. Że prawidłowym rozwiązaniem jest dostarczać Javę od Suna. Biedny sędzia nie wiedział, że takie coś nie mieści się w głowie nikomu w Microsofcie. Dlatego w roku 2003, Service Pack 1 przepakowano, celem ponownego usunięcia Javy. Na zawsze. That sort of thinking got us into this mess. Teraz mamy moje JVM od Oracla… Czy była to wystarczająca nauczka dla Microsoftu, aby nie stosować polityki „embrace-extend-extinguish”? Oczywiście, że nie. Zdumiewającym jest jednak, że śmieszki z Redmond nie tylko nie przestali forsować własnych interpretacji standardów. Robili to dalej z samą Javą. To jest niezła niespodzianka. Zanim ją wyjaśnimy, warto zwrócić uwagę na to, co podczas wojen o Javę, stało się z Visual Studio.
Microsoft odkrył potencjał Web Service’ów. Wiele złego można powiedzieć o (zapomnianym już dziś nieco) DCOM RPC, ale podstawowe jego założenie, czyli możliwość uruchamiania wspólnego kodu i wywoływania procedur na obszarze należącym do wspólnej przestrzeni nazw („domenie”) jest idealnym scenariuszem dla rozproszonych aplikacji. Niestety, DCOM (RMI zresztą też) w wielu przypadkach bardzo kiepsko się skaluje. Bywa też szalenie niebezpieczny. Dlatego kiepsko się nadaje do wykorzystania w internecie. A Internet w owym czasie czynił pierwsze kroki na drodze oferowania oprogramowania jako usługi. Stąd też pojawił się plan udostępnienia oprogramowania jako zbioru komunikujących się ze sobą mikrousług, do których da się subskrybować. Bez wykorzystania ActiveX czy innych okropności. Komunikacja przebiegałaby obiektowo i z wykorzystaniem XML. Mocne słowa. Mocne i zachęcające – brzmi to bowiem jak naturalny krok w branżowej ewolucji, znaczący rozwój podstaw projektowych, zaoferowanych kilka lat wcześniej przez Javę. Pierwszy raz usłyszeliśmy o owej nadchodzącej potędze w 2000 roku. Nosiła ona wtedy nieznośną nazwę „Next Generation Windows Services”. Następnie przemalowaną ją na nieco bardziej strawną - .NET Framework.
Co oferował .NET w roku 2000? Cóż, nic. Należało więc pójść drogą Javy i przylepiać etykietki do produktów, które już istnieją. Dzięki temu usługa profilu Hotmail zmieniła się w .NET Passport, MSN Messenger, w .NET Messenger Service, a budowany w pośpiechu Whistler, czyszczący backlog projektowy Windows 2000, miał nosić dumne miano „Windows.NET 1.0” (poważnie).
Naturalnie, nowych wspaniałych serwisów nie można było pisać w Javie. Potrzebny był więc nowy język (i środowisko uruchomieniowe). Ze swej natury (i ze względu na autora, który stworzył również J++), musiał on być podobny do Javy. Tak powstał C#. Poprawnie zrobiona Java. .NET Framework został zaś poprawnie zrobioną maszyną wirtualną. Dzięki niej C#, podobnie jak Java, był niezależny od systemu operacyjnego. Tak długo, jak na ów system wydano maszynę wirtualną (CLR). Widać tutaj wojnę inżynierów z marketingowcami: stworzono coś uniwersalnego, a następnie wydano tylko dla Windows (oraz FreeBSD! Pewnie mi nie wierzycie!). Zmieniło się to 15 lat później.
C# zadebiutował w spóźnionym Visual Studio 7.0, nazwanym (a jakże!) Visual Studio.NET. Dzięki niemu, w połączeniu z nową wersją ASP (ASP.NET) możliwe było tworzenie nowej generacji usług Web. Tym razem nie trzeba było się uciekać do podłych sztuczek, by przyciągnąć programistów Javy. C# nie był celowo błędną implementacją JVM, aczkolwiek zachowano go „w duchu” swojej starszej siostry. Udało się wzbudzić zainteresowanie branży oferując wysokiej jakości produkt, a nie ładnie opakowaną podróbkę. Javowcom łatwo było się nauczyć nowego języka, a tworzone aplikacje mogły pracować albo na pulpicie, albo w przeglądarce WWW, bez konieczności doinstalowania żadnych koszmarków. Microsoft najwyraźniej raz na zawsze rozwiązał swój kompleks względem Javy i uniknął wszelkich problemów prawnych…
Postanowiono jednak zastosować niebezpieczną grę, którą Steve Ballmer nazwał kiedyś „ujeżdżaniem niedźwiedzia”. Gdy udaje się mocno trzymać niedźwiedzia, da się dotrzeć na nim do celu. Jeżeli jednak z niedźwiedzia się spadnie, jedynym losem jest pożarcie. Na polu usług sieciowych, niedźwiedziem był Sun, ze swoją Javą. Microsoft mógł trzymać się niedźwiedzia i biec razem nim, bo tracąc równowagę narażał się na pozwy i śmierć. Tą śmiercią zginął J++. Tym razem należało jechać na niedźwiedziu, dziergać swoje ASP.NET, gdy Sun buduje swoje JSP. Idąc na wojnę z Sunem, Microsoft spadłby z niedźwiedzia i jego C# zostałby ususzony w kolejnej nieczystej batalii patentowej. Dlatego nie wolno drażnić niedźwiedzia, nie wiercić się i grzecznie jechać na jego grzbiecie.
Microsoft, co w dalszym ciągu mnie zdumiewa, postanowił rozdrażnić niedźwiedzia i podejść do Javy ponownie. Podczas, gdy przeprawy sądowe zakończyły się wątłą ugodą, a nowy C# zaoferował atrakcyjne dla programistów rozwiązanie o konkurencyjnej funkcjonalności, zaprezentowano światu język J#.
Borze iglasty, dlaczego. C# był przecież na tyle zrozumiały dla Javowców, że istnienie języka-mostu było niepotrzebne. Nieuzasadnione i ryzykowne. Czy był to przejaw arogancji? Nagłe zwątpienie, że C# jednak nie jest „wystarczająco dobry” dla programistów rozwiązań Suna? A może jest to kolejny dowód na to, że od swego powstania, Microsoft jest zbiorem wiecznie walczących ze sobą, wrogich obozów o agresywnie odmiennych poglądach?
J# został całkowicie zignorowany. Pojawił się w Visual Studio 2003 i odszedł w Visual Studio 2008. Myślę, że od początku biła od niego aura „ależ jest to nieziemsko zły pomysł” i nabrała się na niego grupa jeszcze mniejsza, niż rycerze żenady od Silverlighta. J# wymagał nawet oddzielnego środowiska uruchomieniowego! Sam .NET Framework, jakimś cudem, nie wystarczał. Schizofreniczny język był w dodatku reklamowany jako kontynuacja przeklętego J++. Przecież to jest jawne proszenie się o kłopoty! Niczym osoba skazana za molestowanie seksualne, J# na każdym kroku musiał informować użytkownika „this is not endorsed by Sun Microsystems, Inc.”. Tymczasem Sun nawet nie zareagował na nowe, dziwne podchody wokół Javy. Być może oceniono, że inicjatywa umrze na tyle szybko, że nie warto się o nią sądzić. Racja. Ale Microsoft też nieco na tym skorzystał, sondując niejako, jak bardzo w dobie C#, Sun będzie się ich dalej czepiać.
Nikt nie zna żadnego programisty J#, ponieważ tacy ludzie, podobnie, jak posiadacze licencji na WinRARa, zwyczajnie nie istnieją. Pożegnanie ze środowiskiem uruchomieniowym J# nastąpiło w roku 2007, gdy Visual Studio, Windows i MSDN raz na zawsze przestały oferować cokolwiek związanego z Javą. Nastąpiły czasy powszechnie panoszącej się maszyny JVM dostarczanej przez Oracle. Na temat owego odrażającego, niechlujnego nowotworu, toczącego niegdyś wszystkie laptopy, a dziś instalowanego dobrowolnie (!!) przez rzesze masochistów, już niegdyś pisałem.
Epilog
Być może uda mi się dotrwać do czasów, których runtime Javy nie przewala się przez komputery w moim pobliżu. Wszak strony napisane w JSP nie wymagają ode mnie skażenia oślizłym JRE, a potrafią być doskonałe, o wiele lepsze, niż niejedna strona w PHP. Pozostaje mi jedynie czekać, aż to nastąpi. I patrzeć z oddali, jak Microsoft ujeżdża kolejnego niedźwiedzia…
Cheers!