Java COM Automation with Jacob and JBuilder
Introduction
JACOB is a JAVA-COM Bridge that allows calling COM Automation components from
Java. It uses JNI to make native calls into the COM and Win32 libraries. Thus,
Java Classes can be combined to any DLL or ActiveX control, extending the functionalities
of resident components in applications (e.g.: Word, Excel, PowerPoint and which
want other systems that use components COM or DLLs). JACOB abstracts the complexity
of the JNI, offering one complete framework for communication with components
COM/DLL through code-source. This paper it offers the possibility to explore
the functionalities of the JACOB, as well as presents practical examples of
as to use this framework.
Download and Install Procedures
JACOB framework is an open-source project located in Sourceforge.net website.
To have access to the project it has access the Jacob
Website. Two options of download exist:
- Download jacob_x.x_src.zip to get the code source (if
customizations in the framework will be necessary)
- Download jacob_x.x.zip to only get the binary code. (if
it will be only to use)
The current version has only 229k, this exactly, very small. Open zip file
and unpacks the same where to desire.
To use framework it includes the jacob.jar file in classpath of your project
and jacob.dll in the Windows system directory (e.g. c:windowssystem32 or equivalent).
To get more information on the Jacob it looks at in the docs Jacob folder.
The Framework Packages and Classes
The First Example - Microsoft Word
This example is based in source-code provided in an article written by Ruhl,
K., 2003.
- Open JBuilder.
- Create a New Project. Go to in File > New Project >
Set a name to the Project (e.g.: JacobProject) > Click in the
Next button.
- Config the Jacob Library Path. Go to the Required Libraries
Tab > Click in the Add... button > In the Library Tab, click int the
New... button (if not the library included yet) > Set Jacob in the Name
field > Click in the Add... button > Select the Jacob.jar file, installed
in the your local disk. (e.g.: c:jacob_1.9jacob.jar) > Click
Ok > Click Ok > Click Ok > Click in the Finish button.
- Create a new Class. Go to File > New Class > Set
a name to the Class (e.g.: Word) > Click Ok.
- Create two new .doc files. c:jacob_1.9file_in.doc for
the strInputDoc and c:jacob_1.9file_out.doc (you do set other name, if
prefers). These files will be used in the example.
- Implement below code to the class and run it.
package jacobproject;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Variant;
import com.jacob.com.Dispatch;
public class Word {
String strDir = "c:jacob_1.9";
String strInputDoc = strDir + "file_in.doc";
String strOutputDoc = strDir + "file_out.doc";
String strOldText = "[label:import:1]";
String strNewText =
"I am some horribly long sentence, so long that [insert anything]";
boolean isVisible = true;
boolean isSaveOnExit = true;
public Word() {
ActiveXComponent oWord = new ActiveXComponent("Word.Application");
oWord.setProperty("Visible", new Variant(isVisible));
Dispatch oDocuments = oWord.getProperty("Documents").toDispatch();
Dispatch oDocument = Dispatch.call(oDocuments, "Open", strInputDoc).
toDispatch();
Dispatch oSelection = oWord.getProperty("Selection").toDispatch();
Dispatch oFind = oWord.call(oSelection, "Find").toDispatch();
Dispatch.put(oFind, "Text", strOldText);
Dispatch.call(oFind, "Execute");
Dispatch.put(oSelection, "Text", strNewText);
Dispatch.call(oSelection, "MoveDown");
Dispatch.put(oSelection, "Text",
"nSo we got the next line including BR.n");
Dispatch oFont = Dispatch.get(oSelection, "Font").toDispatch();
Dispatch.put(oFont, "Bold", "1");
Dispatch.put(oFont, "Italic", "1");
Dispatch.put(oFont, "Underline", "0");
Dispatch oAlign = Dispatch.get(oSelection, "ParagraphFormat").
toDispatch();
Dispatch.put(oAlign, "Alignment", "3");
Dispatch oWordBasic = (Dispatch) Dispatch.call(oWord, "WordBasic").
getDispatch();
Dispatch.call(oWordBasic, "FileSaveAs", strOutputDoc);
Dispatch.call(oDocument, "Close", new Variant(isSaveOnExit));
oWord.invoke("Quit", new Variant[0]);
}
public static void main(String[] args) {
Word word = new Word();
}
}
Ready! Now, open the file c:jacob_1.9file_out.doc for view the results!
This example shows the use of the COM Server of the Microsoft Word. To learn
to use the API of a COM Server it is necessary to study its TLB archive or the
technical documentation supplied for the manufacturer. The use of the Jacob
in itself is explained to follow.
The Package Structure
The Jacob has two packages:
- com.jacob.activeX: package that contains the ActiveXComponent
class.
- com.jacob.com: It contains all the other classes and elements
of the framework.
The Jacob Classes
The Jacob is a simple framework. Thus, he has few classes to know itself, looks
at:
- ActiveXComponent Class: This class provides a higher level,
more object like, wrapper for top of the Dispatch object and is the base class
to create an java object that encapsulates a COM object.
- Dispatch Class: Object represents MS level dispatch object.
Each instance of this, points at some data structure on the MS windows side.
This will be the class more used by the programmer, for being the father class
of all the other classes of framework. It has the methods also more used,
as the methods call, callSub, get, invoke, invokeSub and put. These methods
are explained after.
- Variant Class: The multi-format data type used for all
call backs and most communications between Java and COM. It provides a single
class that can handle all data types. It maps the COM Variant datatype.
- ComException Class: Standard exception thrown by COM JNI
code when there is a generic problem.
ComFailException Class: COM Fail Exception class, raise when there is a problem
with a call to the COM class.
The Jacob Methods
The methods of the Jacob make the calls to the methods of COM/DLL objects and
also they allow set values to the properties of COM/DLL objects. The methods
most used are:
- call method: method of the Dispatch class, is used to call
methods of the COM/DLL objects. This method has several implementations that
allow you flexibility in their use. It may return the result of the called
method in a Variant variable. It must be used in the place of invoke method.
- callSub method: equal to the method call, however does
not return a Variant.
- get method: used to get the value of a property of the
COM object. The value is returned in a Variant variable.
- put method: used to set the value of a property of the
COM object.
- invoke method: equal to the method call, however it is
more difficult to use, prefers method call.
- invokeSub method: equal to the method callSub, however
it is more difficult to use, prefers method callSub.
- getProperty method: method of the ActiveXComponent class.
Retrieves a property and returns it as a Variant.
- setProperty method: method of the ActiveXComponent class.
Set a property of the object.
The second Example – call of a DLL
Creating a DLL
This step was created with Delphi 2005, however is possible to use any tool
that has supported the development of DLLs. Open the Delphi Tool.
- Create the DLL. Go to File > New > Other > ActiveX
> ActiveX Library > Ok.
- Save the Project. Go to File > Save All > Choose
a Directory and a Filename (e.g.: TestJacob.bdsproj).
- Create an Automation Object. File > New > Other…
> ActiveX > Automation Object > set JacobObject value to the coClass
Name field > Ok.
- Save the files. File > Save All > Save the TestJacob.tlb
> Save the second file with TestJacob_Unt.pas.
- Create the property. Go to View > Type Library >
Select IJacobObject > Click with the right button > New > Property
> set computerName value to the name of the property > set BSTR value
to the type. Delete second property (put property, this property is read only).
- Click in the Refresh Implemetation button. Minimize Window.
- Go to the implementation unit. Go to View Unit Button (Crtl
+ F12) > Choose TestJacob_Unt file.
- Implement the function Get_computerName, with the below
code.
- Include the SysUtils and Windows units to the uses clause in
the top of the file.
- Save the Files. Go to the File > Save All.
- Register the DLL. Go to the
View Menu > Type Library > Click in the Register Type Library.
function TJacobObject.Get_computerName: WideString;
var
CompName: array[0..256] of Char;
i: DWord;
begin
i:=256;
GetComputerName(CompName, i);
result:=StrPas(CompName);
end;
Observation: to register the DLL in the DOS command is regsvr32
<nome do arquivo> and regsvr /u <nome do arquivo> to unregister
Create the Jacob Java Code that uses the DLL
- Open the JBuilder Project used in the first example.
- Create a New Class in JBuilder.
- Implement the below code and run the program class.
package jacobproject;
import com.jacob.activeX.ActiveXComponent;
public class DLL {
public DLL() {}
public static void main(String[] args) {
ActiveXComponent oWord = new ActiveXComponent("JacobDLL.JacobObject");
System.out.print(oWord.getProperty("computerName"));
}
}
Ready! This is example is running!
Alternatives to the Jacob
The are alternatives to the Jacob framewok, look:
- Jawin: The Java/Win32 integration project (Jawin) is a
free, open source architecture for interoperation between Java and components
exposed through Microsoft's Component Object Model (COM) or through Win32
Dynamic Link Libraries (DLLs).
- Java2COM (commercial): is a bi-directional Java-COM bridging
tool that enables Java applications to use COM objects and makes possible
to expose Java objects as if they were COM objects.
- JNI: JavaTM Native Interface (JNI) is a standard programming
interface for writing Java native methods and embedding the JavaTM virtual
machine* into native applications.
Conclusion
Framework Jacob is a good option to natively integrate the languages that support
DLLs (VB, Net, Delphi, C++, etc) and the Java. Before, the developers had to
write all the mapping code and to understand complex interface JNI to carry
through a simple call of ActiveX or DLL component. As we saw the Jacob is extremely
simple. It is enough to know some basic methods (invoke, call, put, getProperty
and setProperty) and two classes (ActiveXComponent and Dispatch).
References
- Ruhl, K.. Tutorial: Jacob & Microsoft Word. http://www.land-of-kain.de/jacob/.
(Jun. 2003).
- Jacob Official Web Site. http://sourceforge.net/projects/jacob-project.
- Jawin Official Web Site. http://sourceforge.net/projects/jawinproject
- JNI Official Web Site. http://java.sun.com/j2se/1.4.2/docs/guide/jni/index.html.
- Java2COM Official Web Site. http://www.argussoftware.net/products/com_argus_java2com.html