Поэтому неслучайно предыдущее занятие мы завершили репликой «Знай свой компилятор IDL», а заключительное посвятили рассмотрению наиболее популярных и доступных компиляторов:

  • idltojava из пакета Java 2 корпорации Sun Microsystems;
  • idl2java из пакета Visibroker компании Inpise;
  • idl из пакета OrbixWeb фирмы IONA Technologies.

Однако есть и другая причина, почему именно эти три программы попали в поле нашего зрения. Дело в том, что пробные версии OrbixWeb и Visibroker могут быть получены через Web-узлы http://www.iona.com и http://www.inprise.com, а Java 2 с набором утилит, включающих idltojava, так и вовсе распространяется бесплатно.

Как гласит поговорка, сходная ситуация рождает сходные мысли. То же самое можно сказать и про компиляторы IDL. Раз уж они выполняют одну и ту же задачу, то у них имеются и общие опции. Так, практически все компиляторы обладают ключиками, которые в явной форме говорят, где искать включаемые файлы, указанные в IDL-файле директивой препроцессора #include. То же можно сказать и об опциях задания каталога вывода, куда записываются результаты компиляции.

Отдельно несколько слов об tie-архитектуре. Несмотря на название, внушающее опасение, здесь ничего сложного нет. Как известно, в современном объектно-ориентированном программировании есть всего два способа создания новых объектов: наследование и агрегация. В первом случае новый объект наследует все свойства и методы родительского объекта, добавляя к этому «джентльменскому набору» свои собственные методы и свойства. По сути, новый объект считает родительские составляющие своей собственностью. Что же касается агрегации, то здесь дело обстоит чуть сложнее. Создаваемый новый объект хранит ссылку на другой объект, чьи функции он собирается позаимствовать. Если к новому объекту обращаются за сервисом, имеющимся в объекте-предке, то создаваемый объект через хранимую ссылку передает запрос к старому объекту, который и делает основную работу. Подобный подход принят в объектных моделях Microsoft COM и DCOM. В CORBA же он называется tie.

Не огорчайтесь, если вы не поняли, для чего служит та или иная опция, или вас озадачил непонятный термин. В учебном курсе, посвященном CORBA, вы найдете ответы на многие вопросы.

А теперь собственно о компиляторах.

Java 2

Самый простой компилятор IDL удалось найти в наборе Sun JDK 1.2, иначе называемом Java 2. Из трех приведенных в этой статье компиляторов компилятор idltojava оказался самым рудиментарным и... неаккуратным, хотя и наиболее быстрым. Его главная особенность — отсутствие препроцессора. Взамен idltojava по переменным среды пытается обнаружить препроцессор от компилятора языков Cи/Cи++. Сложность состоит в том, что искомый препроцессор должен выводить результаты своей работы в стандартный поток вывода, т. е. на экран, откуда они будут перехвачены и переданы на трансляцию в исходные тексты на языке Java. Лучше всего, как это ни странно, с этими обязанностями справляется препроцессор из компилятора Microsoft Visual C++. Экая гремучая смесь!

Вторая особенность, точнее, недоделка, в том, что исходники, полученные в результате трансляции, выполнены в переносимом стиле, рекомендуемом комитетом OMG, т. е. не содержат метода bind() для получения ссылки на объект. На первый взгляд, это нормально, поскольку метод bind() не описан в спецификации CORBA, а следовательно, и не нужен. Но общепринятая практика создания CORBA-приложений показывает, что довольно часто удобно пользоваться именно методом bind(), вместо того чтобы колдовать с сервисом имен (Naming Service). Судя по всему, разработчики из Sun Microsystems решили, что сервера имен из Java 2 вполне хватит. А зря. Вот конкурирующие фирмы в своих изделиях предусмотрели генерацию bind(), одновременно оставив программисту возможность отключать данную возможность через опции командной строки.

Итак, вот формат запуска компилятора idltojava:
idltojava [ <опции> | <флаги> ] <имя файла>.idl

Опций у него немного (табл. 1), зато флагов побольше (табл. 2). Флаги могут быть включенными или выключенными. Если упомянуть имя флажка, то он будет включен:

-f<флаг>
Если же после префикса -f вставить no-, флаг выключается:
-fno-<флаг>
По умолчанию включены следующие флаги:
-fclient 
-fcpp 
-fportable 
-fserver 
-fwrite-files 
и выключены:
-fcaseless 
-flist-flags 
-flist-options 
-fmap-included-files 
-ftie 
-fverbose 
-fversion 

Следует также отметить, что создатели idltojava не очень-то внимательно читали спецификацию CORBA, поэтому случается, что компилятор производит ошибочную генерацию исходных текстов.

Таблица 1. Опции компилятора idltojava из пакета Java 2

-j <каталог> Определяет каталог, куда компилятор IDL должен поместить сгенерированные Java-файлы. Между опцией и именем каталога обязательно должен быть символ пробела!
-I <каталог> Говорит компилятору, где искать включаемые файлы, отмеченные директивой препроцессора #include в IDL-файле
-D <имя> Определяет макроопределение с именем, заданным параметром <имя>
-U <имя> Отменяет макроопределение с именем, заданным параметром <имя>. Является противоположностью опции -D

Таблица 2. Флаги компилятора idltojava из пакета Java 2

-fcaseless Говорит компилятору не обращать внимание на регистр идентификаторов при сравнении
-fclient Указывает на необходимость генерации клиентской части
-fcpp Запускает препроцессор Cu/Cu++. Препроцессор ищется компилятором по значению переменной среды CPP, в которой должен быть прописан полный путь к запускаемому файлу препроцессора. Вторая важная переменная среды — CPPARGS, задающая аргументы препроцессора
-flist-flags Вызывает показ текущего состояния всех флагов
-flist-options Распечатывает на экране список опций командной строки
-fmap-included-files Производит трансляцию всех файлов, включенных директивой #include
-fportable Генерирует переносимые скелеты и заглушки в соответствии с рекомендациями комитета OMG
-fserver Указывает на необходимость генерации серверной части
-ftie Указывает на то, что генерация Java-файлов должна производиться для tie-архитектуры. Если флаг -fserver выключен, то -ftie игнорируется
-fverbose Отображает детали процесса компиляции
-fversion Печатает версию компилятора idltojava print its version
-fwrite-files Дает команду записывать полученные в результате компиляции файлы на диск

Visibroker

Inprise Visibroker (в данном случае мы говорим о версии 3.4) — очень серьезный продукт. Он напоминает хорошо отлаженный станок для получения кода. И, как всякий прецизионный инструмент, несколько медлителен в работе. Если не указать никаких опций, то от обилия полученных исходных текстов зарябит в глазах! Тут вам и стандартные файлы, и классы, необходимые для получения приложений на основе tie-архитектуры, и даже пример того, как можно создать серверный объект на основе сгенерированных интерфейсов и классов. Имя этого класса начинается с префикса _example_.

Общий вид командной строки для запуска компилятора из Visibroker следующий:

idl2java [<опции>] <имя файла>.idl

OrbixWeb

Самый серьезный конкурент Inprise Visibroker — OrbixWeb от IONA. Этот пакет также сделан очень и очень тщательно, и компилятор IDL в его составе весьма хорош. Чтобы использовать его, наберите командную строку по следующей схеме:

idl [ <опции> ] <имя файла>.idl
Опции помогут настроить среду компиляции под ваши нужды (табл. 4).

Если взглянуть на значение ключей командной строки, то становится очевидно, насколько близко друг к другу следуют мысли разработчиков из Inpise и IONA. Набор ключей компиляции, несмотря на разные буквы, столь одинаков! Поэтому опытному разработчику не составит труда использовать оба компилятора. Корпорация Inprise даже пошла на беспрецедентный шаг — включила в среду пакета JBuilder 3 возможность вызывать компилятор IONA OrbixWeb вместо своего собственного!

Таблица 3. Опции компилятора idl2java из пакета Visibroker

-package <имя> Говорит компилятору поместить сгенерированные Java-файлы в пакет с именем, взятым из параметра <имя>
-root_dir <каталог> Изменяет каталог, в который записываются сгенерированные файлы. Вместо каталога по умолчанию будет использован тот, который указан в параметре <каталог>
-idl2package idl pkg Задает правила трансляции имен IDL в пакеты Java. Например, следующая строка -idl2package ::CORBA org.omg.CORBA говорит, что любое имя IDL, находящееся внутри области видимости ::CORBA, будет транслироваться и помещаться в пакет org.omg.CORBA в соответствии с правилами трансляции спецификации CORBA
-version Отображает версию Visibroker for Java
-portable Включает генерацию переносимых заглушек, использующих DII. Без этой опции idl2java генерирует специфические для VisiBroker исходные тексты
-strict Генерирует исходные тексты для кода, который может быть запущен в любой системе с ORB, совместимой со спецификацией CORBA. По своей сути опция -strict эквивалентна включенным опциям -portable, -no_toString, -no_bind при одновременно выключенных -serializable, -smart_stub и -obj_wrappers
-smart_stub В Helper-классе создает дополнительные методы, используемые для установки и использования «хитрых» заглушек
-incl_files_code Генерирует исходные тексты Java для включаемых файлов
-all_serializable При установленной опции все структуры, исключения, энумераторы и дискриминируемые объединения реализуют интерфейс java.io.Serializable
-serializable Тип данных, получаемый в результате трансляции идентификатора из параметра , должен реализовать интерфейс java.io.Serializable
-map_keyword

<ключевое слово>

<соответствие>
Добавляет слово из параметра <ключевое слово> в список ключевых слов и ассоциирует его с Java-идентификатором из параметра <соответствие>. С этого момента любой идентификатор, конфликтующий с тем, который задан в параметре <ключевое слово>, будет транслирован в Java в идентификатор, заданный параметром <ключевое слово>
-no_stub Отключает генерацию исходных текстов для заглушек
-no_skel Отключает генерацию исходных текстов для скелетов
-deprecated_skel Включает генерацию скелетов с устаревшими именами. В ранних версиях Visibroker имена скелетов соответствовали схеме _sk_<имя интерфейса>, тогда как по новой схеме имена соответствуют схеме _<имя интерфейса>ImplBase. Данная опция нужна для совместимости с системами, построенными раньше
-no_comments Отключает автоматическую генерацию комментариев к получаемым исходным текстам
-no_examples По умолчанию Visibroker генерирует пример реализации объекта. Данная опция подавляет создание такого рода примера
-no_tie Указывает на то, что для tie-архитектуры генерация Java-файлов производиться не должна
-no_toString Отключает генерацию метода toString()
-no_bind Указывает компилятору не создавать метода bind()

Таблица 4. Опции компилятора idl из пакета OrbixWeb

-A Требуется, если в IDL-файле содержатся описания структур, дискриминирующих объединений, последовательностей или ссылок на объекты, экземпляры которых могут быть переданы в качестве параметров типа any
-C Требуется, когда препроцессор IDL не должен выбрасывать комментарии из IDL-файла. Часто используется совместно с опцией -E
-D <имя> Определяет макроопределение с именем, заданным параметром <имя>. Присваивает ему значение 1
-D <имя>=

<определение>
Определяет макроопределение с именем, заданным параметром <имя>. Присваивает ему значение, взятое из параметра <определение>
-E Запускает IDL-препроцессор, не вызывая собственно компилятора IDL. Результат работы препроцессора посылается в стандартный поток вывода, т.е. по умолчанию на экран
-I <каталог> Явно задает каталог, откуда компилятор должен брать включаемые файлы. Любая директива #include<имя файла> языка IDL приведет к поиску файла, заданного параметром <имя файла> в каталоге, указанном в параметре <каталог>
-K Опция поддержки спецификатора типа opaque
-N Говорит компилятору: генерировать код для всех файлов, включенных директивой #include. Без данной опции включаемые файлы компилируются, но на выходе для них не образуется исходных текстов
-jO <каталог> Определяет каталог, в который будет помещен результат работы компилятора IDL. Путь к каталогу может быть задан как явно, так и относительно
-jc Производит генерацию исходных текстов на языке высокого уровня только для клиентской части
-jP [<пакет> |

<модуль>=

<пакет>]
Определяет пакет Java, в который помещаются все сгенерированные исходные тексты (параметр <пакет>). Второй вариант предусматривает отображение модуля IDL (параметр <модуль>) в определенный пакет (параметр <пакет>). По умолчанию все сгенерированные исходные тексты помещаются в глобальный пакет Java, что может привести к конфликту имен. Поэтому настоятельно рекомендуется использовать данную опцию
-jQ Заставляет компилятор IDL генерировать метод сравнения equals() во всех получаемых в результате трансляции файлах
-U <имя> Отменяет макроопределение с именем, заданным параметром <имя>. Является противоположностью опции -D. Если имя задано опцией -U, то даже наличие опции -D не приведет к определению данного макроимени
-flags Показывает подсказку по всем опциям компилятора IDL
-m <протокол> Генерирует код для передачи данных по сети с использованием протокола, определенного параметром <протокол>. Существуют три варианта: IIOPOnly (задано по умолчанию) — использовать стандартный для CORBA протокол IIOP; orbixOnly — создать исходные тексты для применения коммуникационного протокола Orbix; interOp — произвести генерацию обоих предыдущих видов кода передачи данных
-jOMG Включает генерацию кода, соответствующую рекомендациям комитета OMG. Таким образом, в полученном исходном тексте вы не найдете специфических методов, например bind()
-v Показывает информацию о версии компиляторов IDL и JDK, после чего завершает выполнение

* * *

К сожалению, разница между приложениями, созданными с помощью разных продуктов, остается. Хотя с каждым днем она все меньше и меньше. Большие надежды связываются с новой ожидаемой спецификацией CORBA версии 3. В идеале, она не оставит возможности для разночтения стандартов, что в свою очередь положительно скажется на совместимости всех получаемых приложений CORBA.