Java Gradle Build: NoClassDefFoundError - java

My build.gradle file is as following
apply plugin: 'java' sourceCompatibility = 1.8
repositories {
mavenCentral() }
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile 'io.javalin:javalin:1.3.0'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.4'
compile 'org.slf4j:slf4j-simple:1.7.25' }
jar {
manifest {
attributes(
'Class-Path': configurations.runtime.files.collect {"$it.name"}.join(' '),
'Main-Class': 'products.ProductAPI'
)
} }
task stage {
dependsOn 'build'
dependsOn 'clean'
build.mustRunAfter clean }
Trying to build a java application with gradle and deploy it to a heroku server. I have some issues on java -jar build/libs/MyApp-0.0.1.jar as it returns the following:
Exception in thread "main" java.lang.NoClassDefFoundError:
io/javalin/Javalin at products.ProductAPI.main(ProductAPI.java:7)
Caused by: java.lang.ClassNotFoundException: io.javalin.Javalin at
java.net.URLClassLoader.findClass(URLClassLoader.java:381) at
java.lang.ClassLoader.loadClass(ClassLoader.java:424) at
sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338) at
java.lang.ClassLoader.loadClass(ClassLoader.java:357)

To run your app without any NoClassDefFoundError, you should have your dependencies in the runtime class path. Creating a fat jar is the simplest solution. Change your jar section like below;
jar {
manifest {
attributes(
'Class-Path': configurations.compile.files.collect {"$it.name"}.join(' '),
'Main-Class': 'products.ProductAPI')}
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}
}
run gradle build command and jar with dependencies will be created.
Other way is to add jars to runtime class path are; with java -cp flag. (Also If your application has already a classpath folder configured, copying dependencies in this folder will add them to the classpath)

Related

Can't build javafx project with gradle in intellij idea

I build my project using gradle jar command, then try to start my application using command java -jar MyProject.jar
After that I have error:
Error: Could not find or load main class org.apdalgo.Main<br>
Caused by: java.lang.NoClassDefFoundError: javafx/application/Application
My build.gardle:
plugins {
id 'java'
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.7'
}
group 'org.apdalgo'
version '1.0-SNAPSHOT'
sourceCompatibility = 11
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
}
javafx {
version = "12"
modules = [ 'javafx.controls', 'javafx.fxml' ]
}
mainClassName = 'org.apdalgo.Main'
jar {
manifest {
attributes 'Main-Class': 'org.apdalgo.Main',
'Class-Path': configurations.runtime.files.collect { "lib/$it.name" }.join(' ')
}
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
The command line need a bit more see https://openjfx.io/openjfx-docs/#install-javafx
java --module-path <PATH_TO_FX> --add-modules javafx.controls

How to run my Gradle Project as a JAR from terminal

I have a GRADLE application which has the following structure:
It has some dependencies as well (can see it from the image above)
I have built it using ./gradlew clean build
I am trying to run the following from the terminal java -jar build/libs/script-application-1.0-SNAPSHOT.jar which is throwing no main manifest attribute, in script-application-1.0-SNAPSHOT.jar
I have the following in build.gradle
plugins {
id 'java'
}
jar {
manifest {
attributes(
'Main-Class': 'Application'
)
}
}
group 'ScriptApplication'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.9.3'
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
}
Please help. How can I run the jar from terminal? The next step is to run the jar from a remote server.
Edit:
Followed the suggestion from the comment and updated my build.gradle. But I still don't understand where will the jar get generated and how will I run the jar?
plugins {
id 'java'
}
group 'ScriptApplication'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.9.3'
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
}
task fatJar(type: Jar) {
manifest {
attributes 'Main-Class': 'Application'
}
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
Had to add:
task fatJar(type: Jar) {
manifest {
attributes 'Main-Class': 'Application'
}
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
Then run gradle clean and gradle fatJar.
Then one can run the jar by:
java -jar build/libs/<application>.jar

Gradle Heroku Task 'stage'

I have a problem with deploying gradle project to heroku.
Here is my gradle.build file
plugins {
id 'java'
id 'distribution'
}
group 'com.artek.ej_bot'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
flatDir {
dirs 'libs'
}
mavenCentral()
}
dependencies {
compile files(fileTree(dir: 'libs', includes: ['*.jar']))
compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.6'
testCompile group: 'junit', name: 'junit', version: '4.12'
}
task stage {
dependsOn installDist
}
And I keep getting this error:
It looks like your project does not contain a 'stage' task, which Heroku needs in order to build your app
I run this command heroku config:set GRADLE_TASK="build" in terminal and deploy became successful
here's how I have setup the stage task for my gradle project deployed on Heroku
task stage(type: Copy, dependsOn: ['build', 'clean', 'shadowJar']) {
from 'build/libs/app-0.0.1.jar'
into project.rootDir
rename {
'app.jar'
}
}
stage.mustRunAfter(clean)

no main manifest attribute, in jar in Intellij Idea, using Gradle

Same thing works in my other project, but here I get an error :
no main manifest attribute, in jar
here's my Gradle :
group 'com.vladdrummer.txtadventureserver'
version '1.0-SNAPSHOT'
apply plugin: 'java'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile "com.sparkjava:spark-core:2.7.2"
}
Here's where manifest is :
So, it seems to be in a right place.
The manifest itself :
Manifest-Version: 1.0
Main-Class: TextAdventureServer
and the Artifact:
So, it seems to me that everything is in place, but when I build Artifact and try java -jar txtadventureserver_main.jar - it shows me error:
no main manifest attribute, in txtadventureserver_main.jar
Where did I make a mistake?

Gradle build dependancy throwing ClassNotFoundException

I am currently writing my first Gradle build script to help structure a simple Java app to be used from the command line.
Below is the full build.gradle code
apply plugin: 'java'
apply plugin: 'eclipse'
defaultTasks 'clean', 'build'
repositories {
mavenCentral()
}
jar {
baseName = 'napier-deploy'
version = '1'
manifest {attributes 'Main-Class': 'com.Main'}
}
dependencies {
compile 'org.apache.httpcomponents:fluent-hc:4.3.3'
compile 'org.apache.httpcomponents:httpclient-cache:4.3.3'
compile 'org.apache.httpcomponents:httpcore:4.1'
compile 'org.apache.httpcomponents:httpmime:4.3.3'
compile 'org.apache.httpcomponents:httpclient:4.3.3'
testCompile 'junit:junit:4.11'
testCompile 'org.mockito:mockito-all:1.9.5'
}
task wrapper(type: Wrapper) {
gradleVersion = '1.11'
}
Running the gradle assemble --info command shows the dependancies being downloaded from Maven, but when I try to launch the Jar from the commandline I get the following error:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/http/HttpEntity
at com.Main.main(Main.java:17)
Caused by: java.lang.ClassNotFoundException: org.apache.http.HttpEntity
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
... 1 more
HttpEntity is included in the httpcomponents.httpcore artefact, so I do not see why the JVM is having trouble finding the class.
Any comments are appreciated.
After some research I have used the following build script to build my Jar successfully.
apply plugin: 'java'
apply plugin: 'eclipse'
defaultTasks 'clean', 'build'
repositories {
mavenCentral()
}
jar {
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
configurations.runtime.collect {
it.isDirectory() ? it : zipTree(it)
}
}
manifest {
attributes 'Implementation-Title': 'ndeploy',
'Implementation-Version': '0.1.0',
'Built-By': System.getProperty('user.name'),
'Built-Date': new Date(),
'Built-JDK': System.getProperty('java.version'),
'Main-Class': 'com.Main'
}
}
dependencies {
compile 'org.apache.httpcomponents:fluent-hc:4.3.3'
compile 'org.apache.httpcomponents:httpclient-cache:4.3.3'
compile 'org.apache.httpcomponents:httpcore:4.1'
compile 'org.apache.httpcomponents:httpmime:4.3.3'
compile 'org.apache.httpcomponents:httpclient:4.3.3'
testCompile 'junit:junit:4.11'
testCompile 'org.mockito:mockito-all:1.9.5'
}
buildscript {
dependencies {
classpath fileTree(dir: '../../build/libs', include: '*.jar', excludes: ['*javadoc.jar', '*sources.jar'])
}
}
Comments appreciated
Since the runtime configuration also contains the compile configuration, then you can exclude a snippet of code which collecting compile config from the example above.

Categories