您的位置:首页 > 移动开发 > Objective-C

Creating MTS ActiveX Object in Java

2007-05-28 21:34 519 查看
From: http://www.adiscon.com/mts/javaplan.htm

Jeff Lederer
jlederer@6dos.com

This is a cookbook approach to creating an MTS ActiveX object in java and testing locally, remotely and with IIS. The summary of the steps are:

Create a directory to hold intermediate files

Create an idl file to define the interface and coclass of the object

Compile the idl file to create a type library that defines the object.

Create the interface and coclass definition java classes

Create the java implementation file

Compile the above java files into .class files.

Generate a dll file that incorporates the type library file and the implementation, interface, and coclass java classes.

Create an MTS package and install the above dll file in the package.

Create VB5 client that tests that test this MTS activex object locally.

Create an MTS export package.

Run the export package on remote machine to register the type libraries

Run client on remote machine.

Use the object in an ASP file under IIS.

I am sure in some future release of VJ++, Microsoft will combine steps 2 through 7 into a wizard. I used the utilities and programs that came with the SDK-Java 2.0 release, the MTS 2.0 beta 3 release and MTS 1.0. As of Dec 22, 1997, Microsoft has released a "golden" version MTS 2.0 and a new SDK-Java 2.1. All test were done on Windows NT Server 4.0, Service Pack 3.

The "local" machine (where the Java object was installed) had an ODBC entry for database "pubs".

This write up assumes all packages were installed in their default directories:

DirectoryLocation
%WINDIR%c:/winnt
Web Scriptsc:/InetPub/scripts

Create directory

Create a directory to hold intermediate files files.

mkdir c:/src


All the java utility programs will be run from this directory.

Create IDL file TestConnectjtx.idl in directory c:/src

Below is a copy of the IDL file:

#include <JavaAttr.h>
#include <MtxAttr.H>
[
uuid(86d718a2-7029-11d1-a077-004005378d36),
helpstring("Simple MTS sample, written in java"),
version(1.0)
]

library TESTCONNECTJTXLib
{
importlib("stdole32.tlb");
[
object,
uuid(86d718a1-7029-11d1-a077-004005378d36),
dual,
helpstring("ITestConnectjtx Interface"),
pointer_default(unique)
]
interface ITestConnectjtx : IDispatch
{
[ helpstring("CreateConnection Method") ]
HRESULT CreateConnection([out, retval] VARIANT * rtn);
}

[
// This is the CLSID
uuid(86d718a0-7029-11d1-a077-004005378d36),
helpstring("CTestConnect Class"),
JAVACLASS("TestConnectjtx.TestConnectObj"),
PROGID("TestConnectjtx.TestConnect"),
TRANSACTION_REQUIRES_NEW
]

coclass CTestConnectjtx
{
[default] interface ITestConnectjtx;
};
};

Files "JavaAttr.h" and "MtxAttr.h" were taken from the MTS 1.0 distribution disk.

(This idl file can be created from scratch with a text editor and using GUIDGEN to generate the GUIDs, but I really created it by running:

jvc TestConnectObj.java
javaidl /r- /t- /d /w- TestConnectObj.class
rename TestConnectObjLib.idl TestConnectjtx.idl


with a version of TestConnectObj.java (see source code a little later in this document) that does not implement ITestConnectjtx, and added the include statements, the JAVACLASS, PROGID, and TRANSACTION_REQUIRES_NEW statements, [default] argument, and changed the first helpstring statement in the outputted idl file. Javaidl also generated the GUIDs needed within the idl file. Javaidl came with VJ++ 1.1)

Create tlb file in c:/src directory

Run the midl program against the idl file:

midl TestConnectjtx.idl


This program will only run correctly if the environmental "include" variable has the path to where the JavaAttr.h and MtxAttr.h files are stored. You can modify this variable using the Control Panel, System applet.

I am running midl version 3.01.74.

Create interface java class files

Run the jactivex program (in the c:/src directory) against the newly created tlb file:

jactivex /javatlb /cj /xi /r /p TestConnectjtx /p:b- /l TestConnectjtx.rsp TestConnectjtx.tlb


The parameters are:

ParameterDefinition
/javatlbSpecifies typelib translation
/cjGenerates a template file for each coclass that can be edited to implement that coclass in Java. The file is named <coclass>Impl.java. (in this case CTestConnectjtxImpl.java)
/xiCauses the method declarations and COM declarations to be duplicated in the coclass java files. This simplifies using COM objects from Java because default interface methods can be called directly on the object without first casting to an interface pointer.
/rCauses jactivex to register all type libraries that are mentioned on the command line. This allows early binding of objects and negates the necessity to run javareg later.
/p TestConnectjtxSpecifies the target directory for .java files generated by jactivex. In this case, the files are placed in directory c:/winnt/java/Trustlib/TestConnectjtx.
/p:b-This option excludes the basename as the package for the converted class. In this case, the files will placed in the directory under Trustlib of the package given in the /p parameter.
/l TestConnectjtx.rspGenerates a response file for jvc that lists every .java file created by jactivex.
This will create CTestConnectjtx.java, ITestConnectjtx.java, ITestConnectjtxDefault.java and CTestConnectjtxImpl.java files in subdirectory c:/winnt/java/TrustLib/TestConnectjtx, and TestConnectjtx.rsp (jvc compiler response file) in c:/src directory

I am running jactivex version Java V4.0 (Beta Release) 4.79.2228

Create java implementation file

This file (TestConnectObj.java) is created using a text editor and placed in the c:/winnt/java/TrustLib/TestConnectjtx subdirectory.

//
//
// TestConnect
//
//

package TestConnectjtx;

import com.ms.com.*;
import com.ms.mtx.*;
import msado15.*;

public class TestConnectObj implements IObjectControl, ITestConnectjtx
{
private IObjectContext mContext = null;

public void Activate()
{
mContext = MTx.GetObjectContext();
}

public void Deactivate()
{
mContext = null;	// arguably not required, but safer
}

public boolean CanBePooled()
{
return true;
}

public Variant CreateConnection()
{
Variant var;
String msg;

var = new Variant();
msg = new String();

// just to be safe
if(mContext == null) {
msg = "Did not initiate mContext";
mContext = MTx.GetObjectContext();
}
else {
msg = "Initiated mContext";
}

if(mContext != null) {
mContext.SetAbort();
msg = msg + ", SetAbort";

}
else {
msg = msg + ", Still did not initiate mContext";
}

_Connection conn;

conn = new Connection();
try {
conn.Open("pubs","sa","",-1);
msg = msg + ", open";
if(mContext != null) {
mContext.SetComplete();
msg = msg + ", SetComplete";
}
}

catch(com.ms.com.ComFailException e) {
Errors errs;
msado15.Error err;
int i;
Variant x;
x = new Variant();

errs = conn.getErrors();
if(errs.getCount()>0) {
x.putInt(0);
err = errs.getItem(x);
msg = msg + ", SQL Error: " + err.getDescription();
}
else {
msg = msg + ", COM Exception: " +e.getHResult() + ", " +
" with message: " + e.getMessage();
}
}

catch(Exception e) {
msg = msg + ", General error in class " + e.getClass() +
" with message: " + e.getMessage();
}

finally {
if (conn != null) {
if (conn.getState() == ObjectStateEnum.adStateOpen) {
conn.Close();
msg = msg + ", close";
}
ComLib.release (conn);
}
var.putString(msg);
return var;
}
}

}

The IObjectControl methods (Activate, Deactivate, CanBePooled) are called by MTS, CreateConnection is the method created to test connection pooling.

Compile java files

Compile the interface files (using the response file created by jactivex) and the implementation file with the jvc compiler (that came with SDK-Java 2.0 and not VJ++ 1.1). I ran jvc from the c:/src directory.

jvc @TestConnectjtx.rsp
jvc c:/winnt/java/TrustLib/TestConnectjtx/TestConnectObj.java


I am running jvc Version 1.02.4337

Generate DLL file

Generate dll file from the java class files and type library using the exegen program (while in the c:/src directory) .

exegen /d /out:TestConnectjtx.dll TestConnectjtx.tlb c:/winnt/java/trustlib/TestConnectjtx/*.class


The parameters are:

ParameterDefinition
/dGenerate an ActiveX DLL (rather than an .EXE)
/out:TestConnectjtx.dllName of the outputted DLL
This program was run from the c:/src directory. The input to this package is all the class files generated in the previous step and the type library. The file TestConnectjtx.dll is created in the c:/src directory.

Register dll as object

Register the newly created dll using regsvr32 program (while in the c:/src directory):

regsvr32 TestConnectjtx.dll


I used version 5.00.1586.1. Be careful, I searched my hard drive and found about a half dozen different versions of this program installed by different packages and SDKs.

Register with MTS Console

I created a new package (TestJava) and added the TestConnectjtx.dll as a component in this package using Transaction Server Explorer application.

To create a new package:

Select Console Root:Microsoft Transaction Server:My Computer:Packages Installed

Right click mouse, select New:Package from the popup menu.

Select empty package from dialog box

Enter package name (in this case TestJava).

To simplify this test, I set the property for this package by:

right clicking on the package name (TestJava) and in the popup menu selecting properties

selecting the Identity tab in the dialog box.

I set "this user" to the user that created the java object in the package.

To install activex object

Select Console Root:Microsoft Transaction Server:My Computer:Packages Installed: TestJava: Components

Right click mouse, select New:Component from the popup menu

Select Install new component(s) in the dialog box

Select Add files, use the file browser and select TestConnectjtx.dll in directory c:/src

To simplify this test, I set the property for the java object by:

right clicking the mouse on the object name (TestConnectjtx.TestConnect) and in the popup menu selecting properties

selecting the security tab in the dialog box.

disabled the "Enable authorization checking" check box.

I intend to set permissions in a way that makes sense for our environment at later time.

Create Client Program that uses this object

I created a VB5 exe program that calls this object. Before writing the routine, I selected the "Project:References" menu item and selected ""Simple MTS sample, written in java" (see the first help string in idl file above). The VB program consists of just a simple form with one button named Command1 and a Label control named Label1. Below is the code for the click event of the Command1 button:

Private Sub Command1_Click()

Dim objTest As CTestConnectjtx
Dim msg As Variant

On Error GoTo Handler

' Create instances of test object

Set objTest = CreateObject("TestConnectjtx.TestConnect")
msg = objTest.CreateConnection()
Set objTest = Nothing
Label1.Caption = msg

Exit Sub

Handler:
MsgBox Err.Description, vbOKOnly, "MTS VB TEST APP"
End Sub

This VB program was be compiled to an exe file. (called VBTestJava.exe).

Running Locally

VBTestJava.exe works when running the VB5 client, MTS 2.0, and object on the same machine. The label caption in this VB program shows that the context is initiated in the Activate method, and the CreateConnection method executes correctly.

Export Package

I create an export package using the MTS Console program. To export a package with MTS Console program:

highlight Console Root:Microsoft Transaction Server:My Computer:Packages Installed: TestJava , right click the mouse

Select export in the popup menu

Use the browse button and select the c:/src directory and enter TestConnect.pak as the file name.

This will create two files: TestConnect.pak and c:/src/clients/TestConnect.exe

Register Package on Remote Machine

In another machine in our NT domain, I ran TestConnect.exe (created in the last step). This created a new directory and file on that machine: c:/Program files/Remote Application/{{9E02CD9B-6C06-11D1-9623-0060974FBFB7}/TestConnecttjx.dll

Running Remotely

To run the object remotely, I then ran the VB client program VBTestJava.exe on the remote machine. The program's label caption indicated that the object ran with MTS context.

Testing Object with IIS 4.0 I tried this object with IIS 4.0.

I placed the following file in directory c:/InetPub/scripts:

<%Response.Buffer%>
<HEAD><TITLE>Java MTS Test</TITLE></HEAD>

<BODY>
<H1>Java MTS Test</H1>

<%
ON ERROR RESUME NEXT
Set objTest = Server.CreateObject("TestConnectjtx.TestConnect")

if Err.Number < 0 then
Response.Write Err.Description & "</BODY>"
Response.End
End if

Response.Write objTest.CreateConnection()

if Err.Number < 0 then
Response.Write Err.Description & "</BODY>"
Response.End
End if
%>
<P>Done
</BODY>

This file was placed on the "local" machine running the MTS 2.0, IIS 4.0, and the ActiveX Java object, and the "remote machine" with IIS 4.0 and export package version of the ActiveX Java object. In both cases, the correct result were displayed indicating the object ran within the MTS context.

[Back to the MTS Resource Center]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: