Getting class not found error with Gradle jar - scala

I'm new to Gradle and built a Jar build using Gradle. When I tried executing that jar using spark-submit, I'm getting a Class Not Found error. I'm able to execute the same application in IntelliJ IDEA, but getting error when executing as Independent JAR.
Below are the contents of build.gradle:
/*
* This file was generated by the Gradle 'init' task.
*/
apply plugin: 'scala'
apply plugin: 'idea'
apply plugin: 'org.sonarqube'
// Applying Sonar Qube details for gradle
apply from: "${rootProject.rootDir}/gradle/sonar.gradle"
repositories {
mavenLocal()
mavenCentral()
maven {
url = uri('https://repo1.maven.org/maven2')
}
}
dependencies {
implementation 'com.google.code.gson:gson:2.8.2'
implementation 'io.netty:netty-all:4.1.42.Final'
implementation 'com.github.jengelman.gradle.plugins:shadow:4.0.1'
testImplementation "org.scalatest:scalatest_2.11:$scalaTestVersion"
runtime "com.apple.jvm.commons:commons-metrics:0.13.1"
}
buildscript {
dependencies {
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.6'
}
}
sourceSets {
main {
scala {
srcDirs = ['src/main/scala']
}
}
test {
scala.srcDirs = ['src/test/scala']
}
}
sonarqube {
properties {
property "sonar.projectName", "App-name"
property "sonar.projectKey", "App-name"
property "sonar.sourceEncoding", "UTF-8"
property "sonar.tests", "src/test"
property "sonar.sources", "src/main"
property "sonar.scala.coverage.reportPaths", "$buildDir/reports/scoverage/scoverage.xml"
property "sonar.coverage.jacoco.xmlReportPaths", "$buildDir/jacoco/jacoco.xml"
property "sonar.test.exclusions", "src/test/**"
}
}
configurations {
jars
}
// Force Jacksom-module version to handle below error.
//com.fasterxml.jackson.databind.JsonMappingException: Scala module 2.8.8 requires Jackson Databind version >= 2.8.0 and < 2.9.0
configurations.all {
resolutionStrategy {
force "com.fasterxml.jackson.module:jackson-module-scala_2.11:2.9.5"
}
}
jar {
manifest {
attributes(
'Class-Path': configurations.compile.files.collect {"$it.name"}.join(' '),
'Main-Class': 'com.github.MainClass'
)}
from {
files(sourceSets.main.output.classesDirs)
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}{
exclude "META-INF/*.SF"
exclude "META-INF/*.DSA"
exclude "META-INF/*.RSA"
}
zip64 true
archiveClassifier = 'jar-with-dependencies'
}
/*task fatJar(type: Jar) {
//manifest.from jar.manifest
manifest {
attributes 'Main-Class': 'com.github.MainClass'
}
zip64 true
archiveClassifier = 'jar-with-dependencies'
from files(sourceSets.main.output.classesDirs)
from {
configurations.runtime.asFileTree.files.collect {zipTree(it) }
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
} {
exclude "META-INF/*.SF"
exclude "META-INF/*.DSA"
exclude "META-INF/*.RSA"
}
with jar
}
artifacts {
archives fatJar
}*/
I tried building the Jar with both ./gradlew clean build and ./gradlew clean fatJar
and executing below command:
spark-submit --master local --deploy-mode client --class com.github.MainClass /local_path/.out/libs/App-name-1.0-SNAPSHOT-jar-with-dependencies.jar
Error:
java.lang.ClassNotFoundException: com.github.MainClass
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at org.apache.spark.util.Utils$.classForName(Utils.scala:238)
at org.apache.spark.deploy.SparkSubmit.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:810)
at org.apache.spark.deploy.SparkSubmit.doRunMain$1(SparkSubmit.scala:167)
at org.apache.spark.deploy.SparkSubmit.submit(SparkSubmit.scala:195)
at org.apache.spark.deploy.SparkSubmit.doSubmit(SparkSubmit.scala:86)
at org.apache.spark.deploy.SparkSubmit$$anon$2.doSubmit(SparkSubmit.scala:924)
at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:933)
at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
2020-12-02 13:02:49 INFO ShutdownHookManager:54 - Shutdown hook called
2020-12-02 13:02:49 INFO ShutdownHookManager:54 - Deleting directory /private/var/folders/sq/npjk1mkn7lgfm57mf9g_3rrh0000gn/T/spark-8ab912b5-23ef-4182-9c70-947f2cd2831a

Related

How download jar file with pom file in gradle folder?

I add compile 'org.apache.commons:commons-vfs2-project:2.3' to my build.gradle file, but I found there is ~\.gradle\caches\modules-2\files-2.1\org.apache.commons\commons-vfs2-project\2.3\860b837e62ab6d3282e7ff96f63ea21aebcdba40\commons-vfs2-project-2.3.pom, how can I download jar file?
Here is one of the solution.
Below is the build.gradle for a sample project
I have included 2 plugins and written script to include additional scripts while building jar.
There are some eclipse generated scripts which I have not removed.
apply plugin: 'java'
/**Following plugins are needed */
apply plugin: 'maven-publish'
apply plugin: 'maven'
/**Just to include jar versioning*/
version = '1.0.0'
repositories {
jcenter()
}
dependencies {
compile 'org.slf4j:slf4j-api:1.7.25'
testCompile 'junit:junit:4.12'
}
apply plugin: 'eclipse'
eclipse {
classpath {
downloadSources = true // default: true
downloadJavadoc = true // default: false
}
}
def eclipseSourceFolders=[
'src/main/java',
'src/main/resources',
'src/test/java',
'src/test/resources'
];
tasks.eclipse.dependsOn << {
for (String sourceFolder: eclipseSourceFolders){
def resourceDir = new File(project.projectDir, sourceFolder)
if( !resourceDir.exists() && ! resourceDir.mkdirs() ) {
logger.info("Not able to create %1",resourceDir);
}
}
}
/**
Add Following scripts to placs pom.xml within jar and .pom file within libs folder*/
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
}
/** While creating jar generate and place pom.xml also place .pom file in libs folder */
jar {
into("META-INF/maven/$project.group/$project.name") {
from { generatePomFileForMavenJavaPublication }
rename ".*", "pom.xml"
}
doLast {
pom {
project {
}
}.writeTo("$buildDir/libs/$project.name-${version}.pom")
}
}

Shrinking Scala with ProGuard

to make it short: I am unable to shrink my more complex scala programs with Proguard. I think I am overlooking something, but currently I have no Idea what it could be.
My Current setup relys upon a build.gradle-file to shrink my compiled fat-jar.
import proguard.gradle.ProGuardTask
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'net.sf.proguard:proguard-gradle:5.2.1'
}
}
plugins {
id 'application'
id 'java'
id 'scala'
}
mainClassName = 'app.Main'
sourceCompatibility = 1.8
repositories {
...
}
dependencies {
...
}
jar {
manifest {
attributes(
'Class-Path': configurations.compileClasspath.files.collect {"$it.name"}.join(' '),
'Main-Class': 'app.Main'
)
}
from {
configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
task proguarding(type: ProGuardTask, dependsOn: jar) {
configuration 'proguard-rules.pro'
libraryjars files(configurations.compileClasspath.collect { it })
injars "$buildDir/libs/Main.jar"
outjars "$buildDir/libs/Shrunk.jar"
}
These are my proguard rules inside the proguard-rules.pro file
-keep class testing.** { *; }
-dontoptimize
-dontobfuscate
#-dontpreverify
#-dontnote
-ignorewarnings
-forceprocessing
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-dontwarn scala.**
-keep class !scala*.** { *; }
-dontwarn **$$anonfun$*
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-keep class ... # imagine like 5-thousend different keep-rules I tried
-keepclassmembers class * {
** MODULE$;
}
All the Programs/ Libs I tried to shrink so far didn't work after the shrinking.
Except for the most basic scala program:
package main
import java.io._
object Main extends App {
val pw = new PrintWriter(new File("hello.txt" ))
pw.write("Hello, world")
pw.close()
}
This one I could shrink from 5.5mb to 432kb, but everything else won't work and instead throws me run time errors like NullPointerExceptions or something about the stackmap.
Exception in thread "main" java.lang.VerifyError: Expecting a stackmap frame at branch target 14
Exception Details:
Location:
generator/Main$.parameters()Lscalafx/application/JFXApp$Parameters; #4: ifne
Reason:
Expected stackmap frame at this location.
Bytecode:
0x0000000: 2ab4 0010 9a00 0a2a b700 1ca7 0007 2ab4
0x0000010: 0011 b0
at generator.Main.main(Main.scala)
I found out, that these problems arose through the dontpreverify-option, but If I don't use "-dontpreverify", it won't even compile.
Without that option ProGuard is not able to find superclasses (just like this guy)
So I tried every keep-option I could find.
None of the solutions I found helped in any way. If anybody knows what's wrong, please help I am at the end of my nerves.
If somebody knows another shrinker for jar files that is actually easy to use, please tell me.
Btw, The GUI was even more confusing than the gradle plugin so, I ditched that approach
The mistake I made, was not to include the java runtime jar from the jdk
Here is the gradle with the proguarding task
import proguard.gradle.ProGuardTask
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'net.sf.proguard:proguard-gradle:6.0.3'
}
}
plugins { ... }
version '1.0'
mainClassName = 'app.Main'
sourceCompatibility = 1.8
repositories { ... }
dependencies { ... }
jar {
manifest {
attributes(
'Class-Path': configurations.compileClasspath.files.collect {"$it.name"}.join(' '),
'Main-Class': 'app.Main'
)
}
from {
configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
task proguarding(type: ProGuardTask, dependsOn: jar) {
configuration 'proguard-rules.pro'
libraryjars files(configurations.compileClasspath.collect { it })
injars "$buildDir\\libs\\" + project.name + "-" + version + ".jar"
outjars "$buildDir\\libs\\" + project.name + "-" + version + "_shrunk" + ".jar"
}
And here are the pro-guard rules inside proguard-rules.pro
-keep class app.** { *; }
#-dontoptimize
-dontobfuscate
#-dontnote
#-dontusemixedcaseclassnames
-ignorewarnings
-forceprocessing
-libraryjars C:/Program Files/Java/jdk1.8.0_181/jre/lib/rt.jar
-libraryjars C:/Program Files/Java/jdk1.8.0_181/jre/lib/ext/jfxrt.jar
Now I don't get any warnings and everything compiles just fine.

Scala shadow jar not able to find Main class

Does anyone know what is the problem. It is something with the scala version. I am trying to create a shadow jar using gradle and scala. I am continuously getting this error. My main class is exactly at this location com.pro.TempMain. I have tried different version nothing seems to work. However if I put a java class it totally works.
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: scala/Function0
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
at java.lang.Class.getMethod0(Class.java:3018)
at java.lang.Class.getMethod(Class.java:1784)
at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
Caused by: java.lang.ClassNotFoundException: scala.Function0
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 7 more
This is my gradle file configuation:
buildscript {
repositories {
mavenCentral()
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.0.1"
}
}
plugins {
id 'java'
id 'com.github.johnrengelman.shadow' version '1.2.3'
id 'com.github.maiflai.scalatest' version '0.12'
}
group 'com.pro'
version '1.0-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'scala'
apply plugin: 'com.github.johnrengelman.shadow'
apply plugin: 'idea'
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenCentral()
}
jar {
manifest {
attributes 'Main-Class': 'com.pro.TempMain'
}
}
sourceSets {
main {
scala {
srcDirs = ['src/main/scala']
}
}
test {
scala {
srcDirs = ['src/test/scala']
}
}
}
shadowJar {
zip64 true
}
dependencies {
compile 'org.scala-lang:scala-library:2.12.0'
}

Unable to import spring-boot gradle project in eclipse workspace

Gradle setup for Spring-boot application : build.gradle file i have used sourcesSet where my all java source file resides.
buildscript {
repositories {
//Required repos
mavenCentral()
maven { url "http://repo.spring.io/snapshot" }
maven { url "http://repo.spring.io/milestone" }
mavenLocal()
}
dependencies {
//Required dependency for spring-boot plugin
classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.1.2.BUILD-SNAPSHOT'
}
}
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'spring-boot'
apply plugin: 'eclipse-wtp'
bootRepackage {
mainClass = 'com.test.app.Application'
}
war {
baseName = 'companies'
version = '0.1'
}
repositories {
mavenCentral()
maven { url "http://repo.spring.io/snapshot" }
maven { url "http://repo.spring.io/milestone" }
mavenLocal()
}
dependencies {
compile 'org.springframework.boot:spring-boot-starter-web'
//Required dependency for JSP
providedRuntime 'org.apache.tomcat.embed:tomcat-embed-jasper'
}
sourceSets {
main {
java {
srcDir 'app/GeneratedSource'
srcDir 'app/JavaSource'
srcDir 'web/JavaSource'
}
resources {
srcDir 'app/GeneratedSource'
srcDir 'app/JavaSource'
srcDir 'web/JavaSource'
}
}
}
eclipse {
classpath {
defaultOutputDir = file('web/WebContent/WEB-INF/classes')
}
}
webAppDirName = 'web/WebContent'
libsDirName = 'war'
war {
baseName = baseName
version = appVersion
archiveName = warName
}
task printClasspath {
doLast {
configurations.testRuntime.each { println it }
}
enter image description hereCommand Line able to build model
When in eclipse while importing gradle project it is showing error
Iam unable to import Gradle project in Eclipse
Do you have a Gradle plugin for eclipse?
Help -> Eclipse MArketplace -> Search "Gradle" -> Install the Gradle STS integration.
In addition I recomend you change Spring Boot version to '1.3.3.RELEASE'.
buildscript {
ext {
springBootVersion = '1.3.3.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}}
In my case there was an update available for the gradle plugin. Once I updated the plugin using eclipse marketplace everything worked fine and project was imported properly.

Is it possible to extend a gradle build script configured in a binary plugin?

I've created a Gradle plugin below:
class CommandServiceProjectPlugin implements Plugin<Project> {
public void apply(Project project) {
project.buildscript{
repositories {
maven: {
url: 'http://localhost:8081/artifactory/zailab-virtual-repo'
credentials: {
username = "admin"
password = "password"
}
}
}
/*Spring Boot Gradle plugin */
dependencies {
classpath: 'org.springframework.boot:spring-boot-gradle-plugin:1.1.6.RELEASE'
}
}
project.apply plugin: 'spring-boot'
project.apply plugin: 'java'
project.apply plugin: 'eclipse'
project.repositories {
maven: {
url: 'http://localhost:8081/artifactory/zailab-virtual-repo'
}
}
project.dependencies {
/*Spring Boot dependencies */
compile: 'org.springframework.boot:spring-boot-starter-test'
compile: 'org.springframework.boot:spring-boot-starter-aop'
compile: 'org.springframework.boot:spring-boot-starter-data-mongodb'
compile: 'org.springframework.boot:spring-boot-starter-integration'
compile: 'org.springframework.boot:spring-boot-starter-amqp'
/*Axon dependencies */
compile: 'org.axonframework:axon-core:2.3.1'
compile: 'org.axonframework:axon-mongo:2.3.1'
}
}
}
I then apply the plugin within another project as below, but it seems the buildscript definitions override/conflict as the 'spring-boot' plugin cannot be found. Am I attempting the impossible or is there perhaps another way to achieve what I am trying to do?
buildscript {
repositories {
maven {
url 'http://localhost:8081/artifactory/zailab-virtual-repo'
credentials {
username = "admin"
password = "password"
}
}
}
dependencies {
classpath(group: 'com.zailab', name: 'zailab-command-service-build', version: '1.0.0- SNAPSHOT')
}
}
apply plugin: 'com.zailab.command.service.project'
Thanks,
Roscoe
As far as I know, it's not possible to add build script dependencies programmatically from a plugin.
Reason for this is build script life cycle - invocation of plugins' apply method happens after the project's classpath configuration had already been resolved.
You should either configure the buildscript in project's build script, or package classpath dependencies with the plugin.