ngageoint / geopackage-android

GeoPackage Android Library
http://ngageoint.github.io/geopackage-android
MIT License
94 stars 32 forks source link

Getting NPE in UserCursor's constructor for table.getUserColumns() #75

Closed Mshey closed 2 years ago

Mshey commented 2 years ago

Calling rawQuery(String sql, String[] selectionArgs) on a FeatureWrapperConnection item throws NPE. As I investigated, I encountered a little bug in the geopackage library. This is my stacktrace:

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'mil.nga.geopackage.user.UserColumns mil.nga.geopackage.user.UserTable.getUserColumns()' on a null object reference
        at mil.nga.geopackage.user.UserCursor.<init>(UserCursor.java:86)
        at mil.nga.geopackage.features.user.FeatureCursor.<init>(FeatureCursor.java:27)
        at mil.nga.geopackage.features.user.FeatureWrapperConnection.wrapCursor(FeatureWrapperConnection.java:31)
        at mil.nga.geopackage.features.user.FeatureWrapperConnection.wrapCursor(FeatureWrapperConnection.java:13)
        at mil.nga.geopackage.user.UserWrapperConnection.convertCursor(UserWrapperConnection.java:42)
        at mil.nga.geopackage.user.UserConnection.handleCursor(UserConnection.java:317)
        at mil.nga.geopackage.user.UserConnection.query(UserConnection.java:304)
        at mil.nga.geopackage.user.UserConnection.rawQuery(UserConnection.java:76)

As you can see, the NPE is thrown here:

     /**
     * Constructor
     *
     * @param table  table
     * @param cursor cursor
     */
    protected UserCursor(TTable table, Cursor cursor) {
        this(table, table.getUserColumns(), cursor);
    }

But if you got back until the FeatureWrapperConnection class, you can observe, that the wrapCursor method calls the FeatureCursor constructor with table parameter set to null:

    /**
     * {@inheritDoc}
     */
    @Override
    protected FeatureCursor wrapCursor(Cursor cursor) {
        return new FeatureCursor(null, cursor);
    }

Can you please put a null check in the UserCursor constructor, so that it won't throw any NPE in the future?

Version Information:

bosborn commented 2 years ago

I think the last usage of the WrapperConnection classes was removed in 3.3.0.

Including:

UserWrapperConnection
AttributesWrapperConnection
FeatureWrapperConnection
TileWrapperConnection
UserCustomWrapperConnection

They were previously used to read table and column metadata. That logic was replaced by a common geopackage-core implementation. They could probably be removed or deprecated.

In what context are you trying to use FeatureWrapperConnection? Or can you provide a code usage example?

Are you trying to perform a raw query on a specific feature table?

FeatureDao featureDao = geoPackage.getFeatureDao(featureTable);
FeatureCursor cursor = featureDao.rawQuery(sql, selectionArgs);
try {
    for (FeatureRow featureRow : featureCursor) {
       // ...
    }
}finally {
    cursor.close();
}
Mshey commented 2 years ago

Thank you for your quick answer. We just migrated from 3.4.0 to 6.2.0 (big step, I know :P), so now we have encountered a lot of bugs. I change the item type from FeatureWrapperConnection to FeatureDao, and everything is working fine. Have great day!