After registering an extension, how do you retrieve the same instance elsewhere, and what's the difference between getByType, findByName, and capturing the create() return value?
answer
- create returns the instance
- getByType = typed, throws
- findByType = typed, nullable
- getByName/findByName = untyped
- same single instance every time
basics
~10 sextensions.create returns the instance, so capture it directly. Later you can fetch it from the ExtensionContainer: getByType(MyExtension::class.java) (typed, throws if absent) or findByName("myExt") (by name, returns null/Object if absent).
solid answer
~40 s`extensions.create("myExt", MyExtension::class.java)` **returns** the created instance, so the simplest approach is to assign it: `val ext = project.extensions.create(...)`. Elsewhere (e.g. another part of the plugin, or a second plugin) you query the `ExtensionContainer`. `extensions.getByType(MyExtension::class.java)` looks it up **by type** and returns a typed `MyExtension`, throwing `UnknownDomainObjectException` if none matches. `extensions.findByType(MyExtension::class.java)` is the nullable variant. `extensions.getByName("myExt")` / `findByName("myExt")` look up **by registered name**, returning `Any`/`Object?` — you must cast. Prefer `getByType` for typed, refactor-safe access within your own plugin; use name-based lookup when you only know the string name (e.g., interacting with another plugin's extension). All of them return the **same single instance** Gradle created — extensions are not re-instantiated per lookup.
code
kotlin · 9 lines// Capture at creation
val ext = project.extensions.create("report", ReportExtension::class.java)
// Elsewhere, typed and required
val again = project.extensions.getByType(ReportExtension::class.java)
// React to another plugin's extension only if present
val other = project.extensions.findByName("otherExt")
if (other != null) { /* configure cautiously */ }go deeper
Know that create returns the instance and that you can fetch an extension back from project.extensions.
Distinguish getByType/findByType (typed) from getByName/findByName (untyped) and get* (throws) vs find* (nullable).
Choose retrieval strategy by context, including cross-plugin integration via pluginManager.withPlugin then getByType, and Kotlin DSL sugar (the/configure).
Establish conventions for safe cross-plugin extension access (capability detection, optional null-guarded lookups) to keep plugin interactions robust.
## One instance, many ways to reach it When you call `extensions.create`, Gradle builds **one** instance and stores it in the project's `ExtensionContainer`. Every retrieval returns that same object; there's no re-creation. ## The retrieval options **1. Capture the return value (preferred when you create it):** ```kotlin val ext = project.extensions.create("myExt", MyExtension::class.java) ``` Direct, typed, no lookup needed. **2. By type:** ```kotlin val ext = project.extensions.getByType(MyExtension::class.java) // throws if absent val maybe = project.extensions.findByType(MyExtension::class.java) // null if absent ``` Type-safe and refactor-friendly. Use when another part of your code knows the class but not the instance. **3. By name:** ```kotlin val raw = project.extensions.getByName("myExt") // returns Any, throws if absent val rawOrNull = project.extensions.findByName("myExt") // Any? ``` Returns an untyped object; you must cast. Useful when integrating with another plugin whose extension type you can't import, or when only the string name is known. ## getX vs findX `getX` variants **throw** `UnknownDomainObjectException` when nothing matches — good for required dependencies where absence is a programming error. `findX` variants return **null**, suitable for optional integration ("configure this only if the other plugin's extension is present"). ## Kotlin DSL sugar In Kotlin you'll often see `the<MyExtension>()` or `configure<MyExtension> { }`, which delegate to `getByType`/`configure` under the hood. ## Practical guidance - Within the plugin that created it: capture the `create` return value. - Cross-cutting code that knows the type: `getByType` (or `findByType` if optional). - Reacting to a foreign plugin's extension by name: `findByName` guarded by a null check, or better, `pluginManager.withPlugin(...) { ... }` then `getByType`. ## Gotcha Don't call `create` twice for the same name — it throws because the name is already registered. Retrieve, don't re-create.
- When would you prefer findByType over getByType?When the extension may legitimately be absent — e.g. optional integration with another plugin. findByType returns null instead of throwing, letting you branch.
- What happens if you call extensions.create twice with the same name?It throws because that name is already registered in the ExtensionContainer. You should retrieve the existing instance instead of re-creating.
saying these in an interview costs you the question
- Thinking each getByType/findByName creates a new instance — it returns the single stored object.
- Using getByName and forgetting it returns an untyped Object that needs casting.