How to create Java Gradle project from command line?
It should create standard maven folder layout like on the picture below.
UPDATE:
.1. From http://www.gradle.org/docs/current/userguide/tutorial_java_projects.html
I need to create file build.gradle with 2 lines
apply plugin: 'java'
apply plugin: 'eclipse'
.2. Add to build.gradle task below, than execute gradle create-dirs
task "create-dirs" << {
sourceSets*.java.srcDirs*.each { it.mkdirs() }
sourceSets*.resources.srcDirs*.each { it.mkdirs() }
}
.3. Then run gradle eclipse (or corresponding string to other IDE plugin configured)
So is there way to do it in one command?
To create a Java project: create a new project directory, jump into it and execute
gradle init --type java-library
Source folders and a Gradle build file (including a wrapper) will be build.
The gradle guys are doing their best to solve all (y)our problems ;-).
They recently (since 1.9) added a new feature (incubating): the "build init" plugin.
See: build init plugin documentation
Finally after comparing all solution, I think starting from build.gradle file can be convenient.
Gradle distribution has samples folder with a lot of examples, and there is gradle init --type basic comand see Chapter 47. Build Init Plugin. But they all needs some editing.
You can use template below as well, then run gradle initSourceFolders eclipse
/*
* Nodeclipse/Enide build.gradle template for basic Java project
* https://github.com/Nodeclipse/nodeclipse-1/blob/master/org.nodeclipse.enide.editors.gradle/docs/java/basic/build.gradle
* Initially asked on
* http://stackoverflow.com/questions/14017364/how-to-create-java-gradle-project
* Usage
* 1. create folder (or general Eclipse project) and put this file inside
* 2. run `gradle initSourceFolders eclipse` or `gradle initSourceFolders idea`
* #author Paul Verest;
* based on `gradle init --type basic`, that does not create source folders
*/
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
task initSourceFolders { // add << before { to prevent executing during configuration phase
sourceSets*.java.srcDirs*.each { it.mkdirs() }
sourceSets*.resources.srcDirs*.each { it.mkdirs() }
}
task wrapper(type: Wrapper) {
gradleVersion = '1.11'
}
// In this section you declare where to find the dependencies of your project
repositories {
// Use Maven Central for resolving your dependencies.
// You can declare any Maven/Ivy/file repository here.
mavenCentral()
}
// In this section you declare the dependencies for your production and test code
dependencies {
//compile fileTree(dir: 'libs', include: '*.jar')
// The production code uses the SLF4J logging API at compile time
//compile 'org.slf4j:slf4j-api:1.7.5'
// Declare the dependency for your favourite test framework you want to use in your tests.
// TestNG is also supported by the Gradle Test task. Just change the
// testCompile dependency to testCompile 'org.testng:testng:6.8.1' and add
// 'test.useTestNG()' to your build script.
testCompile "junit:junit:4.11"
}
The result is like below.
That can be used without any Gradle plugin for Eclipse,
or with (Enide) Gradle for Eclipse, Jetty, Android alternative to Gradle Integration for Eclipse
Unfortunately you cannot do it in one command. There is an open issue for the very feature.
Currently you'll have to do it by hand. If you need to do it often, you can create a custom gradle plugin, or just prepare your own project skeleton and copy it when needed.
EDIT
The JIRA issue mentioned above has been resolved, as of May 1, 2013, and fixed in 1.7-rc-1. The documentation on the Build Init Plugin is available, although it indicates that this feature is still in the "incubating" lifecycle.
Here is what it worked for me.. I wanted to create a hello world java application with gradle with the following requirements.
The application has external jar dependencies
Create a runnable fat jar with all dependent classes copied to the jar
Create a runnable jar with all dependent libraries copied to a directory "dependencies" and add the classpath in the manifest.
Here is the solution :
Install the latest gradle ( check gradle --version . I used gradle 6.6.1)
Create a folder and open a terminal
Execute gradle init --type java-application
Add the required data in the command line
Import the project into an IDE (IntelliJ or Eclipse)
Edit the build.gradle file with the following tasks.
Runnable fat Jar
task fatJar(type: Jar) {
clean
println("Creating fat jar")
manifest {
attributes 'Main-Class': 'com.abc.gradle.hello.App'
}
archiveName "${runnableJar}"
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
} with jar
println("Fat jar is created")
}
Copy Dependencies
task copyDepends(type: Copy) {
from configurations.default
into "${dependsDir}"
}
Create jar with classpath dependecies in manifest
task createJar(type: Jar) {
println("Cleaning...")
clean
manifest {
attributes('Main-Class': 'com.abc.gradle.hello.App',
'Class-Path': configurations.default.collect { 'dependencies/' +
it.getName() }.join(' ')
)
}
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
} with jar
println "${outputJar} created"
}
Here is the complete build.gradle
plugins {
id 'java'
id 'application'
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.slf4j:slf4j-api:1.7.30'
implementation 'ch.qos.logback:logback-classic:1.2.3'
implementation 'ch.qos.logback:logback-core:1.2.3'
testImplementation 'junit:junit:4.13'
}
def outputJar = "${buildDir}/libs/${rootProject.name}.jar"
def dependsDir = "${buildDir}/libs/dependencies/"
def runnableJar = "${rootProject.name}_fat.jar";
//Create runnable fat jar
task fatJar(type: Jar) {
clean
println("Creating fat jar")
manifest {
attributes 'Main-Class': 'com.abc.gradle.hello.App'
}
archiveName "${runnableJar}"
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
} with jar
println("Fat jar is created")
}
//Copy dependent libraries to directory.
task copyDepends(type: Copy) {
from configurations.default
into "${dependsDir}"
}
//Create runnable jar with dependencies
task createJar(type: Jar) {
println("Cleaning...")
clean
manifest {
attributes('Main-Class': 'com.abc.gradle.hello.App',
'Class-Path': configurations.default.collect { 'dependencies/' +
it.getName() }.join(' ')
)
}
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
} with jar
println "${outputJar} created"
}
Gradle build commands
Create fat jar : gradle fatJar
Copy dependencies : gradle copyDepends
Create runnable jar with dependencies : gradle createJar
More details can be read here : https://jafarmlp.medium.com/a-simple-java-project-with-gradle-2c323ae0e43d
If you are using Eclipse, for an existing project (which has a build.gradle file) you can simply type gradle eclipse which will create all the Eclipse files and folders for this project.
It takes care of all the dependencies for you and adds them to the project resource path in Eclipse as well.
I could handle it using a groovy method in build.gradle to create all source folders for java, resources and test. Then I set it to run before gradle eclipse task.
eclipseClasspath.doFirst {
initSourceFolders()
}
def initSourceFolders() {
sourceSets*.java.srcDirs*.each { it.mkdirs() }
sourceSets*.resources.srcDirs*.each { it.mkdirs() }
}
Now we can setup a new gradle Java EE project to eclipse with only one command. I put this example at GitHub
I just tried with with Eclipse Neon.1 and Gradle:
------------------------------------------------------------
Gradle 3.2.1
------------------------------------------------------------
Build time: 2016-11-22 15:19:54 UTC
Revision: 83b485b914fd4f335ad0e66af9d14aad458d2cc5
Groovy: 2.4.7
Ant: Apache Ant(TM) version 1.9.6 compiled on June 29 2015
JVM: 1.8.0_112 (Oracle Corporation 25.112-b15)
OS: Windows 10 10.0 amd64
On windows 10 with Java Version:
C:\FDriveKambiz\repo\gradle-gen-project>java -version
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b15, mixed mode)
And it failed miserably as you can see in Eclipse.
But sailed like a soaring eagle in Intellij...I dont know Intellij, and a huge fan of eclipse, but common dudes, this means NO ONE teste Neon.1 for the simplest of use cases...to import a gradle project.
That is not good enough.
I am switching to Intellij for gradle projects:
Related
I'm adding Checker Framework to an existing Java Gradle build. I have Checker integrated and raising issues and that's all working great. But now that I've added it, my build is no longer producing a .jar file as it once did.
Previously, I'd get a .jar at build/libs/myproject.jar. Now instead I see build/checkerframework and build/main but no build/libs and no .jar.
My build.gradle is below. Anyone attempted this before? Any success?
I guess I'd also accept an answer that shows how run Checker outside of the build, e.g. gradle check to run a build with Checker, and gradle build to produce a .jar. But I'd really prefer to have just a single build step if at all possible.
Thanks!
plugins {
id "org.checkerframework" version "0.5.18"
id 'application'
}
apply plugin: 'org.checkerframework'
checkerFramework {
checkers = [
'org.checkerframework.checker.nullness.NullnessChecker',
'org.checkerframework.checker.units.UnitsChecker'
]
}
repositories {
jcenter()
}
java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
jar {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
// Embed all dependencies to create a "fat jar" as required for AWS deployment.
// Exclude 3rd-party signing files to prevent security errors at runtime
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
} {
exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA'
}
manifest {
attributes('Main-Class': 'client.CliMain')
}
}
If the build is passing, then adding -processor should not affect whether a .jar file is produced. (Unless you pass -proc:only or the like.)
If the build is failing, then Gradle won't build the jar files.
You said the Checker Framework is "raising issues", so maybe the build is failing.
I've created a JavaFX 11 app that is ready to be deployed.
I use Gradle 5.0 as my build tool and this command to compile the jar:
jar {
manifest {
attributes(
'Main-Class': 'checkmydigitalfootprint.MainApp'
)
}
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
Then on command line I've tried different commands to run the jar file:
java -jar CheckMyDigitalFootprint.jar
java -jar CheckMyDigitalFootprint.jar --module-path="/users/joseph/eclipse-workspace/javafx-sdk-11.0.1/lib" --add-modules=javafx.controls
java -jar CheckMyDigitalFootprint.jar --module-path="/users/joseph/eclipse-workspace/javafx-sdk-11.0.1/lib" --add-modules=javafx.controls --add-exports=javafx.graphics/com.sun.javafx.util=ALL-UNNAMED --add-exports=javafx.base/com.sun.javafx.reflect=ALL-UNNAMED --add-exports=javafx.base/com.sun.javafx.beans=ALL-UNNAMED --add-exports=javafx.graphics/com.sun.glass.utils=ALL-UNNAMED --add-exports=javafx.graphics/com.sun.javafx.tk=ALL-UNNAMED
But all result in the same error:
Error: JavaFX runtime components are missing, and are required to run this application
Rest of build.gradle:
plugins {
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.5'
id 'eclipse'
}
repositories {
mavenCentral()
}
dependencies {
/* uncomment for cross-platform jar: */
// compile "org.openjfx:javafx-graphics:11:win"
// compile "org.openjfx:javafx-graphics:11:linux"
compile "org.openjfx:javafx-graphics:11:mac"
compile 'com.jfoenix:jfoenix:9.0.8'
compile 'org.json:json:20180813'
compile 'com.google.api-client:google-api-client:1.23.0'
compile 'com.google.oauth-client:google-oauth-client-jetty:1.23.0'
compile 'com.google.apis:google-api-services-gmail:v1-rev83-1.23.0'
compile group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '2.3.1'
compile 'com.sun.activation:javax.activation:1.2.0'
compile group: 'com.sun.mail', name: 'javax.mail', version: '1.6.2'
testCompile "org.testfx:testfx-core:4.0.15-alpha"
testCompile "org.testfx:testfx-junit:4.0.15-alpha"
}
javafx {
modules = [ 'javafx.controls', 'javafx.fxml' ]
}
run {
if (osdetector.os == 'windows') {
// Temporal fix for Eclipse with JDK 1.8 and Windows
systemProperty "java.library.path", "C:\tmp"
}
}
jar {
manifest {
attributes(
'Main-Class': 'checkmydigitalfootprint.MainApp'
)
}
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
mainClassName = 'checkmydigitalfootprint.MainApp'
This is explained on official OpenJFX website
The solution is simple, just add following VM option:
--module-path /path/to/javafx-sdk-11.0.1/lib --add-modules=javafx.controls,javafx.fxml
for your Gradle project apply JavaFX gradle plugin
plugins {
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.5'
}
add the required modules. e.g:
javafx {
modules = [ 'javafx.controls' ]
}
Specify version of JavaFX
javafx {
version = "11.0.+"
}
Hopefully this will help you :)
You solve the problem by using this
Java -jar --module-path /path/to/javafx-sdk-11.0.1/lib --add-modules=javafx.controls,javafx.fxml (path to your jar file)
I have no experience with Gradle but was having the same problem with a runnable jar giving the "JavaFX runtime components are missing...". (Using openJDK/JFX 11.) Even when the vm arguments were correctly included in the command line. The problem was the "Library handling" option for building the runnable jar. "Extract required libraries.." didn't do the job. "Package required libraries..." was the correct option for building a runnable jar file with JavaFX dependency.
To also solve this problem.....
You can create another main class aside the main class javafx provided and then call the javafx main class from the main class you created. In this way you can create an executable jar with all the javafx runtime module present and create an installer form the jar. This is mostly applicable when you are using any jdk above 8
I am using Gradle to build my Java project in Eclipse. gradle.build is as follows
apply plugin: 'java'
repositories {
mavenCentral()
}
dependencies {
compile group: 'com.flowpowered', name: 'flow-nbt', version: '1.0.0'
compile group: 'org.reflections', name: 'reflections', version: '0.9.10'
}
All libraries are functioning properly when run through Eclipse. But sometimes it is useful to work on the command line. When run on the command line, the runtime error Exception in thread "main" java.lang.NoClassDefFoundError: com/flowpowered/nbt/regionfile/SimpleRegionFileReader occurs, even though the build is successful and the code contains imports from those libraries. I have tried cleans and rebuilds, along with gradlew build --refresh-dependencies, but I still encounter the same runtime error.
I would assume that the libraries are just never actually imported? Or that they are not being stored where the java project thinks they are? I'm unfamiliar with Gradle, so any advice on this is welcome.
Based on the posted build.gradle file you are not packaging the application as an executable JAR.
First apply the application plugin. But this will not be enough as you won't be able to run the executable as a single JAR without all of its dependencies. Apply the shadow plugin too.
These two plugins will give you access to the following tasks:
run: execute the application from gradle's command line.
runShadow: execute the application but with all dependencies packaged in a single JAR, alongside your compiled classes and resources.
shadowJar: create a single "fat JAR" with compiled classes and all dependencies.
Thus your build.gradle may look like this
plugins {
id 'java'
id 'application'
id 'com.github.johnrengelman.shadow' version '1.2.4'
}
mainClassName = 'com.acme.YourMainClassName'
repositories {
mavenCentral()
}
dependencies {
compile group: 'com.flowpowered', name: 'flow-nbt', version: '1.0.0'
compile group: 'org.reflections', name: 'reflections', version: '0.9.10'
}
Plugin documentation:
https://github.com/johnrengelman/shadow
https://docs.gradle.org/3.4/userguide/application_plugin.html#useApplicationPlugin
Another solution without using any plugins and still end up with a runnable fat jar
jar {
archiveName = 'NameOfYourApp.jar'
manifest {
attributes 'Main-Class': 'uk.co.cdl.Main',
'Class-Path': configurations.runtime.files.collect { "lib/$it.name" }.join(' '),
'Implementation-Version': project.version
}
from(configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }) {
include/exclude anything if need to if not take the curlys off
}
}
dependencies {
compile 'org.slf4j:slf4j-api:1.7.13'
compile group: 'org.apache.commons', name: 'commons-math3' , version: '+'
testCompile 'junit:junit:4.12'
}
Even if I add this, when I run gradle build, it works, and codes with commons-math3 can be compiled. But when I run a jar file in build/,
it says Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/math3/complex/Complex
But the official Gradle site says, the resource in 'compile' will also be included in 'runtime' dependency. and I also tried adding the commons-math to runtime. but it does not work.
Maybe this is my misunderstood of the dependency system.
How can I include external library from maven repository into a jar file made by the Gradle.
What you are looking for is either the distribution zips produced by the application plugin or the shadow jar (also called fat jar) produced by the shadowJar plugin:
The distribution zip (application plugin)
About the distribution zip
The distribution zips look like this:
my-app-0.2.0.zip
├──bin
│ ├──my-app
│ └──my-app.bat
└──lib
├──my-app-0.2.0.jar
├──slf4j-api.1.7.13.jar
└──commons-math3-3.6.jar
You can then run your application with its dependencies by unzipping what has been produced in build/distributions/ and running either my-app.bat (on windows) or ./my-app (on linux or OS X)
Building a distribution zip
Here is a sample gradle build file for making a distribution zip:
build.gradle
apply plugin: 'java'
apply plugin: 'application'
mainClassName = 'org.myapp.Main'
repositories { jcenter() }
dependencies {
compile 'org.slf4j:slf4j-api:1.7.13'
compile 'org.apache.commons:commons-math3:3.6'
testCompile 'junit:junit:4.12'
}
Can be run with gradle distributionZip or gradle distributionTar. To just run the application, use gradle run.
The shadow jar
About the shadow jar
The shadow jar is one giant jar file that is a combination of your program and its libraries, packed together into one file. You will get a file that is self-contained and can be run by a double-click on most systems (e.g. on Windows that works, on Xubuntu it can be run by right-clicking and selecting 'Run with Oracle Java 8 Runtime', etc...).
Building a distribution zip
Here is, again, a sample build.gradle file:
apply plugin: 'java'
apply plugin: 'com.github.johnrengelman.shadow'
mainClassName = 'org.myapp.Main'
jar {
manifest {
attributes('Main-Class': mainClassName)
}
}
buildscript {
repositories { jcenter() }
dependencies {
classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.2'
}
}
repositories { jcenter() }
dependencies {
compile 'org.slf4j:slf4j-api:1.7.13'
compile 'org.apache.commons:commons-math3:3.6'
testCompile 'junit:junit:4.12'
}
Run it with gradle shadowJar - Your jar with packed dependencies will be in build/libs and it will be named my-app-x.x.x-all.jar.
Gradle is first of all a build tool (just like maven, btw).
Its "responisiblity" starts when you feed it a source file and ends when you get your artifact (in your case its a jar).
Now when you're going to actually run your application there is a plethora of different options here.
If you just run java -jar <your_jar> you are responsible by yourself to construct the classpath.
If you run it with some kind of external runner, you should read the documentation of it and supply it a classpath.
Hope this helps
Until now I created runnable JAR files via the Eclipse "Export..." functionallity but now I switched to IntelliJ IDEA and Gradle for build automation.
Some articles here suggest the "application" plugin, but this does not entirely lead to the result I expected (just a JAR, no start scripts or anything like this).
How can I achieve the same result Eclipse does with the "Export..." dialog?
An executable jar file is just a jar file containing a Main-Class entry in its manifest. So you just need to configure the jar task in order to add this entry in its manifest:
jar {
manifest {
attributes 'Main-Class': 'com.foo.bar.MainClass'
}
}
You might also need to add classpath entries in the manifest, but that would be done the same way.
See http://docs.oracle.com/javase/tutorial/deployment/jar/manifestindex.html
If you already have defined an application context, you can re-use the definition rather than duplicate it:
application {
// Define the main class for the application.
mainClass = 'com.foo.bar.MainClass'
}
jar {
manifest {
attributes 'Main-Class': application.mainClass
}
}
Both JB Nizet and Jorge_B's answers are correct.
In its simplest form, creating an executable JAR with Gradle is just a matter of adding the appropriate entries to the manifest. However, it's much more common to have dependencies that need to be included on the classpath, making this approach tricky in practice.
The application plugin provides an alternate approach; instead of creating an executable JAR, it provides:
a run task to facilitate easily running the application directly from the build
an installDist task that generates a directory structure including the built JAR, all of the JARs that it depends on, and a startup script that pulls it all together into a program you can run
distZip and distTar tasks that create archives containing a complete application distribution (startup scripts and JARs)
A third approach is to create a so-called "fat JAR" which is an executable JAR that includes not only your component's code, but also all of its dependencies. There are a few different plugins that use this approach. I've included links to a few that I'm aware of; I'm sure there are more.
shadow
one-jar
spring-boot
capsule
Least effort solution for me was to make use of the gradle-shadow-plugin
Besides applying the plugin all that needs to be done is:
Configure the jar task to put your Main class into manifest
jar {
manifest {
attributes 'Main-Class': 'com.my.app.Main'
}
}
Run the gradle task
./gradlew shadowJar
Take the app-version-all.jar from build/libs/
And finally execute it via:
java -jar app-version-all.jar
As others have noted, in order for a jar file to be executable, the application's entry point must be set in the Main-Class attribute of the manifest file. If the dependency class files are not collocated, then they need to be set in the Class-Path entry of the manifest file.
I have tried all kinds of plugin combinations and what not for the simple task of creating an executable jar and somehow someway, include the dependencies. All plugins seem to be lacking one way or another, but finally I got it like I wanted. No mysterious scripts, not a million different mini files polluting the build directory, a pretty clean build script file, and above all: not a million foreign third party class files merged into my jar archive.
The following is a copy-paste from here for your convenience..
[How-to] create a distribution zip file with dependency jars in subdirectory /lib and add all dependencies to Class-Path entry in the manifest file:
apply plugin: 'java'
apply plugin: 'java-library-distribution'
repositories {
mavenCentral()
}
dependencies {
compile 'org.apache.commons:commons-lang3:3.3.2'
}
// Task "distZip" added by plugin "java-library-distribution":
distZip.shouldRunAfter(build)
jar {
// Keep jar clean:
exclude 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA', 'META-INF/*.MF'
manifest {
attributes 'Main-Class': 'com.somepackage.MainClass',
'Class-Path': configurations.runtime.files.collect { "lib/$it.name" }.join(' ')
}
// How-to add class path:
// https://stackoverflow.com/questions/22659463/add-classpath-in-manifest-using-gradle
// https://gist.github.com/simon04/6865179
}
Hosted as a gist here.
The result can be found in build/distributions and the unzipped contents look like this:
lib/commons-lang3-3.3.2.jar
MyJarFile.jar
Contents of MyJarFile.jar#META-INF/MANIFEST.mf:
Manifest-Version: 1.0
Main-Class: com.somepackage.MainClass
Class-Path: lib/commons-lang3-3.3.2.jar
This is for Kotlin DSL (build.gradle.kts).
Method 1 (no need for application or other plugins)
tasks.jar {
manifest.attributes["Main-Class"] = "com.example.MyMainClass"
// OR another notation
// manifest {
// attributes["Main-Class"] = "com.example.MyMainClass"
// }
}
If you use any external libraries, use below code. Copy library JARs in libs sub-directory of where you put your result JAR. Make sure your library JAR files do not contain space in their file name.
tasks.jar {
manifest.attributes["Main-Class"] = "com.example.MyMainClass"
manifest.attributes["Class-Path"] = configurations
.runtimeClasspath
.get()
.joinToString(separator = " ") { file ->
"libs/${file.name}"
}
}
Note that Java requires us to use relative URLs for the Class-Path attribute. So, we cannot use the absolute path of Gradle dependencies (which is also prone to being changed and not available on other systems). If you want to use absolute paths, maybe this workaround will work.
Create the JAR with the following command:
./gradlew jar
The result JAR will be created in build/libs/ directory by default.
Method 2: Embedding libraries (if any) in the result JAR (fat or uber JAR)
tasks.jar {
manifest.attributes["Main-Class"] = "com.example.MyMainClass"
val dependencies = configurations
.runtimeClasspath
.get()
.map(::zipTree) // OR .map { zipTree(it) }
from(dependencies)
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
Creating the JAR is exactly the same as the previous method.
Method 3: Using the Shadow plugin (to create a fat or uber JAR)
plugins {
id("com.github.johnrengelman.shadow") version "6.0.0"
}
// Shadow task depends on Jar task, so these will be reflected for Shadow as well
tasks.jar {
manifest.attributes["Main-Class"] = "org.example.MainKt"
}
Create the JAR with this command:
./gradlew shadowJar
See Shadow documentations for more information about configuring the plugin.
Running the created JAR
java -jar my-artifact.jar
The above solutions were tested with:
Java 17
Gradle 7.1 (which uses Kotlin 1.4.31 for .kts build scripts)
See the official Gradle documentation for creating uber (fat) JARs.
For more information about manifests, see Oracle Java Documentation: Working with Manifest files.
Note that your resource files will be included in the JAR file automatically (assuming they were placed in /src/main/resources/ directory or any custom directory set as resources root in the build file). To access a resource file in your application, use this code (note the / at the start of names):
Kotlin
val vegetables = MyClass::class.java.getResource("/vegetables.txt").readText()
// Alternative ways:
// val vegetables = object{}.javaClass.getResource("/vegetables.txt").readText()
// val vegetables = MyClass::class.java.getResourceAsStream("/vegetables.txt").reader().readText()
// val vegetables = object{}.javaClass.getResourceAsStream("/vegetables.txt").reader().readText()
Java
var stream = MyClass.class.getResource("/vegetables.txt").openStream();
// OR var stream = MyClass.class.getResourceAsStream("/vegetables.txt");
var reader = new BufferedReader(new InputStreamReader(stream));
var vegetables = reader.lines().collect(Collectors.joining("\n"));
You can use the SpringBoot plugin:
plugins {
id "org.springframework.boot" version "2.2.2.RELEASE"
}
Create the jar
gradle assemble
And then run it
java -jar build/libs/*.jar
Note: your project does NOT need to be a SpringBoot project to use this plugin.
Have you tried the 'installApp' task? Does it not create a full directory with a set of start scripts?
http://www.gradle.org/docs/current/userguide/application_plugin.html
Thank you Konstantin, it worked like a charm with few nuances. For some reason, specifying main class as part of jar manifest did not quite work and it wanted the mainClassName attribute instead. Here is a snippet from build.gradle that includes everything to make it work:
plugins {
id 'java'
id 'com.github.johnrengelman.shadow' version '1.2.2'
}
...
...
apply plugin: 'application'
apply plugin: 'com.github.johnrengelman.shadow'
...
...
mainClassName = 'com.acme.myapp.MyClassMain'
...
...
...
shadowJar {
baseName = 'myapp'
}
After running gradle shadowJar you get myapp-{version}-all.jar in your build folder which can be run as java -jar myapp-{version}-all.jar.
You can define a jar artifact in the module settings (or project structure).
Right click the module > Open module settings > Artifacts > + > JAR > from modules with dependencies.
Set the main class.
Making a jar is then as easy as clicking "Build artifact..." from the Build menu. As a bonus, you can package all the dependencies into a single jar.
Tested on IntelliJ IDEA 14 Ultimate.
I checked quite some links for the solution, finally did the below mentioned steps to get it working. I am using Gradle 2.9.
Make the following changes in your build,gradle file :
Mention plugin:
apply plugin: 'eu.appsatori.fatjar'
Provide the Buildscript:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "eu.appsatori:gradle-fatjar-plugin:0.3"
}
}
Provide the Main Class:
fatJar {
classifier 'fat'
manifest {
attributes 'Main-Class': 'my.project.core.MyMainClass'
}
exclude 'META-INF/*.DSA', 'META-INF/*.RSA', 'META-INF/*.SF'
}
Create the fatjar:
./gradlew clean fatjar
Run the fatjar from /build/libs/ :
java -jar MyFatJar.jar
Here is the solution I tried with Gradle 6.7
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.
More details : https://jafarmlp.medium.com/a-simple-java-project-with-gradle-2c323ae0e43d
Configure Main Class to your Manifest
If you are using gradle project, just add the following into your build.gradle
jar {
manifest {
attributes(
'Main-Class': 'pokerhandscorer.PokerHandScorer'
)
}
}
Where 'pokerhandscorer' is the name of the package name,
and PokerHandScorer is the main class name
This creates a jar file into your \build\libs{jarFilename}.jar
Run jar file using java -jar /{path}/{jarFileName.jar}
java -jar /{path}/{jarFileName.jar}