codeconsole opened a new pull request, #16095:
URL: https://github.com/apache/grails-core/pull/16095

   ## Problem
   
   An application generated by Forge with MongoDB selected does not start:
   
   ```
   com.mongodb.MongoSocketOpenException: Exception opening socket
   Caused by: java.net.ConnectException: Connection refused
   ```
   
   Nothing starts a MongoDB, so the application only works if one happens to be 
listening on the configured url. There is currently no embedded option on 
`8.0.x` at all — the `embedded-mongodb` feature that existed on `7.0.x` was 
dropped, and it was test-scoped and pinned to MongoDB 3.2.1 in any case.
   
   ## Approach
   
   A new module, `grails-data-mongodb-embedded`, contributes an 
`ApplicationContextInitializer` that starts a server and publishes its url into 
whichever properties the application reads. It is an initializer rather than an 
auto configuration because the url has to be in the `Environment` before the 
datastore bean that reads it is created.
   
   Two backends sit behind one interface:
   
   | | `in-memory` (mongo-java-server) | `flapdoodle` |
   |---|---|---|
   | Ships as | `api` dependency of the module | `compileOnly`; applications 
add it |
   | Start | milliseconds, in-JVM | ~1s, downloads mongod once |
   | Fidelity | no transactions, change streams, `$text` | real mongod |
   | Persistence | none | `database-dir` |
   
   Flapdoodle is deliberately **not** a dependency of the module: it pulls in 
`org.jgrapht:jgrapht-core`, offered under LGPL-2.1 or EPL-2.0, which an Apache 
release should not require. An application that wants a real mongod adds it 
itself, the same way it picks a SQL driver. The published pom contains only 
`spring-context`, `mongo-java-server` and `slf4j-api`.
   
   The target property is configuration (`embedded.mongodb.property-names`, 
defaulting to `grails.mongodb.url`) rather than hardcoded, so the module is not 
limited to Grails Data. Spring Data users remain better served by flapdoodle's 
own `de.flapdoodle.embed.mongo.spring3x` auto configuration, which this does 
not duplicate.
   
   ## Forge
   
   `GrailsDataMongoDB` wires this in by default rather than offering it as a 
separate feature, since the starter not working was the problem. Development 
and test use the in-memory backend; production uses flapdoodle and keeps its 
database in `./prodDb`, mirroring how the H2 database is wired for the Grails 
website application. **No source is generated into the application** — only the 
dependency and the `environments:` configuration.
   
   ## Verifying
   
   A generated MongoDB application, with no MongoDB installed and no Docker:
   
   ```
   EmbeddedMongoInitializer : Embedded MongoDB started at 
mongodb://localhost:27017/foo using the in-memory backend
   Application              : Started Application in 1.686 seconds
   Grails application running at http://localhost:8080 in environment: 
development
   ```
   
   `GET /` returns 200, a driver round-trips a document, and no `mongod` 
process exists — port 27017 is held by the application JVM.
   
   `EmbeddedMongoInitializerSpec` covers both backends against real servers: a 
driver round-trip through each, backend selection and its error messages, 
publishing into several properties, reusing a server that is already listening 
(the devtools restart path), and the in-memory backend refusing `database-dir` 
rather than silently discarding data.
   
   ## Notes for review
   
   - **`SbomPlugin`**: mongo-java-server declares only `"The BSD License"`, 
which CycloneDX maps to BSD-4-Clause. [Its 
LICENSE](https://github.com/bwaldvogel/mongo-java-server/blob/main/LICENSE) has 
three numbered clauses and no advertising clause, so it is BSD-3-Clause. Mapped 
alongside the `org.jline` entries that need the identical correction.
   - **`publish-root-config.gradle`**: a module missing from 
`publishedProjects` fails configuration with `Extension of type 
'GrailsPublishExtension' does not exist`, which does not point at the allowlist.
   - **`compileOnly 'org.apache.groovy:groovy'`** in the module: its main 
sources are Java so that a plain Spring Boot application can use it, but every 
published module still produces a groovydoc jar, and groovydoc cannot infer its 
classpath without Groovy present.
   - The in-memory backend reports `buildInfo.version` as `5.0.0`, so 
development and test report 5.0 while production under flapdoodle reports 8.0. 
Worth documenting.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to