Opened 14 years ago

Closed 14 years ago

#3711 closed defect (fixed)

EXCEPTION_ACCESS_VIOLATION, when using GDAL Java API

Reported by: jimmyzhao Owned by: ilucena
Priority: highest Milestone:
Component: JavaBindings Version: 1.7.1
Severity: critical Keywords: GDAL, GeoRaster
Cc: warmerdam

Description (last modified by jimmyzhao)

I use GDAL Java API to write raster data to Oracle Spatial GeoRaster Object, and encouter a strange problem:

" # # A fatal error has been detected by the Java Runtime Environment:

# # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0afa0770,pid=5904, tid=5548

# # JRE version: 6.0_15-b03

# Java VM: Java HotSpot(TM) Client VM (14.1-b02 mixed mode windows-x86 )

# Problematic frame:

# C [gdal17.dll+0x190770]

# # An error report file with more information is saved as: # D:\workspace\GDALTest\hs_err_pid5904.log

# # If you would like to submit a bug report, please visit: # http://java.sun.com/webapps/bugreport/crash.jsp[[BR]]

# The crash happened outside the Java Virtual Machine in native code.

"

This is my Java codes:

import java.nio.ByteBuffer;

import org.gdal.gdal.Band;
import org.gdal.gdal.Dataset;
import org.gdal.gdal.Driver;
import org.gdal.gdal.gdal;
import org.gdal.gdalconst.gdalconstConstants;


public class GDALTest3 {

	public static void main(String[] args) {

		Dataset dataset1;
		Dataset dataset2;
		
		Band band1;
		Band band2;
		
		Driver driver;
		
		gdal.AllRegister();
		
		driver = gdal.GetDriverByName("georaster");
		
		dataset1 = gdal.Open("geor:georaster/georaster@orcl,rdt_01,1");
		band1 = dataset1.GetRasterBand(1);
		
		int xSize = dataset1.getRasterXSize();
		int ySize = dataset1.getRasterYSize();
		int bands = dataset1.getRasterCount();
		
		String options[] = new String[]{"INSERT=VALUES(103, 'new.tif', SDO_GEOR.INIT('rdt_01',3))", "BLOCKXSIZE=512", "BLOCKYSIZE=512"};
		dataset2 = driver.Create("georaster:georaster/georaster,,georaster_table,georaster",
				xSize, ySize, bands, band1.getDataType(), options);
		
		dataset2.SetGeoTransform(dataset1.GetGeoTransform());
		dataset2.SetProjection(dataset1.GetProjection());
		
		band2 = dataset2.GetRasterBand(1);
		
		ByteBuffer buffer = ByteBuffer.allocateDirect(xSize);
		
		for( int i =0; i < ySize; i++ ) {
			
			buffer = band1.ReadRaster_Direct(0,i,xSize,1);
			
			band2.WriteRaster_Direct(0,i,xSize,1,buffer);
		}
		
		dataset2.FlushCache();
		
		System.out.println("generate a new georaster : " + dataset2.GetDescription());
		
		dataset1.delete();
		dataset2.delete();		
	}

}

When executing the sentence "Dataset2.FlushCache();", the above problem rises.

By the way, I can use gdal_translate to load GTiff file to Oracle Georaster database successfully, and I can also export Oracle Spatial GeoRaster data to GTiff file with GDAL Java API. But why can't I use GDAL Java API to load GTiff file to Oracle GeoRaster database?

The version of GDAL is 1.7.1, and it is compiled with Visual Studio 2008. The version of Oracle is 11gR2. The GTiff image is 183MB with 3 bands. The log of exact error is attached.

Attachments (7)

hs_err_pid5904.log (11.6 KB ) - added by jimmyzhao 14 years ago.
error report
hs_err_pid1464.log (11.7 KB ) - added by jimmyzhao 14 years ago.
right.txt (6.7 KB ) - added by jimmyzhao 14 years ago.
wrong.txt (5.8 KB ) - added by jimmyzhao 14 years ago.
right.JPG (211.5 KB ) - added by jimmyzhao 14 years ago.
wrong.JPG (141.8 KB ) - added by jimmyzhao 14 years ago.
GDALLoader.java (2.2 KB ) - added by jimmyzhao 14 years ago.

Download all attachments as: .zip

Change History (19)

by jimmyzhao, 14 years ago

Attachment: hs_err_pid5904.log added

error report

by jimmyzhao, 14 years ago

Attachment: hs_err_pid1464.log added

comment:1 by jimmyzhao, 14 years ago

Description: modified (diff)

comment:2 by jimmyzhao, 14 years ago

Owner: changed from Even Rouault to ilucena

comment:3 by jimmyzhao, 14 years ago

Description: modified (diff)

comment:4 by ilucena, 14 years ago

Jimmy,

I could not replicate that problem on Linux or Windows. I made a few corrections on that sample code in order to make sure that it could support a more than one bands and check for Byte datatype. I don't think it will fix the problem but make the that code a little bit more consistent.

import java.nio.ByteBuffer;

import org.gdal.gdal.Band;
import org.gdal.gdal.Dataset;
import org.gdal.gdal.Driver;
import org.gdal.gdal.gdal;
import org.gdal.gdalconst.gdalconstConstants;

public class GDALTest {

	public static void main(String[] args) {
		Dataset dataset1;
		Dataset dataset2;
		Band band1;
		Band band2;
		Driver driver;

		gdal.AllRegister();
		
		driver = gdal.GetDriverByName("georaster");

		dataset1 = gdal.Open("geor:scott/tiger@orcl,gdal_rdt,181");
		band1 = dataset1.GetRasterBand(1);

		int xSize = dataset1.getRasterXSize();
		int ySize = dataset1.getRasterXSize();
		int nBand = dataset1.GetRasterCount();
		int dType = band1.getDataType();

		if (dType != gdalconstConstants.GDT_Byte) {
            System.err.println("Only support Byte.");
            System.exit(1);			
		}
		
		dataset2 = driver.Create("geor:scott/tiger@orcl", xSize, ySize, nBand,
				dType);

		dataset2.SetGeoTransform(dataset1.GetGeoTransform());
		dataset2.SetProjection(dataset1.GetProjection());

		ByteBuffer buffer = ByteBuffer.allocateDirect(xSize);

		for (int iBand = 1; iBand <= nBand; iBand++) {
			band1 = dataset1.GetRasterBand(iBand);
			band2 = dataset2.GetRasterBand(iBand);
			for (int iRow = 0; iRow < ySize; iRow++) {
				buffer = band1.ReadRaster_Direct(0, iRow, xSize, 1);
				band2.WriteRaster_Direct(0, iRow, xSize, 1, buffer);
			}
		}
		dataset2.FlushCache();

		System.out.println("generate a new georaster : "
				+ dataset2.GetDescription());

		dataset1.delete();
		dataset2.delete();
	}
}

I wrote that you are using GDAL 1.7.1 I would think that it would be better to use the last official release, the version 1.7.2.

comment:5 by ilucena, 14 years ago

Cc: warmerdam added

Jimmy,

I tested this code with GDAL 1.7 and got a very similar problem. I then translate that code to C and got the same problem, even with GDAL 1.6. That problem doesn't seems to happen on 1.8 dev, as I tested previously. I am attaching the C code so I can ask others to take a look. I will keep work on that and keep you posted.

#include <stdlib.h>
#include <gdal.h>

int main(int argc, char** argv)
{
    GDALDatasetH dataset1;
    GDALDatasetH dataset2;

    GDALRasterBandH band1;
    GDALRasterBandH band2;

    GDALDriverH driver;

    GDALAllRegister();

    dataset1 = GDALOpen("on_test.tif", GA_ReadOnly);

    band1 = GDALGetRasterBand(dataset1, 1);

    int xSize = GDALGetRasterXSize(dataset1);
    int ySize = GDALGetRasterYSize(dataset1);
    int bands = GDALGetRasterCount(dataset1);

#ifdef CREATE_A_NEW_GEORASTER

    driver = GDALGetDriverByName("georaster");

    dataset2 = GDALCreate(driver, "geor:scott/tiger@orcl",
            xSize, ySize, bands, GDALGetRasterDataType(band1), NULL);

#else

    dataset2 = GDALOpen("geor:scott/tiger@orcl,gdal_rdt,196", GA_Update);

#endif

    double geoTransf[6];
    GDALGetGeoTransform(dataset1, geoTransf);
    GDALSetGeoTransform(dataset2, geoTransf);
    GDALSetProjection(dataset2,
            GDALGetProjectionRef(dataset1));

    band2 = GDALGetRasterBand(dataset2, 1);

    GByte* buffer = (GByte*) malloc(sizeof (GByte) * xSize);

    for (int i = 0; i < ySize; i++)
    {
        GDALRasterIO(band1, GF_Read, 0, i, xSize, 1, buffer, xSize, 1, GDT_Byte, 1, 1);
        GDALRasterIO(band2, GF_Write, 0, i, xSize, 1, buffer, xSize, 1, GDT_Byte, 1, 1);
    }

    const char* version = GDALVersionInfo("VERSION_NUM");

    printf("GDAL version %s\n", version);

    const char* name = GDALGetDescription(dataset2);

    GDALFlushCache(dataset2); // It will crash on OCILobWrite()

    GDALClose(dataset2);
    GDALClose(dataset1);

    free( buffer );
    
    printf("generate a new georaster : %s\n", name);

    return (EXIT_SUCCESS);
}


in reply to:  5 comment:6 by jimmyzhao, 14 years ago

Thanks so much,ilucena. I feel sorry that this problem must cost you much time. Do you mean I should test my sample codes with GDAL-1.8dev? Can you tell me the exact version? Thank you! Replying to ilucena:

Jimmy,

I tested this code with GDAL 1.7 and got a very similar problem. I then translate that code to C and got the same problem, even with GDAL 1.6. That problem doesn't seems to happen on 1.8 dev, as I tested previously. I am attaching the C code so I can ask others to take a look. I will keep work on that and keep you posted.

#include <stdlib.h>
#include <gdal.h>

int main(int argc, char** argv)
{
    GDALDatasetH dataset1;
    GDALDatasetH dataset2;

    GDALRasterBandH band1;
    GDALRasterBandH band2;

    GDALDriverH driver;

    GDALAllRegister();

    dataset1 = GDALOpen("on_test.tif", GA_ReadOnly);

    band1 = GDALGetRasterBand(dataset1, 1);

    int xSize = GDALGetRasterXSize(dataset1);
    int ySize = GDALGetRasterYSize(dataset1);
    int bands = GDALGetRasterCount(dataset1);

#ifdef CREATE_A_NEW_GEORASTER

    driver = GDALGetDriverByName("georaster");

    dataset2 = GDALCreate(driver, "geor:scott/tiger@orcl",
            xSize, ySize, bands, GDALGetRasterDataType(band1), NULL);

#else

    dataset2 = GDALOpen("geor:scott/tiger@orcl,gdal_rdt,196", GA_Update);

#endif

    double geoTransf[6];
    GDALGetGeoTransform(dataset1, geoTransf);
    GDALSetGeoTransform(dataset2, geoTransf);
    GDALSetProjection(dataset2,
            GDALGetProjectionRef(dataset1));

    band2 = GDALGetRasterBand(dataset2, 1);

    GByte* buffer = (GByte*) malloc(sizeof (GByte) * xSize);

    for (int i = 0; i < ySize; i++)
    {
        GDALRasterIO(band1, GF_Read, 0, i, xSize, 1, buffer, xSize, 1, GDT_Byte, 1, 1);
        GDALRasterIO(band2, GF_Write, 0, i, xSize, 1, buffer, xSize, 1, GDT_Byte, 1, 1);
    }

    const char* version = GDALVersionInfo("VERSION_NUM");

    printf("GDAL version %s\n", version);

    const char* name = GDALGetDescription(dataset2);

    GDALFlushCache(dataset2); // It will crash on OCILobWrite()

    GDALClose(dataset2);
    GDALClose(dataset1);

    free( buffer );
    
    printf("generate a new georaster : %s\n", name);

    return (EXIT_SUCCESS);
}


comment:7 by ilucena, 14 years ago

Jimmy,

You can get the latest (under development) version of GDAL by SVN:

svn checkout https://svn.osgeo.org/gdal/trunk/gdal gdal

If you use Windows, TortoiseSVN (http://tortoisesvn.tigris.org/) is your friend.

Or you can also get the nightly, automatically generated zip file from here:

http://www.gdal.org/daily/

There are too many changes on the code since version 1.7.2, so it would take much more time for me to fix that version and using 1.8 is perfectly safe.

Regards,

Ivan

in reply to:  7 comment:8 by jimmyzhao, 14 years ago

Hi, Ivan,

Thank you so much! I will try the latest version. Best wishes. Jimmy

Replying to ilucena:

Jimmy,

You can get the latest (under development) version of GDAL by SVN:

svn checkout https://svn.osgeo.org/gdal/trunk/gdal gdal

If you use Windows, TortoiseSVN (http://tortoisesvn.tigris.org/) is your friend.

Or you can also get the nightly, automatically generated zip file from here:

http://www.gdal.org/daily/

There are too many changes on the code since version 1.7.2, so it would take much more time for me to fix that version and using 1.8 is perfectly safe.

Regards,

Ivan

comment:9 by ilucena, 14 years ago

Jimmy,

I cannot answer your e-mail sent from the address:

-------Original Message-------
From: Jimmy <181797177@…>
To: Ivan Lucena <ivan.lucena@…>
Subject: Re: [gdal-dev] EXCEPTION_ACCESS_VIOLATION, when using GDAL Java API
Sent: Aug 10 '10 04:36

Hi, Ivan,
Thanks to your advice, now I can load GTiff file into GeoRaster database with GDAL 1.8-dev. But now I encounter two new problems:

  1. After I loaded a GTiff file to GeoRaster database, I used GeoRasterViewer to check the result. I found that the result in GeoRasterViewer has wrong colors, just like painted in red and blue(See wrong.jpg in attachment). But I really loaded the three bands into database.
  2. If I used gdal_translate command to load GTiff file to GeoRaster database, only 2 minutes were needed. But when I used my program to load the same file to database, more than 6 minutes were needed. How can I improve the performance?
    The sample codes, the right image and the wrong image are attached. Can you help me?
  1. Can you send a gdalinfo report from the source geotiff and the imported georaster
  1. You could improve performance by reading block by block instead of row by row.

in reply to:  9 comment:10 by jimmyzhao, 14 years ago

Thanks,Ivan,

The reports of the two images,generated by gdalinfo command, are attached. right.txt is the right image(loaded into database by gdal_translate command)'s report, while wrong.txt is the wrong image(loaded into database by my sample codes)'s report. The two images are generated from the same source image. The two reports are different in line 43~line 44, line 48~line 49 and line 53~line 54. But I don't know the cause of these differences. Snapshots in GeoRasterViewer of the two images are also attached.The sample codes are also attached. Can you tell me why the two reports are different? Thanks.

Best regards. Jimmy Replying to ilucena:

Jimmy,

I cannot answer your e-mail sent from the address:

-------Original Message-------
From: Jimmy <181797177@…>
To: Ivan Lucena <ivan.lucena@…>
Subject: Re: [gdal-dev] EXCEPTION_ACCESS_VIOLATION, when using GDAL Java API
Sent: Aug 10 '10 04:36

Hi, Ivan,
Thanks to your advice, now I can load GTiff file into GeoRaster database with GDAL 1.8-dev. But now I encounter two new problems:

  1. After I loaded a GTiff file to GeoRaster database, I used GeoRasterViewer to check the result. I found that the result in GeoRasterViewer has wrong colors, just like painted in red and blue(See wrong.jpg in attachment). But I really loaded the three bands into database.
  2. If I used gdal_translate command to load GTiff file to GeoRaster database, only 2 minutes were needed. But when I used my program to load the same file to database, more than 6 minutes were needed. How can I improve the performance?
    The sample codes, the right image and the wrong image are attached. Can you help me?
  1. Can you send a gdalinfo report from the source geotiff and the imported georaster
  1. You could improve performance by reading block by block instead of row by row.

by jimmyzhao, 14 years ago

Attachment: right.txt added

by jimmyzhao, 14 years ago

Attachment: wrong.txt added

by jimmyzhao, 14 years ago

Attachment: right.JPG added

by jimmyzhao, 14 years ago

Attachment: wrong.JPG added

by jimmyzhao, 14 years ago

Attachment: GDALLoader.java added

comment:11 by ilucena, 14 years ago

Jimmy,

The solution to the initial problem would be to change the code to write block by blocks, what is not ideal, or upgrade to GDAL 1.8dev-trunk where the GeoRaster driver is working correctly on that behalf.

About the problem you reported later, the RGB composition, would you mind to open a new case for that issue if that is still a problem for you.

Thanks

comment:12 by ilucena, 14 years ago

Resolution: fixed
Status: newclosed
Note: See TracTickets for help on using tickets.