Pivotal Knowledge Base

Follow

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

Environment

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

Purpose

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.

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.

Procedure

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.

 

Comments

Powered by Zendesk