merged R-1_9 release tag against the root-B-1_9
This commit is contained in:
355
docs/EventCallbacks.htm
Normal file
355
docs/EventCallbacks.htm
Normal file
@@ -0,0 +1,355 @@
|
||||
<html xmlns:o="urn:schemas-microsoft-com:office:office"
|
||||
xmlns:w="urn:schemas-microsoft-com:office:word"
|
||||
xmlns="http://www.w3.org/TR/REC-html40">
|
||||
|
||||
<head>
|
||||
<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
|
||||
<meta name=ProgId content=Word.Document>
|
||||
<meta name=Generator content="Microsoft Word 11">
|
||||
<meta name=Originator content="Microsoft Word 11">
|
||||
<link rel=File-List href="EventCallbacks_files/filelist.xml">
|
||||
<title>Jacob can register Java classes for MS application events or callbacks</title>
|
||||
<!--[if gte mso 9]><xml>
|
||||
<o:OfficeDocumentSettings>
|
||||
<o:RemovePersonalInformation/>
|
||||
</o:OfficeDocumentSettings>
|
||||
</xml><![endif]--><!--[if gte mso 9]><xml>
|
||||
<w:WordDocument>
|
||||
<w:DisplayBackgroundShape/>
|
||||
<w:SpellingState>Clean</w:SpellingState>
|
||||
<w:GrammarState>Clean</w:GrammarState>
|
||||
<w:ValidateAgainstSchemas/>
|
||||
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
|
||||
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
|
||||
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
|
||||
<w:Compatibility>
|
||||
<w:SelectEntireFieldWithStartOrEnd/>
|
||||
<w:UseWord2002TableStyleRules/>
|
||||
</w:Compatibility>
|
||||
<w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>
|
||||
</w:WordDocument>
|
||||
</xml><![endif]--><!--[if gte mso 9]><xml>
|
||||
<w:LatentStyles DefLockedState="false" LatentStyleCount="156">
|
||||
</w:LatentStyles>
|
||||
</xml><![endif]-->
|
||||
<style>
|
||||
<!--
|
||||
/* Style Definitions */
|
||||
p.MsoNormal, li.MsoNormal, div.MsoNormal
|
||||
{mso-style-parent:"";
|
||||
margin:0in;
|
||||
margin-bottom:.0001pt;
|
||||
mso-pagination:widow-orphan;
|
||||
font-size:12.0pt;
|
||||
font-family:"Times New Roman";
|
||||
mso-fareast-font-family:"Times New Roman";}
|
||||
p.MsoPlainText, li.MsoPlainText, div.MsoPlainText
|
||||
{margin:0in;
|
||||
margin-bottom:.0001pt;
|
||||
mso-pagination:widow-orphan;
|
||||
font-size:10.0pt;
|
||||
font-family:"Courier New";
|
||||
mso-fareast-font-family:"Times New Roman";}
|
||||
span.SpellE
|
||||
{mso-style-name:"";
|
||||
mso-spl-e:yes;}
|
||||
span.GramE
|
||||
{mso-style-name:"";
|
||||
mso-gram-e:yes;}
|
||||
@page Section1
|
||||
{size:8.5in 11.0in;
|
||||
margin:1.0in 65.95pt 1.0in 65.95pt;
|
||||
mso-header-margin:.5in;
|
||||
mso-footer-margin:.5in;
|
||||
mso-paper-source:0;}
|
||||
div.Section1
|
||||
{page:Section1;}
|
||||
/* List Definitions */
|
||||
@list l0
|
||||
{mso-list-id:369961789;
|
||||
mso-list-type:hybrid;
|
||||
mso-list-template-ids:-80199436 -1920937264 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;}
|
||||
@list l0:level1
|
||||
{mso-level-text:"%1\)";
|
||||
mso-level-tab-stop:42.0pt;
|
||||
mso-level-number-position:left;
|
||||
margin-left:42.0pt;
|
||||
text-indent:-24.0pt;}
|
||||
@list l0:level2
|
||||
{mso-level-tab-stop:1.0in;
|
||||
mso-level-number-position:left;
|
||||
text-indent:-.25in;}
|
||||
@list l0:level3
|
||||
{mso-level-tab-stop:1.5in;
|
||||
mso-level-number-position:left;
|
||||
text-indent:-.25in;}
|
||||
@list l0:level4
|
||||
{mso-level-tab-stop:2.0in;
|
||||
mso-level-number-position:left;
|
||||
text-indent:-.25in;}
|
||||
@list l0:level5
|
||||
{mso-level-tab-stop:2.5in;
|
||||
mso-level-number-position:left;
|
||||
text-indent:-.25in;}
|
||||
@list l0:level6
|
||||
{mso-level-tab-stop:3.0in;
|
||||
mso-level-number-position:left;
|
||||
text-indent:-.25in;}
|
||||
@list l0:level7
|
||||
{mso-level-tab-stop:3.5in;
|
||||
mso-level-number-position:left;
|
||||
text-indent:-.25in;}
|
||||
@list l0:level8
|
||||
{mso-level-tab-stop:4.0in;
|
||||
mso-level-number-position:left;
|
||||
text-indent:-.25in;}
|
||||
@list l0:level9
|
||||
{mso-level-tab-stop:4.5in;
|
||||
mso-level-number-position:left;
|
||||
text-indent:-.25in;}
|
||||
@list l1
|
||||
{mso-list-id:1316765558;
|
||||
mso-list-type:hybrid;
|
||||
mso-list-template-ids:860497186 -1920937264 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;}
|
||||
@list l1:level1
|
||||
{mso-level-text:"%1\)";
|
||||
mso-level-tab-stop:42.0pt;
|
||||
mso-level-number-position:left;
|
||||
margin-left:42.0pt;
|
||||
text-indent:-24.0pt;}
|
||||
@list l1:level2
|
||||
{mso-level-tab-stop:1.0in;
|
||||
mso-level-number-position:left;
|
||||
text-indent:-.25in;}
|
||||
@list l1:level3
|
||||
{mso-level-tab-stop:1.5in;
|
||||
mso-level-number-position:left;
|
||||
text-indent:-.25in;}
|
||||
@list l1:level4
|
||||
{mso-level-tab-stop:2.0in;
|
||||
mso-level-number-position:left;
|
||||
text-indent:-.25in;}
|
||||
@list l1:level5
|
||||
{mso-level-tab-stop:2.5in;
|
||||
mso-level-number-position:left;
|
||||
text-indent:-.25in;}
|
||||
@list l1:level6
|
||||
{mso-level-tab-stop:3.0in;
|
||||
mso-level-number-position:left;
|
||||
text-indent:-.25in;}
|
||||
@list l1:level7
|
||||
{mso-level-tab-stop:3.5in;
|
||||
mso-level-number-position:left;
|
||||
text-indent:-.25in;}
|
||||
@list l1:level8
|
||||
{mso-level-tab-stop:4.0in;
|
||||
mso-level-number-position:left;
|
||||
text-indent:-.25in;}
|
||||
@list l1:level9
|
||||
{mso-level-tab-stop:4.5in;
|
||||
mso-level-number-position:left;
|
||||
text-indent:-.25in;}
|
||||
ol
|
||||
{margin-bottom:0in;}
|
||||
ul
|
||||
{margin-bottom:0in;}
|
||||
-->
|
||||
</style>
|
||||
<!--[if gte mso 10]>
|
||||
<style>
|
||||
/* Style Definitions */
|
||||
table.MsoNormalTable
|
||||
{mso-style-name:"Table Normal";
|
||||
mso-tstyle-rowband-size:0;
|
||||
mso-tstyle-colband-size:0;
|
||||
mso-style-noshow:yes;
|
||||
mso-style-parent:"";
|
||||
mso-padding-alt:0in 5.4pt 0in 5.4pt;
|
||||
mso-para-margin:0in;
|
||||
mso-para-margin-bottom:.0001pt;
|
||||
mso-pagination:widow-orphan;
|
||||
font-size:10.0pt;
|
||||
font-family:"Times New Roman";
|
||||
mso-ansi-language:#0400;
|
||||
mso-fareast-language:#0400;
|
||||
mso-bidi-language:#0400;}
|
||||
</style>
|
||||
<![endif]-->
|
||||
</head>
|
||||
|
||||
<body lang=EN-US style='tab-interval:.5in'>
|
||||
|
||||
<div class=Section1>
|
||||
|
||||
<p class=MsoPlainText>Jacob can register Java classes for MS application events
|
||||
or callbacks.<span style='mso-spacerun:yes'><EFBFBD> </span>The normal flow for this
|
||||
is:</p>
|
||||
|
||||
<p class=MsoPlainText><o:p> </o:p></p>
|
||||
|
||||
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
||||
l1 level1 lfo2;tab-stops:list 42.0pt'><![if !supportLists]><span
|
||||
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>1)<span
|
||||
style='font:7.0pt "Times New Roman"'>
|
||||
</span></span></span><![endif]>Application thread creates an instance of the
|
||||
event handler and registers it with Jacob</p>
|
||||
|
||||
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
||||
l1 level1 lfo2;tab-stops:list 42.0pt'><![if !supportLists]><span
|
||||
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>2)<span
|
||||
style='font:7.0pt "Times New Roman"'>
|
||||
</span></span></span><![endif]>The application continues on doing other work.</p>
|
||||
|
||||
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
||||
l1 level1 lfo2;tab-stops:list 42.0pt'><![if !supportLists]><span
|
||||
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>3)<span
|
||||
style='font:7.0pt "Times New Roman"'>
|
||||
</span></span></span><![endif]>Some time later, the MS application takes some
|
||||
action and initiates the event callback.</p>
|
||||
|
||||
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
||||
l1 level1 lfo2;tab-stops:list 42.0pt'><![if !supportLists]><span
|
||||
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>4)<span
|
||||
style='font:7.0pt "Times New Roman"'>
|
||||
</span></span></span><![endif]>The Java VM receives the event and spins up a
|
||||
new thread to handle it.</p>
|
||||
|
||||
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
||||
l1 level1 lfo2;tab-stops:list 42.0pt'><![if !supportLists]><span
|
||||
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>5)<span
|
||||
style='font:7.0pt "Times New Roman"'>
|
||||
</span></span></span><![endif]>The Jacob <span class=SpellE>EventProxy</span>
|
||||
in the <span class=SpellE>dll</span> is called by the VM.</p>
|
||||
|
||||
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
||||
l1 level1 lfo2;tab-stops:list 42.0pt'><![if !supportLists]><span
|
||||
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>6)<span
|
||||
style='font:7.0pt "Times New Roman"'>
|
||||
</span></span></span><![endif]>The Jacob <span class=SpellE>EventProxy</span>
|
||||
creates Variant objects to handle the parameters of the passed in event.</p>
|
||||
|
||||
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
||||
l1 level1 lfo2;tab-stops:list 42.0pt'><![if !supportLists]><span
|
||||
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>7)<span
|
||||
style='font:7.0pt "Times New Roman"'>
|
||||
</span></span></span><![endif]>The Jacob <span class=SpellE>EventProxy</span>
|
||||
uses reflection to map the event name to a method name with the exact same
|
||||
name.</p>
|
||||
|
||||
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
||||
l1 level1 lfo2;tab-stops:list 42.0pt'><![if !supportLists]><span
|
||||
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>8)<span
|
||||
style='font:7.0pt "Times New Roman"'>
|
||||
</span></span></span><![endif]>The Jacob <span class=SpellE>EventProxy</span>
|
||||
sends the message to the registered event handler.</p>
|
||||
|
||||
<p class=MsoPlainText><o:p> </o:p></p>
|
||||
|
||||
<p class=MsoPlainText>Swing developers should note that this message comes in
|
||||
on a thread other than the event thread.<span style='mso-spacerun:yes'><EFBFBD>
|
||||
</span>All objects receiving events that require user intervention or drawing
|
||||
in the UI should use <span class=SpellE><span class=GramE>invokeLater</span></span><span
|
||||
class=GramE>(</span>) to post requests for actions onto the event queue.<span
|
||||
style='mso-spacerun:yes'><EFBFBD> </span>Failure to do so will insure random failures
|
||||
in the GUI.</p>
|
||||
|
||||
<p class=MsoPlainText><o:p> </o:p></p>
|
||||
|
||||
<p class=MsoPlainText>Java Web Start (JWS) and other launchers can have
|
||||
additional issues related to the class loader.<span style='mso-spacerun:yes'><EFBFBD>
|
||||
</span>The Jacob C++ library uses <span class=SpellE><span class=GramE>FindClass</span></span><span
|
||||
class=GramE>(</span>) to find the Variant class when building the parameter
|
||||
list.<span style='mso-spacerun:yes'><EFBFBD> </span><span class=SpellE><span
|
||||
class=GramE>FindClass</span></span><span class=GramE>(</span>) uses the system
|
||||
class loader which includes only the classes specified at run time or in the
|
||||
CLASSPATH.<span style='mso-spacerun:yes'><EFBFBD> </span>Most of the application
|
||||
classes in this situation live in an alternate set of class loaders that were
|
||||
created when the launcher located and ran the application classes.<span
|
||||
style='mso-spacerun:yes'><EFBFBD> </span>This means that the search for Variant will
|
||||
fail usually with the silent and immediate termination of the Java application.<span
|
||||
style='mso-spacerun:yes'><EFBFBD> </span>The thread <span class=SpellE>classloader</span>
|
||||
probably can<61>t be used to try and find the class because this new thread does
|
||||
not have a <span class=SpellE>classloader</span> associated with it other than
|
||||
the system class loader.<span style='mso-spacerun:yes'><EFBFBD> </span>The end result
|
||||
is that the Variant class needs to be located via other means and that the
|
||||
thread <span class=SpellE>classloader</span> should be set to be the context
|
||||
class loader of the event handler class.</p>
|
||||
|
||||
<p class=MsoPlainText><o:p> </o:p></p>
|
||||
|
||||
<p class=MsoPlainText>The Jacob <span class=SpellE>EventProxy</span> class has
|
||||
been modified (off of the 1.8 tree) so that it takes a two step approach to
|
||||
towards fixing these problems.</p>
|
||||
|
||||
<p class=MsoPlainText><span style='mso-tab-count:2'><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span></p>
|
||||
|
||||
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
||||
l0 level1 lfo4;tab-stops:list 42.0pt'><![if !supportLists]><span
|
||||
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>1)<span
|
||||
style='font:7.0pt "Times New Roman"'>
|
||||
</span></span></span><![endif]>The <span class=SpellE>EventProxy</span>
|
||||
constructor now accepts an extra object, an instance of the Variant class.<span
|
||||
style='mso-spacerun:yes'><EFBFBD> </span>This gives the <span class=SpellE>EventProxy</span>
|
||||
a way to get to the Variant class and thus to its <span class=SpellE>classloader</span>.
|
||||
All of the callers of the constructor have been modified to pass a Variant
|
||||
object to the <span class=SpellE>EventProxy</span> without programmer
|
||||
intervention.</p>
|
||||
|
||||
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
||||
l0 level1 lfo4;tab-stops:list 42.0pt'><![if !supportLists]><span
|
||||
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>2)<span
|
||||
style='font:7.0pt "Times New Roman"'>
|
||||
</span></span></span><![endif]><span class=SpellE>EventProxy</span> first
|
||||
attempts to locate the Variant class using <span class=SpellE>FindClass</span>()</p>
|
||||
|
||||
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
||||
l0 level1 lfo4;tab-stops:list 42.0pt'><![if !supportLists]><span
|
||||
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>3)<span
|
||||
style='font:7.0pt "Times New Roman"'>
|
||||
</span></span></span><![endif]>Failing that, it looks to see if a variant
|
||||
object had been passed in. If so, it calls <span class=GramE>class(</span>) and
|
||||
goes from there.<span style='mso-spacerun:yes'><EFBFBD> </span></p>
|
||||
|
||||
<p class=MsoPlainText style='margin-left:42.0pt;text-indent:-24.0pt;mso-list:
|
||||
l0 level1 lfo4;tab-stops:list 42.0pt'><![if !supportLists]><span
|
||||
style='mso-fareast-font-family:"Courier New"'><span style='mso-list:Ignore'>4)<span
|
||||
style='font:7.0pt "Times New Roman"'>
|
||||
</span></span></span><![endif]>If all that fails, it logs a message and then
|
||||
fails in the spectacular fashion of the previous versions.</p>
|
||||
|
||||
<p class=MsoPlainText><o:p> </o:p></p>
|
||||
|
||||
<p class=MsoPlainText>Developers can receive call back events in JWS other Java
|
||||
launching programs without implementing any additional code.<span
|
||||
style='mso-spacerun:yes'><EFBFBD> </span>They should be aware that their callback
|
||||
methods may need to set the class <span class=GramE>loader.:</span></p>
|
||||
|
||||
<p class=MsoPlainText><span style='mso-tab-count:1'><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span>Public xxx <span
|
||||
class=SpellE><span class=GramE>someHandler</span></span><span class=GramE>(</span>Variant[]
|
||||
<span class=SpellE>foo</span>){</p>
|
||||
|
||||
<p class=MsoPlainText><span style='mso-tab-count:2'><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span><span
|
||||
class=SpellE><span class=GramE>Thread.currentThread</span></span><span
|
||||
class=GramE>(</span>).<span class=SpellE>setContextClassLoader</span>(</p>
|
||||
|
||||
<p class=MsoPlainText><span style='mso-tab-count:3'><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span><span
|
||||
class=SpellE><span class=GramE>this.getClass</span></span><span class=GramE>(</span>).<span
|
||||
class=SpellE>getClassLoader</span>());</p>
|
||||
|
||||
<p class=MsoPlainText><span style='mso-tab-count:2'><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span>// do
|
||||
something</p>
|
||||
|
||||
<p class=MsoPlainText><span style='mso-tab-count:1'><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span>}</p>
|
||||
|
||||
<p class=MsoPlainText><o:p> </o:p></p>
|
||||
|
||||
<p class=MsoPlainText>There may still be a dual event queue issue in JWS
|
||||
applications that needs to be looked at.</p>
|
||||
|
||||
<p class=MsoPlainText><o:p> </o:p></p>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
69
docs/HowToBuild.txt
Normal file
69
docs/HowToBuild.txt
Normal file
@@ -0,0 +1,69 @@
|
||||
(2/2005)
|
||||
To build and run:
|
||||
|
||||
Unpack the source archive or check the files out of CVS into d:\jacob
|
||||
|
||||
Install the following tools
|
||||
Microsfot Visual Studio, a stripped down version is available from the MS web site.
|
||||
Eclipse from www.eclipse.org.
|
||||
Java jdk 1.4 (this was built using 1.4.2.06)
|
||||
|
||||
The following configuration was used by most of the development team:
|
||||
JDK = d:\j2sdk1.4.2_06
|
||||
DEST_DIR = d:\jacob
|
||||
MSDEVDIR = d:\apps\\"Microsoft Visual Studio"\VC98
|
||||
|
||||
This project has been converted completely over to ANT. You can
|
||||
run ANT from inside of eclipse or from the command line.
|
||||
The ant process is driven off of a configuration file
|
||||
compilation_tools.properties. Instructions on the information required
|
||||
in that file are contained in build.xml in the root directory.
|
||||
|
||||
Ant, via build.xml will do the following with teh default target.
|
||||
Build the Java code
|
||||
Build the jni code
|
||||
create the dll
|
||||
create jar file
|
||||
|
||||
The package target creates the
|
||||
javadoc and
|
||||
zip files
|
||||
|
||||
ECLIPSE
|
||||
|
||||
Eclipse users will have to do some minor tweaks to their project if they
|
||||
want to use the integrated build process. This is because the unit
|
||||
tests are com.jacob.com files located in the unittest directory while
|
||||
the jacob files themselves are in com.jacob.com off the root directory.
|
||||
(Eventually the the jacob files will be moved to src)
|
||||
Eclipse automatically adds the whole project as a source directory
|
||||
Remove the root of the project from the build path
|
||||
Add folders samples, src and unittest to the build path
|
||||
Exclude *.txt from each of the newly added folders.
|
||||
|
||||
A couple of the samples require a J2EE library in order to compile. This
|
||||
means you'll have to add a J2EE jar file to your classpath. This
|
||||
isn't a problem when using ANT because the Servlet examples are excluded
|
||||
from the build.
|
||||
|
||||
|
||||
|
||||
--- old instructions for makefiles that no longer exist --
|
||||
|
||||
To build:
|
||||
Run VCVARS32 to set up your MS Visual C++ environment
|
||||
cd d:\jacob
|
||||
nmake
|
||||
|
||||
(from dan)I developed this with the C++ compiler and ATL version
|
||||
that ship with VC++ 6.0, so I'm not sure if different versions will
|
||||
work.
|
||||
|
||||
This is currently designed to compile against JDK 1.4.2. The future
|
||||
of the Microsoft SDK is in doubt so support may be discontinued
|
||||
in the future.
|
||||
|
||||
|
||||
The java code is in com\jacob\*.
|
||||
The C++ code is in .\jni.
|
||||
|
||||
51
docs/JacobComLifetime.html
Normal file
51
docs/JacobComLifetime.html
Normal file
@@ -0,0 +1,51 @@
|
||||
<H1>COM Object Lifetime in JACOB</H1>
|
||||
<p>
|
||||
<H2>introduction</H2>
|
||||
<p>
|
||||
JACOB Version 1.7 implements a new
|
||||
<a href="JacobThreading.html">Threading Model</a> that is more
|
||||
compatible with COM apartments. There is also an incompatibility
|
||||
between the Java object lifetime model and that of COM objects.
|
||||
COM Objects live and die by their reference count, whereas Java
|
||||
objects are collected by the Garbage Collector (GC) based on algortihms
|
||||
that are hidden from the user.
|
||||
<H2>COM Object Lifetime in JACOB Prior to Version 1.7</H2>
|
||||
<p>
|
||||
In version 1.6 and earlier, JACOB objects which wrapped COM objects
|
||||
had <code>finalize()</code> methods that would call a native
|
||||
<code>release</code> method which would call a COM <code>Release</code>.
|
||||
<p>
|
||||
This has many problems. For one thing, the GC may take a long time to
|
||||
kick in and resource consumption may grow. However, the more problematic
|
||||
issue is that finalizers are called from a separate thread, and, as was
|
||||
discussed in the <a href="JacobThreading.html">Threading Model</a>
|
||||
document, this can result in COM errors if the object is running in an
|
||||
STA. Even if the object is running in an MTA, the finalizer may decide
|
||||
to run after we have terminated the thread that holds the component, in
|
||||
which case we would get fatal errors and crashes.
|
||||
<H2>COM Object Lifetime in JACOB in Version 1.7</H2>
|
||||
<p>
|
||||
In Version 1.7, all JACOB objects which wrap COM objects extend
|
||||
<code>com.jacob.com.JacobObject</code>. This object has some special
|
||||
code to register itself with a <code>com.jacob.com.ROT</code> object
|
||||
which represents a Running Object Table (ROT). This table maps a
|
||||
Thread to the set of JacobObjects created in that thread. Therefore,
|
||||
when you call <code>ComThread.Release()</code>, the ROT checks whether
|
||||
that thread has created any objects, and these objects are released
|
||||
by calling their native <code>release</code> method (which is public).
|
||||
<p>
|
||||
This lifetime management method ties the lifecycle to the thread's
|
||||
lifecycle rather than the GC. The JacobObject's still have finalizers,
|
||||
but they will typically not perform the native <code>release</code>
|
||||
since that has already been called. The native <code>release</code>
|
||||
methods were written such that you can call them multiple times without
|
||||
worrying - since they zero out the native pointer when called the first
|
||||
time.
|
||||
<p>
|
||||
If you choose to call <code>release</code> methods on your objects
|
||||
yourself, that is allowed. In that case, when the thread is released
|
||||
the release calls will be no-ops.
|
||||
<p>
|
||||
It becomes important for you to call <code>ComThread.Release()</code>
|
||||
on any thread before you allow it to exit, otherwise you may get
|
||||
some random crashes later on in your code.
|
||||
410
docs/JacobThreading.html
Normal file
410
docs/JacobThreading.html
Normal file
@@ -0,0 +1,410 @@
|
||||
<H1>COM Apartments in JACOB</H1>
|
||||
<p>
|
||||
<H2>introduction</H2>
|
||||
<p>
|
||||
The COM model for Threading differs from the Java model.
|
||||
In COM, each component can declare whether or not it support
|
||||
multi-threading.
|
||||
|
||||
You can find some basic information about COM threading at:
|
||||
<p>
|
||||
<a href="http://www.execpc.com/~gopalan/com/com_threading.html">
|
||||
http://www.execpc.com/~gopalan/com/com_threading.html</a>
|
||||
<p>
|
||||
<a href="www.microsoft.com/msj/0297/apartment/apartment.htm">
|
||||
www.microsoft.com/msj/0297/apartment/apartment.htm</a>
|
||||
<p>
|
||||
<a href="http://www.cswl.com/whiteppr/white/multithreading.html">
|
||||
http://www.cswl.com/whiteppr/white/multithreading.html
|
||||
</a>
|
||||
<p>
|
||||
The term <b>Single Threaded Apartment (STA)</b> refers to a thread
|
||||
where all COM objects created in that thread are
|
||||
single-threaded. This can manifest itself in two ways:
|
||||
<br>
|
||||
Either all calls into that component are made from the same thread
|
||||
that created the component
|
||||
<br>
|
||||
OR any call that is made from another thread gets serialized by COM.
|
||||
This serialization of calls is done by using a Windows message loop and
|
||||
posting messages to a hidden window (I'm not kidding). The way COM
|
||||
achieves this is by requiring any other thread to make calls through
|
||||
a local Proxy object rather than the original object (more on this
|
||||
when we discuss the JACOB DispatchProxy class).
|
||||
<p>
|
||||
What does this mean for a Java application? If you are using a component
|
||||
that declares itself as <b>ThreadingModel "Apartment"</b> (you can
|
||||
find this out by looking in the registry under its CLSID), and you plan
|
||||
to create, use and destroy this component in one thread - then you are
|
||||
following the rules of an STA and you can declare the thread as an
|
||||
STA thread.
|
||||
<p>
|
||||
On the other hand, if you need to make method calls from another thread
|
||||
(e.g. in a servlet) then you have a few choices. Either you
|
||||
create the component in its own STA, by extending
|
||||
<code>com.jacob.com.STA</code>, and use the
|
||||
<code>com.jacob.com.DispatchProxy</code> class to pass the Dispatch
|
||||
pointer between threads, or you can declare your thread as an MTA
|
||||
thread. In that case, COM will make
|
||||
the cross-thread calls into the STA that is running your component.
|
||||
If you create an Apartment threaded component in the MTA,
|
||||
COM will automatically create an STA for you and put your
|
||||
component in there, and then marshall all the calls.
|
||||
<p>
|
||||
This brings us to the notion of a <b>Main STA</b>. COM requires that
|
||||
if there is any Apartment threaded component in your application, then
|
||||
the first STA created is tagged as the <b>Main STA</b>. COM uses the
|
||||
Main STA to create all the Apartment threaded components that are
|
||||
created from an MTA thread. The problem is that if you have already
|
||||
created an STA, then COM will pick that as the Main STA, and if you
|
||||
ever exit that thread - the whole application will exit.
|
||||
|
||||
<H2>COM Threads in JACOB Prior to Version 1.7</H2>
|
||||
<p>
|
||||
Up until version 1.7 of JACOB, there was only one model available
|
||||
in JACOB:
|
||||
<ul>
|
||||
<li>
|
||||
Before version 1.6: All threads were automatically initialized as STAs.
|
||||
</li>
|
||||
<li>
|
||||
In version 1.6: All threads were automatically initialized as MTAs.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
The reason for the change in default was that tagging a Java thread
|
||||
as an STA can cause problems. Any Java Swing application, as well as
|
||||
servlets and applets need to be able to make calls from multiple
|
||||
threads. If you try to make COM method calls across STA threads - it
|
||||
will fail!
|
||||
<p>
|
||||
In most cases, the default chosen by JACOB 1.6 (MTA) works fine, however
|
||||
there are some notable exceptions that have caused people grief. One
|
||||
such exception is in the case of MAPI. It turns out that if you try to
|
||||
create a MAPI object from an MTA thread - it simply fails and exits.
|
||||
This has caused some people to recompile JACOB 1.6 back with the STA
|
||||
default.
|
||||
<p>
|
||||
There is another problem with MTA threads: when you are using Apartment
|
||||
threaded components, we already noted that COM will create the
|
||||
components in the Main STA. If one doesn't exist, COM will create it.
|
||||
However, this means that <b>all</b> Apartment threaded components will
|
||||
be created in the <b>same STA</b>. This creates a bottleneck, and a
|
||||
dependency between unrelated components. Also, if that STA exits, then
|
||||
all components are destroyed and the application will likely crash.
|
||||
|
||||
<H2>COM Threads in JACOB Version 1.7</H2>
|
||||
<p>
|
||||
In Version 1.7 we have added finer grained control to allow the
|
||||
Java programmer to control how COM creates its components.
|
||||
Unfortunately, this means that you need to have a pretty good
|
||||
understanding of the dark and mystical subject of COM Apartments.
|
||||
There are a few different cases you need to consider:
|
||||
<H3>Default</H3>
|
||||
<p>
|
||||
If you simply run code that was created in Version 1.6 and ignore
|
||||
the COM threading issue, then you will get the same behavior as in 1.6:
|
||||
Each java thread will be an MTA thread, and all Apartment threaded
|
||||
components will be created by COM in its own Main STA. This typically
|
||||
works for most applications (exceptions noted above).
|
||||
<H3>Create Your Own Apartment</H3>
|
||||
<p>
|
||||
To declare an MTA thread use the following template:
|
||||
<br>
|
||||
<pre>
|
||||
<code>
|
||||
ComThread.InitMTA();
|
||||
...
|
||||
...
|
||||
ComThread.Release();
|
||||
</pre>
|
||||
</code>
|
||||
<br>
|
||||
If you want JACOB to create its own Main STA (rather than having COM
|
||||
choose an STA for you), then you should use:
|
||||
<br>
|
||||
<code>
|
||||
<pre>
|
||||
Thread 1:
|
||||
ComThread.InitMTA(true); // a true tells JACOB to create a Main STA
|
||||
...
|
||||
...
|
||||
ComThread.Release();
|
||||
...
|
||||
Thread 2:
|
||||
ComThread.InitMTA();
|
||||
...
|
||||
...
|
||||
ComThread.Release();
|
||||
...
|
||||
...
|
||||
ComThread.quitMainSTA();
|
||||
</pre>
|
||||
</code>
|
||||
<br>
|
||||
In this case, you can also create the Main STA explicitly:
|
||||
<br>
|
||||
<code>
|
||||
<pre>
|
||||
ComThread.startMainSTA();
|
||||
...
|
||||
...
|
||||
Thread 1:
|
||||
ComThread.InitMTA();
|
||||
...
|
||||
...
|
||||
ComThread.Release();
|
||||
...
|
||||
Thread 2:
|
||||
ComThread.InitMTA();
|
||||
...
|
||||
...
|
||||
ComThread.Release();
|
||||
...
|
||||
...
|
||||
ComThread.quitMainSTA();
|
||||
</pre>
|
||||
</code>
|
||||
<br>
|
||||
In the latter case, all Apartment threaded components will be created in
|
||||
JACOB's main STA. This still has all the problems of components
|
||||
sharing the same Main STA and creating a bottleneck. To avoid that,
|
||||
you can also create STA threads yourself:
|
||||
<br>
|
||||
<code>
|
||||
<pre>
|
||||
ComThread.startMainSTA();
|
||||
...
|
||||
...
|
||||
Thread 1:
|
||||
ComThread.InitSTA();
|
||||
...
|
||||
...
|
||||
ComThread.Release();
|
||||
...
|
||||
Thread 2:
|
||||
ComThread.InitMTA();
|
||||
...
|
||||
...
|
||||
ComThread.Release();
|
||||
...
|
||||
...
|
||||
ComThread.quitMainSTA();
|
||||
</pre>
|
||||
</code>
|
||||
<br>
|
||||
In this example, thread 1 is an STA and thread 2 is an MTA. You could
|
||||
omit the call to ComThread.startMainSTA(), but if you do, then COM will
|
||||
make the first STA your main one, and then if you exit that thread,
|
||||
the application will crash.
|
||||
<p>
|
||||
Actually, Thread 1 is <i>almost</i> an STA. It's lacking a windows
|
||||
message loop. So, this type of STA is fine as long as you are creating
|
||||
a component and using it in the same thread, and not makind event
|
||||
callbacks.
|
||||
<H3>JACOB's STA Class</H3>
|
||||
<p>
|
||||
If you want to create an true STA where you can create a component and
|
||||
then let other threads call methods on it, then you need a windows
|
||||
message loop. JACOB provides a class called:
|
||||
<code>com.jacob.com.STA</code> which does exactly this.
|
||||
<code>
|
||||
<pre>
|
||||
public class com.jacob.com.STA extends java.lang.Thread
|
||||
{
|
||||
public com.jacob.com.STA();
|
||||
public boolean OnInit(); // you override this
|
||||
public void OnQuit(); // you override this
|
||||
public void quit(); // you can call this from ANY thread
|
||||
}
|
||||
</pre>
|
||||
</code>
|
||||
<p>
|
||||
The STA class extends
|
||||
<code>java.lang.Thread</code> and it provides you with two methods
|
||||
that you can override: <code>OnInit</code> and <code>OnQuit</code>.
|
||||
These methods are called from the thread's <code>run</code> method
|
||||
so they will execute in the new thread. These methods allow you to
|
||||
create COM components (Dispatch objects) and release them.
|
||||
To create an STA, you subclass it and override the OnInit.
|
||||
<p>
|
||||
The <code>quit</code> method is the <b>only</b> other method that
|
||||
can be called from any thread. This method uses the Win32 function
|
||||
<code>PostThreadMessage</code> to force the STA's windows message loop
|
||||
to exit, thereby terminating the thread.
|
||||
<p>
|
||||
You will then need to make calls into the component that is running
|
||||
in the STA thread. If you simply try to make calls from another thread
|
||||
on a Dispatch object created in the STA thread, you will get a COM
|
||||
Exception. For more details see:
|
||||
<a href="http://www.develop.com/effectivecom">
|
||||
Don Box 'Effective COM' Rule 29</a>: Don't Access raw
|
||||
interface pointers across apartment boundaries.
|
||||
<H3>The DispatchProxy Class</H3>
|
||||
Since you cannot call methods directly on a Dispatch object created
|
||||
in another STA JACOB provides a method for the class that created
|
||||
the Dispatch object to marshal it to your thread. This is done via
|
||||
the <code>com.jacob.com.DispatchProxy</code> class.
|
||||
<code>
|
||||
<pre>
|
||||
public class DispatchProxy extends JacobObject {
|
||||
public DispatchProxy(Dispatch);
|
||||
public Dispatch toDispatch();
|
||||
|
||||
public native void release();
|
||||
public void finalize();
|
||||
}
|
||||
</code>
|
||||
</pre>
|
||||
<p>
|
||||
This class works as follows: the thread that created the Dispatch
|
||||
object constructs an instance of DispatchProxy(Dispatch) with the
|
||||
Dispatch as a parameter. This instance can then be accessed from
|
||||
another thread, which will invoke its <code>toDispatch</code> method
|
||||
proxy as if it were local to your thread. COM will do the inter-thread
|
||||
marshalling transparently.
|
||||
<p>
|
||||
The following example is part of samples/test/ScriptTest2.java in the
|
||||
JACOB distribution. It shows how you can create the ScriptControl
|
||||
in one STA thread and make method calls on it from another:
|
||||
<code>
|
||||
<pre>
|
||||
import com.jacob.com.*;
|
||||
import com.jacob.activeX.*;
|
||||
|
||||
class ScriptTest2 extends STA
|
||||
{
|
||||
public static ActiveXComponent sC;
|
||||
public static Dispatch sControl = null;
|
||||
public static DispatchProxy sCon = null;
|
||||
|
||||
public boolean OnInit()
|
||||
{
|
||||
try
|
||||
{
|
||||
System.out.println("OnInit");
|
||||
System.out.println(Thread.currentThread());
|
||||
String lang = "VBScript";
|
||||
|
||||
sC = new ActiveXComponent("ScriptControl");
|
||||
sControl = (Dispatch)sC.getObject();
|
||||
|
||||
// sCon can be called from another thread
|
||||
sCon = new DispatchProxy(sControl);
|
||||
|
||||
Dispatch.put(sControl, "Language", lang);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnQuit()
|
||||
{
|
||||
System.out.println("OnQuit");
|
||||
}
|
||||
|
||||
public static void main(String args[]) throws Exception
|
||||
{
|
||||
try {
|
||||
ComThread.InitSTA();
|
||||
ScriptTest2 script = new ScriptTest2();
|
||||
Thread.sleep(1000);
|
||||
|
||||
// get a thread-local Dispatch from sCon
|
||||
Dispatch sc = sCon.toDispatch();
|
||||
|
||||
// call a method on the thread-local Dispatch obtained
|
||||
// from the DispatchProxy. If you try to make the same
|
||||
// method call on the sControl object - you will get a
|
||||
// ComException.
|
||||
Variant result = Dispatch.call(sc, "Eval", args[0]);
|
||||
System.out.println("eval("+args[0]+") = "+ result);
|
||||
script.quit();
|
||||
System.out.println("called quit");
|
||||
} catch (ComException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally
|
||||
{
|
||||
ComThread.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</code>
|
||||
<p>
|
||||
You can try to modify the <code>Dispatch.call</code> invocation in
|
||||
the main thread to use <code>sControl</code> directly, and you will see
|
||||
that it fails. Notice that once we construct the ScriptTest2 object
|
||||
in the main thread, we sleep for a second to allow the other thread
|
||||
time to initialize itself.
|
||||
<p>
|
||||
The STA thread calls <code>sCon = new DispatchProxy(sControl);</code>
|
||||
to save a global reference to the DispatchProxy that represents the
|
||||
<code>sControl</code> object. The main thread then calls:
|
||||
<code>Dispatch sc = sCon.toDispatch();</code> to get a local Dispatch
|
||||
proxy out of the DispatchProxy object.
|
||||
<p>
|
||||
At most <b>one(!)</b>
|
||||
thread can call toDispatch(), and the call can be made only once.
|
||||
This is because a IStream object is used to pass the proxy, and
|
||||
it is only written once and closed when you read it.
|
||||
If you need multiple threads to access a Dispatch pointer, then
|
||||
create that many DispatchProxy objects. For more details please
|
||||
refer to the Don Box reference above.
|
||||
|
||||
|
||||
<H3>Recommended Procedure</H3>
|
||||
<ul>
|
||||
<li>
|
||||
It is recommended that you always allow JACOB to manage the main STA
|
||||
rather than letting COM create one on its own or tag one of yours.
|
||||
</li>
|
||||
<li>
|
||||
Declare an STA thread using ComThread.InitSTA()
|
||||
if all your
|
||||
method calls for that component are going to come from the same thread.
|
||||
</li>
|
||||
<li>
|
||||
If you want an STA thread that allows other threads to call into it,
|
||||
use the <code>com.jacob.com.STA</code> class as outlined above.
|
||||
</li>
|
||||
<li>
|
||||
If you have a COM component that declares its ThreadingModel as
|
||||
"Free" or "Both", then use the MTA.
|
||||
</li>
|
||||
<li>
|
||||
In most cases, if you need to make method calls from multiple threads,
|
||||
you can simply
|
||||
use MTA threads, and allow COM to create the components in
|
||||
the Main STA. You should only create your own STA's and DispatchProxy
|
||||
if you understand COM well enough to know when the MTA solution
|
||||
will fail or have other shortcomings.
|
||||
<p>
|
||||
There are 3 examples in the samples/test directory that demonstrate
|
||||
these cases:
|
||||
<p>
|
||||
ScriptTest.java - creates an STA for the ScriptControl component and
|
||||
runs all its method calls from that STA.
|
||||
<p>
|
||||
ScriptTest2.java - creates a separate STA thread, and makes
|
||||
method calls into the component from another thread using DispatchProxy.
|
||||
<p>
|
||||
ScriptTest3.java - creates a separate MTA thread, and makes method
|
||||
calls into the component from another MTA thread. This is simpler
|
||||
than ScriptTest2 for most applications.
|
||||
<p>
|
||||
<h3>Default Threading Model</h3>
|
||||
If you create a new thread, and don't call
|
||||
<code>ComThread.InitSTA()</code> or <code>ComThread.InitMTA()</code>
|
||||
on it, then the first time your java code creates a JacobObject, it
|
||||
will try to register itself with the ROT, and when it sees that the
|
||||
current thread is not initialized, it will initialize it as MTA.
|
||||
This means that the code to do this is no longer inside the native
|
||||
jni code - it is now in the <code>com.jacob.com.ROT</code> class.
|
||||
For more details on the ROT, see the
|
||||
<a href="JacobComLifetime.html">Object Lifetime</a> document.
|
||||
344
docs/WhatsNew.html
Normal file
344
docs/WhatsNew.html
Normal file
@@ -0,0 +1,344 @@
|
||||
<h1>What's New in JACOB 1.9</H1>
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
<b>Event Callbacks</b>
|
||||
<ul>
|
||||
|
||||
<li>Variant parameters can now be modified by the receiver to be passed
|
||||
back to the COM caller </li>
|
||||
<li>Callbacks can now be received when running in JWS other launchers where
|
||||
JACOB.jar is not in the system classloader's path.</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<b>Dispatch API Clarifications</B>
|
||||
<ul>
|
||||
|
||||
<li>All static method's first parameters have been more strongly typed
|
||||
to the Dispatch class, rather than Object. This may call for code
|
||||
changes in the cases of code that just asigned Dispatch objects
|
||||
to variables of type Object rather than Dispatch or one of its subclasses </li>
|
||||
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<b>Dispatch subclasses are now supported with pointer modifying constructor</b>
|
||||
<ul>
|
||||
|
||||
<li>Dispatch and ActiveXComponent now includes a constructor to be used by Dispatch subclasses
|
||||
that swaps the pointers around. This eliminates the need for every Dispatch subclass
|
||||
to have a constructor that swapped and nulled out the pointers to the COM layer.
|
||||
All samples have updated to use the new api </li>
|
||||
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<b>ActiveXComponent has been upgraded</b><ul>
|
||||
|
||||
<li>ActiveXComponent methods return ActiveXComponets </li>
|
||||
<li>Methods have been added to the ActiveXComponents to retrieve
|
||||
parameters as Dispatch objects or ActiveX components. The
|
||||
Script Tests have been updated to show the same programs in Dispatch
|
||||
format or ActiveXComponentFormat </li>
|
||||
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<b>Memory Management</b>
|
||||
<ul>
|
||||
|
||||
<li>Beta test option that lets an application use automatic object object
|
||||
removal through the use of weak reference hash maps in the ROT class. The
|
||||
default behavior of manual release via the COMThread class has been retained as
|
||||
the default behavior. Developers can test automatic memory collection by
|
||||
using the command line option <i>-Dcom.JACOB.autogc=true</i> </li>
|
||||
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<b>JNI Changes</b>
|
||||
<ul>
|
||||
|
||||
<li>Erroneous Array dimension checking fixed for certain boolean set and get functions
|
||||
</li>
|
||||
<li>Alternative method for finding Variant class for callbacks in JWS
|
||||
or other application lanchers where the system classloader does not
|
||||
know about JACOB classes. </li>
|
||||
<li>Unicode is supported for putString and putStringRef</li>
|
||||
<li>EventProxy zeros out the com object reference in the Variant objects
|
||||
that are created by EventProxy so that they are not double released,
|
||||
by both the Java VM and calling code from the COM side. The caller
|
||||
is supposed to be responsible for releasing the memory it created.
|
||||
This fix only applies to Variants created in callbacks. </li>
|
||||
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<b>Logging Additions</b><ul>
|
||||
|
||||
<li>Debugging logging to standard out for JACOB can be turned on by using the
|
||||
command line option <i>-Dcom.JACOB.debug=true</i></li>
|
||||
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<b>Visual Studio</b><ul>
|
||||
|
||||
<li>The VisualStudio directory in the CVS repository will be removed in the next
|
||||
release</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<b>Documentation</b><ul>
|
||||
|
||||
<li>API documentation via Javadoc is now being generated for all classes.</li>
|
||||
|
||||
<li>The development team is looking for help in upgrading the quality of the
|
||||
class documentation</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<b>Build Changes</b>
|
||||
<ul>
|
||||
|
||||
<li>A static method has been added to JacobObject that returns the build version</li>
|
||||
|
||||
<li>The project is now being built using ANT. Most of the developers are
|
||||
running this from inside of Eclipse</li>
|
||||
<li>All makefiles have been purged</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h2>Tracked Changes</h2>
|
||||
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%">
|
||||
<tr>
|
||||
<td width="100%" colspan="2"><b>Bugs</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="13%">1116101</td>
|
||||
<td width="87%">jacob-msg 0284 : Access Violation while garbage collecting</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="13%">1114159</td>
|
||||
<td width="87%">Problem with COM Error Trapping in JACOB DLL</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="13%">1113610</td>
|
||||
<td width="87%">Bad error check in SafeArray.cpp</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="13%">1066698</td>
|
||||
<td width="87%">Minor Memory leak in Dispatch.cpp</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="13%">1065533</td>
|
||||
<td width="87%">Problem with unicode conversion</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="13%">1053871</td>
|
||||
<td width="87%">solution for memory leak in 1.7</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="13%">1053870</td>
|
||||
<td width="87%">JACOB0msg 2019 - Safe Array</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="13%">1053866</td>
|
||||
<td width="87%">getHResult only returns 80020009</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="13%">960646</td>
|
||||
<td width="87%">But in SafeArray:: getBoolean for 2D arrays</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="13%"> </td>
|
||||
<td width="87%"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="100%" colspan="2"><b>Patches</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="13%">1115187</td>
|
||||
<td width="87%">EventCallbacks fail w/Variant ClassNotFoundException in JWS</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="13%">1105915</td>
|
||||
<td width="87%">Fix for event handling memory corruption</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="13%">1090104</td>
|
||||
<td width="87%">Weak Reference in teh ROT</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="13%">1068544</td>
|
||||
<td width="87%">in/out parameter support for event handlers</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="13%">981540</td>
|
||||
<td width="87%">jre 1.4.2 fix as patch</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="13%"> </td>
|
||||
<td width="87%"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="100%" colspan="2"><b>Feature Requests</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="13%">1049390</td>
|
||||
<td width="87%">static Version information</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="13%">1049224</td>
|
||||
<td width="87%">Javadocs or at least script to generate it</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="13%">1049158</td>
|
||||
<td width="87%">API to get ProgId of ActiveXComponent</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="13%"> </td>
|
||||
<td width="87%"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h1>What's New in JACOB 1.8</H1>
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
<b>Move To SourceForge</b>
|
||||
The project is not housed at
|
||||
<a href="http://sourceforge.net/projects/jacob-project/">Sourceforge.net</a>.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<b>Licensing Change</b>
|
||||
All limitations on commercial use of JACOB have been removed and it
|
||||
is now being developed under a BSD license at
|
||||
<a href="http://sourceforge.net/projects/jacob-project/">Sourceforge.net</a>.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<b>Compiled with Java 1.4.2</b>
|
||||
Version 1.8 was compiled with JSEE 1.4.2 and fixes the compilation bug
|
||||
that was remnant of compilation with JDK 1.1.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<b>Baseline For Change</b>
|
||||
This version is the baseline for the first CVS checkin and we encourage
|
||||
people to start contributing to the project with this version.
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<li>
|
||||
<h1>What's New in JACOB 1.7</H1>
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
<b>Explicit COM Threading Model Support:</b>
|
||||
See a detailed discussion of
|
||||
<a href="JacobThreading.html">COM Apartments in JACOB</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<b>New COM Object Lifetime model:</b>
|
||||
See a detailed discussion of
|
||||
<a href="JacobComLifetime.html">COM Object Lifetime in JACOB</a>.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<b>Improved Event Handling:</b>
|
||||
Thanks to code contributed by
|
||||
<a href="mailto:n.o.bouvin@daimi.au.dk">
|
||||
Niels Olof Bouvin</a>
|
||||
and <a href="mailto:jehoej@daimi.au.dk">Henning Jae</a> JACOB 1.7 can
|
||||
read the type information of a Connection Point interface by looking
|
||||
it up in the registry. This makes it possible to use events with IE as
|
||||
well as office products.
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<b>Improved Dispatch:</b>
|
||||
Error messages from Invoke failures are now printed out as well as
|
||||
allowing the passing in of arguments to a Get method.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<b>EnumVariant Implementation:</b>
|
||||
Makes it easier to iterate over COM collections. Thanks to code
|
||||
contributed by
|
||||
<a href="mailto:Thomas.Hallgren@eoncompany.com">Thomas Hallgren</a>.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<b>SafeArray leaks:</b>
|
||||
SafeArrays were not being properly freed prior to version 1.7, many
|
||||
other memory leaks were fixed as well.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<b>Visual Studio Project:</b>
|
||||
For those who want to debug: vstudio/JACOB. At the moment all the
|
||||
native code is replicated there from the jni directory...
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
<H1>Related Links</H1>
|
||||
<ul>
|
||||
<li>
|
||||
The JACOB mailing list is hosted at yahoo groups:
|
||||
<a href="http://groups.yahoo.com/group/jacob-project">
|
||||
http://groups.yahoo.com/group/JACOB-project</a>.
|
||||
<b>This is the preferred way to get support for JACOB</b>. It also
|
||||
includes an extensive archive. If you are doing any development with
|
||||
JACOB, please join the list.
|
||||
<li>
|
||||
Massimiliano Bigatti has developed
|
||||
<a href="http://www.bigatti.it/projects/jacobgen/">
|
||||
JACOBgen - a generator that automatically creates JACOB code from
|
||||
Type Libraries</a>
|
||||
</li>
|
||||
<li>
|
||||
Steven Lewis is developing a version of Java2Com that supports JACOB
|
||||
code generation. See:
|
||||
<a href="http://www.lordjoe.com/Java2Com/index.html">
|
||||
http://www.lordjoe.com/Java2Com/index.html</a>.
|
||||
<li>
|
||||
To find documentation on the com.ms.com package, go to:
|
||||
<a href="http://www.microsoft.com/java/download/dl_sdk40.htm">
|
||||
http://www.microsoft.com/java/download/dl_sdk40.htm</a>
|
||||
and at the bottom of the page is a link that says:
|
||||
Microsoft SDK for Java 4.0 Documentation Only. You should download
|
||||
that file and install it. Then, view sdkdocs.chm and look for
|
||||
"Microsoft Packages Reference". Hopefully, the next release of
|
||||
JACOB will include full javadoc (volunteers?)...</li>
|
||||
3
docs/todo.txt
Normal file
3
docs/todo.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
1. Make everything check the current thread's mta-ness
|
||||
2. Write more documentation
|
||||
3. Get someone to help write the Javadoc
|
||||
Reference in New Issue
Block a user