what's the gradle alternative to a fat JAR? - java

If transitive libs aren't packaged with the JAR task:
By default, jar task in gradle builds an executable jar file from your project source files. It will not contain any transitive libs that are needed for your program.
To the contrary, Netbeans does package JAR dependencies or transitive libs. Rather than a fat JAR how does gradle include libs?
plugins {
id 'com.gradle.build-scan' version '1.8'
id 'java'
id 'application'
}
mainClassName = 'net.bounceme.dur.mbaas.json.Main'
buildScan {
licenseAgreementUrl = 'https://gradle.com/terms-of-service'
licenseAgree = 'yes'
}
repositories {
jcenter()
}
jar {
manifest {
attributes 'Main-Class': 'net.bounceme.dur.mbaas.json.Main'
}
}
dependencies {
//compile fileTree(dir: 'libs', include: ['*.jar'])
runtime group: 'com.google.firebase', name: 'firebase-admin', version: '5.2.0'
compile fileTree(dir: 'lib', include: '*.jar')
}
in relation to another question: what's the "way" to package libs with the JAR task which doesn't result in a "fat JAR"?

When using the application plugin, all libraries used by the application (own jar or transitive libraries) are put in a libs folder when packaged as an app. then these libs are referenced in the shell or batch script as classpath when launching the app.
The easiest way to create a fatjar in gradle, is to use the shadow plugin available via the plugin portal. see https://plugins.gradle.org/plugin/com.github.johnrengelman.plugin-shadow for details

Related

Cannot use classes from .jar file

I've made a .jar with .java classes and tried to import them into my project, but it doesn't work.
When I build the project, I get:
> Task :compileJava FAILED
error: package skija does not exist
import static skija.scenes.*;
In my gradle I've tried to add this .jar via multiple methods and none of them work
build.gradle:
repositories {
flatDir {
dirs 'lib'
}
}
dependencies {
implementation fileTree(dir: 'lib', include: '*.jar')
implementation fileTree(dir: 'lib', includes: ['*.jar'])
implementation files('lib/scenes.jar')
implementation name: 'scenes'
}
Additionally, I've modified settings.gradle, which doesn't change anything:
pluginManagement {
buildscript {
repositories {
flatDir {
dirs 'lib'
}
}
dependencies {
classpath fileTree(dir: 'lib', includes: ['*.jar'])
classpath name: 'scenes'
}
}
}
Next, I've added libraries from the Idea Project Structure Libraries.
One is pointing to lib folder, and another points directly to the .jar file. This didn't help either.
I use a jar.bat script placed inside of PATH that calls jar.exe
jar.bat:
"C:\Program Files\Java\jdk-16.0.1\bin\jar.exe" %*
The scenes.jar was made with jar cfv scenes.jar * command.
Snipped of jar tf scenes.jar:
>"C:\Program Files\Java\jdk-16.0.1\bin\jar.exe" tf scenes.jar
META-INF/
META-INF/MANIFEST.MF
skija/scenes/
skija/scenes/BitmapImageScene.java
skija/scenes/BitmapScene.java
skija/scenes/BlendsScene.java
skija/scenes/BreakIteratorScene.java
skija/scenes/CodecScene.java
skija/scenes/ColorFiltersScene.java
skija/scenes/DebugTextBlobHandler.java
skija/scenes/DebugTextRun.java
skija/scenes/DecorationsBenchScene.java
skija/scenes/DrawableScene.java
skija/scenes/EmptyScene.java
skija/scenes/FigmaScene.java
skija/scenes/FontRenderingScene.java
skija/scenes/FontScene.java
skija/scenes/FontSizeScene.java
skija/scenes/FontVariationsScene.java
skija/scenes/GeometryScene.java
skija/scenes/HUD.java
skija/scenes/ImageBenchScene.java
skija/scenes/ImageCodecsScene.java
skija/scenes/ImageFiltersScene.java
skija/scenes/ImagesScene.java
skija/scenes/MaskFiltersScene.java
There is no point sticking .java files in a jar file. You need to compile the java files, which produces .class files. Put those in the jar file.

How can I add the processing core.jar to a gradle project?

So, I'm trying to make a project using processing, and I intend to use gradle because I like how it simplifies the compiling of the process. In a class I was given a build.gradle that uses the deprecated function compile like this:
dependencies {
// Dependency on local binaries
compile fileTree(dir: 'libs', include: ['*.jar'])
}
jar {
manifest {
attributes "Main-Class": mainClassName
}
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}
}
when I run this code, I get a warning from gradle telling me that this build is using some features that will be discontinued in gradle 7.0, I have confirmed that this features are the compile section of the build.gradle . So, I've been trying to include the processing core.jar in gradle using the newer functions of gradle, but i have been unable to succeed. So, how can I add the processing core.jar as a local library to my gradle project using the newest gradle?
thanks in advance and sorry for any spelling mistakes.
You need to stop using the compile configuration.
Instead you should use implementation for dependency declarations and runtimeClasspath for fat jar packaging.
Your example adapted:
dependencies {
// Dependency on local binaries
implementation fileTree(dir: 'libs', include: ['*.jar'])
}
jar {
manifest {
attributes "Main-Class": mainClassName
}
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}

Is there a way for Gradle to resolve dependencies using curl command? [duplicate]

I have tried to add my local .jar file dependency to my build.gradle file:
apply plugin: 'java'
sourceSets {
main {
java {
srcDir 'src/model'
}
}
}
dependencies {
runtime files('libs/mnist-tools.jar', 'libs/gson-2.2.4.jar')
runtime fileTree(dir: 'libs', include: '*.jar')
}
And you can see that I added the .jar files into the referencedLibraries folder here: https://github.com/WalnutiQ/wAlnut/tree/version-2.3.1/referencedLibraries
But the problem is that when I run the command: gradle build on the command line I get the following error:
error: package com.google.gson does not exist
import com.google.gson.Gson;
Here is my entire repo: https://github.com/WalnutiQ/wAlnut/tree/version-2.3.1
According to the documentation, use a relative path for a local jar dependency as follows.
Groovy syntax:
dependencies {
implementation files('libs/something_local.jar')
}
Kotlin syntax:
dependencies {
implementation(files("libs/something_local.jar"))
}
If you really need to take that .jar from a local directory,
Add next to your module gradle (Not the app gradle file):
repositories {
flatDir {
dirs("libs")
}
}
dependencies {
implementation("gson-2.2.4")
}
However, being a standard .jar in an actual maven repository, why don't you try this?
repositories {
mavenCentral()
}
dependencies {
implementation("com.google.code.gson:gson:2.2.4")
}
You could also do this which would include all JARs in the local repository. This way you wouldn't have to specify it every time.
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
}
The following works for me:
compile fileTree(dir: 'libs', include: '*.jar')
Refer to the Gradle Documentation.
You can try reusing your local Maven repository for Gradle:
Install the jar into your local Maven repository:
mvn install:install-file -Dfile=utility.jar -DgroupId=com.company -DartifactId=utility -Dversion=0.0.1 -Dpackaging=jar
Check that you have the jar installed into your ~/.m2/ local Maven repository
Enable your local Maven repository in your build.gradle file:
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
implementation ("com.company:utility:0.0.1")
}
Now you should have the jar enabled for implementation in your project
A solution for those using Kotlin DSL
The solutions added so far are great for the OP, but can't be used with Kotlin DSL without first translating them. Here's an example of how I added a local .JAR to my build using Kotlin DSL:
dependencies {
compile(files("/path/to/file.jar"))
testCompile(files("/path/to/file.jar"))
testCompile("junit", "junit", "4.12")
}
Remember that if you're using Windows, your backslashes will have to be escaped:
...
compile(files("C:\\path\\to\\file.jar"))
...
And also remember that quotation marks have to be double quotes, not single quotes.
Edit for 2020:
Gradle updates have deprecated compile and testCompile in favor of implementation and testImplementation. So the above dependency block would look like this for current Gradle versions:
dependencies {
implementation(files("/path/to/file.jar"))
testImplementation(files("/path/to/file.jar"))
testImplementation("junit", "junit", "4.12")
}
The accepted answer is good, however, I would have needed various library configurations within my multi-project Gradle build to use the same 3rd-party Java library.
Adding '$rootProject.projectDir' to the 'dir' path element within my 'allprojects' closure meant each sub-project referenced the same 'libs' directory, and not a version local to that sub-project:
//gradle.build snippet
allprojects {
...
repositories {
//All sub-projects will now refer to the same 'libs' directory
flatDir {
dirs "$rootProject.projectDir/libs"
}
mavenCentral()
}
...
}
EDIT by Quizzie: changed "${rootProject.projectDir}" to "$rootProject.projectDir" (works in the newest Gradle version).
Shorter version:
dependencies {
implementation fileTree('lib')
}
The Question already has been answered in detail. I still want to add something that seems very surprising to me:
The "gradle dependencies" task does not list any file dependencies. Even though you might think so, as they have been specified in the "dependencies" block after all..
So don't rely on the output of this to check whether your referenced local lib files are working correctly.
A simple way to do this is
compile fileTree(include: ['*.jar'], dir: 'libs')
it will compile all the .jar files in your libs directory in App.
Some more ways to add local library files using Kotlin DSL (build.gradle.kts):
implementation(
files(
"libs/library-1.jar",
"libs/library-2.jar",
"$rootDir/foo/my-other-library.jar"
)
)
implementation(
fileTree("libs/") {
// You can add as many include or exclude calls as you want
include("*.jar")
include("another-library.aar") // Some Android libraries are in AAR format
exclude("bad-library.jar")
}
)
implementation(
fileTree(
"dir" to "libs/",
// Here, instead of repeating include or exclude, assign a list of paths
"include" to "*.jar",
"exclude" to listOf("bad-library-1.jar", "bad-library-2.jar")
)
)
The above code assumes that the library files are in libs/ directory of the module (by module I mean the directory where this build.gradle.kts is located).
You can use Ant patterns in includes and excludes as shown above.
See Gradle documentations for more information about file dependencies.
Thanks to this post for providing a helpful answer.
I couldn't get the suggestion above at https://stackoverflow.com/a/20956456/1019307 to work. This worked for me though. For a file secondstring-20030401.jar that I stored in a libs/ directory in the root of the project:
repositories {
mavenCentral()
// Not everything is available in a Maven/Gradle repository. Use a local 'libs/' directory for these.
flatDir {
dirs 'libs'
}
}
...
compile name: 'secondstring-20030401'
The best way to do it is to add this in your build.gradle file and hit the sync option
dependency{
compile files('path.jar')
}
The solution which worked for me is the usage of fileTree in build.gradle file.
Keep the .jar which need to add as dependency in libs folder. The give the below code in dependenices block in build.gradle:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
}
You can add jar doing:
For gradle just put following code in build.gradle:
dependencies {
...
compile fileTree(dir: 'lib', includes: ['suitetalk-*0.jar'])
...
}
and for maven just follow steps:
For Intellij:
File->project structure->modules->dependency tab-> click on + sign-> jar and dependency->select jars you want to import-> ok-> apply(if visible)->ok
Remember that if you got any java.lang.NoClassDefFoundError: Could not initialize class exception at runtime this means that dependencies in jar not installed for that you have to add all dependecies in parent project.
For Gradle version 7.4 with Groovy build file
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
implementation ':gson-2.2.4'
}
If you are on gradle 4.10 or newer:
implementation fileTree(dir: 'libs', includes: ['*.jar'])
Goto File -> Project Structure -> Modules -> app -> Dependencies Tab -> Click on +(button) -> Select File Dependency - > Select jar file in the lib folder
This steps will automatically add your dependency to gralde
Very Simple
Be careful if you are using continuous integration, you must add your libraries in the same path on your build server.
For this reason, I'd rather add jar to the local repository and, of course, do the same on the build server.
An other way:
Add library in the tree view. Right click on this one. Select menu "Add As Library".
A dialog appear, let you select module. OK and it's done.

Configure .jar to expose its dependencies

I have 3 modules: annotations, annotation_processor and app.
annotations/build.gradle
apply plugin: 'java-library'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
}
annotation_processor/build.gradle
apply plugin: 'java-library'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
api project(":annotations")
api "com.squareup:javapoet:1.11.1"
}
repositories {
mavenCentral()
}
sourceCompatibility = "1.8"
targetCompatibility = "1.8"
task deleteJar(type: Delete) {
delete 'libs/annotations.jar'
}
task createJar(type: Copy) {
from('build/intermediates/bundles/release/')
into('libs/')
include('classes.jar')
rename('classes.jar', 'annotations.jar')
}
createJar.dependsOn(deleteJar, build)
and app/build.gradle
dependencies {
...
implementation files('libs/annotation_processor.jar')
annotationProcessor files('libs/annotation_processor.jar')
...
}
When I run the project I get the following error.
error: package com.annotations does not exist
If I include annotations as a project the project I can skip this error but then I get.
Caused by: java.lang.NoClassDefFoundError: com/annotations/ProviderApi
at com.annotation_processor.ProviderAnnotationProcessor.getSupportedAnnotationTypes(ProviderAnnotationProcessor.java:45)
at org.gradle.api.internal.tasks.compile.processing.DelegatingProcessor.getSupportedAnnotationTypes(DelegatingProcessor.java:47)
at org.gradle.api.internal.tasks.compile.processing.NonIncrementalProcessor.getSupportedAnnotationTypes(NonIncrementalProcessor.java:33)
at org.gradle.api.internal.tasks.compile.processing.DelegatingProcessor.getSupportedAnnotationTypes(DelegatingProcessor.java:47)
at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor.access$101(TimeTrackingProcessor.java:37)
at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor$2.create(TimeTrackingProcessor.java:68)
at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor$2.create(TimeTrackingProcessor.java:65)
at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor.track(TimeTrackingProcessor.java:117)
at org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor.getSupportedAnnotationTypes(TimeTrackingProcessor.java:65)
I can't access any of the dependencies (Java Poet and annotation module) from annotation_processor even though I have replaced implementation with api. Which should've expose the dependencies, but haven't.
I need the dependencies of the .jar file in the app module.
I'm new to Java Library and it may be I'm making a basic mistake, but can't seem to figure out, I've been at it for more than a day now.
You have to create a multi module gradle project.
I provide a small snippet of a multi module project.
project(':module1') {
dependencies {
compile project(':module-service-api')
compile 'org.apache.commons:commons-lang3:3.3.2'
compile 'log4j:log4j:1.2.17'
}
}
//module-app depends on module-service-impl
project(':module2') {
dependencies {
compile project(':module1')
}
For more details about multi module project, refer to the file build.gradle in the following project.
https://github.com/debjava/gradle-multi-module-project-1
If you want to create a fat jar or one jar, you have to include Gradle shadow plugin so that you can distribute the jar file along with other dependencies.
Refer below the link.
https://plugins.gradle.org/plugin/com.github.johnrengelman.shadow

Adding dependencies for gradle

I have in gradle.build:
dependencies {
classpath 'something:1.0'
}
What I need to add in the file to add a local .jar file, which java can "import"?
But I don't need to include this .jar in my application. Just like a shared library.
I tried:
classpath 'something:1.0','somethingelse:1.0'
classpath 'something:1.0, somethingelse:1.0'
classpath { 'something:1.0','somethingelse:1.0' }
compile files('somethingelse.jar')
classpath files('lib/somethingelse.jar')
classpath fileTree(dir: 'lib', include: '*.jar')
I think you want compile name: This recipie is in a gradle file I inherited.
repositories {
flatDir {
dirs 'lib'
}
dependencies {
compile name: 'jdom'
compile name: 'jebl-0.3'
}
BTW, this question appears to be a duplicate of
How to add local .jar file dependency to build.gradle file?

Categories

Resources