# Init script's classpath dependencies are not accessible in the build script

**URL:** https://discuss.gradle.org/t/init-scripts-classpath-dependencies-are-not-accessible-in-the-build-script/7044
**Category:** Old Forum Archive
**Created:** [November 29, 2012, 12:10am UTC](https://discuss.gradle.org/t/init-scripts-classpath-dependencies-are-not-accessible-in-the-build-script/7044 "2012-11-29T00:10:00Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![Detelin](https://avatars.discourse-cdn.com/v4/letter/d/3e96dc/32.png) [@Detelin](https://discuss.gradle.org/u/Detelin)
#### Post date: [November 29, 2012, 12:10am UTC](https://discuss.gradle.org/t/init-scripts-classpath-dependencies-are-not-accessible-in-the-build-script/7044/1 "2012-11-29T00:10:00Z")

</div>

I’m trying to add an init script dependency containing some classes that must be visible by Gradle and all Projects, however it happens that those classes are only visible during the execution of the init script (and within the Gradle instance) but any attempt to import and load them from a Project fails:

```gradle
//init.gradle
initscript {
    repositories {
        mavenCentral()
    }
          dependencies {
        classpath 'commons-collections:commons-collections:3.2'
    }
}
  gradle.ext.myMap = new org.apache.commons.collections.map.MultiKeyMap()

```

```gradle
//build.gradle
gradle.ext.myMap as org.apache.commons.collections.map.MultiKeyMap

```

Executing the above fails with ‘unable to resolve class org.apache.commons.collections.map.MultiKeyMap’ (during compilation of the build.gradle file). After struggling a bit (a lot) with this, I have found a workaround:

```gradle
//init.gradle
gradle.projectsLoaded {
    MutableURLClassLoader projectCl = rootProject.buildscript.classLoader as MutableURLClassLoader
    projectCl.addURLs((initscript.getClassLoader() as URLClassLoader).getURLs() as List)
}

```

However this has the drawback that classes are actually loaded into two separate class loaders so if I start passing objects between them I get a ClassCastException:

```gradle
//build.gradle
import org.apache.commons.collections.keyvalue.MultiKey
  //fails with java.lang.ClassCastException: Key must be a MultiKey
gradle.ext.myMap.put(new MultiKey('key'), 'value')

```

So I wonder whether this problem could be considered a real issue or there are some reasons for it to be that way?

I’m using Gradle 1.3

P.S. I’m actually exploring this area in an attempt to [Configure different set of repositories based on project status](http://forums.gradle.org/gradle/topics/configure_different_set_of_repositories_based_on_project_status).

Thanks,

Detelin

---

<div class="post-metadata">

### Author: ![Peter\_Niederwieser](https://avatars.discourse-cdn.com/v4/letter/p/9f8e36/32.png) [@Peter\_Niederwieser](https://discuss.gradle.org/u/Peter_Niederwieser)
#### Post date: [November 29, 2012, 8:58am UTC](https://discuss.gradle.org/t/init-scripts-classpath-dependencies-are-not-accessible-in-the-build-script/7044/2 "2012-11-29T08:58:00Z")

</div>

This works as designed. (Not saying I’m entirely happy with the design.) To make a library available to build scripts, you can do something like this (in the init script):

```gradle
rootProject {
    buildscript {
        dependencies {
            classpath ...
        }
    }
}

```

For a complete example, see the ‘customDistribution’ sample in the full Gradle distribution. This won’t work for applied scripts though. I’m not aware of a way to make it work for applied scripts, other than declaring the dependencies in the applied script itself.

---

<div class="post-metadata">

### Author: ![Detelin](https://avatars.discourse-cdn.com/v4/letter/d/3e96dc/32.png) [@Detelin](https://discuss.gradle.org/u/Detelin)
#### Post date: [November 29, 2012, 9:43am UTC](https://discuss.gradle.org/t/init-scripts-classpath-dependencies-are-not-accessible-in-the-build-script/7044/3 "2012-11-29T09:43:00Z")

</div>

Thanks, this seems a bit better than the class loader hacks I have been doing but one problem is that I would also need to configure the repositories that the init script uses for the build script as well. I’m not interested in using these dependencies in applied build script (I saw the [other topic](http://forums.gradle.org/gradle/topics/how_to_refer_to_classes_on_the_buildscript_classpath_in_an_applied_script) about this), what I’m trying to do is to initialize some domain objects early before the projects are evaluated, then to set them as extra properties or an extension so that our build plugins can reuse them rather than having to re-create them. I think what I’m trying to do exactly what the [basic usage of an init script](http://gradle.org/docs/current/userguide/init_scripts.html) mentions: \> - Set up enterprise-wide configuration, such as where to find custom plugins. \> - Set up properties based on the current environment, such as a developer’s machine vs. a continuous integration server.

But with this limitation, I’m not able to do this kind of setup using custom classes, but must use only standard Gradle/Java types ☹

---

<div class="post-metadata">

### Author: ![Peter\_Niederwieser](https://avatars.discourse-cdn.com/v4/letter/p/9f8e36/32.png) [@Peter\_Niederwieser](https://discuss.gradle.org/u/Peter_Niederwieser)
#### Post date: [November 29, 2012, 9:56am UTC](https://discuss.gradle.org/t/init-scripts-classpath-dependencies-are-not-accessible-in-the-build-script/7044/4 "2012-11-29T09:56:00Z")

</div>

I don’t understand. What’s the problem with the solution I posted? Did you have a look at the ‘customDistribution’ sample?

---

<div class="post-metadata">

### Author: ![Detelin](https://avatars.discourse-cdn.com/v4/letter/d/3e96dc/32.png) [@Detelin](https://discuss.gradle.org/u/Detelin)
#### Post date: [November 29, 2012, 1:24pm UTC](https://discuss.gradle.org/t/init-scripts-classpath-dependencies-are-not-accessible-in-the-build-script/7044/5 "2012-11-29T13:24:00Z")

</div>

The problem is that I want to execute code before the projects are evaluated, so this code cannot be on the buildscript classpath, but has to be on the init script classpath. On the other hand, this code needs to create and store objects somewhere (Gradle/Project instance) where they can be later accessed by build plugins applied to the projects.

If this cannot be achieved by configuring the init script classpath, can I add this piece of code somewhere else so it becomes part of Gradle and:

- code and objects created by it are visible by init script
- code and objects created by it are visible by build scripts

---

<div class="post-metadata">

### Author: ![Peter\_Niederwieser](https://avatars.discourse-cdn.com/v4/letter/p/9f8e36/32.png) [@Peter\_Niederwieser](https://discuss.gradle.org/u/Peter_Niederwieser)
#### Post date: [November 29, 2012, 1:45pm UTC](https://discuss.gradle.org/t/init-scripts-classpath-dependencies-are-not-accessible-in-the-build-script/7044/6 "2012-11-29T13:45:00Z")

</div>

Unfortunately, I’m not aware of a way to do so.

---

<div class="post-metadata">

### Author: ![Detelin](https://avatars.discourse-cdn.com/v4/letter/d/3e96dc/32.png) [@Detelin](https://discuss.gradle.org/u/Detelin)
#### Post date: [November 30, 2012, 2:24pm UTC](https://discuss.gradle.org/t/init-scripts-classpath-dependencies-are-not-accessible-in-the-build-script/7044/7 "2012-11-30T14:24:00Z")

</div>

Ok, while there might be cases where inheriting init script dependencies in the build script classpath might be undesirable (I cannot think of such right now), I think that it is more common to assume that if something is declared as a dependency in the init script, it would be available for the build scripts as well. Also, would not this also solve [GRADLE-2407](http://issues.gradle.org/browse/GRADLE-2407)?

---

<div class="post-metadata">

### Author: ![Peter\_Niederwieser](https://avatars.discourse-cdn.com/v4/letter/p/9f8e36/32.png) [@Peter\_Niederwieser](https://discuss.gradle.org/u/Peter_Niederwieser)
#### Post date: [November 30, 2012, 2:49pm UTC](https://discuss.gradle.org/t/init-scripts-classpath-dependencies-are-not-accessible-in-the-build-script/7044/8 "2012-11-30T14:49:00Z")

</div>

In larger builds, a global script class path can cause version conflict problems. Nevertheless I consider it necessary to have a way to globally share dependencies between all scripts in a build. I’ll create an issue, let’s see where it goes.
