<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p>Hi Tom,</p>
<p>please file an issue at <a class="moz-txt-link-freetext" href="https://github.com/OSGeo/gdal/issues">https://github.com/OSGeo/gdal/issues</a> with
your reproducer snippet</p>
<p>Even<br>
</p>
<div class="moz-cite-prefix">Le 17/07/2025 à 02:28, Tom Moore a
écrit :<br>
</div>
<blockquote type="cite"
cite="mid:1370f2a3-3753-4ef1-8f75-770c79b988a7@app.fastmail.com">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title></title>
<div>Hi Evan</div>
<div><br>
</div>
<div>I seem to still be having problems closing datasets in Java
resulting in a JVM crash, using gdal-3-13-3_x64 downloaded from
the GISInternals site. Below is the stack trace information. <br>
</div>
<div>
<div><br>
</div>
<div>--------------- T H R E A D ---------------</div>
<div><br>
</div>
<div>Current thread (0x000001ffd39932c0): JavaThread
"Finalizer" daemon [_thread_in_native, id=25140,
stack(0x000000ba6eb00000,0x000000ba6ec00000) (1024K)]</div>
<div><br>
</div>
<div>Stack: [0x000000ba6eb00000,0x000000ba6ec00000],
sp=0x000000ba6ebfed60, free space=1019k</div>
<div>Native frames: (J=compiled Java code, j=interpreted, Vv=VM
code, C=native code)</div>
<div>C [gdal.dll+0xc86927]</div>
<div><br>
</div>
<div>Java frames: (J=compiled Java code, j=interpreted, Vv=VM
code)</div>
<div>j org.gdal.gdal.gdalJNI.delete_Dataset(J)V+0</div>
<div>j org.gdal.gdal.Dataset.delete()V+25</div>
<div>j org.gdal.gdal.Dataset.finalize()V+1</div>
<div>j java.lang.System$2.invokeFinalize(Ljava/lang/Object;)V+1
<a class="moz-txt-link-abbreviated" href="mailto:java.base@21.0.6">java.base@21.0.6</a></div>
<div>j
java.lang.ref.Finalizer.runFinalizer(Ljdk/internal/access/JavaLangAccess;)V+115
<a class="moz-txt-link-abbreviated" href="mailto:java.base@21.0.6">java.base@21.0.6</a></div>
<div>j java.lang.ref.Finalizer$FinalizerThread.run()V+29
<a class="moz-txt-link-abbreviated" href="mailto:java.base@21.0.6">java.base@21.0.6</a></div>
<div>v ~StubRoutines::call_stub 0x000001ffa369100d</div>
<div><br>
</div>
<div>siginfo: EXCEPTION_ACCESS_VIOLATION (0xc0000005), reading
address 0xffffffffffffffff<br>
</div>
<div><br>
</div>
<div> The crash is happening when the swig delete_Dataset
method, called by the finalizer, calls into the gdal.dll.</div>
<div><br>
</div>
</div>
<div>I tried calling Open() and Close() several times in a row to
see if this would trigger the problem, like this:</div>
<div>gdal.<i>AllRegister</i>();</div>
<div> Dataset ds = gdal.Open(filename); </div>
<div> ds.Close();</div>
<div> ds.Close(); </div>
<div><br>
</div>
<div>but that seemed to work ok.</div>
<div><br>
</div>
<div>I also tried open and close sequences, like this:</div>
<div> Dataset ds = gdal.Open(filename);</div>
<div> ds.Close();</div>
<div> ds = gdal.Open(filename);<br>
</div>
<div> ds.Close(); </div>
<div> ds = gdal.Open(filename);</div>
<div> System.gc();</div>
<div> System.runFinalization();</div>
<div><br>
</div>
<div>This didn't trigger a problem either. I did a few more
tests, repeating steps of opening a dataset, reading a band,
closing the dataset, and this didn't do it either.</div>
<div><br>
</div>
<div>If I enable CPL_DEBUG then my pattern of access that causes
the crash is:</div>
<div>GDAL:
GDALDriver::Create(GTiff,c:/tmp/test1.tif,10,10,1,Int32,000001BCB9893680)</div>
<div>GDAL: GDALClose(c:/tmp/test1.tif, this=000001BCB9872A90)</div>
<div>GDAL: GDALOpen(c:/tmp/test1.tif, this=000001BCB98784D0)
succeeds as GTiff.</div>
<div>GDAL: GDALClose(c:/tmp/test1.tif, this=000001BCB98784D0)</div>
<div>GDAL: GDALOpen(c:/tmp/test1.tif, this=000001BCBE486550)
succeeds as GTiff.</div>
<div>GDAL: GDALOpen(c:/tmp/test1.tif.vat.dbf,
this=000001BCBE10D070) succeeds as ESRI Shapefile.</div>
<div>GDAL: GDALClose(c:/tmp/test1.tif.vat.dbf,
this=000001BCBE10D070)</div>
<div>GDAL: GDALClose(c:/tmp/test1.tif, this=000001BCBE486550)</div>
<div><br>
</div>
<div>
<div>Around this point the finalizer kicks in and the JVM
crashes.</div>
<div><br>
</div>
</div>
<div>This is a hard one for me to track down, because I don't know
the tooling to debug native cpp code from within Java. What I
could do is insert some debugging statements in to the code to
try to see what is going on. If you have any suggestions about
this I would be happy to try it.</div>
<div><br>
</div>
<div>Tom</div>
<div><br>
</div>
<div><br>
</div>
<div>On Fri, May 30, 2025, at 5:53 PM, Even Rouault wrote:</div>
<blockquote type="cite" id="qt" style="">
<div><br>
</div>
<div>Le 30/05/2025 à 23:39, Tom Moore a écrit :</div>
<div>> Hi Even</div>
<div>></div>
<div>> I just wanted to update you and provide a record for
posterity with </div>
<div>> the results of me playing around with gdal/java and
resource management.</div>
<div>></div>
<div>> It appears to me that Dataset objects should not be
closed from Java </div>
<div>> client code. If you do then often there will be an
access violation </div>
<div>> (native null pointer) that will crash the JVM. From
the dump file the </div>
<div>> following stack trace shows the Java code being
executed when the </div>
<div>> exception occurs:</div>
<div><br>
</div>
<div>I believe this issue should be fixed in 3.11.0 per </div>
<div><a
href="https://github.com/OSGeo/gdal/commit/ec4ca7930b48653bb0fac27b59c6c1bf883c45f2"
moz-do-not-send="true" class="moz-txt-link-freetext">https://github.com/OSGeo/gdal/commit/ec4ca7930b48653bb0fac27b59c6c1bf883c45f2</a></div>
<div><br>
</div>
<div>Actually historically this was the .delete() method that
should be </div>
<div>called. The exposition of .Close() is quite recent and was
broken (until </div>
<div>the above mentioned fix)</div>
<div><br>
</div>
<div>></div>
<div>> Java frames: (J=compiled Java code, j=interpreted,
Vv=VM code)</div>
<div>> j org.gdal.gdal.gdalJNI.delete_Dataset(J)V+0</div>
<div>> j org.gdal.gdal.Dataset.delete()V+25</div>
<div>> j org.gdal.gdal.Dataset.finalize()V+1</div>
<div>> j
java.lang.System$2.invokeFinalize(Ljava/lang/Object;)V+1 </div>
<div>> <a class="moz-txt-link-abbreviated" href="mailto:java.base@21.0.6">java.base@21.0.6</a></div>
<div>> j </div>
<div>>
java.lang.ref.Finalizer.runFinalizer(Ljdk/internal/access/JavaLangAccess;)V+115 </div>
<div>> <a class="moz-txt-link-abbreviated" href="mailto:java.base@21.0.6">java.base@21.0.6</a></div>
<div>> j java.lang.ref.Finalizer$FinalizerThread.run()V+29
<a class="moz-txt-link-abbreviated" href="mailto:java.base@21.0.6">java.base@21.0.6</a></div>
<div>></div>
<div>> So it looks like the swig bindings implement a
finalizer to dispose of </div>
<div>> the native object when the reference is no longer
reachable (nice!). </div>
<div>> However it looks like there might not be any
protection to prevent bad </div>
<div>> things from happening when the Delete method is called
more than </div>
<div>> once. It appears that in this case that when the
finalizer calls </div>
<div>> Delete on the Dataset the jvm crashes because the
Dataset has already </div>
<div>> been closed manually and the resources have already
been released.</div>
<div>></div>
<div>> If I am correct in this conclusions then this is not a
problem. If </div>
<div>> correct I suggest that either the docs be updated to
indicate do not </div>
<div>> manually call Delete on the Dataset object, or change
the Delete </div>
<div>> method code to gracefully handle multiple calls
(better choice).</div>
<div>></div>
<div>> By the way, something to note for the future is that
finalizers have </div>
<div>> been deprecated since Java 9 (2017). This is
described in </div>
<div>> <a href="https://openjdk.org/jeps/421"
moz-do-not-send="true" class="moz-txt-link-freetext">https://openjdk.org/jeps/421</a>.
Although deprecated, finalizers are </div>
<div>> still allowed in modern jdk's and probably will be for
a while yet. At </div>
<div>> some future time they will be removed. The suggested
replacement for </div>
<div>> finalizers are cleaners, but they are only available
in Java 9+. When </div>
<div>> finalizers are removed there will need to be a new set
of bindings </div>
<div>> that use cleaners. You can probably ignore this
problem for a few </div>
<div>> more years, but at some point you will need to provide
two sets of </div>
<div>> Java bindings (one required for Java 8 and earlier,
and one required </div>
<div>> for some future Java and later).</div>
<div><br>
</div>
<div>Thanks for the heads up. Seizing the opportunity to remind
interesting </div>
<div>parties in the GDAL Java bindings that they should not be
shy and are </div>
<div>welcome to be proactive. On my side, they are very very
minimilastically </div>
<div>maintained.</div>
<div><br>
</div>
<div>Even</div>
<div><br>
</div>
<div>-- </div>
<div><a href="http://www.spatialys.com" moz-do-not-send="true"
class="moz-txt-link-freetext">http://www.spatialys.com</a></div>
<div>My software is free, but my time generally not.</div>
<div><br>
</div>
<div><br>
</div>
</blockquote>
<div><br>
</div>
<div id="sig151763583">
<div class="signature">--</div>
<div class="signature">Tom Moore</div>
<div class="signature">Spatial Planning Systems</div>
<div class="signature">960 Burkes Bluff Lane</div>
<div class="signature">Deep River ON K0J 1P0</div>
<div class="signature">Canada</div>
<div class="signature"><br>
</div>
<div class="signature">Phone: +1 613 584 9354</div>
</div>
<div><br>
</div>
</blockquote>
<pre class="moz-signature" cols="72">--
<a class="moz-txt-link-freetext" href="http://www.spatialys.com">http://www.spatialys.com</a>
My software is free, but my time generally not.</pre>
</body>
</html>