Бета-версия Java 1.1 компании Netscape тоже содержит модификации
Недавно компания Sun Microsystems подала в суд на Microsoft, обвинив последнюю в нарушении условий договора по вопросам совместимости Java. Sun утверждает, что Microsoft внесла не оговоренные в контракте изменения в основные библиотеки классов Java. В данной статье специалист по Java Джон Зуковски приводит список классов, методов и переменных, добавленных в Microsoft SDK for Java и изъятых из него. В статье подробно описывается то, о чем многие упоминают лишь вскользь - модификации и их значение для разработчиков. Кроме того, автор дает указания, как с помощью Microsoft SDK писать программы, соответствующие принципу "написано однажды - работает везде", и как создавать приложения, работающие с Microsoft Internet Explorer 4.0.
Совсем недавно вышел Microsoft Internet Explorer (IE) 4.0, и вот компания начала поставки версии 2.0 пакета средств разработки Software Developers Kit (SDK) for Java. Согласно документу Win32 Virtual Machine for Java Release Notes, с IE 4.0 поставляется та же версия виртуальной машины (VM) для Java, что и с новым SDK. Мой опыт использования файлов классов Java, поставляемых с этим SDK, и сравнение их с файлами классов Java, которые поставляются с версией 1.1.4 пакета Java Development Kit (JDK) компании Sun? полностью объясняют, почему президент JavaSoft Алана Баратц сказал: "Microsoft обманным путем модифицировала основные классы Java и встроила их в свой SDK". Эти слова были произнесены на пресс-конференции Sun, где компания давала разъяснения по поводу ее судебного иска против Microsoft.
Я проанализировал классы и обнаружил семь областей, которым следует уделять особое внимание при разработке приложений с помощью Microsoft SDK for Java, если вы хотите, чтобы они работали в других средах, сертифицированных на соответствие Java 1.1.
1. Новые классы.
2. Новые методы.
3. Новые переменные.
4. Модифицированные интерфейсы.
5. Библиотеки com.ms.
6. Отсутствующие методы.
7. Различия в поведении объектов.
Как видно из этого списка, речь идет о чем-то гораздо более существенном, нежели отсутствие поддержки JNI и RMI, которая часто упоминается в статьях на эту тему.
Баратц употребил выражение "обманным путем", потому что в сопровождающей SDK документации (файл javadoc) ни слова не сказано о вышеупомянутых изменениях. Чтобы убедиться в их наличии, можно воспользоваться средством ClassVue, поставляемым с этим SDK или просто посмотреть исходный текст. Первый вариант предпочтительнее, поскольку для генерации некоторых классов использовался не тот исходный текст, который поставляется с SDK. Незнакомые с ClassVue разработчики могут воспользоваться его аналогом из JDK - javap.
Я постарался предоставить на ваш суд максимально полный список изменений, но мог что-то и упустить. В ряде случаев сказанное относится к группе элементов, поэтому использовать методы с именами, похожими на упомянутые в статье, также не рекомендуется. Все описанные ниже проблемы касаются библиотек java.lang, java.io, java.awt, java.util и java.security.
Что же изменено в каждой из библиотек?
Что здесь делает этот класс?
Первая категория изменений, обнаруженных в Microsoft SDK for Java, относится к новым классам, методам и переменным, добавленным в системные библиотеки. Системные библиотеки, или ядро Java API, - это библиотеки, в которых полные имена классов начинаются с java.*. В java.awt было введено 16 новых классов.
Новые классы Microsoft для работы с peer-компонентами AWT
WButtonPeer | WCheckboxMenuItemPeer | WCheckboxPeer | WChoicePeer |
WLabelPeer | WListPeer | WMenuBarPeer | WMenuItemPeer |
WMenuPeer | WPopupMenuPeer | WScrollbarPeer | WScrollPanePeer |
WTextAreaPeer | WTextComponentPeer | WTextFieldPeer | WUIPeer |
За исключением последнего, все эти классы содержат функции для работы с объектами типа peer, т.е. платформно-зависимыми представлениями графических компонентов, например кнопок или меню. Вообще говоря, эти классы должны были поставляться в отдельной библиотеке, подобной sun.awt.windows или sun.awt.motif. А так как использовать их необязательно, от этого можно с легкостью отказаться. WUIPeer - это тоже peer-класс, но он содержит методы, которые будут работать только в JVM производства Microsoft. Старайтесь не использовать и его. Кроме того, Microsoft ввела новые классы с атрибутом доступа package-private (т.е. доступные лишь в пределах библиотеки), в частности __AwtUIBand и __UIMenuRoot. Поскольку за пределами java.awt их вызвать нельзя, вы не сможете использовать их напрямую.
Откуда взялись эти методы и переменные экземпляров?
Наиболее важный из новых методов называется getBaseName(). Хорошо еще, что он снабжен атрибутом доступа package-private (хотя вообще говоря, его следовало бы сделать просто private, т.е. доступным только в пределах класса). Остальные изменения, например назначение методу loadClassInternal() атрибута private вместо package private, связаны с особенностями реализации, и не должны беспокоить разработчиков.
Не пытаясь приуменьшить роль изменений, произведенных Microsoft внутри библиотек, я хочу заметить, что разработчики не смогут получить к ним доступ, если только не будут расширять системные библиотеки самостоятельно. Поскольку разработчики кросс-платформенных приложений никогда не сделают подобной ошибки, никаких проблем, надеюсь, здесь не возникнет.
Настоящие же проблемы связаны с новыми методами Microsoft, снабженными атрибутом доступа public (т.е. общедоступными).
Public-методы, введенные Microsoft в основные библиотеки Java
Класс | Новые методы |
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) |
Если вы не хотите, чтобы ваши Java-программы работали только в среде Microsoft, не используйте эти методы. Кроме них Microsoft добавила три новые переменные и множество констант, определяющих национальные установки.
Переменные, добавленные в Java API
Класс | Новая переменная | |
java.awt.Font | pData | |
java.awt.SystemColor | appWorkspace | |
java.lang.reflect.Member | PUBLIC_DECLARED | |
java.util.Locale | AFRIKAANS | KOREAN_VERTICAL |
ALBANIAN | LATVIAN | |
AUSTRALIA | LITHUANIAN | |
BASQUE | MEXICAN | |
BELGIAN | NEWZEALAND | |
BELGIAN_FRENCH | NORWEGIAN | |
BRAZILIAN | NORWEGIAN_NYNORSK | |
BULGARIAN | POLISH | |
BYELORUS | PORTUGESE | |
CATALAN | ROMANIAN | |
CROATIAN | RUSSIAN | |
CZECH | SERBIAN | |
DANISH | SIMPLIFIED_CHINESE_VERTICAL | |
DUTCH | SINGAPORE | |
ESTONIAN | SLOVAKIAN | |
FINNISH | SLOVENIAN | |
GERMAN_AUSTRIAN | SOUTH_AFRICA | |
GERMAN_SWISS | SPANISH | |
GREEK | SPANISH_MODERN | |
HEBREW | SWEDISH | |
HUNGARIAN | SWISS | |
ICELANDIC | THAI | |
INDONESIAN | TRADITIONAL_CHINESE_VERTICAL | |
IRELAND | TURKISH | |
JAPANESE_VERTICAL | UKRANIAN |
PUBLIC_DECLARED - новая переменная класса Member, appWorkspace - новая перменная SystemColor, а pData ранее была определена как private, а стала public. Совет прежний - не используйте эти переменные. Судя по объектам Locale, среда Microsoft понимает несколько языков, "незнакомых" среде JavaSoft. Это, конечно, неплохо, но тем не менее для обеспечения совместимости вместо использования новых констант Microsoft вам придется создавать объекты Locale с необходимыми параметрами самостоятельно. Правда, в этом случае потребуются некоторые дополнительные усилия при форматировании сообщений.
Для каждой новой константы Locale в библиотеку java.text.resource добавлены по два класса типа public. Поскольку, согласно документации Sun, не рекомендуется напрямую вызывать функции API из text.resource, я считаю, что никакой опасности эти дополнения не создают.
Модифицированные интерфейсы
Интерфейс определяет шаблон (template), которому должен соответствовать класс. Microsoft изменила шаблоны некоторых интерфейсов библиотеки java.security.
Новые методы в интерфейсах java.security
Интерфейс | Новые методы |
java.security.interfaces.DSAPrivateKey | getAlgorithm(), getEncoded(), getFormat(), getParams() |
java.security.interfaces.DSAPublicKey | getAlgorithm(), getEncoded(), getFormat(), getParams() |
При создании класса, использующего интерфейс, для каждого его метода необходимо описать свой метод внутри класса. Увеличивая число методов в интерфейсах, Microsoft делает неработоспособными в своей среде все классы, использующие интерфейсы, определенные в JDK. Если вы хотите, чтобы ваша программа работала как в среде Microsoft, так и в других средах, то всякий раз при использовании одного из вышеуказанных интерфейсов вам придется самостоятельно описывать новые методы.
Com.ms изнутри
Com.ms - это группа классов, поставляющаяся в составе предложенной Microsoft реализации Java 1.1. Классы библиотек com.ms недоступны пользователям Netscape Navigator/Communicator и сред, соответствующих спецификации Java 1.1. Если вы решили воспользоваться каким-либо классом библиотеки com.ms, то весьма вероятно, что вы лишите свою программу переносимости. В качестве примера приведу получение FontMetrics с помощью метода getFontMetrics() класса Toolkit. Несмотря на то, что метод объявлен в соответствии со стандартом (public FontMetrics getFontMetrics()), на самом деле он возвращает копию объекта com.ms.awt.FontMetricsX. Если вы будете затем использовать полученное, как FontMetricsX, ваша программа заработает только в JVM Microsoft; используя же FontMetrics, вы сохраните переносимость программы.
Из правила неиспользования классов com.ms есть исключение - классы AFC (Microsoft Application Foundation Classes) из библиотеки com.ms.ui написаны на чистом Java, поэтому их применять можно. Однако, если у пользователей вашей программы нет IE 4.0, вам придется предоставить им AFC отдельно.
(Впрочем, этого не следует делать, пока Microsoft не выпустила кросс-платформенную реализацию AFC: классы AFC, встроенные в IE 4 и SDK, используют некоторые особенности, свойственные только виртуальной машине Java, разработанной Microsoft. Компания вскоре обещает выпустить AFC для других браузеров, в частности для Netscape Navigator 3.0. Подробности можно узнать на Web-узле Microsoft.)
Чего нет в SDK?
Из всех классов, которые я просмотрел, в предлагаемой Microsoft реализации Java 1.1 не представлен один-единственный метод. Отсутствие метода, пусть даже одного, пусть даже незначительного - серьезное нарушение. В классе java.io.ByteOutputStream нет метода toString(), параметром которого является имя конвертера буферизованных данных в символьную строку (ByteToCharConverter). Такое преобразование позволяет выводить на экран текст сообщений в определенной кодировке. В отсутствие метода toString() можно применить обходное решение, получив с помощью toByteArray() данные из потока в чистом виде и преобразовав их в нужную кодировку с помощью конструктора String. Строго следуя этому указанию (при работе с JDK и другими средами), вы всегда получите программу, которая будет работать в среде Microsoft.
Что в SDK по-другому?
Мы подошли к категории отличий, которые не имеют отношения ни к новым классам, ни к новым методам. Я говорю об отличиях в поведении объектов. С переходом на новую среду не стоит ожидать, что она будет вести себя так, как вы привыкли. Например, когда вышел Netscape Navigator 3.0 beta 5, оказалось, что в нем расширено число AWT-событий, о которых получают сообщения программы. Программы, не адаптированные к этим изменениям, вели себя непредсказуемо. С новым SDK вас ожидают аналогичные трудности.
На запрос о версии виртуальной машины Java Microsoft для Win32 она выдает "1.1" (заметьте, просто "1.1"). Сейчас Sun поставляет JDK версии 1.1.4. Другими словами, в JVM компании Microsoft может не оказаться некоторых дополнений или исправленных ошибок. Возможно, ошибок и не было (в связи с особенностями реализации) или Microsoft самостоятельно исправила их, не изменив номер версии. Однако, если вы посмотрите на исходные тексты классов в JDK и SDK, вы легко заметите их функциональные различия. Потому, даже если вы не использовали новые методы, созданная в SDK программа все равно может вести себя в JDK по-другому.
Приведу пример. Если вы, используя java.awt.BorderLayout, создаете компонент, не указывая названия квадранта (South, East, North, West или Center), JDK и Java Runtime Environment поместят его в центральный. При создании компонента с недопустимым именем квадранта (например, "Top"), вызов BorderLayout повлечет сообщение об ошибке IllegalArgumentException. Та же программа (пытающаяся создать компонент без названия квадранта), запущенная в среде Microsoft, вообще не выводит компонент. (Компонент Swing JFrame, например, из-за этого становится невозможно использовать). Еще одно отличие: при вызове класса Dialog с нулевым значением параметра Frame (родительский объект диалога) JDK выдает сообщение IllegalArgumentException, тогда как среда Microsoft допускает такой вызов. По мере использования разных программ в IE 4.0 обнаружатся и другие отличия этого типа.
Для специалистов расскажу еще кое о каких изменениях. Некоторые отличия (а иногда - улучшения) могут остаться не замеченными разработчиками. Например, блокировку (locking) объекта можно выполнять на различных уровнях (удобство, дающее SDK некоторое преимущество). Надеюсь, что улучшения, введенные Microsoft, найдут свое отражение в JDK, и наоборот. В JDK стоит перенести и ряд усовершенствований SDK в отношении производительности. Например, при попытке изменить цвет или шрифт компонента, в среде Microsoft выполняется проверка, не равно ли новое значение старому. В среде Sun модификация выполняется даже если это не нужно. Подобные незначительные улучшения в совокупности дают существенное повышение производительности.
Последствия
Итак, мы выяснили, что Microsoft изменила основные библиотеки классов Java. Имеет ли компания на это право в соответствии с контрактом Sun, предстоит решить суду. Хотя в целом изменения относительно невелики, сути дела это не меняет. Если суд решит, что модификации не имеют значения, то Microsoft в дальнейшем почувствет себя вправе вносить любые изменения.
Давайте посмотрим на различные модификации и их возможные последствия для разработчиков и пользователей.
Заключение
К сожалению, мир Java раскалывается. Вот-вот выйдет первая бета-версия Java 1.2, отдельные элементы которой Microsoft не собирается поддерживать. Пока разработчики ждут появления надежного инструмента, Microsoft и Sun ведут споры о составе ядра Java. Кто выиграет дело, станет известно лишь спустя какое-то время. Пока же разработчикам приходится разбираться в неустановившихся технологиях и принимать ответственные решения. Хотя различия между платформами незначительны, они все равно имеются. Что делать: изменить принципу "написано однажды - работает везде" и использовать расширения, работающие только на VM Microsoft, или сохранить верность концепции 100% Pure Java? Если стоящая перед вами задача не требует использования JNI и RMI, выбор сделать не так-то легко.
Хорошо еще, что с помощью Microsoft SDK все же можно создавать приложения, соответствующие критерию 100% Pure Java. Избегая использования новых классов, методов и переменных, появившихся в системных библиотеках Java, и не применяя непереносимых библиотек com.ms, вы сможете создавать кросс-платформенные Java-программы. Не используя отсутствующий в SDK метод, вы получите возможность писать работающие в IE 4.0 программы на JDK, JBuilder, VisualAge for Java или VisualCafe 2.0. Желаю успехов!
Джон Зуковски - эксперт по программному обеспечению при институте MageLang, автор справочного руководства по Java AWT, книг "Borland JBuilder: Опыт работы не требуется" и "В фокусе - Java". Ему можно написать по адресу john.zukowski@javaworld.com.
Бета-версия Java 1.1 компании Netscape тоже содержит модификации
В начале октября Netscape выпустила вторую предварительную версию модуля поддержки Java 1.1 для Communicator 4.0. Поскольку это бета-версия, я предлагаю вашему вниманию краткий обзор реализации Java API компанией Netscape. Вот что я выяснил.
Пока Netscape, как и Microsoft, не обеспечила поддержку JNI. По сообщению компании, модуль проходит стадию закрытого бета-тестирования. Открытое тестирование начнется "в ближайшее время".
В реализации Netscape отсутствует библиотека java.security. Как сказал Стив Томас (ответственный за разработку Java менеджер Netscape), Netscape создала свою собственную модель защиты апплетов еще до Sun, и работает с ней над объединением двух моделей. "Защита апплетов - это проблема, которую надо решать на уровне конкретного браузера; нам приходится учитывать в частности такие вещи, как взаимодействие Java и JavaScript", - отметил Томас. Модель безопасности Netscape охватывает в том числе авторизованные объекты JavaScrpit и Web-страницы, что обеспечивает взаимодействие объектов на страницах без ограничения степени защиты или числа их функциональных возможностей. "В будущем году разработкой нашей VM будет заниматься Центр переноса и настройки Java, и проблема несовместимости будет быстро устранена; наша цель - обеспечить 100% совместимость", - утверждает Томас.
Netscape добавила 27 методов (или поменяла их атрибуты доступа) с атрибутом доступа public в основные библиотеки классов Java. Были также введены новые методы с атрибутом protected. Включая последние, общее число модификаций превышает количество изменений в реализации Microsoft. Netscape не добавляла переменные, не модифицировала интерфейсы и не изымала методы.
Public-методы, добавленные в системные библиотеки Java
Класс | Новые методы |
java.lang.ClassLoader | checkMatchPrincipalAlways(int), getCodeBase() |
java.lang.SecurityManager | checkAccess(Thread, Throwable), checkCreateSecurityManagerAccess(), checkMatchPrincipalAlways(int), checksMatchPrincipalAlways(int), checkScopePermission(int), checkURLConnect(URL), checkURLConnect(URL, URL), enablePrivilege(String), isNotSecurePrincipalFromStack(Object), isPrivilegeEnabled(String), getNonSystemPrincipalFromStack(Object), resetScopePermission(), revertPrivilege(), setScopePermission(), setSecurityManager() |
java.net.URL | getData() |
java.net.InetAddress | InetAddress(int) |
java.awt.Toolkit | enterPumpForModal(Thread), EventQueue getEventQueue() [было - package-private] |
java.awt.EventQueue | EventQueue(Thread), clearQueuesTable(), getQueue(ThreadGroup), putQueue(ThreadGroup, EventQueue), removeQueue(ThreadGroup) |
java.beans.Introspector | getClassForName(String) |
Каковы последствия модификаций?
Чтобы обеспечить соответствие программ критерию 100% Pure Java, при их создании следует избегать использования новых методов. Если этого не делать, апплеты будут работать только в Communicator с модулем поддержки Java версии public release 2.
Как и Microsoft, Netscape добавила в свой продукт новые библиотеки. В основном они написаны на чистом Java (как например VisiBroker компании Java VisiGenics или ObjectStore компании ObjectDesign). Это сделано для того, чтобы пользователи не ждали загрузки библиотек всякий раз, когда они понадобятся (в IE 4.0 будет происходить именно так). Кроме "чистых" библиотек Netscape добавила библиотеку связи с JavaScript, которая, как мне кажется, будет работать только в Communicator. Для обеспечения соответствия критерию 100% Pure Java я не советую использовать эту библиотеку.
Я не хочу приуменьшить важность дополнений, сделанных Netscape, но их следует рассматривать в нужном контексте. В отличие от Microsoft, Netscape не предлагает среду разработки Java-программ. (JavaScript используется в Visual JavaScript для подключения JavaBeans, а не Java). Чтобы использовать новые методы, программисты во-первых, должны о них знать, а во-вторых, разбираться с ними по исходным текстам. Тем не менее, если Sun требует от Microsoft устранить изменения, то и от Netscape она должна требовать того же. Кроме того, если Netscape хочет пройти тесты Sun на соответствие Java 1.1, ей необходимо улучшить объектную архитектуру, а также обеспечить поддержку JNI и стандартной модели безопасности Java. Sun не имеет права устанавливать двойной стандарт и позволять Netscape делать то, за что на Microsoft был подан иск. Тем временем, разработчики ожидают появления полноценной поддержки Java 1.1 в Netscape Communicator.
Ресурсы
Win32 Virtual Machine for Java Release Notes
http://microsoft.com/java/sdk/20/relnotes/vm.htm
Правило 3 из "100% Pure Java Cookbook" компании SunTest
http://www.suntest.com/100percent/cpd/doc/cbook/cookbook.html#8592
Application Foundation Classes от Microsoft
http://microsoft.com/java/sdk/20/relnotes/afc.htm
Microsoft's SDK for Java
http://microsoft.com/java/sdk/20/relnotes/intro.htm