apache / apache/grails-core

Change in behaviour of Groovy's properties when used with a dynamic finder

Open
#12,051 0 comments 2 reactions 0 assignees View on GitHub
Dominant language
Groovy
Stars
2.9k
Forks
975
Avg merge
1d 22h
Merged PRs (30d)
92

Description

### Description

Our code was working fine on production handling thousands of requests daily until 3 days ago when we made some code changes. We tried to investigate the issue for 2 days but all seemed okay. Digging further, we were able to find the reason for the code failure which we are assuming is not a bug in Grails Framework but maybe this is how Groovy works.

But because the behaviour of some Groovy code was changing because of the usage of Grails' dynamic finders that's why we created this issue. Explaining further the issue.

### Task List

- [x] Steps to reproduce provided
- [x] Stacktrace (if present) provided
- [x] Example that reproduces the problem uploaded to Github
- [x] Full description of the issue provided (see below)

### Steps to Reproduce

1. `git clone https://github.com/letscooee/mongo-test-app`
2. `cd mongo-test-app`
3. Run app (Requires MongoDB to showcase but not a bug in Mongo GORM) `./gradlew bootRun`
4. Open `http://localhost:8080/book/test1` in the browser.

### Expected Behaviour

The instance of `Book` should save.

### Actual Behaviour

An exception occurs (not because of ORM) but because of different behaviour of `requestData.properties` in https://github.com/letscooee/mongo-test-app/blob/d12fb447f590ea221a476b0122d118d87ca35d5c/grails-app/services/mongo/test/BookService.groovy#L12.

### Environment Information

- **Operating System**: macOS Big Sur
- **Grails Version:** 4.0.12
- **JDK Version:** 1.8.0_202

### Example Application

https://github.com/letscooee/mongo-test-app

### Further Description

In the above code, If we print this line `Map props = requestData.properties as Map` in a Groovy class (with `@GrailsCompileStatic`), the value of `props` is like-

```java
>>>1: [class:class org.grails.web.json.JSONObject, empty:false]
>>>2: [class:class org.grails.web.json.JSONObject, empty:false]
Props datatype -> class java.util.LinkedHashMap
```

But if we uncomment the L15 (which is calling a Grails' dynamic finder), the same code prints-

```java
>>>1: [foo:Bar, age:2]
>>>2: [foo:Bar, age:2]
Props datatype -> class java.util.LinkedHashMap
```

And because of the first scenario (where the Groovy's [`getProperties()`](https://docs.groovy-lang.org/latest/html/api/org/codehaus/groovy/runtime/DefaultGroovyMethods.html#getProperties(java.lang.Object)) is being invoked), the MongoDB is throwing the exception (**REMEMBER- We are not talking about this MongoDB exception here**)-

```java
Caused by: org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class java.lang.Class.
at org.bson.codecs.configuration.CodecCache.getOrThrow(CodecCache.java:46)
at org.bson.codecs.configuration.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:63)
at org.bson.codecs.configuration.ChildCodecRegistry.get(ChildCodecRegistry.java:51)
at org.grails.datastore.bson.codecs.CodecExtensions$MapCodec.encode(CodecExtensions.groovy:309)
```

### Workaround

Of course, the simple workaround is available by replacing `requestData.properties` to `requestData.getJSONObject("properties")` (and handling exception) but the behaviour should not alter.

Contributor guide

Open the contributing guide

Research direction

Clone the linked mongo-test-app and run the reproduction steps, then inspect grails-app/services/mongo/test/BookService.groovy around the requestData.properties access and the dynamic finder on L15. Compare the printed properties with that finder enabled and disabled, using the linked Groovy getProperties documentation for context. Done means the properties value remains consistent regardless of the dynamic finder call.

Written by the indexing model from the issue text.

Assessment

Tech stack
groovy
Domain
backend, databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.