SF 1775889 - There was a like when passing arrays of indexes as part of set or get methods. 1775889 mentioned setString() but there were others also.

This commit is contained in:
clay_shooter
2007-08-27 03:34:56 +00:00
parent 74a8d04978
commit a8758521ad
5 changed files with 254 additions and 34 deletions

View File

@@ -24,12 +24,21 @@
<td width="13%" valign="top">&nbsp;</td>
<td width="87%" valign="top">&nbsp;</td>
</tr>
<tr>
<td width="13%" valign="top">1775889</td>
<td width="87%" valign="top">(M4) Fixed leak setString(int[],value) and other setString() methods</td>
</tr>
<tr>
<td width="13%" valign="top">&nbsp;</td>
<td width="87%" valign="top">&nbsp;</td>
</tr>
<tr>
<td width="100%" colspan="2"><b>Patches</b></td>
</tr>
<tr>
<td width="13%" valign="top">1709841 </td>
<td width="87%" valign="top">(M1) Compiled with Visual Studio 2005.
<td width="87%" valign="top">(M1) Compiled with Visual Studio 2005. Jacob now requires
2005 or later libraries.
See the UsingJacob.html file for impact this has on NT, 2000 and Server 2003 users.
</td>
</tr>
@@ -40,7 +49,6 @@
backwards compatible by default.
</td>
</tr>
<tr>
<tr>
<td width="13%" valign="top">&nbsp;</td>
<td width="87%" valign="top">&nbsp;</td>

View File

@@ -2456,10 +2456,12 @@ JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_setVariants
}
/* PLEASE NOTE THE LINE:
jint *jIndices = env->GetIntArrayElements(indices, NULL);
which I added to replace "long idx[2] = {i,j};" from the 2D case.
Not sure if this is correct. Also, check that I am doing the null test and
dimension test correctly.
jint *jIndices = env->GetIntArrayElements(indices, NULL);
which I added to replace "long idx[2] = {i,j};" from the 2D case.
Not sure if this is correct. Also, check that I am doing the null test and
dimension test correctly.
Would really like to call env->ReleaseIntArrayElements(indices, jIndices, NULL);
in here but I can't get it to work
*/
#define GETNDCODE(varType, varAccess, jtyp) \
@@ -2500,10 +2502,12 @@ dimension test correctly.
//---------------------------------
/* PLEASE NOTE THE LINE:
jint *jIndices = env->GetIntArrayElements(indices, NULL);
which I added to replace "long idx[2] = {i,j};" from the 2D case.
Not sure if this is correct. Also, check that I am doing the null test and
dimension test correctly.
jint *jIndices = env->GetIntArrayElements(indices, NULL);
which I added to replace "long idx[2] = {i,j};" from the 2D case.
Not sure if this is correct. Also, check that I am doing the null test and
dimension test correctly.
Would really like to call env->ReleaseIntArrayElements(indices, jIndices, NULL);
in here but I can't get it to work
*/
#define SETNDCODE(varType, varAccess) \
@@ -2586,6 +2590,7 @@ JNIEXPORT jobject JNICALL Java_com_jacob_com_SafeArray_getVariant___3I
} else {
ThrowComFail(env, "safearray type is not variant/dispatch", -1);
}
env->ReleaseIntArrayElements(indices, jIndices, NULL);
return newVariant;
}
@@ -2633,6 +2638,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_setVariant___3ILcom_jacob_co
} else {
ThrowComFail(env, "safearray type is not variant/dispatch", -1);
}
env->ReleaseIntArrayElements(indices, jIndices, NULL);
}
/*
@@ -2756,6 +2762,7 @@ JNIEXPORT jstring JNICALL Java_com_jacob_com_SafeArray_getString___3I
VARIANT v;
VariantInit(&v);
SafeArrayGetElement(psa, jIndices, &v);
env->ReleaseIntArrayElements(indices, jIndices, NULL);
if (FAILED(VariantChangeType(&v, &v, 0, VT_BSTR))) {
return NULL;
}
@@ -2765,18 +2772,22 @@ JNIEXPORT jstring JNICALL Java_com_jacob_com_SafeArray_getString___3I
} else if (vt == VT_BSTR) {
BSTR bs = NULL;
SafeArrayGetElement(psa, jIndices, &bs);
env->ReleaseIntArrayElements(indices, jIndices, NULL);
jstring js = env->NewString((jchar*)bs, SysStringLen(bs)); // SR cast SF 1689061
return js;
}
} else {
ThrowComFail(env, "safearray cannot get string", 0);
env->ReleaseIntArrayElements(indices, jIndices, NULL);
return NULL;
}
}
/*
* Class: com_jacob_com_SafeArray
* Method: setString
* Signature: ([ILjava/lang/String;)V
* Method: setStringjIndices, NULL);ILjava/lang/String;)V
*
* This method has a leak in it somewhere.
*/
JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_setString___3ILjava_lang_String_2
(JNIEnv *env, jobject _this, jintArray indices, jstring s)
@@ -2788,6 +2799,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_setString___3ILjava_lang_Str
}
// ??? Not sure if this is correct type for call to SafeArrayGetElement()
// could have individually retrieved the indicies
jint *jIndices = env->GetIntArrayElements(indices, NULL);
if (!jIndices) {
@@ -2819,6 +2831,8 @@ JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_setString___3ILjava_lang_Str
} else {
ThrowComFail(env, "safearray cannot set string", 0);
}
// need to unpin the copied array SF: 1775889
env->ReleaseIntArrayElements(indices, jIndices, NULL);
}
/*
@@ -2898,6 +2912,7 @@ JNIEXPORT jboolean JNICALL Java_com_jacob_com_SafeArray_getBoolean___3I
VARIANT v;
VariantInit(&v);
SafeArrayGetElement(sa, jIndices, (void*) &v);
env->ReleaseIntArrayElements(indices, jIndices, NULL);
if (FAILED(VariantChangeType(&v, &v, 0, VT_BOOL))) {
ThrowComFail(env, "safearray change type failed", -1);
return NULL;
@@ -2907,9 +2922,11 @@ JNIEXPORT jboolean JNICALL Java_com_jacob_com_SafeArray_getBoolean___3I
} else if (vt == VT_BOOL) {
VARIANT_BOOL vb;
SafeArrayGetElement(sa, jIndices, (void*) &vb);
env->ReleaseIntArrayElements(indices, jIndices, NULL);
jboolean jb = vb == VARIANT_TRUE ? JNI_TRUE: JNI_FALSE;
return jb;
} else {
env->ReleaseIntArrayElements(indices, jIndices, NULL);
return NULL;
}
}
@@ -2954,6 +2971,7 @@ JNIEXPORT void JNICALL Java_com_jacob_com_SafeArray_setBoolean___3IZ
} else {
ThrowComFail(env, "safearray type mismatch", -1);
}
env->ReleaseIntArrayElements(indices, jIndices, NULL);
}

View File

@@ -484,14 +484,14 @@ public class SafeArray extends JacobObject {
public native String getString(int sa_idx1, int sa_idx2);
/**
* string access
* puts a string into an element in a single dimensional safe array
* @param sa_idx
* @param c
*/
public native void setString(int sa_idx, String c);
/**
* string access
* puts a string into an element in a two dimensional array.
* @param sa_idx1
* @param sa_idx2
* @param c

View File

@@ -70,19 +70,20 @@ public class BaseTestCase extends TestCase {
// change all "." to ^ for later conversion to "/" so we can append resource names with "."
classPackageName = classPackageName.replace('.', '^');
System.out.println("classPackageName:" + classPackageName);
String fullPathToResource = (classPackageName.length() > 0 ? classPackageName
+ "^"
: "")
+ resourceName;
System.out.println("classPackageName: " + classPackageName);
String fullPathToResource;
if (classPackageName.length()> 0){
fullPathToResource = classPackageName + "^" + resourceName;
} else {
fullPathToResource = resourceName;
}
fullPathToResource = fullPathToResource.replace('^', '/');
System.out.println("fullPathToResource:" + fullPathToResource);
System.out.println("fullPathToResource: " + fullPathToResource);
URL urlToLibrary =
classInSamePackageAsResource.getClassLoader().getResource(fullPathToResource);
assertNotNull(urlToLibrary);
assertNotNull("URL to resource "+resourceName+" should not be null",urlToLibrary);
String fullPathToResourceAsFile = urlToLibrary.getFile();
System.out.println("url to library: "+urlToLibrary);
System.out.println("fullPathToResourceAsFile: "+fullPathToResourceAsFile);

View File

@@ -0,0 +1,193 @@
package com.jacob.test.safearray;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.JacobObject;
import com.jacob.com.SafeArray;
import com.jacob.com.Variant;
import com.jacob.test.BaseTestCase;
/**
* This test program demonstrates a weak in the setString(int[],String) method in SafeArray.
* To see the leak:
* <ul>
* <li>Bring up the windows task manager and click on the performance tab.
* <li>Run the test program
* </ul>
* You should see the Page File Usage History graph rise at te end of every cycle.
* Running the same program with setString(r,c,String) does not show the same symptoms
*/
public class SafeArrayLeak extends BaseTestCase {
/**
* ----------------------------------------------------------------------------------------------------------------------------
*
* ----------------------------------------------------------------------------------------------------------------------------
*/
public void testLeakWithSetString() {
ActiveXComponent xl = null;
Dispatch workbooks = null;
Dispatch workbook = null;
Dispatch workSheets = null;
Dispatch sheet = null;
Dispatch tabCells = null;
SafeArray sa = null;
//-Dcom.jacob.autogc=true
System.out.println("Jacob version: "+JacobObject.getBuildVersion());
for(int t = 0; t < 10; t++) {
// look at a large range of cells
String position = "A7:DM8934";
try {
xl = new ActiveXComponent("Excel.Application");
System.out.println("Excel version=" + xl.getProperty("Version"));
xl.setProperty("Visible", new Variant(false));
workbooks = xl.getProperty("Workbooks").toDispatch();
workbook = Dispatch.get(workbooks,"Add").toDispatch();
workSheets = Dispatch.get(workbook, "Worksheets").toDispatch();
sheet = Dispatch.get(workbook, "ActiveSheet").toDispatch();
// grab the whole range specified above.
tabCells = Dispatch.invoke(sheet, "Range", Dispatch.Get,
new Object[] { position },
new int[1]).toDispatch();
sa = Dispatch.get(tabCells, "Value").toSafeArray(true);
System.out.println("Ub0=" + sa.getUBound(1)); // nbCol
System.out.println("Ub1=" + sa.getUBound(2)); // nbLgn
// number of rows
int nbLgn = sa.getUBound(2);
// number of columns
int nbCol = sa.getUBound(1);
int[] colLgn = new int[] { 0, 0 };
// now set a value on every cell in the range we retrieved
for(int i = 1; i <= nbLgn; i++) {
colLgn[1] = i;
for(int j = 1; j <= nbCol; j++) {
colLgn[0] = j;
// this one works with out a leak 1.13-M3
//sa.setString(j, i, "test");
// This one leaks with 1.13-M3 and earlier
sa.setString(colLgn, "test");
}
}
Dispatch.put(tabCells, "Value", sa);
Variant f = new Variant(false);
Dispatch.call(workbook, "Close", f);
System.out.println("Close");
}
catch(Exception e) {
e.printStackTrace();
}
finally {
if (sa != null) {
try {
sa.safeRelease();
}
catch(Exception e) {
e.printStackTrace();
}
finally {
sa = null;
}
}
if (tabCells != null) {
try {
tabCells.safeRelease();
}
catch(Exception e) {
e.printStackTrace();
}
finally {
tabCells = null;
}
}
if (sheet != null) {
try {
sheet.safeRelease();
}
catch(Exception e) {
e.printStackTrace();
}
finally {
sheet = null;
}
}
if (workSheets != null) {
try {
workSheets.safeRelease();
}
catch(Exception e) {
e.printStackTrace();
}
finally {
workSheets = null;
}
}
if (workbook != null) {
try {
workbook.safeRelease();
}
catch(Exception e) {
e.printStackTrace();
}
finally {
workbook = null;
}
}
if (workbooks != null) {
try {
workbooks.safeRelease();
}
catch(Exception e) {
e.printStackTrace();
}
finally {
workbooks = null;
}
}
if (xl != null) {
try {
xl.invoke("Quit", new Variant[] {});
}
catch(Exception e) {
e.printStackTrace();
}
try {
xl.safeRelease();
}
catch(Exception e) {
e.printStackTrace();
}
finally {
xl = null;
}
}
ComThread.Release();
}
}
}
}