Java plugin can't configure dependencies properly

plugins

(Paulo Márcio de Almeida Mendes Rocha) #1

Hello, i’m new to gradle and i just want to say that i really enjoy the tool, the possibilities it give me, i think i’ll never need another build script tool.

To conitnue my learning curve, i’m trying to build a simple java multi project now, i have two projects: p1 and p2, p1(application) depends on p2(library), for simplicity i’m using only one gradle scipt:

allprojects{
}

project(':p1'){
    apply plugin: 'java'
    group = 'paulo.teste.hehe'
    version = '1.0'
    
    dependencies{
        compile project(':p2')
    }

    jar {
       /*from configurations.compile.collect { zipTree it } workaround*/
       manifest.attributes(
           'Class-Path': 'paulo.teste.hehe',
           'Main-Class': 'paulo.teste.hehe.Main'
       )
   }
}
project(':p2'){
    apply plugin: 'java-library'
    group = 'paulo.teste2.hehe'
    version = '1.0'
}
subprojects{
    sourceSets {
        main {
            java {
                srcDirs = ['./']
            }
        }
    }
}

p1 is just a folder that contains the file Main.java:

package paulo.teste.hehe;

import paulo.teste2.hehe.StaticClass;

public class Main{
    public static void main(String[] args){
        StaticClass.print(args);
    }
}

And p2 is just a folder that contains StaticClass.java:

package paulo.teste2.hehe;

public class StaticClass{
    public static void print(String[] args){
        for(String a : args){
            System.out.println(a);
        }
    }
}

I compile this project(gradle build) ok, but when i try to run, java cant find the StaticClass, this is because the jar generated for p1 does not include the .class file from p2(but it is generated). I have found some workaround, for example use zipTree to place the p2.jar contents inside the p1.jar:

 from configurations.compile.collect { zipTree it }

I tried other options besides the compile, for example: implementation, runtimeOnly, none works. Can someone help me here? I think this is a job for the java plugin to place the dependencies in the right place, so i am not comfortable using the zipTree approach and need to know how to configure the plugin properly. Thanks in advance


(James Justinic) #2

This is the normal expected behavior. By default, each project builds a JAR file that only contains the contents from that project. When you run the program, you need to provide java with the entire required classpath (-cp), which would include both p1.jar and p2.jar.

If you want to bundle an application for easier distribution, you have multiple options. The application plugin will put all the dependencies in a folder and generate start scripts. You can also create a fat JAR yourself (the zipTree method is the traditional way to implement this) or use the Shadow plugin, which allows additional customization.


(Paulo Márcio de Almeida Mendes Rocha) #3

Yes i end up realizing it, and it is really better this way, it gives me more controll over the project by doing just the minimum, and if i really need i still can write a script to pack the jars.

Thanks for helping.