Using custom classes WITHIN the buildscript block

Hi, I’ve developed a custom class, MyClass, which defines a static method “myMethod”. I’ve compiled the class and created a jar containing this class. Now I need to use this method within a buildscript block, that is, within my build.gradle I need this buildscript block::

buildscript {
 dependencies {
  classpath files("../libs/myJar-1.0.jar")
 }
    MyClass.myMethod("myValue")
}
  ..rest of the script is omitted...

But when I run the build I get the following error:

  • What went wrong: > A problem occurred evaluating root project ‘myProject’. > No such property: MyClass for class: org.gradle.api.internal.initialization.DefaultScriptHandler

Which seems reasonable, since In the buildscript I’m setting the classpath for the project, but not for the buildscript itself.

So my question is: How can I set the classpath for the builscript itself?

I found a quirk, declaring the dependencies in a parent project buildscript and then using MyClass within the subproject buildscript, but this seems to me far from optimal, since it forces me to declare a (not needed and not existent) parent project.

Is there any other way to solve this problem?

Thanks, Luca

So my question is: How can I set the classpath for the builscript itself?

In short, you can’t. The ‘buildscript’ block is really just for declaring the class path of the remainder of the build script. Don’t try to do funky stuff there.

Too bad :slight_smile:

I will rephrase: Is there any way to add something to gradle “itself” classpath ?

The real issue is: I would like to define a new kind of repository, that all my buildscript will use. I don’t like the idea of putting everywhere in my buildscript something like:

repositories {
 ivy {
  url "${MY_REPOSITORY_URL}"
  layout 'pattern' , {
   artifact "[my]/[custom]/[tree]/[artifact]-[revision](-[classifier])(.[ext])"
   ivy "[my]/[custom]/[tree]/ivy-[revision].xml"
  }
 }
 mavenCentral()
}

I would prefer to say something like:

repositories {
 myCustomizedRepository()
 mavenCentral()
}

But, to do this, I cannot use the buildscript, since this way, at least in the buildscript, I will need to define this repository… this is a chicken and egg problem…

May be that something like this can be done in the gradle.settings file? Can you shed some light on this? thanks, Luca

1 Like

You’ll have to declare the build script repository once per build, in the root project’s ‘buildscript {}’ block. There is ultimately no way around that. (There might be a way to do it in ~/.gradle/init.gradle, but then your build is no longer portable. You can try to use apply from: ‘http://…’, to: buildscript to cut down on the configuration a bit, but this approach has limitations. At the very least, you’ll lose the ability to build offline.) If you use a repository with a standard layout, you’ll only have to configure the URL. Otherwise, you’ll have to configure a bit more.

Thanks Peter, I’m not too happy but I understand your point. A last question, just for the sake of clarity: what do you think if I should add a class of mine to gradle classpath?

I don’t understand the question.

Well, my idea would be to create a custom ArtifactRepository.class, putting it side by side with native gradle classes (may be in the same jar or may be in a separate jar, but including the new class directly in the gradle classpath).

If my custom class sits there (that is, within gradle classpath itself), I shoud be able to import this custom class from my gradle script without adding a jar to the buildscript classpath.

For example, it’s the mechanism that jboss uses when you want to augment system behaviour with your code. You simply put your jar in the app server shared lib directory, and, at the startup, jboss AS load this classes in its classpath as it was a native jboss developed library.

Thanks, Luca

You can create a custom distribution that includes your own plugins. Have a look at the ‘customDistribution’ sample in the full Gradle distribution.