I'm trying to set up a Gradle project with some Velocity functions in it.
So far I have the following files:
src/main/java/com/veltes/velotest.java:
package com.veltes;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import java.io.*;
public class velotest {
public static void main(String[] args) {
try {
VelocityEngine ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
ve.init();
VelocityContext context = new VelocityContext();
context.put("name", "World");
Template t = ve.getTemplate("com/veltes/velotest.vm");
StringWriter writer = new StringWriter();
t.merge(context, writer);
System.out.println(writer.toString());
File logFile = new File("C:/users/xxxx/Desktop/velotest.html");
try {
writeFile(logFile, t, context);
}
catch (IOException io) {
}
} catch (Exception e) {
}
}
private static void writeFile(File logFile, Template t, VelocityContext context) throws IOException {
Writer logWriter;
logWriter = new BufferedWriter(new FileWriter(logFile));
try {
t.merge(context, logWriter);
}
catch (ResourceNotFoundException rnfe) {
}
catch (ParseErrorException pee) {
}
catch (MethodInvocationException mie) {
}
catch (Exception e) {
}
logWriter.flush();
logWriter.close();
}
}
build.gradle:
group 'velocitytest'
version '1.0-SNAPSHOT'
apply plugin: 'groovy'
apply plugin: 'java'
sourceCompatibility = 1.5
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.3.11'
testCompile group: 'junit', name: 'junit', version: '4.11'
compile 'velocity:velocity:1.4'
}
Now, when I run gradle assemble and gradle build everything is fine, but when I try to run the project (same for running the built jar in build/libs/ and for running the velotest class in IntelliJ), I get the following error:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/collections/ExtendedProperties
at org.apache.velocity.runtime.RuntimeInstance.< init >(RuntimeInstance.java:183)
at org.apache.velocity.app.VelocityEngine.(VelocityEngine.java:60)
at com.veltes.velotest.main(velotest.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.collections.ExtendedProperties
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 8 more
It's a bit strange that there is no jar in build/tmp/
Does anyone of you knows a solution?
You need to create a runnable jar if you want to be able to run it.
You can use shadojar plugin or extend the jar task to pack the runtime deps into an artifact.
jar {
archiveName = 'Name.jar'
manifest {
attributes 'Main-Class': 'your.main.class',
'Class-Path': configurations.runtime.files.collect { "lib/$it.name" }.join(' '),
'Implementation-Version': project.version
}
from(configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }) {}
}
For intelliJ problem:
apply plugin: 'idea'
Then run gradle idea task, this will refresh .iws .ipr .iml files in your project and sync the classpaths. Or if you use intelliJ support (which is not yet ideal) try to refresh it there. I think in version 2017.1.3 the gradle integration is a bit better.
Adding
from(configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }) {} to build.gradle file fixed it for me, like this:
jar {
manifest {
attributes(
'Main-Class': 'gradle22.Library'
)
}
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}
}
Related
I have a simple program that reads a text file (test.txt) line by line and prints each line to the console. In intellij it works just fine.
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.io.File;
public class testing {
public static void main(String[] args) {
testing main= new testing();
main.handleData("test.txt");
// handleData();
//System.out.println("hello world");
}
public void handleData(String fileName) {
System.out.println("Testing");
File file= new File(getClass().getResource(fileName).getPath());
try {
Scanner scanner = new Scanner(file);
while(scanner.hasNextLine()){
System.out.println(scanner.nextLine());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
I am trying to build it with gradle and when i run the jar command java -jar out/artifacts/helloTestingWorld_jar/helloTestingWorld.jar I get an error saying the path is null
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.net.URL.getPath()" because the return value of "java.lang.Class.getResource(String)" is null
at testing.handleData(testing.java:22)
at testing.main(testing.java:12)
My build.gradle file looks like this
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
}
jar {
manifest {
attributes "Main-Class": "src.main.java.testing"
}
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
test {
useJUnitPlatform()
}
My resource folder is marked as the resource root and my java folder that contains my main class is marked as the source root. I am thinking that I might have to add the text file as a dependency in the jar file?
I have had a look at all of the other suggestions on here and the all lead to the same result. I have tried rebuilding the project from scratch and still the same result.
I have also tried using InputStream instead of File
InputStream in = getClass().getResourceAsStream(fileName);
When I use InputStream I get this error
Exception in thread "main" java.lang.NullPointerException
at java.base/java.io.Reader.<init>(Reader.java:168)
at java.base/java.io.InputStreamReader.<init>(InputStreamReader.java:76)
at java.base/java.util.Scanner.<init>(Scanner.java:566)
at testing.handleData(test.java:23)
at testing.main(test.java:10)
I am using spring-boot version 1.5.12 and gradle 5.2.1.
I have added Sentry library in my project as mentioned in its documents like below :
implementation 'io.sentry:sentry:1.7.23'
Gradle downloads the related jarFile in : \.gradle\caches\modules-2\files-2.1\io.sentry\sentry\1.7.23
and also I can see it in my IDE in External Libraries part
then I configed it in my local environment and everything worked fine and I could see my Exception reports in Sentry dashboard.
but after that when I wanted to create a version of project for my production environment, the build operation ended successfully but this new library is not in the folder(which is the result of my build operation named Distribution) which contains myPro.jar and other libraries that I use , I faced the Exception :
Exception in thread "main" java.lang.NoClassDefFoundError: io/sentry/Sentry
at ir.anarestan.ipc.boot.Boot.initSentry(Boot.java:22)
at ir.anarestan.ipc.boot.Boot.main(Boot.java:17)
Caused by: java.lang.ClassNotFoundException: io.sentry.Sentry
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 2 more
here is my build.gradle file :
group 'pc-server'
version '0.2.1-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'groovy'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
<some other dependecies>
implementation 'io.sentry:sentry:1.7.23'
}
apply plugin: 'application'
mainClassName = 'ir.anarestan.ipc.boot.Boot'
jar {
manifest {
attributes 'Main-Class': mainClassName,
'Class-Path': configurations.runtime.files.collect {"$it.name"}.join(' ')
}
}
task fatJar(type: Jar) {
manifest {
attributes 'Implementation-Title': 'Gradle Jar File PC',
'Implementation-Version': version,
'Main-Class': 'ir.anarestan.ipc.boot.Boot'
}
baseName = project.name + '-all'
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
ext.distributionDir= "${rootDir}/dist/core"
ext.mainClassName = 'ir.anarestan.ipc.boot.Boot'
jar {
manifest {
attributes("Implementation-Title": project.name,
"Implementation-Version": version,
"Main-Class": mainClassName,
"Class-Path": configurations.compile.collect { it.getName() }.join(' '))
}
destinationDir = file("$distributionDir")
}
task copyLibs(type: Copy){
from configurations.compile
into "$distributionDir"
}
task copyConfig(type: Copy){
from "$projectDir/src/main/resources/"
into "$distributionDir"
}
task distribution(dependsOn: ['copyLibs', 'copyConfig', 'jar']){
}
and I face Exception here :
#SpringBootApplication
#EnableMongoRepositories(basePackages = {"ir.anarestan.ipc.repository.mongodb"})
public class Boot {
public static void main(String[] args) {
SpringApplication.run(Boot.class, args);
Sentry.init();
}
}
any help would be appreciated, it has take me lots of time!!!
I created a small mqtt application using eclipse paho mqtt library in kotlin with Gradle in Intellij IDE. it runs fine when running it through Intellij but when I build it and run the jar file that gets created I get a NoClassDefFoundError error.
From other questions I have seen about this it looks like it has something to do with the class path but I am not sure what needs to be done if that is indeed the issue because I am using gradle and not jar files for libraries.
I was following this tutorial
Here is my gradle file
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.4.31'
id 'application'
}
group = 'me.package'
version = '1.0-SNAPSHOT'
repositories {
mavenCentral()
maven {
url "https://repo.eclipse.org/content/repositories/paho-snapshots/"
}
}
dependencies {
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5'
testImplementation 'org.jetbrains.kotlin:kotlin-test-junit'
}
test {
useJUnit()
}
compileKotlin {
kotlinOptions.jvmTarget = '1.8'
}
compileTestKotlin {
kotlinOptions.jvmTarget = '1.8'
}
application {
mainClassName = 'com.publisher.MainKt'
}
tasks.jar {
manifest {
attributes 'Main-Class': 'com.publisher.MainKt'
}
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
}
And my MainKt file
package com.publisher
import org.eclipse.paho.client.mqttv3.*
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence
import java.io.File
fun main(args: Array<String>) {
val client = MqttClient("tcp://192.168.0.55:1883","publisher", MemoryPersistence())
val connOpts = MqttConnectOptions()
connOpts.isCleanSession = false
connOpts.isAutomaticReconnect = true
client.setCallback(object: MqttCallback {
override fun connectionLost(cause: Throwable?) {
println("Connection lost")
println(cause!!.message)
}
override fun messageArrived(topic: String?, message: MqttMessage?) {
println("Message Received for topic: $topic")
println("Message: ${message!!.payload}")
}
override fun deliveryComplete(token: IMqttDeliveryToken?) {
println("Message delivered")
}
})
try{
client.connect(connOpts)
println("Connected")
client.subscribe("config/+", 1) { topic, message ->
println("Getting configuration for $message")
val path = System.getProperty("user.dir")
val file = File("$path/${message}.json")
if(file.exists()){
client.publish("/devices/ + $message + /config", MqttMessage(file.readBytes()))
}
}
}catch (e: MqttException){
println("Error: ${e.localizedMessage}")
e.printStackTrace()
}
}
The way you start your application does not include the dependencies, meaning your MQTT driver and the Kotlin dependencies are not included.
Do the following:
gradle distZip
# alternatively
gradle distTar
This will create a zip/tar file containing all the dependencies and a start script. Use that to start your application.
You could consider the Shadow plugin, as it is straightforward to use. Your build.gradle would look something like this:
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.4.31'
// Shadow plugin
id 'com.github.johnrengelman.shadow' version '6.1.0'
id 'java'
}
group = 'me.package'
version = '1.0-SNAPSHOT'
repositories {
mavenCentral()
maven {
url "https://repo.eclipse.org/content/repositories/paho-snapshots/"
}
}
dependencies {
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5'
testImplementation 'org.jetbrains.kotlin:kotlin-test-junit'
}
test {
useJUnit()
}
compileKotlin {
kotlinOptions.jvmTarget = '1.8'
}
compileTestKotlin {
kotlinOptions.jvmTarget = '1.8'
}
application {
mainClassName = 'com.publisher.MainKt'
}
tasks.jar {
manifest {
attributes 'Main-Class': 'com.publisher.MainKt'
}
}
So your fat JAR is generated in the /build/libs directory with all the dependencies included.
I have a project configured with Gradle and Kotlin. It's a command line utility and I would like to be able to run the generated jar from my terminal. However I get the following error:
Exception in thread "main" java.lang.NoClassDefFoundError: kotlin/jvm/internal/Intrinsics
at com.autentia.impt.MainKt.main(Main.kt)
Caused by: java.lang.ClassNotFoundException: kotlin.jvm.internal.Intrinsics
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)
... 1 more
My gradle configuration is as follows:
buildscript {
ext.kotlin_version = '1.2.20'
ext.junit_platform_version = '1.0.1'
ext.junit_version = '5.0.0'
ext.moshi_version = '1.5.0'
ext.jna_version = '4.5.0'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.junit.platform:junit-platform-gradle-plugin:$junit_platform_version"
}
}
version '1.0-SNAPSHOT'
apply plugin: 'kotlin'
apply plugin: 'application'
apply plugin: 'org.junit.platform.gradle.plugin'
mainClassName = 'com.autentia.impt.MainKt'
repositories {
mavenCentral()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib"
implementation "org.jetbrains.kotlin:kotlin-reflect"
implementation "com.squareup.moshi:moshi:$moshi_version"
implementation "com.squareup.moshi:moshi-kotlin:$moshi_version"
implementation "net.java.dev.jna:jna:$jna_version"
testImplementation("org.junit.jupiter:junit-jupiter-api:$junit_version")
testRuntime("org.junit.jupiter:junit-jupiter-engine:$junit_version")
}
sourceSets {
main.kotlin.srcDirs += 'src/main/kotlin'
}
task wrapper(type: Wrapper) {
gradleVersion = '4.4.1'
}
jar {
manifest {
attributes "Main-Class": mainClassName
}
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
The command I use to generate the jar is ./gradlew clean build and the command I use to run the jar is java -jar build/libs/impt-1.0-SNAPSHOT.jar.
I've tried following the official docs and also I've tried with these resources: 1, 2 and 3 without any luck.
Just change implementation configurations to compile. (At least for kotlin-stdlib)
The compile configuration is deprecated and should be replaced by implementation or api in Gradle plugin for Android, however for kotlin-gradle-plugin, I think you still need compile.
Alright I had the same problem and finally figured this out:
My main class name was Main.kt and this is what I had in my build.gradle file when I was getting the same error:
jar {
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
manifest {
attributes(
'Class-Path': configurations.compile.collect { it.getName() }.join(' '),
'Main-Class': "play.Main"
)
}
}
Although I noticed when I create the jar artifact in Intellij, it uses play.MainKt as my Main-Class name (yeah, weird naming convention), then I changed my build.gradle file to this:
jar {
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
manifest {
attributes(
'Class-Path': configurations.compile.collect { it.getName() }.join(' '),
'Main-Class': "play.MainKt"
)
}
}
and now I am not getting that error.
I'm trying to connect Velocity with Gradle builder. So I created a Gradle project in IntelliJ, put the Gradle-Velocity-Plugin into the project directory, imported the Velocity jar and created the following files:
build.gradle:
group 'xxxxx'
version '1.0-SNAPSHOT'
apply plugin: 'java'
sourceCompatibility = 1.5
repositories {
mavenCentral()
jcenter()
}
buildscript {
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath 'org.anarres.gradle:gradle-velocity-plugin:[1.0.0,)'
}
}
apply plugin: 'velocity'
jar {
manifest {
attributes 'Main-Class': 'test.HelloWorld'
}
}
HelloWorld.java:
package test;
import java.io.StringWriter;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
public class HelloWorld
{
public static void main(String[] args)
{
try {
VelocityEngine ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
ve.init();
VelocityContext context = new VelocityContext();
context.put("name", "World");
Template t = ve.getTemplate( "helloworld.vm" );
StringWriter writer = new StringWriter();
t.merge( context, writer );
System.out.println( writer.toString() );
}
catch (Exception e) {
System.out.println("failed");
}
}
}
Now, when I execute gradle tasks, everything is fine, but when I execute gradle assemble, I get errors, that the velocity packages do not exist.
Does anyone of you got an idea how to fix this?
Thank you.