Scala gradle console app with java libararies - scala

I have Scala console app that uses a java library. I am new to both Gradle and Scala. I am not using any IDE, just VS Code and Gradle.
I can build the app using Gradle, but when trying to run I get an exception, class not found.
$ gradle run
Exception in thread "main" java.lang.NoClassDefFoundError: scala/Product$class
at scopt.Head$.<init>(options.scala:148)
at scopt.Head$.<clinit>(options.scala)
at scopt.OptionParser.head(options.scala:251)
at console.App$$anon$1.<init>(App.scala:20)
at console.App$.main(App.scala:19)
at console.App.main(App.scala)
Caused by: java.lang.ClassNotFoundException: scala.Product$class
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 6 more
I am guessing that jar files are not getting copied into the build/distribution or build/libs folder.
The build file looks like:
plugins {
// Apply the scala plugin to add support for Scala
id 'scala'
id 'application'
id 'distribution'
}
repositories {
// Use jcenter for resolving your dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
maven {
url 'https://plugins.gradle.org/m2/'
}
}
dependencies {
implementation 'org.scala-lang:scala-library:2.12.7'
implementation 'org.mongodb.scala:mongo-scala-bson_2.12:2.5.0'
implementation 'org.apache.poi:poi:4.0.1'
implementation 'org.apache.logging.log4j:log4j-core:2.11.1'
implementation 'org.apache.logging.log4j:log4j-api:2.11.1'
implementation 'org.slf4j:slf4j-nop:1.7.25'
implementation 'org.apache.poi:poi-ooxml:4.0.1'
implementation group: 'com.github.scopt', name: 'scopt_2.11', version: '3.7.1'
implementation group: 'com.google.guava', name: 'guava', version: '27.0.1-jre'
implementation group: 'org.apache.logging.log4j', name: 'log4j-api-scala_2.12', version: '11.0'
implementation 'com.github.pcj:google-options:1.0.0'
// Use Scalatest for testing our library
testImplementation 'junit:junit:4.12'
testImplementation 'org.scalatest:scalatest_2.12:3.0.5'
// Need scala-xml at test runtime
testRuntimeOnly 'org.scala-lang.modules:scala-xml_2.12:1.1.1'
}
group = 'matches'
version = '1.0'
description = 'matches'
sourceCompatibility = '11'
mainClassName = 'console.App'
application {
mainClassName = "console.App"
}
I am not sure what I need to add to the build.

You are mixing libraries os scala 2.11 and scala 2.12. Change scopt to
implementation group: 'com.github.scopt', name: 'scopt_2.12', version: '3.7.1'

Related

How do I run a scala application using gradle?

I added the scala plugin to gradle, but i don't how to run it. There's no run task when i create a scala project.
How do I run the scala project?
My gradle build script:
apply plugin: 'idea'
apply plugin: 'scala'
repositories {
mavenLocal()
maven {
url "http://maven.aliyun.com/nexus/content/groups/public/"
}
mavenCentral()
}
dependencies {
compile group: 'org.scala-lang', name: 'scala-library', version: '2.13.1'
}
You need to provide the classpath as well. Change run task declaration to:
task run(type: JavaExec, dependsOn: classes) {
main = 'Demo'
classpath = sourceSets.main.runtimeClasspath
}
And it will work fine. Demo.

Eclipse is not using gradle dependencies jar during run or debug

I am trying to do basic hibernate task using Gradle project.
Dependency jars are download by Gradle and placed in Project and External Dependencies library.
I don't get any compile time error. But when I try to run or debug the main class in Eclipse, I am getting class not found NoClassDefFoundError.
Exception in thread "main" java.lang.NoClassDefFoundError: org/hibernate/cfg/Configuration
When I checked the build path, I could see the dependency library is configured with required jars but still eclipse is not using it.
But when I add the jar manually in the build path, I am not getting this exception.
Build.gradle File
plugins {
// Apply the java-library plugin to add support for Java Library
id 'java-library'
}
apply plugin: "eclipse"
dependencies {
// This dependency is exported to consumers, that is to say found on their compile classpath.
api 'org.apache.commons:commons-math3:3.6.1'
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation 'com.google.guava:guava:23.0'
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
// https://mvnrepository.com/artifact/org.hibernate/hibernate-core
compile group: 'org.hibernate', name: 'hibernate-core', version: '5.3.6.Final'
// https://mvnrepository.com/artifact/com.oracle.jdbc/ojdbc6
runtime group: 'com.oracle.jdbc', name: 'ojdbc6', version: '11.1.0.6.0'
// https://mvnrepository.com/artifact/com.oracle/ojdbc6
runtime group: 'com.oracle', name: 'ojdbc6', version: '11.2.0.4.0-atlassian-hosted'
}
// In this section you declare where to find the dependencies of your project
repositories {
// Use jcenter for resolving your dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
mavenCentral()
}
Thanks in advance!!!
I think you should update the classpath with the latest changes in the build file. Eclipse does not do that automatically in all versions.
Go to package explorer, right-click the build.gradle file, then from the context menu select gradle->refresh gradle project.
You can also enable auto sync from the preferences menus, go to gradle, and check the "Automatic Project Synchronization" checkbox.
Remove/comment this dependency and try.
runtime group: 'com.oracle.jdbc', name: 'ojdbc6', version: '11.1.0.6.0'
My Build.gradle:
plugins {
// Apply the java-library plugin to add support for Java Library
id 'java-library'
}
dependencies {
// This dependency is exported to consumers, that is to say found on their compile classpath.
api 'org.apache.commons:commons-math3:3.6.1'
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation 'com.google.guava:guava:23.0'
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
// https://mvnrepository.com/artifact/org.hibernate/hibernate-core
compile group: 'org.hibernate', name: 'hibernate-core', version: '5.3.6.Final'
// https://mvnrepository.com/artifact/com.oracle.jdbc/ojdbc6
// runtime group: 'com.oracle.jdbc', name: 'ojdbc6', version: '11.1.0.6.0'
// https://mvnrepository.com/artifact/com.oracle/ojdbc6
runtime group: 'com.oracle', name: 'ojdbc6', version: '11.2.0.4.0-atlassian-hosted'
}
// In this section you declare where to find the dependencies of your project
repositories {
// Use jcenter for resolving your dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
}
With the eclipse plugin, there are different build tasks being added:
./gradlew cleanEclipse eclipse

Gradle: Setting up Scala project with Apache Spark in Eclipse

I am not able to setup a Scala project with Apache Spark dependency in Eclipse. Using a Scala IDE plugin and Gradle plugins in Eclipse. build.gradle project looks like this:
apply plugin: 'scala'
apply plugin: 'eclipse'
repositories{
mavenCentral()
mavenLocal()
}
dependencies{
compile 'org.slf4j:slf4j-api:1.7.5'
compile "org.scala-lang:scala-library:2.11.2"
compile 'com.sparkjava:spark-core:2.3'
testCompile "junit:junit:4.11"
}
task run(type: JavaExec, dependsOn: classes) {
main = 'Main'
classpath sourceSets.main.runtimeClasspath
classpath configurations.runtime
}
Under the Referenced Libraries I can see spark-core-2.3.jar. But I can't import any Spark library into Scala class.
I did try running gradle eclipse command but no luck.
You're referencing the wrong dependency - instead of com.sparkjava:spark-core:2.3 (which belongs to another project, Spark web framework), you should include:
compile 'org.apache.spark:spark-core_2.11:2.0.1'
This uses latest stable version (2.0.1).

Add sigar library to build.gradle in java project

I am using Sigar library to find system level resource usage in my java application. I added Sigar to my build.gradle (as suggested at http://mvnrepository.com/artifact/org.fusesource/sigar/1.6.4) as shown below:
// Apply the java plugin to add support for Java
apply plugin: 'java'
// In this section you declare where to find the dependencies of your project
repositories {
// Use 'jcenter' for resolving your dependencies.
// You can declare any Maven/Ivy/file repository here.
maven {
url "https://plugins.gradle.org/m2/"
}
jcenter()
mavenCentral()
}
// In this section you declare the dependencies for your production and test code
dependencies {
// The production code uses the SLF4J logging API at compile time
compile 'org.fusesource:sigar:1.6.4'
// 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.12'
}
When I try to run my project I get following error:
Exception in thread "main" java.lang.UnsatisfiedLinkError: org.hyperic.sigar.Mem.gather(Lorg/hyperic/sigar/Sigar;)V
at org.hyperic.sigar.Mem.gather(Native Method)
at org.hyperic.sigar.Mem.fetch(Mem.java:30)
at org.hyperic.sigar.Sigar.getMem(Sigar.java:304)
at SystemResources.SystemMemory.getSystemMemory(SystemMemory.java:37)
at SystemResources.SystemResources.getSystemResources(SystemResources.java:25)
at Test.Driver.main(Driver.java:31)
After searching on Stackoverflow and other places, I know there are .dll and .so files whose path has to be modified. But when I add my library using gradle I am not able to change the path of my native library (in Properties->Java Build path->Library-> -> Native Library Path). Also i tried using
-Djava.library.path="./sigar-bin/lib" ${build_files}
and
-Djava.library.path="./lib" ${build_files}
in my environment variable in run configuration but it doesn't help.
I need to use gradle file to import sigar and that works perfectly. But how do I reference those .dll and .so files for my project to work?
After #Brian's comments this is what I am trying for build.gradle:
// Apply the java plugin to add support for Java
apply plugin: 'java'
apply plugin: 'eclipse'
// In this section you declare where to find the dependencies of your project
repositories {
// Use 'jcenter' for resolving your dependencies.
// You can declare any Maven/Ivy/file repository here.
maven {
url "https://plugins.gradle.org/m2/"
}
jcenter()
mavenCentral()
}
//Setting extra information for the project in key value pair
//Key - nativeLibsDir, Value - $buildDir/libs/natives
project.ext.set('nativeLibsDir', "${buildDir}/libs/natives")
configurations {
nativeBundle
}
// In this section you declare the dependencies for your production and test code
dependencies {
// The production code uses the SLF4J logging API at compile time
compile 'org.slf4j:slf4j-api:1.7.13'
compile 'org.fusesource:sigar:1.6.4'
runtime 'org.fusesource:sigar:1.6.4'
nativeBundle 'org.fusesource:sigar:1.6.4:native'
// 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.12'
}
jar {
manifest {
attributes 'Main-Class': 'Test.Driver'
}
//baseName = project.name + '-all'
//from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
//with jar
}
task extractNativeBundle(type: Sync) {
from {
configurations.nativeBundle.collect { zipTree(it) }
}
into file(project.nativeLibsDir)
}
test {
dependsOn extractNativeBundle
systemProperty "java.library.path", project.nativeLibsDir
}
Even after this I get following error:
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: org/hyperic/sigar/SigarException
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: org.hyperic.sigar.SigarException
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)
... 7 more

Running a jar produce from gradle build

I have a simple gradle file from which I build a jar file.
When I run the jar file however I get and error: 'Exception in thread "main" java.lang.NoClassDefFoundError: scala/Predef$'
The build.gradle looks like this:
apply plugin: 'scala'
apply plugin: 'distribution'
def mainClass = "com.domain.Hello"
distributions {
custom {}
}
repositories {
mavenCentral()
}
dependencies {
compile group: 'org.scala-lang', name: 'scala-library', version: '2.11.4'
}
jar {
manifest {
attributes 'Main-Class': mainClass
}
}
task run(type: JavaExec, description: "Runs the project") {
main = mainClass
classpath sourceSets.main.runtimeClasspath
classpath configurations.runtime
}
When you run the jar you need to include the scala-library on the classpath, like this
scala -cp [scala library jar] [project jar]
If you don't want to have to do this, take a look at this blog post http://blogs.steeplesoft.com/posts/2013/09/04/building-fat-jars-with-gradle/
You need to include ''scala-compile' package beside 'scala-library'