How to get a NameNotFoundException when Non Existing Methods are used in OQL
search cancel

How to get a NameNotFoundException when Non Existing Methods are used in OQL

book

Article ID: 294159

calendar_today

Updated On:

Products

VMware Tanzu Gemfire

Issue/Introduction

When executing an OQL query on which the SELECT clause invokes a non-existing method from a domain object, GemFire doesn't throw any exceptions as it used to do in old versions (6.X) and, instead, it just returns an empty ResultSet.

As an example, executing SELECT * FROM /testRegion tr WHERE tr.getStringKey().length2() would throw:

Caused by: com.gemstone.gemfire.cache.query.NameNotFoundException: No applicable and accessible method named ' length2 ' was found in class ' java.lang.String ' for the argument types []
at com.gemstone.gemfire.cache.query.internal.MethodDispatch.resolveGeneral(MethodDispatch.java:127)
at com.gemstone.gemfire.cache.query.internal.MethodDispatch.resolve(MethodDispatch.java:96)
at com.gemstone.gemfire.cache.query.internal.MethodDispatch.(MethodDispatch.java:43)
at com.gemstone.gemfire.cache.query.internal.CompiledOperation.eval0(CompiledOperation.java:259)
at com.gemstone.gemfire.cache.query.internal.CompiledOperation.evaluate(CompiledOperation.java:175)
at com.gemstone.gemfire.cache.query.internal.CompiledComparison.evaluate(CompiledComparison.java:75)
at com.gemstone.gemfire.cache.query.internal.CompiledSelect.doNestedIterations(CompiledSelect.java:649)
at com.gemstone.gemfire.cache.query.internal.CompiledSelect.doNestedIterations(CompiledSelect.java:721)
at com.gemstone.gemfire.cache.query.internal.CompiledSelect.doIterationEvaluate(CompiledSelect.java:577)
at com.gemstone.gemfire.cache.query.internal.CompiledSelect.evaluate(CompiledSelect.java:413)
at com.gemstone.gemfire.cache.query.internal.DefaultQuery.executeUsingContext(DefaultQuery.java:526)
at com.gemstone.gemfire.cache.query.internal.DefaultQuery.execute(DefaultQuery.java:365)
at com.gemstone.gemfire.cache.query.internal.DefaultQuery.execute(DefaultQuery.java:303)
at com.gemstone.gemfire.internal.cache.tier.sockets.BaseCommand.processQueryUsingParams(BaseCommand.java:1695)
at com.gemstone.gemfire.internal.cache.tier.sockets.BaseCommand.processQuery(BaseCommand.java:1641)
at com.gemstone.gemfire.internal.cache.tier.sockets.command.Query.cmdExecute(Query.java:87)
at com.gemstone.gemfire.internal.cache.tier.sockets.BaseCommand.execute(BaseCommand.java:181)
at com.gemstone.gemfire.internal.cache.tier.sockets.ServerConnection.doNormalMsg(ServerConnection.java:799)
at com.gemstone.gemfire.internal.cache.tier.sockets.ServerConnection.doOneMessage(ServerConnection.java:930)
at com.gemstone.gemfire.internal.cache.tier.sockets.ServerConnection.run(ServerConnection.java:1179)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at com.gemstone.gemfire.internal.cache.tier.sockets.AcceptorImpl$1$1.run(AcceptorImpl.java:555)
at java.lang.Thread.run(Thread.java:748)

However, starting with GemFire 7.X, no exception is thrown and nothing is shown in the logs, the query just returns an empty ResultSet.

In the past this feature has been leveraged to validate the OQLs written by the developers.


Environment


Cause

The change to the query engine was made back in 2010. The main reasons for the change were to improve security and consistency. Throwing a detailed exception instead of returning an empty result might allow an attacker to get detailed information about the structure of the objects stored within the region. For the regular use cases, considering that the domain objects stored in GemFire belong to the user's organization and only specific people have access to the OQL engine within the environment, the developers should know in advance the structure of the objects and how to correctly query their fields and methods.

Resolution

The behavior won't be back to what it was but, instead, there's an internal flag that can be used to get the old feature: gemfire.QueryService.QueryHeterogeneousObjects.

In summary, if the user wants the OQL engine to throw an exception whenever the query tries to invoke a non-existing method from a domain object, then the cache members must be started with the system property gemfire.QueryService.QueryHeterogeneousObjects set as false.


Additional Information

Environment

Pivotal GemFire 7.x, 8.x, and 9.x