BurntPieCrust
BurntPieCrust

Reputation: 30

Gradle & Java: adding files as dependencies

Gradle Noob here. I have a very simple project that I'm trying to use to better understand dependencies and how to import different files in Java with Gradle. I have the following File Structure:

$ ls
build.gradle  dependencies  src

$ ls dependencies/
Hello.java Hello.jar

$ ls src/
Temp.java

With the following three files

build.gradle:

apply plugin: 'java'

dependencies {
        compile fileTree(dir: 'dependencies', include:'**/*.jar')
}

sourceSets {
    main {
        java {
            srcDirs = ['src']
        }
    }
}

task compile(type: JavaCompile) {
    source = file('src')
}

Hello.java

public class Hello{
        int l = 1;
        public Hello(){
                System.out.println(l);
        }

        public static void main(String[] args){
                Hello h = new Hello();
        }
}

Temp.java:

public class Temp {

        public static void main( String[] args0){
        Hello h = new Hello();
        }

}

When running gradle jar on the command line, It seems that gradle builds successfully, however when trying to run my jar...

   $ java -classpath build/libs/testproject.jar Temp
Exception in thread "main" java.lang.NoClassDefFoundError: Hello
        at Temp.main(Temp.java:5)
Caused by: java.lang.ClassNotFoundException: Hello
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 1 more

Based on the documentation on Gradle, I can't seem to see what I'm doing incorrectly. What is my dependency specification doing in build.gradle, and why isn't that allowing Temp.java to see Hello.java? How do I fix this?

Thanks in advance for the help.

Upvotes: 0

Views: 2666

Answers (2)

lance-java
lance-java

Reputation: 28061

If you're a gradle noob... I suggest you follow gradle's very sensible conventions

  1. src/main/java for java sources
  2. src/main/resources for resources (xml etc added to the jar/classpath)
  3. src/test/java for test java sources
  4. src/test/resources for test resources
  5. jars should be referenced from a repository, jars shouldn't live in a lib directory under your project (and shouldn't be comitted to source control)

Upvotes: 2

alijandro
alijandro

Reputation: 12167

The jars from dependencies or subproject will not package to your root project jar by defaults.

if you want to add it in your root project's jar, you can modify jar task of your root project and add the classes.

jar {
    //...
    from 'dependencies/classes/Hello.class'
    //...
}

Then run the jar task again to create the jar, ./gradlew jar

At this time, your program should run properly.

$ java -cp build/lib/testproject.jar Temp

More simple solution, apply application plugin in your root project

apply plugin: 'application'
mainClassName = 'Temp'

and run the program with ./gradlew run

There some articles have covered this topics, see

https://www.mkyong.com/gradle/gradle-create-a-jar-file-with-dependencies/

Upvotes: 2

Related Questions