1

I am new to Java and Gradle, and have a very newbie question. I have the following Java file:

public class TestMain {
    public static void main(String[] args) {
        System.out.println("Hello.....");
    }
}

I am able to compile the above file using javac, and run it using command "java TestMain".

I am now trying to do the same using gradle build framework. I performed the following steps: run "gradle init --type java-library copied the above file into src/main/java/

When I run "./gradlew build", I get a TestMain.class file, and a also a "building-java-file.jar" (the whole gradle directory is in building-java-file directory).

$ ls -l build/classes/main/TestMain.class 
-rw-r--r--  1 user1  foo\eng  610 May 22 17:22 build/classes/main/TestMain.class

$ java  build/classes/main/TestMain
Error: Could not find or load main class build.classes.main.TestMain

How do I run the TestMain.class? Also, what is the reason for gradle creating the jar file - building-java-file.jar?

Btw, my build.gradle file is pretty empty.

apply plugin: 'java'

repositories {
    jcenter()
}

dependencies {
    // The production code uses the SLF4J logging API at compile time
    compile 'org.slf4j:slf4j-api:1.7.21'

    testCompile 'junit:junit:4.12'
}

Thank you, Ahmed.'

Ahmed A
  • 3,362
  • 7
  • 39
  • 57
  • See this SO post: https://stackoverflow.com/questions/21358466/gradle-to-execute-java-class-without-modifying-build-gradle – Naveen Kumar May 23 '18 at 00:51
  • Regarding changing the name of the jar you can do so using `jar.archiveName = “myjar.jar”` – piy26 May 23 '18 at 00:52
  • @piy26 My question is more to the point, why is the jar file even being created. Is that implicitly done or is it because I did a "gradle init --type java-library" – Ahmed A May 23 '18 at 00:57
  • @NaveenKumar To clarify, I have to use gradle to execute the java file that contains "main". I cannot independently execute it using java? If so, why not? what is the logic? – Ahmed A May 23 '18 at 00:59
  • 1
    Each Gradle java project makes a jar when running `build` task. The `classes` task only makes the class files. Gradle user guide page on the java plugin has some good visuals and info regarding it. Also you may want to use the `application` plugin. – Aarjav May 23 '18 at 01:04

3 Answers3

2

Answers to my question are explained clearly in the Gradele documentation site.

Basically, start with: gradle init --type java-application

Link: https://guides.gradle.org/building-java-applications/?_ga=2.79084180.165016772.1527029076-64181247.1527029076

Ahmed A
  • 3,362
  • 7
  • 39
  • 57
0

Use JavaExec. As an example put the following in build.gradle

task execute(type:JavaExec) {
   main = mainClass
   classpath = sourceSets.main.runtimeClasspath
}

To run gradle -PmainClass=Boo execute. You get

$ gradle -PmainClass=Boo execute
:compileJava
:compileGroovy UP-TO-DATE
:processResources UP-TO-DATE
:classes
:execute
I am BOOMMMM!

mainClass is a property passed in dynamically at command line. classpath is set to pickup the latest classes.

If you do not pass in the mainClass property, this fails as expected.

$ gradle execute

FAILURE: Build failed with an exception.

* Where:
Build file 'xxxx/build.gradle' line: 4

* What went wrong:
A problem occurred evaluating root project 'Foo'.
> Could not find property 'mainClass' on task ':execute'.
Nikunj Chavda
  • 47
  • 1
  • 1
  • 10
0

I think you are looking for a solution to create a runnable jar. Here is the solution what you can add it in the build.gradle

  • Execute gradle init --type java-application

  • Add the following gradle task to the build.gradle.

  • Runnable fat Jar (with all dependent libraries copied to the jar)

     task fatJar(type: Jar) {
    
          manifest {
              attributes 'Main-Class': 'com.example.gradle.App'
          }
          from {
              configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
          } with jar
    
        }
    

Runnable jar with all dependencies copied to a directory and adding the classpath to the manifest

def dependsDir = "${buildDir}/libs/dependencies/"
task copyDependencies(type: Copy) {
    from configurations.compile
    into "${dependsDir}"
}
task createJar(dependsOn: copyDependencies, type: Jar) {
  
    manifest {
        attributes('Main-Class': 'com.example.gradle.App',
                'Class-Path': configurations.compile.collect { 'dependencies/' + it.getName() }.join(' ')
        )
    }
    with jar
}

How to use ?

Add the above tasks to build.gradle
Execute gradle fatJar //create fatJar
Execute gradle createJar // create jar with dependencies copied.

A complete article, which I wrote on this topic, can be read here : A simple java project with Gradle

jfk
  • 4,335
  • 34
  • 27