7

I am getting very frustrated. I can't find a single, cohesive answer for my problem anywhere on the internet. Lots of documentation, nothing that brings it all together, though (that I can find).

All I need is someone to tell me:

  • how to set up a groovy project (EDIT: Including where to put source files, in what directories, directory structure, etc.)
  • assuming I haven't build groovy before
  • or java before (I have, but work with me)
  • in a way that I can specify a dependency (this is my dependency --> https://github.com/bpsm/edn-java) so probably using maven or gradle
  • one that has a main class and a main method (again, work with me)
  • at the end of the build, I need a jar file that I can execute via java -jar <groovy-project>.jar which prints out "hello world"

As simply as possible.

djhaskin987
  • 9,741
  • 4
  • 50
  • 86
  • Which IDE are you using? If you know how to setup java project & and it is no different for groovy. Just need to add `groovy-all-xxx.jar` in the classpath. – Rao Jun 28 '17 at 05:13
  • 1
    @Rao I stated clearly in the question that I'm looking for an answer as if I didn't know how to set up a java project. Truthfully, I kind of don't. I've worked on java projects before and it's been a while since I've set one up, but I'm rusty – djhaskin987 Jun 29 '17 at 02:04
  • To create skeleton for the Groovy application (everything except external dependencies) run `gradle init --type groovy-application --dsl kotlin`. Right after it's done `gradle build` will give you JAR file. – Ilya Serbis Jan 28 '19 at 09:29

2 Answers2

13

I strongly recommend Gradle; it is very simple to setup (though I too struggled when learning it). I added the resulting project in my github.

Let's create a project structure from zero without an IDE. I presume you already have $JAVA_HOME set up.

1. Creating the project structure

  1. Download Gradle and put it in your $PATH

  2. Create your directory project (I created /tmp/gr8ex)

  3. Switch to it and run gradle init [1]

  4. Edit the build.gradle created file and add these line:

    plugins { // [2]
        id 'groovy'
    }
    
    repositories { mavenCentral() } // [3]
    
    dependencies { // [4]
        testCompile 'org.codehaus.groovy:groovy-all:2.4.8'
        compile 'org.codehaus.groovy:groovy-all:2.4.8'
        testCompile 'junit:junit:4.12'
    }
    

Now the source files; we need to create the default directory structure that gradle uses (we can change it, but let's go with the defaults):

  1. This is to create the source code dir:

    mkdir -p src/main/groovy
    
  2. And the test source folder:

    mkdir -p src/test/groovy
    
  3. The end result should look like this:

    gr8ex
        ├── build.gradle
        ├── gradle
        │   └── wrapper
        │       ├── gradle-wrapper.jar
        │       └── gradle-wrapper.properties
        ├── gradlew
        ├── gradlew.bat
        ├── settings.gradle
        └── src
            ├── main
            │   └── groovy
            └── test
                └── groovy
    

2. Adding source code

  1. Let's add a test package:

    mkdir -p src/test/groovy/org/gr8ex
    
  2. And a test. I'm using gedit src/test/groovy/org/gr8ex/HelloTest.groovy:

    package org.gr8ex
    
    class HelloTest extends GroovyTestCase {
        void 'test Hello should return "Hello, World!"' () {
            assert new Hello().world == "Hello, World!"
        }
    }
    
  3. Let's execute the test and check it fails:

    gradle test
    
  4. Yep, it failed:

    /tmp/gr8ex/src/test/groovy/org/gr8ex/HelloTest.groovy: 5: unable to resolve class Hello 
     @ line 5, column 12.
              assert new Hello().world == "Hello, World!"
              ^
    
    1 error
    
    :compileTestGroovy FAILED
    
  5. Let's add source folder

    mkdir -p src/main/groovy/org/gr8ex
    
  6. And a source file (I used gedit src/main/groovy/org/gr8ex/Hello.groovy). Note it already have our static main method:

    package org.gr8ex
    
    class Hello {
        def getWorld() {
            "Hello, World!"
        }
    
        static main(args) {
            println new Hello().world
        }
    }
    
  7. Test again (with gradle test) and assert we get the message BUILD SUCCESSFUL:

    $ gradle test
    :compileJava UP-TO-DATE
    :compileGroovy
    :processResources UP-TO-DATE
    :classes
    :compileTestJava UP-TO-DATE
    :compileTestGroovy
    :processTestResources UP-TO-DATE
    :testClasses
    :test
    
    BUILD SUCCESSFUL
    
    Total time: 5.52 secs
    

Done. Time to create our application jar.

3. Creating the jar executable

There is a couple of ways to achieve that (like the shadow plugin). I'm going to stick with a "fatjar" approach.

  1. Let's add a fatjar instruction in our build.gradle [5]:

    task fatjar(type: Jar) {
        manifest {
            attributes 'Main-Class': 'org.gr8ex.Hello'
        }
        from { 
            configurations
                .runtime
                .collect { it.isDirectory() ? it : zipTree(it) }
        }
        with jar
    }
    
  2. Packaging it:

    gradle fatjar
    
  3. The resulting jar will be in builds/libs/gr8ex.jar. Let's execute it:

    $ java -jar build/libs/gr8ex.jar 
    Hello, World!
    
  4. Profit! You can import this project with intellij and (I believe) eclipse.


[1]: Gradle creates some basic structure and add wrapper scripts so it can be executed without Gradle, if needed.

[2]: Here we are telling gradle that this project will use groovy

[3]: We tell gradle to use the mavencentral repository. JCenter is also very popular.

[4]: Here we are telling gradle that this project needs to use the groovy-all lib upon compilation and and testing phases

[5]: If you just stick with a jar {} instruction, like this answer, you will end with a very thin jar which will be missing the groovy libs. This "fatjar" packs your libs into the jar. You might want to tweak it a bit depending on your use case.

Will
  • 14,348
  • 1
  • 42
  • 44
  • 1
    also note, that there are plugins for creating a uber/fatjar for gradle. – cfrick Jun 28 '17 at 16:07
  • @cfrick True! Added the shadow plugin reference. – Will Jun 28 '17 at 16:20
  • 1
    glorious, thanks! +1 for giving me something without the need for an IDE. – djhaskin987 Jun 29 '17 at 02:02
  • I'm glad it helped! :-) – Will Jun 29 '17 at 12:08
  • Thanks for this - it's a huge help for a newcomer like me. But as someone coming from a background of coding in languages other than Java/Groovy, how critical is the highly nested `src/{main,test}/groovy/org/gr8ex` directory structure? Is it possible to follow a flatter structure, for example with just a `src` directory containing a series of `xxx.groovy` files, and a `test` directory with the tests in it? – Paul Moore Jun 01 '18 at 12:52
0

Eclipse may work pretty good with a Groovy Maven setup. You just need a pom.xml similar to this:

...
<plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.2</version>
        <configuration>
          <source>1.7</source>
          <target>1.7</target>
          <compilerId>groovy-eclipse-compiler</compilerId>
          <useIncrementalCompilation>false</useIncrementalCompilation>
        </configuration>
        <dependencies>
          <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-eclipse-compiler</artifactId>
            <version>2.9.1-01</version>
          </dependency>
          <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-eclipse-batch</artifactId>
            <version>2.3.7-01</version>
          </dependency>
          <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy</artifactId>
            <version>2.3.0</version>
          </dependency>
          <dependency>
            <groupId>org.apache.ivy</groupId>
            <artifactId>ivy</artifactId>
            <version>2.4.0</version>
          </dependency>
        </dependencies>
      </plugin>
      <plugin>
        <groupId>org.codehaus.groovy</groupId>
        <artifactId>groovy-eclipse-compiler</artifactId>
        <version>2.9.1-01</version>
        <extensions>true</extensions>
      </plugin>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>build-helper-maven-plugin</artifactId>
        <version>1.9.1</version>
        <executions>
          <execution>
            <id>add-source</id>
            <phase>generate-sources</phase>
            <goals>
              <goal>add-source</goal>
            </goals>
            <configuration>
              <sources>
                <source>wherever/you/like</source>          
              </sources>
            </configuration>
          </execution>
        </executions>
      </plugin>
...
<dependencies>
...
<dependency>
      <groupId>org.codehaus.groovy</groupId>
      <artifactId>groovy-all</artifactId>
      <version>${groovyVersion}</version>
      <scope>provided</scope>
    </dependency>
...
</dependencies>
...

The sources part is optional, as it should look for your sources in src/main/groovy and src/test/groovy. Eclipse should be able to configure your project as a maven project, and acquire automatically the Groovy nature as well.

A call to mvn install should generate a .jar file with your Groovy classes translated into .class files since you have configured a Groovy compiler in maven.

As for the main method, just do as you would normally with maven:

...
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <mainClass>my.mainClass</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>
...
Jorge_B
  • 9,712
  • 2
  • 17
  • 22