I am pretty new to using Gradle. I am using Gradle-7.5.1. I just want a jar file created using Gradle that contains just the manifest file and the source files I wrote but why does the created jar contain a million other things in it?
My gradle.build file is as follows:
apply plugin: 'java'
apply plugin: 'application'
version = '1.0'
sourceSets {
main {
java {
srcDirs = ['src']
}
}
}
task fatJar(type: Jar) {
manifest {
attributes 'Manifest-Version': version,
'Class-Path': configurations.runtimeClasspath.files.collect { it.getName() }.join(' ')
}
baseName = 'MyProj'
from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
repositories {
mavenCentral()
}
dependencies {
implementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25' < etc >
}
What I want in the MyProj-1.0 is:
META-INF (holding the Manifest.MF)
com (holding my src files)
What I get in the jar is:
assets
style
corejava
javax
..and a lot more such things
Thanks in advance for any pointers. As I have banged my head to the point of snapping it!
Related
I've seen many people with "Could not find or load main class" errors when making jar files with Gradle. I have gone through many of the forums and have not found a solution that works for me yet. Following an online tutorial, I was able to set up a Gradle project in VSCode and add dependencies for a basic hello world program. Link to the tutorial I was following here: https://www.youtube.com/watch?v=BwdkyrnJQsg
This worked for me no problem but when I finished my much larger program, it doesn't find my Main.class file. Here's my build.gradle file:
plugins {
id 'java'
id 'java-library'
id 'application'
}
application
{
mainClass = 'Main'
}
java
{
sourceCompatibility = JavaVersion.VERSION_12
targetCompatibility = JavaVersion.VERSION_12
}
project.configurations.implementation.setCanBeResolved(true);
version = '1.0.0'
mainClassName = 'Main'
sourceSets
{
main
{
java
{
srcDirs 'src/main/java'
}
}
}
repositories
{
mavenCentral()
maven
{
url = 'https://licensespring-maven.s3.eu-central-1.amazonaws.com/'
}
}
dependencies
{
implementation 'com.licensespring:licensespring-license-client:2.1.0'
// https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java
implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '4.0.0-alpha-6'
// https://mvnrepository.com/artifact/net.harawata/appdirs
implementation group: 'net.harawata', name: 'appdirs', version: '1.2.0'
// https://mvnrepository.com/artifact/net.java.dev.jna/jna-platform
implementation group: 'net.java.dev.jna', name: 'jna-platform', version: '5.6.0'
// https://mvnrepository.com/artifact/net.java.dev.jna/jna
implementation group: 'net.java.dev.jna', name: 'jna', version: '5.6.0'
// https://mvnrepository.com/artifact/org.slf4j/slf4j-api
implementation group: 'org.slf4j', name: 'slf4j-api', version: '2.0.0-alpha1'
// https://mvnrepository.com/artifact/commons-io/commons-io
implementation group: 'commons-io', name: 'commons-io', version: '2.7'
}
jar
{
manifest
{
attributes(
"Main-Class": "$mainClassName",
"Class-Path": configurations.implementation.collect {it.name}.join(' ')
)
}
dependsOn('dependencies')
from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
}
In src/main/java/ I have my Main.java file with the main method along with all my other .java files. When I run gradlew clean build, my .class files show up under build/classes/java/main.
Just to clarify, when I run java -jar './build/libs/myApplication.jar' I get the Could not find or load main class Main error. Let me know if you need any more specifics.
UPDATE: Switched over to Intellij again and I am getting errors involving the Main Manifest Attribute. I checked the outputted jar and the Manifest file is indeed packaged and it does have a Main Manifest Attribute. PLEASE HELP ME SOMEONE!
Can you try giving source set and full package name for main?
It should look something like this:
sourceSets {
main {
java {
srcDirs 'src/main/java'
}
}
}
project.configurations.implementation.setCanBeResolved(true)
jar{
manifest {
attributes(
"Main-Class": "com.xyz.Main",
"Class-Path": configurations.implementation.collect { it.name }.join(' ')
)
}
dependsOn ('dependencies')
}
I had similar issue to create runnable jar. I could solve it with following example
Solution 1 : Create a fat jar with all dependencies.
task fatJar(type: Jar) {
manifest {attributes 'Main-Class': 'com.example.gradle.App'}
from {
configurations.compile.collect
{ it.isDirectory() ? it : zipTree(it) }
}with jar
}
Solution 2 : Create a runnable jar with dependencies copied to a directory and setting the class path
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
}
Read more on this with an example here
I am looking for javafx 10 or newer. I currently have javafx-sdk-11 and trying to make my programme a single runnable jar file, but apparently since javafx 11, that option isn't available anymore.
So I have to go to the terminal and type the following line to run it :
java --module-path /path/to/javafx/javafx-sdk-11.0.2 or another/lib --add-modules javafx.controls,javafx.fxml,javafx.graphics,javafx.web -jar /path/to/GUI_Music_Gen.jar
Since I can't find older versions of javafx available for download, I ask for your help. If anybody can help me, let me know. Thanks in advance.
Btw, I don't know if this will be an issue for compatibility, but I run macOS X.
I would recommend using dependency management like grade or maven to run JavaFX and Build a working Jar.
I can offer you this build.gradle for a working JavaFX project:
buildscript {
dependencies {
classpath group: 'de.dynamicfiles.projects.gradle.plugins', name: 'javafx-gradle-plugin', version: '8.7.0'
classpath 'org.openjfx:javafx:11'
}
repositories {
mavenLocal()
mavenCentral()
maven {
url "https://plugins.gradle.org/m2/"
}
}
}
plugins {
id 'java'
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.8'
}
sourceCompatibility = 11
targetCompatibility = 11
repositories {
jcenter()
mavenCentral()
}
// configure here
mainClassName = "your.app.main"
publishing {
publications {
mavenAar(MavenPublication) {
from components.java
afterEvaluate {
artifact javadocJar
artifact sourcesJar
}
}
}
}
javafx {
version = "11"
modules = ['javafx.controls', 'javafx.fxml', 'javafx.graphics']
}
sourceSets {
main.java.srcDir "src/main/java"
main.resources.srcDir "src/main/resources"
}
dependencies {
api 'org.apache.commons:commons-math3:3.6.1'
implementation 'com.google.guava:guava:27.0.1-jre'
testImplementation 'junit:junit:4.12'
// use java fx just like a regular dependency :)
implementation 'org.openjfx:javafx:11'
compile group: 'org.openjfx', name: 'javafx', version: '11.0.2'
}
// important Configure your project
jar {
manifest {
attributes(
'Main-Class': 'your.app.main'
)
}
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
compileJava {
doFirst {
options.compilerArgs = [
'--module-path', classpath.asPath,
'--add-modules', 'javafx.controls,javafx.fxml,javafx.graphics'
]
println options.compilerArgs
}
}
Just replace "your.project.main" with your actual main class and everything should run fine.
Also it is really important that your Main class does not extend from Application.
It should only Launch the Application.
I need to use browsermob-proxy.
My project can be run from IDE, but when I build it by gradle and add compile 'net.lightbody.bmp:browsermob-core:2.1.4' into my gradle config file the jar is successfully built (there are no any errors), but the main function is not loaded:
#gradle clean jar
#java -jar build/proxy-0.1.jar
"Error: Could not find or load main class myproject.MainKt"
If I add this utility to my existed package (that could be built and run as a fat jar) it can not be built.
What am I doing wrong?
Is it possible that it is bug in browsermob-proxy?
Thanks.
My gradle file is the following:
group 'proxy'
version '0.1'
buildscript {
ext.kotlin_version = '1.1.3'
repositories {
mavenCentral()
}
dependencies {
classpath group: 'org.jetbrains.kotlin', name: 'kotlin-gradle-plugin', version: kotlin_version
classpath 'org.junit.platform:junit-platform-gradle-plugin:1.0.0-M6'
}
}
apply plugin: 'kotlin'
apply plugin: 'java'
apply plugin: 'org.junit.platform.gradle.plugin'
repositories {
mavenCentral()
jcenter()
maven { url 'https://jitpack.io' }
}
dependencies {
compile 'org.jetbrains.kotlin:kotlin-stdlib-jre8'
compile 'org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version'
compile 'net.lightbody.bmp:browsermob-core:2.1.4'
testCompile("org.junit.jupiter:junit-jupiter-api:5.0.0-M6")
testCompile("org.junit.jupiter:junit-jupiter-params:5.0.0-M6")
testRuntime("org.junit.jupiter:junit-jupiter-engine:5.0.0-M6")
}
jar {
destinationDir = file('build/')
manifest {
attributes 'Main-Class': 'myproject.MainKt'
}
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
After much research, I can't seem to get to the root of a problem I am having in generating a runnable Scala jar file using Gradle. I'm overriding the 'jar' Gradle task to create a jar file (dependencies included) that executes starting from my main class file. However, whenever I run it, regardless of what I use for a Main-Class attribute, the console throws a "Could not find or load main class" error. Here's what I have so far:
build.gradle
buildscript {
repositories {
mavenCentral()
}
}
apply plugin: 'java'
apply plugin: 'scala'
apply plugin: 'application'
repositories {
mavenCentral()
// some other repos
}
version = '1.0'
sourceCompatibility = 1.8
targetCompatibility = 1.8
mainClassName = "com.test.Main"
dependencies {
// my dependencies
}
jar {
zip64 = true
manifest {
attributes "Main-Class": "$mainClassName"
}
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}
}
src/main/scala/com/test/Main.scala
package com.test
object Main {
def main(args: Array[String]): Unit = {
print("Hello world");
}
}
In fact, when I run "java tf test.jar", it shows "com/test/Main.class" in the root of the jar! Am I missing some important class path info or something? I'm running Java 1.8 on macOS Sierra using Gradle 3.5. Any help is appreciated. Thanks!
I had a similar problem and it turns out that my META-INF folder inside my jar file contains a few RSA, SF, and DSA files.
Once I excluded them, it worked!
here is how to based on your jar declaration
jar {
zip64 = true
manifest {
attributes "Main-Class": "$mainClassName"
}
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it)
}
exclude ('META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA')
}
You can use the Shadow Jar Plugin instead of your own jar definition.
Benefits of Shadow
Shadowing a project output has 2 major use cases:
Creating an executable JAR distribution
Bundling and relocating common dependencies in libraries to avoid classpath conflicts
Basic setup:
shadowJar {
baseName = 'your-app'
classifier = 'all'
version = version
configurations = [project.configurations.compile]
}
jar {
manifest {
attributes 'Main-Class': 'com.test.Main'
}
}
You can use the new syntax of Gradle Plugins:
plugins {
id 'java'
id 'scala'
id 'application'
}
We are having an issue with a war built from gradle failing to load in tomcat because of a Security Exception specific to a signed Jar. The stack trace is not showing what jar is causing the problem and to get this thing running I'm wondering if I can exclude the signatures in the build when the war is getting built but don't know how to do that with Gradle. In maven I believe it would be a <filter><exclude> tag but not sure if this type of thing is available in Gradle. Any input would be appreciated, the Exception being thrown is below.
Caused by: java.lang.SecurityException: Invalid signature file digest for
To find out if a jar file is signed, you can unzip the jar file using any zip utility tool. If the jar is signed it will contain files like *.RSA, *.SF or *.DSA under META-INF folder.
To exclude these signature files in gradle build , I did the following in my build.gradle. If you are using any other plugin to create the jar than you should check that plugins documentation for more details.
jar {
from { (configurations.runtime).collect { it.isDirectory() ? it : zipTree(it) } } {
exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA'
}
manifest {
attributes("Main-Class": "com.nk.social.shareit.streams.AppMain")
}}
My entire build.gradle file is as listed below:-
apply plugin: 'scala'
dependencies {
compile group: 'org.apache.kafka', name: 'kafka-streams', version: '0.11.0.1'
compile 'org.scala-lang:scala-library:2.12.2'
compile 'com.sksamuel.elastic4s:elastic4s-core_2.12:5.4.2'
compile 'com.sksamuel.elastic4s:elastic4s-http_2.12:5.4.2'
compile 'org.apache.lucene:lucene-core:6.5.1'
compile 'joda-time:joda-time:2.9.9'
testCompile group: 'org.scalatest', name: 'scalatest_2.12', version: '3.0.4'
}
jar {
from { (configurations.runtime).collect { it.isDirectory() ? it : zipTree(it) } } {
exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA'
}
manifest {
attributes("Main-Class": "com.nk.social.shareit.streams.AppMain")
}
}
Hope this helps.
With the jar, for example given in this thread I have a problem building a fat jar.
The main motivation is that the build process will skip also some dependecens.
A solution found is the following one, it contains only a small change
jar {
manifest {
attributes(
'Class-Path': configurations.compile.collect { it.getName() }.join(' '),
'Main-Class': 'io.vincenzopalazzo.lightning.App'
)
}
from(configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }) {
exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA'
}
}