How to use gradle. Java, and Groovy together?

21,728

Solution 1

Like mentioned above, compiling with the groovy plugin will also compile the java classes. We just have to make sure that the java compile task is not fired on the source as well as the groovy task...

To to this, and retain the source folders (for e.g.: in eclipse), you can use the following refined snippet in the build.gradle:

apply plugin: 'groovy'
//...
sourceSets {
  main {
    java { srcDirs = [] }    // no source dirs for the java compiler
    groovy { srcDirs = ["src/main/java", "src/main/groovy"] }  // compile   everything in src/ with groovy
  }
}

If you just specify the groovy { srcDir "src" }, your main/groovy and main/java folders are identified as packages in eclipse...

Solution 2

tries append to file "build.gradle" the next lines

sourceSets {
      main {
        java { srcDirs = [] }    // no source dirs for the java compiler
        groovy { srcDir "src" }  // compile everything in src/ with groovy
       }
    }

excuse me for my bad english. I hope that this can help your solution.

Solution 3

My solution would be to just have both Java and Groovy classes located in src/main/groovy and src/test/groovy (for test classes). From the compiler point of view it would result in something quite similar to the changes to the sourceSets suggested in the other answers.

From a user perspective I do not see a real benefit to keep the source files in separate folder hierarchies as it makes finding things harder. Also you are likely to migrate your classes between Java and Groovy to select the optimal implementation.

The main benefit is it works out of the box without any configuration in Gradle's build script. So it helps keeping things simple.

Share:
21,728

Related videos on Youtube

sonoerin
Author by

sonoerin

Updated on July 09, 2022

Comments

  • sonoerin
    sonoerin almost 2 years

    I am trying to use a Gradle project in IntelliJ 13 but I keep running into issues such as:

    • Java files can't see Groovy files
    • IntelliJ seems to forget about Groovy and prompts me to configure a GDK for it

    I read that the groovy plugin allows Groovy and Java in mixed own source path, but Java wants its own. So I have the following directory structure:

    • src\main\groovy
    • src\main\java
    • src\test\groovy

    I have a mix of Java and Groovy classes

    Here is my build.gradle:

    apply plugin: 'java'
    apply plugin: 'groovy'
    apply plugin: 'eclipse'
    apply plugin: 'idea'
    apply plugin: 'spring-boot'
    apply plugin: 'jacoco'
    apply plugin: 'war'
    
    
    buildscript {
        repositories {
            maven { url "http://repo.spring.io/libs-snapshot" }
            mavenLocal()
        }
        dependencies {
            classpath("org.springframework.boot:spring-boot-gradle-plugin:1.0.0.RC4")
        }
    }
    
    jar {
        baseName = 'my-app'
        version = '0.1.0'
    }
    
    repositories {
        mavenCentral()
        maven { url "http://repo.spring.io/libs-snapshot" }
    }
    
    dependencies {
        compile("org.springframework.boot:spring-boot-starter-web")
        compile("org.springframework.boot:spring-boot-starter-data-jpa:1.0.0.RC4")
        compile("org.springframework:spring-orm:4.0.0.RC1")
        compile("org.hibernate:hibernate-entitymanager:4.2.1.Final")
        compile("com.h2database:h2:1.3.172")
        compile("joda-time:joda-time:2.3")
        compile("org.thymeleaf:thymeleaf-spring4")
        compile("org.codehaus.groovy.modules.http-builder:http-builder:0.7.1")
        compile ('org.codehaus.groovy:groovy-all:2.2.1')
    
        testCompile('org.spockframework:spock-core:0.7-groovy-2.0') {
            exclude group: 'org.codehaus.groovy', module: 'groovy-all'
        }
        testCompile('org.codehaus.groovy.modules.http-builder:http-builder:0.7+')
        testCompile("junit:junit")
    }
    
    jacocoTestReport {
      <!-- not sure this is right  -->
        group = "Reporting"
        description = "Generate Jacoco coverage reports after running tests."
    }
    
    task wrapper(type: Wrapper) {
        gradleVersion = '1.11'
    }
    

    And here is a build error I get when I run "gradle clean build":

    ...src/main/java/com/product/service/FileDownloadService.java:24:  cannot find symbol 
    symbol  : class FileDownload 
    location: class com.product.service.FileDownloadService
    
    private FileDownload fileDownload;
    

    If I make everything Java, then I don't get any compile or execution errors.

    • Peter Niederwieser
      Peter Niederwieser about 10 years
      The default location for Groovy test code isn't test\main\groovy, but src\test\groovy.
    • M. Deinum
      M. Deinum about 10 years
      and your java code should be in src\main\java this is where the compiler (by default) will look. If you put them somewhere else they won't get compiled.
    • M. Deinum
      M. Deinum about 10 years
      On a unrelated note why are you forcing to use a milestone/release (Spring Orm 4.0.0.RC1) candidate whereas already Spring 4.0.2 is out (and referenced by your starter projects).
    • sonoerin
      sonoerin about 10 years
      I have updated my question with the corrected directories (but not ORM since I am not sure I follow yet) and build error. I don't understand why the directory is sometimes seen and sometimes not.
    • Peter Niederwieser
      Peter Niederwieser about 10 years
      The Java code should be in src\main\groovy, since the OP wants joint compilation. Java code in src\main\java won't see Groovy code (unless reconfigured).
    • M. Deinum
      M. Deinum about 10 years
      The java plugin wants sources in src\main\java, the groovy plugin in src\main\groovy isn't that just the problem, that both of the plugins are specified?
    • Peter Niederwieser
      Peter Niederwieser about 10 years
      No, that isn't the problem. If you want Java/Groovy joint compilation, Java sources have to be passed to the Groovy compiler, and CompileJava tasks aren't involved. (The Java plugin is still involved because the Groovy plugin builds upon it. You don't have to apply the Java plugin explicitly though, as it will get applied by the Groovy plugin anyway.)
  • will
    will about 7 years
    Unfortunately that worked ... Why did I say that? My gradle project (originally) had main/java and main/groovy, with a Groovy main() program. Everything worked marvelously. Without a need for a sourceSets hack -- So the fact that I need to do this simply because I changed my main to be Java importing Groovy classes bothers me. It isn't symmetrical. I hope there's a better way . . .
  • will
    will about 7 years
    One further observation, now my Netbeans IDE says "Groovy in groovy" and "Groovy in java" -- While this works I seek a better answer. This approach is eking-out Groovy files in the Java dir -- And may I say, accidentally compiling Java files it finds along the way. My apologies if I sound like a granny; sometimes just because it works, doesn't mean it is a reasonable method.
  • leroyse
    leroyse about 7 years
    Yes, I also do not like that... but in the meantime, it works and I have to move along with the coding... I'll ask at the next training if I get a chance.
  • Ajax
    Ajax over 5 years
    adding 'src' as a srcDir implies that you are putting both groovy and java into "$projectDir/src". The explicit "set srcDirs" method in the other answer is preferable to this.
  • tschumann
    tschumann over 4 years
    This works but I agree is not ideal (similar to stackoverflow.com/a/37609252/5158636 but this way is programmatic). Without this fix I confusingly I see a thin .jar in build/libs that contains both Java and Groovy classes but the resulting fat .jar in build/distributions ends up containing only Groovy classes.