Продолжается подписка на наши издания! Вы не забыли подписаться?

Создание компонентов для Microsoft Transaction Server на Java

Создание приложений из программных компонентов. Написание компонентов на Java(tm). Использование транзакций для обеспечения надежности и масштабируемости. Для многих разработчиков это звучит неплохо.

Как насчет использования транзакций и Java-компонентов для создания надежных масштабируемых серверных приложений? После выпуска в декабре 1996 года Microsoft Transaction Server 1.0 (MTS) появился первый продукт, работающий с транзакциями на Java.

Эта статья - о разработке компонентов приложений MTS на Java. После общего рассмотрения процесса мы шаг за шагом построим простой компонент. Вслед за этим мы покажем два клиентских приложения и запустим компонент под MTS. В конце мы предложим некоторые советы по отладке и ссылки на другие источники информации по MTS и Java.

Для создания и запуска примеров вам потребуется как Microsoft Transaction Server, так и Microsoft Visual J++(tm). Если у вас нет MTS, закажите бесплатную оценочную версию на www.microsoft.com/transaction.

Предполагается, что вы знаете основы Component Object Model (COM), язык программирования Java и программирование для MTS. Если вы не знакомы с программированием для MTS, хорошей стартовой точкой может стать раздел Programmer's Guide в MTS Reference. Достаточной основой для понимания этой статьи будет чтение первой части (Overview and Concepts) и выполнение упражнений из второй части (Developing Applications in Microsoft Transaction Server).

Процесс разработки для MTS с использованием Java

Создание IDL для вашего компонента.

При создании компонентов MTS на Java первым шаг необходимо в IDL файле создать определение COM-классов ("coclasses") и интерфейсов, реализуемых этими coclass-ами.

Ваши интерфейсы должны использовать только СОМ-типы, переводимые в типы Java. Хорошим выбором будет использование OLE automation совместимых типов и двойных (dual) интерфейсов. Все эти типы переводятся в типы Java. Двойной интерфейс позволяет вызывать ваш компонент как с использованием позднего связывания (early-binding (vtable)), так и с использованием позднего связывания (late-binding (IDispatch)). Это делает ваши серверные Java обекты полностью доступными для клиентов на Visual Basic или различных script-языков (например, VBScript и JavaScript).

К тому же, если вы планируете использование вашего компонента из VBScript, все out parameters должны быть типа Variant.

Полную таблицу соответствия COM-типов и типов Java можно найти в документации к Microsoft Visual J++ под названием "Type Mappings Between Java and COM."

Создайте GUID'ы.

Каждый интерфейс, класс и библиотека в файле IDL нуждается в глобально уникальном идентификаторе COM (GUID - globally unique identifier). Для создания новых GUID следует использовать guidgen.exe. GUIDGEN можно запустить из командной строки, или выбрав "Create GUID" в меню Tools в Microsoft Developer Studio.

Генерация файла библиотеки типов.

Следующий шаг - компиляция вашей IDL-спецификации в файл библиотеки типов (type library (.tlb)). Это можно сделать, запустив Microsoft IDL Compiler (midl.exe) и передав ему ваш .idl-файла файл в качестве параметра. Для компонентов MTS нужна версия MIDL 3.01.59 или более новая (версия 3.01.59 поставляется с MTS 1.0). Более ранние версии некорректно обрабатывают IDL-файлы с множественными пользовательскими атрибутами. Вам придется пользоваться множественными пользовательскими атрибутами при создании компонентов для MTS на Java.

Сгенерируйте Java wrapper классы (классы обертки) для ваших coclass-ов и интерфейсов.

Теперь создадим Java wrapper-ы для COM coclass-ов и COM-интерфесов, описанных в библиотеке типов. Java wrapper-ы создаются с помощью утилиты Visual J++ "Java Typelib Conversion Utility" (javatlb.exe) для .tlb-файла. JAVATLB создаст один wrapper класс (файл .class) для каждого coclass-а в библиотеке типов, а также wrapper класс для каждого интерфейса.

Сгенерируйте суммарную информацию по библиотеке типов.

Сгенерируйте суммарную информацию по библиотеке типов, запустив JAVATLB с ключом /U:T, результатом чего будет файл с названием summary.txt. Файл summary.txt дает Java определения для каждого класса и интерфейса в библиотеке типов, и Java описание для каждого метода интерфейса. Описания методов интерфейсов будут для вас хорошим подспорьем, когда вы начнете писать Java классы реализующие ваши интерфейсы.

Запустите JAVAGUID against the wrapper classes.

Для wrapper классов следует запустить JAVAGUID, поскольку, как сказано в MTS 1.0 Readme, "если какой-либо из MTS API нуждается в параметре GUID, вы должны передать экземпляр класса com.ms.com._Guid. Не используйте Guid, CLSID или IID из пакета com.ms.com; они небудут работать." MTS включает утилиту с названием JAVAGUID, обрабатывающую файлы .class, выдаваемые JAVATLB и производит необходимые изменения.

1. Реализуйте ваши классы на Java.

Для каждого coclass-а, определенного в вашем IDL, создайте реализацию Java-класса. Имя этого класса должно соответствовать имени, указанному в custom IDL атрибуте JAVACLASS. Класс должен реализовать все интерфейсы coclass-а. Опять-таки, проще всего использовать образцы из summary.txt.

2. Скомпилируйте Java-классы.

Скомпилируйте ваши реализации Java, применив Microsoft Visual J++ Compiler (jvc.exe) для каждого файла с исходным текстом на Java; JVC создаст соответствующий файл Java-класса.

3. Постройте свою COM DLL.

Следующий шаг - встраивание библиотеки типов, COM wrapper classes и Java-классов в COM DLL с использованием Java Executable Generator (exegen.exe). Вам потребуется обновленная версия EXEGEN, поставляемая с MTS. Эта версия EXEGEN поддерживает новый ключ /D, создающий DLL.

4. Установите ваши DLL в Microsoft Transaction Server .

Создайте пустой пакет с помощью MTS Explorer, перетащите ваш файл из Windows Explorer и бросьте его в созданный вами пакет.

Пример программы: Hellojtx

Этот раздел описывает процесс написания на Java примера "hello world" для MTS. Пример называется Hellojtx ("hello world in Java, with transactions").

Для создания Hellojtx, вам потребуются EXEGEN, MIDL и JAVAGUID, поставляемые с MTS. Вам также будут нужны JAVATLB, JVC и GUIDGEN поставляемые с Microsoft Visual J++.

В приводимых ниже примерах мы будем использовать каталог c:\src\hellojtc как корневой для проекта Hellojtx. Предполагается, что все средства командной строки кроме EXEGEN находятся там же. Если в вашем случае это не так, вам может потребоваться изменить команды, вводимые в командной строке и пакетный файл (build.bat).

The Hellojtx IDL

Начните с написания hellojtx.idl.

Листинг 1. The Hellojtx IDL.

// hellojtx.idl : исходный IDL файл для hellojtx.dll
//
// Этот файл далжен быть обработан утилитой MIDL
// для получения библиотеки типов (hellojtx.tlb).

#include <MtxAttr.h>
#include <JavaAttr.h>
[ 
   uuid(CBD73841-C640-11d0-BD14-0080C7C1FC93),
   version(1.0),
   helpstring("Simple Microsoft Transaction Server sample, written in Java")
]
library HELLOJTXLib
{
   importlib("stdole2.tlb");
   [
      object,
      uuid(CBD73842-C640-11d0-BD14-0080C7C1FC93),
      dual,
      helpstring("Ihellojtx Interface"),
      pointer_default(unique)
   ]

   interface Ihellojtx : IDispatch
   {
      import "oaidl.idl"; 
      HRESULT SayHello([out] BSTR* pbstrResult,
      [out, retval] long* plRetVal);
   };
   
   [
      uuid(CBD73843-C640-11d0-BD14-0080C7C1FC93),
      helpstring("Hello Class"),
      JAVACLASS("Hellojtx.HelloObj"),
      PROGID("Hellojtx.Hello"),
      TRANSACTION_REQUIRED
   ]
   coclass Chellojtx
   { 
      [default] interface IHellojtx;
   };

};

Сервер Hellojtx будет реализовать один COM-creatable класс:


[
   uuid(CBD73843-C640-11d0-BD14-0080C7C1FC93),
   helpstring("Hello Class"),
   JAVACLASS("Hellojtx.HelloObj"),
   PROGID("Hellojtx.Hello"),
   TRANSACTION_REQUIRED
]
coclass CHellojtx
{
   [default] interface IHellojtx;
};

Очень длинный номер, (CBD73843-C640-11d0-BD14-0080C7C1FC93), глобально уникальный COM идентификатор (GUID) для этого класса. Клиенты, написанные на C или C++ будут запрашивать этот класс по этому GUID. Остальные клиенты предпочитают более короткие, читаемые имена. Visual Basic будет запрашивать Programmatic Identifier (ProgID) указанный в IDL атрибуте PROGID (Hellojtx.Hello). Большинство людей также предпочитают ProgID, так что мы назовем этот класс Hellojtx.Hello.

Когда JAVATLB создает Java wrapper для этого класса, утилита конвертации библиотек типов также будет брать имя wrapper класса из точки входа IDL coclass-а (CHellojtx.class).

Когда мы пишем Java-реализацию Hellojtx.Hello, мы должны сохранять аттрибут JAVACLASS. Мы назовем наш Java-класс HelloObj.class и поместим его в пакет Hellojtx.

При использовании MTS Explorer для разворачивания нашего компонента, Explorer регистрирует атрибут TRANSACTION_REQUIRED и помечает наш компонент, как требующий транзакции. Заменой TRANSACTION_REQUIRED являются TRANSACTION_SUPPORTED, TRANSACTION_NOT_SUPPORTED и TRANSACTION_REQUIRES_NEW. Этот пример не требует использования транзакций, TRANSACTION_REQUIRED мы использовали исключительно для того, чтобы показать, как пометить ваш компонент как требующий транзакции.

Компоненты Hellojtx.Hello реализуют один интерфейс с названием Ihellojtx:

[
   object,
   uuid(CBD73842-C640-11d0-BD14-0080C7C1FC93),
   dual,
   helpstring("IHellojtx Interface"),
   pointer_default(unique)
]
interface IHellojtx : IDispatch
{
   import "oaidl.idl";
   HRESULT SayHello([out] BSTR* pbstrResult,
   [out, retval] long* plRetVal);
};

Интерфейс IHellojtx имеет один метод, названный SayHello (заметьте, что методы, наследуемые от IDispatch не показаны в IDL). Все типы, указанные в описание SayHello's - COM-типы; JAVATLB преобразует эти типы в родные Java-типы.

Hellojtx GUID-ы

При создания новых GUID для библиотеки HELLOJTXLib, интерфейса IHellojtx, и CHellojtx coclass-а использовался GUIDGEN. Не забывайте создавать GUID в ваших собственных проектах!

Запуск MIDL

Запустите midl.exe для Hellojtx.idl:

C:\src\hellojtx>MIDL hellojtx.idl

Это создаст файл библиотеки типов hellojtx.tlb. Для изучения содержимого библиотеки типов можно использовать OLE Object Viewer (oleview.exe).

Запуск JAVATLB

Запустите javatlb.exe для hellojtx.tlb:

C:\src\hellojtx>JAVATLB /d . /p Hellojtx /p:b- hellojtx.tlb

Ключ /d . велит JAVATLB использовать текущий каталог как корневой каталог для создаваемого файла класса. Хранение файлов в одном каталоге несколько упрощает работу на следующих этапах. Ключ /p определяет Hellojtx как Java-пакет для новых классов.

JAVATLB создает два новых файла Java-классов, один для coclass-а и один для интерфейса. Java требует соответствия имен файлов именам классов, так что JAVATLB назовет файлы Chellojtx.class и IHellojtx.class. Так как Java вдобавок требует соответствия имен каталогов именам пакетов, JAVATLB положит файлы в подкаталог Hellojtx.

CHellojtx.class is a COM class wrapper. Java-клиенты будут использовать Chellojtx для создания реализаций класса Hellojtx.Hello. Например:

// code in Java client

Ihellojtx hello = (IHellojtx) new CHellojtx();

Когда Microsoft Java Virtual Machine (Java VM) загружает CHellojtx.class, Java Virtual Machine распознает, что этот класс - wrapper (оберточный). Java Virtual Machine вызовет CoCreateInstance для создания экземпляра COM класса Hellojtx.Hello.

IHellojtx.class COM интерфейс wrapper. Во время исполнения Java VM будет использовать этот класс для переопределения вызовов COM-клиентов в вызовы методов Java класса Hellojtx.HelloObj

Создание summary.txt

Этот шаг не обязателен.

Создайте файл информации о библиотеке типов для Hellojtx, запустив JAVATLB с ключом /U:T :

C:\src\hellojtx>JAVATLB /U:T hellojtx.tlb
Microsoft (R) Visual J++ Java Typelib Conversion Utility Version 1.01.7048
Copyright (C) Microsoft Corp 1996. All rights reserved.
import hellojtx.*;

Результат показывает, что Java-клиенты могут импортировать пакет Hellojtx, используя выражение import hellojtx.*.

Вот содержимое summary.txt:

public class hellojtx/Chellojtx extends java.lang.Object
{

}
public interface hellojtx/IHellojtx extends com.ms.com.Iunknown
{
   public abstract int SayHello(java.lang.String[]);
}

Отсюда видно, как JAVATLB отображает COM-типы, оговоренные в IDL в Java-типы. Вспомним, что мы использовали COM-типы в IDL-описание SayHello:

HRESULT SayHello([out] BSTR* pbstrResult, [out, retval] long* plRetVal);

Поскольку Java поддерживает только input-параметры (не поддерживает возвращаемые параметры), JAVATLB создает массив сроковых объектов для того чтобы реализовать возвращаемый (out) параметр типа BSTR. JAVATLB использует эту технику для всех параметров описанных как - [out].

JAVATLB переназначает retval параметры в возвращаемые значения функций (в нашем случае параметр plRetVal переназначен в возвращаемое значение типа integer)

Примечание: JAVATLB /U:T выдает summary.txt вместе с новыми .class-файлами в каталог Java-классов. В этом примере JAVATLB помещает файлы в c:\winnt\java\trustlib\hellojtx. Чтобы избежать появления множественных копий файлов классов, уничтожьте их в этом каталоге и скопируйте summary.txt обратно в корневой каталог проекта.

Запустите JAVAGUID

Обработайте новые файлы классов утилитой javaguid.exe. JAVAGUID можно запустить только из командной строки, и только из того же каталога, что и обрабатываемые файлы. Перейдите в подкаталог Hellojtx и вызовите JAVAGUID:

C:\src\hellojtx>cd Hellojtx
C:\src\hellojtx\Hellojtx>JAVAGUID CHellojtx.class IHellojtx.class
C:\src\hellojtx\Hellojtx>cd ..

JAVAGUID не создает никаких новых файлов, а редактирует уже имеющиеся, заменяя каждую ссылку на COM GUID ссылкой на com.ms.com._Guid. JAVAGUID также добавляет static переменную в public секцию каждого класса. Эта переменная представляет собой класс _Guid. Клиент использует эту переменную при вызове метода MTS IObjectContext.CreateInstance.

Создайте HelloObj

Теперь самое время написать Java-класс, реализующий IHellojtx.Hello coclass. Имя класса и пакета для этого класса должны соответствовать имени, предварительно указанному в аттрибуте JAVACLASS IDL: Hellojtx.HelloObj. Имена файлов Java должны соответствовать именам классов, так что создайте новый файл HelloObj.class в подкаталоге Hellojtx.

Листинг 2. Реализация Hellojtx coclass.


// Простой пример MTS приложения, написанного на Java
// Copyright (C) 1997 Microsoft Corporation
// All rights reserved.

Package Hellojtx;

Import com.ms.mtx.*;

Public class HelloObj implements IHellojtx
{
   public int SayHello(String[] result)
   {
      try
      {
         result[0] = "Hello from simple MTS Java sample";
         MTx.GetObjectContext().SetComplete();
         Return 0;
      }
      catch(Exception e)
      {
         MTx.GetObjectContext().SetAbort();
         Return -1;
      }
   }
}

SayHello возвращает простое сообщение "Hello". Обратите внимание, как мы используем массив строк для возвращения значения в out параметре.

До этого SayHello вызывает SetComplete, чтобы сообщить MTS, что работа закончена и результаты можно принять:

MTx.GetObjectContext().SetComplete(); 

Заметьте, что этот компонент не нуждается в использовании транзакции, поскольку не выполняет никаких действий над совместно используемыми значимыми данными. Компонент не вызывает никаких менеджеров ресурсов (за информацией о менеджерах ресурсов обращайтесь к MTS 1.0 Programmers Guide). Здесь мы используем транзакцию только чтобы показать, как разрабатывать работающие с транзакциями компоненты. В панели Transaction Statistics MTS Explorer вы можете посмотреть, как этот компонент вызывает транзакции.

Компиляция CHelloObj.java

Скомпилируем реализацию CHelloObj:

C:\src\hellojtx>JVC Hellojtx\HelloObj.java 

Эта компиляция создаст файл HelloObj.class, содержащий байт-код Java, интерпретируемый Java VM во время исполнения. Поскольку HelloObj относится к пакету Hellojtx, HelloObj.class должен находиться в каталоге Hellojtx.

Создание hellojtx.dll

Теперь у нас имеются все составные части, необходимые для создания helppjtx DLL: библиотека типов, wrapper-класс для интерфейса IHellojtx и Java-класс, реализующий COM-класс Hellojtx.Hello. Для создания hellojtx COM DLL запустите из командной строки в корневом каталоге exegen.exe:

C:\src\hellojtx>C:\MTX\TOOLS\EXEGEN /d /r /out:hellojtx.dll hellojtx.tlb *.class 

Ключ /d командует EXEGEN создать DLL, а ключ /out приказывает EXEGEN назвать эту DLL hellojtx.dll. Ключ /r заставит EXEGEN пройти по подкаталогу Hellojtx, где он обнаружит три файла классов (CHellojtx.class, IHellojtx.class и HelloObj.class). EXEGEN поместит копии файлов классов в ветку ресурсов hellojtx.dll.

При исполнении hellojtx.dll будет использовать Java VM (msjava.dll) как COM-сервер для класса Hellojtx.Hello.

Microsoft Java VM (msjava.dll) умеет прикинуться inproc COM-сервером. Для реализации класса Hellojtx.Hello VM будет интерпретировать байт-код Java-класса HelloObj. Чтобы преобразовать входящие вызовы COM-методов в вызовы методов Java, Java VM будет использовать IHellojtx интерфейс wrapper. Оба эти класса находятся в ресурсах фала hellojtx.dll.

Замечание: CHellojtx.class реально не нуждается в помещении в DLL. При исполнении Java VM не нуждается в загрузке wrappers COM-классов, реализуемых DLL.

Установка hellojtx.dll в Microsoft Transaction Server

Откройте MTS Explorer и создайте новый пакет с названием "hellojtx." Если вам не приходилось, создавать новых пакетов в MTS, просто следуйте указаниям, перечисленным в MTS Explorer Help Topics в разделе "Show me how to ... create a new empty package.".

Вслед за этим выберите hellojtx.dll в Windows Explorer, и перетащите DLL в пустой пакет. Готово! MTS Explorer выполнит всю работу по конфигурированию нового компонента.

Создание batch-файла

Может показаться, что для создание Java-компонента для MTS отнимает очень много времени и сил. Однако только два из выполненных нами шагов требуют написания кода: создание IDL и реализация Java-классов. Два других шага выполняются с использованием GUI-средств: создание GUID и развертывание DLL в MTS.

Остальные шаги (запуск MIDL, JAVATLB, JAVAGUID, JVC и EXEGEN) могут быть автоматизированы с помощью batch-файла. В этом примере мы приведем batch-файл, используемый для создания Hellojtx.

MIDL hellojtx.idl
JAVATLB /d . /p Hellojtx /p:b- hellojtx.tlb 
cd Hellojtx 
JAVAGUID CHellojtx.class Ihellojtx.class 
cd .. 
JVC Hellojtx\HelloObj.java
C:\MTX\TOOLS\EXEGEN /d /r /out:hellojtx.dll hellojtx.tlb *.class

Клиенты Hellojtx

Прежде, чем мы сможем увидеть работу компонента Hellojtx.Hello под Microsoft Transaction Server, нужно построить какое-либо клиентское приложение. Рассмотрим написание клиента на Java и Visual Basic.

Java-клиент

Исходный текст Java-клиента состоит из единственного Java-файла, Client.java.

Листинг 4. Реализация Java-клиента.

import Hellojtx.*;
public class Client
{
   public static void main(String args[])
   {
      Ihellojtx myHello;
      String strRet[] = { "<no returned data>" };
      int nRet;
      try
      {
         myHello = (IHellojtx) new Chellojtx();
         System.out.println("Calling SayHello..");
         nRet = myHello.SayHello(strRet);
         System.out.println("nRet = " + nRet);
         System.out.println("strRet = " + strRet[0]);
      }
      catch (Throwable t)
      {
         System.out.println("Exception: " + t.toString());
         t.printStackTrace();
         System.exit(0);
      }
      try
      {
         System.out.println("Hit any key to exit..");
         System.in.read();
         myHello = null;
         System.gc();
      }
      catch (Exception e)
      {
      }
   }
}

Файл Client.java импортирует пакет Hellojtx:

Import Hellojtx.*;

Это позволяет клиенту пропускать имя пакета при обращениях к IHellojtx и CHellojtx.

Заставить клиента создать и вызвать компонент Hellojtx.Hello - важный шаг в построении клиента. Вот верный способ:

Ihellojtx myHello;
MyHello = (IHellojtx) new Chellojtx();
Nret = myHello.SayHello(strRet);

Клиент создает компонент Hellojtx.Hello, используя ключевое слово new, выдавая в качестве аргумента имя, указанное как coclass в .idl-файле (CHellojtx). затем Client.java передает результат интерфейсу (в данном случае Ihellojtx).

Этот код работает, поскольку CHellojtx.class - COM wrapper. Когда Java VM загружает этот класс, она знает, что следует создать реализацию COM-класса Hellojtx.Hello.

Замечание: Хотя это и кажется очевидным, определение класса реализации объекта (например, HelloObj) как аргумента для ключевого слова Java "new" работать не будет.

// Плохой код - работать не будет.
HelloObj myHello;
MyHello = new HelloObj();
Nret = myHello.SayHello(strRet);

Этот код вызовет runtime exception наподобие следующей:

Exception: java.lang.NullPointerException
java.lang.NullPointerException
at Hellojtx/HelloObj.SayHello
at Client.main 

Еще раз обратите внимание, что клиент использует массива строк для получения SayHello's out параметра:

String strRet[] = { "<no returned data>" };
int nRet;
<other code>
nRet = myHello.SayHello(strRet); 

Во втором операторе try, SayHello освобождает myHello и вызывает сборщика мусора Java (Java garbage collector):

myHello = null;
System.gc(); 

Эти вызовы не обязательны. Если их нет, компонент Hellojtx будет жить до тайм-аута DCOM-соединения (по умолчанию, шесть минут). Наличие этих вызовов позволит немедленно уничтожить компонент.

Построение Java-клиента

Для этого следует использовать Microsoft Java compiler (JVC):

C:\src\hellojtx>jvc Client.java

В случае, если JVC может найти пакет Hellojtx, компилятор создаст Client.class. Если же JVC не сможет найти пакет, компилятор выдаст ошибку типа следующей:

Client.java(1,8) : error J0051: Undefined package 'Hellojtx'

В этом примере клиент создается в корневом каталоге проекта. JVC найдет нужные классы (CHellojtx.class и IHellojtx.class) в подкаталоге Hellojtx . Если классы расположены в другом каталоге, компилятор не сможет создать клиента.

Чтобы сделать классы Hellojtx общедоступными, создайте пакет в каталоге Java-класов вашей машины. В этом примере мы создадим подкаталог Hellojtx в c:\winnt\java\trustlibи скопируем туда CHellojtx.class и Ihellojtx.class.

Заметьте, что клиентам не нужен класс HelloObj. Java VM, требующая этот класс во врем выполнения, Java VM найдет его в ресурсной части of hellojtx.dll.

Запуск Java-client

Запустите Microsoft Transaction Server Explorer. Убедитесь с помощью меню Tools Explorer'а, что Microsoft Distributed Transaction Coordinator (MSDTC) запущен - если нет, запустите его.

Теперь мы готовы запустить Java-клиента, используя Microsoft Command-line Loader for Java (jview.exe). Результат запуска клиента:

C:\src\hellojtx>jview Client
Calling SayHello..
nRet = 0
strRet = Hello from simple MTS Java sample
Hit any key to exit.. 

Пока вы не закрыли клиентское приложение, в MTS Explorer можно увидеть , что компонент Hellojtx работает. Убедиться, что компонент исполняет транзакции MSDTC, можно в панели Transaction Statistics .

java1.gif (11323 bytes)

Рис.1 Hellojtx.Hello запущен под управлением Microsoft Transaction Server.

Клиент Visual Basic

Ниже приведен вызов процедуры Microsoft Visual Basic, вызывающей компонент Hellojtx:

Private Sub cmdSayHello_Click()
   Dim myHello As Chellojtx
   Dim str As String
   Dim nRet As Long 
   
   Set myHello = CreateObject("Hellojtx.Hello")
   NRet = myHello.SayHello(str) 
   MsgBox str 
End Sub 
   

До построения этого кода используйте диалог Visual Basic Project References, чтобы "втянуть" ссылку на библиотеку типов Hellojtx; ссылка будет выведена под строкой подсказки, указанной в hellojtx.idl ("Simple Microsoft Transaction Server sample, written in Java").

Единственная хитрость здесь в знании, какой из идентификаторов классов использовать при объявлении переменной myHello и реализации объекта. В Visual Basic 5.0 при объявлении переменной для объекта Hellojtx используйте имя coclass-a, указанное в .idl-файле ("CHellojtx"). В качестве аргумента для CreateObject используйте ProgID, указанный в аттрибуте PROGID ("Hellojtx.Hello").

Удаленный запуск клиентов Visual Basic или Java

Удаленное исполнение клиентов Visual Basic или Java очень похоже на запуск клиентов на одной машине с серверным компонентом Hellojtx.

Начните с использования Microsoft Transaction Server Explorer для конфигурирования Hellojtx.Hello как удаленного (Remote) компонента на клиентском компьютере. Explorer добавит все необходимые вхождения в реестр. (Если вы до этого не инсталлировали MTS Remote Component, обратитесь к разделу "Configuring Remote Components" в помощи к MTS Explorer).

Для запуска удаленного клиента Visual Basic:

Скопируйте исполняемый файл Visual Basic (Client.exe) на клиентскую машину. Убедитесь, что на обеих машинах запущен MTS, и что на сервере работает MSDTC. Теперь запустите Client.exe. Компонент Client свяжется с серверным компонентом Hellojtx на удаленной машине.

Для запуска удаленного клиента Java:

Скопируйте Java-класс (Client.class) на клиентскую машину. Так как Java VM нуждается при исполнении клиента в локальном доступе к Hellojtx's COM wrappers, скопируйте файлы классов Hellojtx в каталог Java-классов клиентской машины. В этом примере CHellojtx.class и IHellojtx.class были скопированы в подкаталог c:\winnt\java\trustlib\hellojtx клиентской машины.

Теперь используйте JVIEW для запуска Java-клиента, который свяжется с серверным компонентом Hellojtx, расположенным на удаленной машине.

Отладка

Отладка - одна из областей, где написание компонента MTS на Java несколько менее удобно, чем на C++ или Visual Basic. Современные средства разработки не позволяют пошаговую отладку компонента, написанного на Java.

Один из способов получения отладочной информации по мере исполнения компонента под MTS заключается в использовании отладки типа "sprintf" . Например, можно добавить вызов System.out.println к оператору try в Hellojtx.HelloObj.SayHello:

try 
{ 

   System.out.println("This msg is from the HelloObj implementation"); 
   result[0] = "Hello from simple MTS Java sample"; 
   MTx.GetObjectContext().SetComplete(); 
   return 0; 
} 

После перестройки HelloObj.class и hellojtx.dll вы можете ожидать появления следующей строки в консольном окне при следующем использовании JVIEW для загрузки класса Client:

C:\src\hellojtx>jview Client
Calling SayHello..
nRet = 0
strRet = Hello from simple MTS Java sample
Hit any key to exit.. 

Однако Hellojtx и JVIEW исполняются в разных процессах, так что ожидаемой строки вы не увидите. Серверный компонент запускается в особом замещающем процессе MTS (mtx.exe), заставляющем println выдавать результат не в консольное окно JVIEW, а в "bit bucket".

Чтобы вывести результат в консольное окно JVIEW, нужно сконфигурировать Hellojtx для исполнения в вызывающем его процессе (JVIEW). В панели Activation диалога Properties Hellojtx сконфигурируйте Hellojtx на исполнение в клиентском процессе.

java2.gif (10254 bytes)

Рис. 2. Конфигурация Hellojtx.Hello для исполнения в его клиентском процессе.

Теперь перезагрузите класс Client. Вызовы Hellojtx println будут видны:

C:\src\hellojtx>jview Client
Calling SayHello..
This msg is from the HelloObj implementation
nRet = 0
strRet = Hello from simple MTS Java sample
Hit any key to exit..

Формат компонентов MTS, написанных на Java

Этапы создания Hellojtx могут служить моделью для создания любого серверного компонента MTS на языке Java.

Метод SayHello, однако, может оказаться чересчур ограниченным для использовании в качестве модели метода компонента MTS. Следующий код описывает общий формат методов компонентов MTS, написанных на языке Java:

Public int MTSJavaMethod () 
{
   IObjectContext context; 
   boolean success = false; 
   IFoo foo = null; 
   try 
   { 
      // Получаем MTS контекст
      context = (IObjectContext) Mtx.GetObjectContext(); 
      
      // занимаем ресурсы. для примера, соединение с базой данных.
      // Используем ресурсы.
      // Выполняем первую порцию работы для первого клиента
      // Извлекаем другой MTS-компонент для выполнения другой работы
      foo = (IFoo) context.CreateInstance(CFoo.clsid, IFoo.iid); 
      
      // все в порядке
      success = true; 
      return 0; 
   }
   catch (Exception e)
   { 
      return -1; 
   } 
   finally 
   { 
      // освобождаем ресурсы
      if (success) // Мы финишировали
      успешно
      context.SetComplete();
      else // Мы потерпели фиаско.
      context.SetAbort();
   }
} 

Исходный текст примеров на Java для MTS 1.0 Sample Bank иллюстрирует, как этот общий формат методов Java реализован в Java-компонентах MTS. Методы IMoveMoney.Perform и IAccount.Post, реализованные классами ImoveMoney и Account показывают более полную реализацию канонической формы "MTS на Java", что и показано выше.

Исходный код Java для классов MoveMoney и Account расположен в подкаталоге MTX\Samples\Account.VJ\Account.

Полную информацию по инсталляции и использованию пакета Bank можно найти в Microsoft Transaction Server Help в разделе "Validating Setup with a SQL Server Transactional Component."


Copyright © 1994-2016 ООО "К-Пресс"