Possible to write build.gradle in pure Java..?


(Carsten Schmied) #1

Hi,

with Ant there was a project that allowed writing Ant-builds in pure Java. I wonder if such a thing could be possible with Gradle?

As a benefit one could read API-docs directly, use the debugger, etc.


(davidmichaelkarr) #2

Note that Gradle allows for more of the reusable code in a script to be written in Java or Groovy, making those pieces directly debuggable. In addition, one of the goals of the Buildship (nextgen Eclipse Gradle plugin) is to be able to step through a build script directly.


(Carsten Schmied) #3

Sounds like good news. I would love to directly code my build scripts in Java.

Do you have a link where I can see some elaborate examples?

XML was a bad decision for Ant and Maven and Groovy was a bad decision for Gradle.
The main problem I have with Groovy is that you always have 3-5 ways with small syntax changes to do the same thing. Goovy looks more like a language where one wanted to show EVERYTHING you could stuff into a language.

To quote the Zen of Python: “There should be one-- and preferably only one --obvious way to do it.” (https://www.python.org/dev/peps/pep-0020/)

After decades with myriads of build tools like Ant, Maven, Gradle I think the best solution would be to have a nice Java library with a lot of well documented utility classes/methods you can use to write pure Java build scripts.


(davidmichaelkarr) #4

I said “more of the reusable code”, not the entire build script. You won’t be able to “code your build script in Java”.

There are some nits I have with Groovy, but calling it a “bad decision” is simply way off. Infinitely better than Maven or Ant.

Most of typical build scripts will use the DSL, which doesn’t even look like Groovy (unless you know it is).


(René Groeschke) #5

Groovy has some real advantages when it comes to writing build scripts. It allows creating a concise and nice DSL which is not possible with Java. Furthermore the simple APIs for dealing with files, xml or urls come in pretty handy as this is what many people do in there build scripts. For example if you need to read a file, you just need a oneliner in where you would need tons of lines to do this properly Sure groovy has some deficits, but I think all major languages allow doing things in different ways.

Another nice thing about groovy is, that you can always fall back to java code. So if you really prefer to write your build scripts using pure java syntax, you can definitely do that.


(Carsten Schmied) #6

Any starters/documentation/articles about writing pure build.gradle scripts in Java? Maybe directly set it up in your IDE with nice hover-documentation for each method?

I read most of the Gradle docu and some books about Gradle and even Groovy. Still I feel very uncomfortable about Gradle/Groovy. I feel like I am not in power. Same feeling with Ant and a bigger extend Maven. It all feels like a big black box.
It’s fairly okay when I really focus for weeks writing a nice complex build script. But after month not writing Gradle/Groovy code it just feels like starting from square one.

I think Groovy is mostly the culprit plus some design decisions in Gradle. Well, I guess I should stop ranting. No point.


(Mark Vieira) #7

IDE integration of build script in general isn’t super great. If you are writing a plugin in Java however you’ll get full support in the IDE since you are just interacting with a regular Java API. In general, for within build scripts you can use the same Java API, which is documented in the JavaDocs. For example, in the case of declaring dependencies:

dependencies {
    testCompile 'junit:junit:4.12'
}

The equivalent Java would be:

dependencies.create("testCompile", "junit:junit:4.12");

(davidmichaelkarr) #8

To be clear, Carsten is not asking about how to write plugins or tasks in Java. He’s asking how to write the ENTIRE BUILD SCRIPT in Java. I’m only saying this so everyone’s clear on what we’re talking about. Obviously, this is not possible to do, nor is it even worth considering.


(Mark Vieira) #9

You could use Java entirely and completely avoid the use of Groovy in a build script if you so desired. There are no APIs that I am aware of that cannot be called from Java. That said, if you want things like static compilation then you could simply write your entire build script as a binary plugin, which would then be applied in a Gradle build script.

Like David mentioned, I wouldn’t particularly recommend this, but the original question was is there a Java API for build scripts. Technically, yes.


(Schalk Cronjé) #10

For me the argument whether Gradle uses Groovy as its DSL enabler is a good decision or not is a moot point. Neitehr is this approach anything new. There is SBT, (Scala) Leiningen (Clojure), Scons (Python), Cons (Perl) & Rake (Ruby) just to think of a few contemporary and past peers.

The main motivator for using a programming language as the DSL enabler is a decision of implementation time-saving made by the creators of the build tool. The second decision is whether it can present a readable, but easily extensible DSL, especially for build script authors that are not au fait with the underlying language.

A third design point is that it should not be necessary to debug a build script. If it is, then usually the build script is too complex, or the build tool’s design is inadequate.

As Mark pointed out, it is possible to craft all of your build.gradle in Java, but frankly if you do that, the build script will be so unreadable, that no-one other than yourself would probably want to maintain it. Build sripts should be slick, as expressive and semantic as possible - it will not happen if written in pure Java.

After all of that, if you feel it is that important that you need a build tool of which Java is the enabling DSL, feel free to create your own Jadel, Jotlin or Jake. Feedback from the market will soon tell you whether it is that useful. Just remember to design it such that a reader of the buildscript can understand the intent without knowing (too much) Java.


(Carsten Schmied) #11

The only benefit for writing in pure Java would be to have the full force of your IDE (e.g. Eclipse) behind it. If I write the Gradle script in pure Java, will I see the Quick-Tip Javadoc when I hover over dependencies.create(…)?

Will I have something like autocomplete, so when I type create. + Space it will show me all available methods and fields for the object dependencies?

Also using the debugger would be nice. I don’t accept the argument that if you need a debugger your script is too complex. First of all, I would simply use the debugger to look at variables relevant in the current context. At the moment I use a bunch of awkward ‘println’ commands to find out the value of variables. This is unbelievably inefficient.

Could there be an automatic way to convert Groovy-Gradle scripts to full Java-scripts (with imports and full IDE support?


(Luke Daley) #12

It is not possible to write a build script in Java. You can however write it in Groovy with Java syntax. This will get you close to full editing support, but you’ll still have to give it some assistance.

If you really want to go down this route. You can write your build as a plugin in Java, and have your actual build script just apply this plugin. This is effectively the same thing.

What you’re going to find though is that you’re going to write far more code. If that’s acceptable, then this will work. What you’ll also hit is that some API is still awkward to use from Java. This almost always comes down to Closure taking methods with no Action overload. We are fixing this and closing this gap over time. You can still create Closure objects from Java though (search this forum for how).


(Dimitar Dimitrov) #13

I can use my IDE (IntelliJ IDEA) for all these things with the Groovy syntax, so if Eclipse does not have a good integration right now, providing one my be more productive direction than recommending less expressive syntax (incidentally, Gradleware are collaborating with eclipse.org on https://github.com/eclipse/buildship)


(Carsten Schmied) #14

Yes. Eclipse’s IDE support for Gradle is almost non-existent. With IDEA it is much better…but not really great. Sometimes it works sometimes it does not. Also some things are simply not possible IDE-support wise since Groovy is a dynamic language.

I just installed IDEA 14.1 to see if anything has changed. Seems to be the same when I tested it last time.

Examples:
apply <Ctrl + Space> doesn’t show you the “from” option. Is ‘from’ part of the ObjectConfigurationAction Closure?

sourceSets.main.java. <Ctrl + Space> give me nothing. I was looking for things like srcDirs, etc.

I could go on and on. I know a lot of people put a lot of effort in this but if it isn’t on the same level as Java autocomplete in IDEA or Eclipse, as is the rest of the IDE integration.

However the worst thing is if something breaks down. I somehow feel Gradle is more of a black box, for example compared to Java when it comes to tracking down problems since there are much more layers of complexity.


(Carsten Schmied) #15

Thanks. I have to look into this. I don’t mind writing double the lines of code if I am writing it ten times as fast and have a way to track down problems within reasonable time.

I actually know Groovy quite well and know what is going on in Gradle scripts. However I tutored a few beginners and they treat Gradle like a bunch of commands they have to learn by heart. They don’t really know what is going on.

They see “apply …” and don’t know that this actually a method that accepts a Map or a Closure. They don’t think that way. They learn it by heart and after a few month on Gradle hiatus they have to start from scratch. Usually they just use Google and copy and paste snippets until it somehow works.
It makes a big difference how you read Gradle scripts inside your head. Do you think: ok, this is the task method I call and the parameters are a Map and the last method argument is a closure to configure the task, etc.
Or do you think: ok, this is the task keyword and the syntax is…well…let me look it up.

I think the two main problems is that you can do the very same thing in 5 different ways with Groovy/Gradle script. That is just unforgivable.
The other thing is that you can leave out a lot of things that change the way you “read” the script inside your head. For example brackets that tell you that a certain command is actually a method.


(Attila Kelemen) #16

Using Groovy as the language of .gradle files is obviously a compromise: Groovy makes it easy to guess what a code supposed to do for the expense of being harder to truly understand. The build scripts themselves (.gradle files) are not supposed to be very complex, they should mostly look like a declaration. And if it is not complex, deep understanding is not necessary. Like in Maven, you don’t actually care what exactly the mojo will do with your tags. You have to just read the docs that writing these tags here tell what about your build. The problem with Maven was not this but that if you wanted anything it did not support out of the box, you were in for a major pain (or it might be practically impossible).

That said, if you are writing very complex code in your build.gradle, you are most likely doing something wrong. Instead, you should just add complex build logic to your buildSrc project where you can (and probably should) use Java for most parts. The build.gradle files should be treated as a being written in a new language (that is why it is called a DSL) documented in the Gradle DSL docs (which is actually quite detailed and good). Most of time you will only add new dependency lines anyway :wink:


(Ruslan Stelmachenko) #17

What I really like in maven and don’t like in gradle is that XML have DTD with all possible structure and documentation. In many editors (eclipse for example) autocomplete of XML files with DTD is very good.
But when I writing build.gradle I lost every time with that magical DSL.


(dieterk) #18

A DSL seems like a good idea but for a substantial percentage of users it has more disadvantages. With XML it is the same just worse.

How I would have done it: all build.gradle files can be written in plain Java and all IDEs treat them like .java files.

Then you build a DSL on top of that, which takes a .java syntax file and strips out the unnecessary parts like imports, braces (and uses indentation like Python), modifiers like final, public, protected and types like void, String, int, etc.

At the end of that transformation the DSL would look like a dynamic language. Like Python/Groovy/Scala. Especially with Java8 you have things like closures directly in Java so you have many powerful options usually reserved for dynamic languages, which means your 1:1 mapping is not as restricted as you may think.

In your IDE, when you open a build.gradle file it opens as a simple.java file with the FULL IDE support for javadoc, autocomplete, etc. No special Gradle plugin necessary!

However, like with XML in Eclipse you would have a second tab (now we need an Gradle plugin for our IDE) at the bottom which shows you the stripped down 1:1 DSL mapping of your .java file.

You could either write DSL code or switch back to the full .java file to see that your changes were applied to the .java code. This also works vice-versa.

When you hit the save button we save build.gradle which is a .java file.

You would get the FULL IDE support for free since your build.gradle is actually a .java file. However you could also write in a DSL which looks very much like a slim dynamic language. In the background everything (Gradle) is pure Java and performance is nice.


(Jerome Angibaud) #19

Hi Carsten, look at the project Jerkar. It does exactly that.
http://jerkar.github.io/


(Carsten Schmied) #20

No doubt many pure Java build tools exist and I know a few.

However I was hoping to just use Java for Gradle with all the IDE benefits and speed.