# DefaultSourceDirectorySet Alternative

**URL:** <https://discuss.gradle.org/t/defaultsourcedirectoryset-alternative/15193>\
**Category:** Help/Discuss\
**Tags:** plugins\
**Created:** [March 15, 2016, 2:09pm UTC](https://discuss.gradle.org/t/defaultsourcedirectoryset-alternative/15193 "2016-03-15T14:09:25Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![daniel\_lew](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/daniel_lew/32/1171_2.png) [@daniel\_lew](https://discuss.gradle.org/u/daniel_lew)\
**Post date:** [March 15, 2016, 2:09pm UTC](https://discuss.gradle.org/t/defaultsourcedirectoryset-alternative/15193/1 "2016-03-15T14:09:25Z")

</div>

I’ve been using `DefaultSourceDirectorySet` in [my plugin](https://github.com/trello/victor) for a while now, in order to add a source set extension for an Android plugin:

```gradle
project.android.sourceSets.all { sourceSet ->
    sourceSet.extensions.create('svg', DefaultSourceDirectorySet, 'svg', project.fileResolver)
}

```

It looks like things have changed in Gradle 2.12 which now crashes when I use `DefaultSourceDirectorySet`, which is fine, since it is an internal API. (In particular, it gives the message “Could not create an instance of type org.gradle.api.internal.file.DefaultSourceDirectorySet\_Decorated.”)

The question I have then is, what is the alternative? Do I need to implement my own `SourceDirectorySet`? Or is there some public way of doing this easily that I am just unaware of?

---

<div class="post-metadata">

**Author:** ![st\_oehme](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/st_oehme/32/5249_2.png) [@st\_oehme](https://discuss.gradle.org/u/st_oehme)\
**Post date:** [March 15, 2016, 2:19pm UTC](https://discuss.gradle.org/t/defaultsourcedirectoryset-alternative/15193/2 "2016-03-15T14:19:16Z")

</div>

> [@daniel\_lew](#):
>
> Do I need to implement my own SourceDirectorySet?

That’s currently the way to go, yes.

---

<div class="post-metadata">

**Author:** ![Lance\_Java](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/lance_java/32/787_2.png) [@Lance\_Java](https://discuss.gradle.org/u/Lance_Java)\
**Post date:** [March 15, 2016, 2:24pm UTC](https://discuss.gradle.org/t/defaultsourcedirectoryset-alternative/15193/3 "2016-03-15T14:24:17Z")

</div>

Another option which still uses internal classes but is likely to be more ‘future proof’

```gradle
SourceDirectorySetFactory factory = 
   project.gradle.services.get(SourceDirectorySetFactory)
DefaultSourceDirectorySet sds = factory.create("svg")

```

---

<div class="post-metadata">

**Author:** ![daniel\_lew](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/daniel_lew/32/1171_2.png) [@daniel\_lew](https://discuss.gradle.org/u/daniel_lew)\
**Post date:** [March 15, 2016, 3:10pm UTC](https://discuss.gradle.org/t/defaultsourcedirectoryset-alternative/15193/4 "2016-03-15T15:10:54Z")

</div>

Wait, seriously? The best solution is for everyone to implement an interface with a couple dozen methods?

---

<div class="post-metadata">

**Author:** ![st\_oehme](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/st_oehme/32/5249_2.png) [@st\_oehme](https://discuss.gradle.org/u/st_oehme)\
**Post date:** [March 15, 2016, 4:02pm UTC](https://discuss.gradle.org/t/defaultsourcedirectoryset-alternative/15193/5 "2016-03-15T16:02:38Z")

</div>

> [@daniel\_lew](#):
>
> The best solution is for everyone to implement an interface with a couple dozen methods?

Note that you don’t _have to_ implement `SourceDirectorySet`. You can define an interface with just the API you care about yourself, like I did for instance in the [Xtext plugin](https://github.com/xtext/xtext-gradle-plugin/blob/master/xtext-gradle-plugin/src/main/java/org/xtext/gradle/tasks/XtextSourceDirectorySet.xtend).

I currently don’t know of a plan to make the `DefaultSourceDirectorySet` of the current Gradle model public.

The new software model already provides a public API for defining custom [LanguageSourceSets](https://docs.gradle.org/current/dsl/org.gradle.language.base.LanguageSourceSet.html).

---

<div class="post-metadata">

**Author:** ![IgorGanapolsky](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/igorganapolsky/32/2665_2.png) [@IgorGanapolsky](https://discuss.gradle.org/u/IgorGanapolsky)\
**Post date:** [March 16, 2016, 12:55am UTC](https://discuss.gradle.org/t/defaultsourcedirectoryset-alternative/15193/6 "2016-03-16T00:55:50Z")

</div>

Then how to use this factory in place of `DefaultSourceDirectorySet`?

---

<div class="post-metadata">

**Author:** ![Lance\_Java](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/lance_java/32/787_2.png) [@Lance\_Java](https://discuss.gradle.org/u/Lance_Java)\
**Post date:** [March 16, 2016, 2:37am UTC](https://discuss.gradle.org/t/defaultsourcedirectoryset-alternative/15193/7 "2016-03-16T02:37:25Z")

</div>

```gradle
project.android.sourceSets.all { sourceSet ->
    sourceSet.extensions.add('svg', factory.create('svg'))
}

```

---

<div class="post-metadata">

**Author:** ![Schalk\_Cronje](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/schalk_cronje/32/6511_2.png) [@Schalk\_Cronje](https://discuss.gradle.org/u/Schalk_Cronje)\
**Post date:** [March 31, 2016, 3:12pm UTC](https://discuss.gradle.org/t/defaultsourcedirectoryset-alternative/15193/8 "2016-03-31T15:12:14Z")

</div>

Another alternative, as described in Idiomatic Gradle, is to use some metaprogramming to work around it and maintain compatibility from Gradle 2.0 - 2.12. An example is here - [https://github.com/ysb33r/gradle-mirah-plugin/blob/master/src/main/groovy/org/ysb33r/gradle/mirah/MirahSourceSet.groovy#L69](https://github.com/ysb33r/gradle-mirah-plugin/blob/master/src/main/groovy/org/ysb33r/gradle/mirah/MirahSourceSet.groovy#L69)

**P.S Some self-promotion following** : You can also read about this in the (free) sample version of Idiomatic Gradle at [http://samples.leanpub.com/idiomaticgradle-sample.pdf](http://samples.leanpub.com/idiomaticgradle-sample.pdf) (Just go to the _Add SourceSet Support for JVM Language_ recipe).

---

<div class="post-metadata">

**Author:** ![Lance\_Java](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/lance_java/32/787_2.png) [@Lance\_Java](https://discuss.gradle.org/u/Lance_Java)\
**Post date:** [March 31, 2016, 3:52pm UTC](https://discuss.gradle.org/t/defaultsourcedirectoryset-alternative/15193/9 "2016-03-31T15:52:28Z")

</div>

I, personally, would maintain backwards compatability via:

```gradle
import org.gradle.util.GradleVersion

boolean useFactory = GradleVersion.current().compareTo(GradleVersion.version("2.12")) >= 0 
project.android.sourceSets.all { sourceSet ->
    if (useFactory) {
        SourceDirectorySetFactory factory = project.gradle.services.get(SourceDirectorySetFactory)
        sourceSet.extensions.add('svg', factory.create('svg'))
    } else {
        sourceSet.extensions.create('svg', DefaultSourceDirectorySet, 'svg', project.fileResolver)
    }
}

```

---

<div class="post-metadata">

**Author:** ![corbantek](https://avatars.discourse-cdn.com/v4/letter/c/3d9bf3/32.png) [@corbantek](https://discuss.gradle.org/u/corbantek)\
**Post date:** [April 28, 2016, 6:57pm UTC](https://discuss.gradle.org/t/defaultsourcedirectoryset-alternative/15193/10 "2016-04-28T18:57:20Z")

</div>

I was having this exact issue, but when I use this code snippet in either 2.12 or 2.13 I’m getting:

`> No service of type SourceDirectorySetFactory available in GradleScopeServices.`

Can anyone provide any help on this issue?

---

<div class="post-metadata">

**Author:** ![TWiStErRob](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/twisterrob/32/7261_2.png) [@TWiStErRob](https://discuss.gradle.org/u/TWiStErRob)\
**Post date:** [October 20, 2018, 8:48am UTC](https://discuss.gradle.org/t/defaultsourcedirectoryset-alternative/15193/11 "2018-10-20T08:48:22Z")

</div>

> [@corbantek](#):
>
> \> No service of type SourceDirectorySetFactory available in GradleScopeServices.

I found that in Gradle 4.10.2 `SourceDirectorySetFactory` is available  
from `project.services` (`ProjectScopeServices`),  
not `project.gradle.services` (`GradleScopeServices`).
