Fat JAR with Kotlin and Apache Spark 2.3 - apache-spark

Im using gradle to build my project mixing Kotlin and Apache Spark, but as soon I declare the spark dependency, the Fat JAR I generate gets non working. Otherwise it will work. The source code not even import anything from Spark
buildscript {
ext.kotlin_version = '1.2.40'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'kotlin'
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
// uncomment this line to get main class 'myownpkg.SparkApplicationKt'
// not found error
// compile 'org.apache.spark:spark-core_2.11:2.3.0'
}
jar {
manifest { attributes 'Main-Class': 'myownpkg.SparkApplicationKt' }
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}

After some experimentation I realized the generated JAR was having there a lot of duplicated files, causing that runtime not finding the .class required.
It was triggered after enable the Spark because it is the dependency causing snowball of other dependencies having the same file paths under META-INF folder
exclude 'META-INF/*'
That line made the trick to avoid duplicates but still wil have a META-INF folder in final JAR

The main reason is because you aren't creating the "FatJar" artifact with necessary dependencies. The compile dir in configuration only contain compiled source code.
From the maven central you need at least the 50 compile dependencies that spark-core require. Have you consider using the shadow plugin ?
Take a look at this thread on gradle discuss.

Related

Android Studio - Too many libraries imported to project eventhough they are not compiled in dependencies

I am creating a new Android application that using Firebase. I followed goolge guide to add Firebase SDK to my project.
below are my project gradle:
buildscript {
repositories {
jcenter(){
url "http://jcenter.bintray.com/"
}
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.0'
classpath 'com.google.gms:google-services:3.0.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
And application build.gradle
....
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
/* For Google Play Services */
//Firebase
//addd firebase notification - messaging.
//add firbaes dynamic link:
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:design:23.4.0'
compile 'com.android.support:support-v4:23.4.0'
compile 'com.android.support:cardview-v7:23.4.0'
compile 'com.google.android.gms:play-services-safetynet:9.0.2'
compile 'com.google.android.gms:play-services-auth:9.0.2'
compile 'com.firebaseui:firebase-ui:0.2.2'
compile 'com.google.firebase:firebase-messaging:9.0.2'
compile 'com.google.firebase:firebase-invites:9.0.2'
compile 'com.google.android.gms:play-services:9.0.2'
}
// ADD THIS AT THE BOTTOM
apply plugin: 'com.google.gms.google-services'
I checked in External library of my project. There are too many library that I don't not need such as: play-service-location-9.0.2, play-service-maps-9.0.2, play-service--nearby-9.0.2...
enter image description here
Could you explain and help me reduce unused library that I don't added into my project ?
Try removing the dependencies you don't need by deleting the dependency from the build.gradle one by one, if you get an error after removing one of your dependencies, add the dependency you just removed back.
As long as you get no errors or problems when removing the dependencies you don't need, everything will be fine.

error: package org.hamcrest does not exist Android Studio 1.5.1

I am using Android studio 1.5.1.
My build.gradle looks like below
allprojects {
repositories {
maven { url 'http://repo1.maven.org/maven2' }
}
}
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.5.0'
}
}
apply plugin: 'com.android.application'
dependencies {
// Unit testing dependencies
testCompile 'org.hamcrest:hamcrest-library:1.3'
testCompile 'junit:junit:4.12'
}
I am writing some JUNIT test cases for my application as below
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
public void testSomething throws Exception {
...
assertThat(result, is(true));
}
But when I am running the tests, it is showing that
error: package org.hamcrest does not exist
error: cannot find symbol assertThat(result, is(true));
But I can go to the definition of assertThat, org.hamcrest etc from studio by going to definition as studio decompiles the jars.
Also I can see the package downloaded in .gradle/caches
Can anyone suggest what I am doing wrong here?
Normally Junit test cases using assertFalse, assertTrue etc is working, only hamcrest matching is giving errors.
Manually add the jar from here
Add it to your libs folder.
Right click the jar, and click add as library.
I had the same issue with getting it to find junit. Looks like Gradle is not doing its job.
I have filed a bug report, Please star:
https://code.google.com/p/android/issues/detail?id=209832&thanks=209832&ts=1463161330

Gradle - How to add war as dependency in simple java project

I have a war file which have classes which needs to be used in my Java project. How can I add war file as dependency in this Java project? Gradle pick jar file but no war file. Is there a way to add war as dependency.
build.gradle
group 'com.asklytics'
version 'unspecified'
apply plugin: 'java'
sourceCompatibility = 1.5
repositories {
mavenCentral()
maven { url "../$localMavenRepoRoot/local-maven-repo" }
}
dependencies {
compile group: 'com.asklytics', name: 'asklytics-mailer', version: '1.0-SNAPSHOT', changing: true
testCompile group: 'junit', name: 'junit', version: '4.11'
}
A war structure is different from a jar structure. You can make gradle pick up a file named something.war as a dependency using #war in the dependency identifier, but you'll likely not be able to use the classes that live in the war.
Probably the best way to do this is to make the project that produces the war, also publish a jar file, which you can then use as a dependency.

including dependency in gradle

I want to include 'org.scribe:scribe:1.3.2' dependency into my gradle project, I have added the following line to my build.gradle file
apply plugin: 'groovy'
repositories {
mavenCentral()
}
dependencies {
runtime 'org.scribe:scribe:1.3.2'
compile 'org.codehaus.groovy:groovy-all:2.2.0'
}
task fbTask << {
MyTask mT = new MyTask()
mT.loginUsingFacebook();
}
Now inside MyTask.groovy
import org.scribe.model.Token
public void loginUsingFacebook() {
Token accessToken = //some code
}
It didn't find the import, which shows that the scribe dependency we specified in build.gradle didn't worked.
So, how to import this scribe dependency into the application , so that i can use it in my Task class.
There are some misconceptions here:
Dependencies declared in the project.dependencies block are for code produced by the build, not for code used by the build.
Gradle tasks cannot be instantiated with new.
How to add a dependency used by the build itself (typically by a build script, task class, or plugin class) depends on where you put the corresponding code. In the simplest case, the task class is declared right in the build script, and its dependencies go into a buildscript block:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "org.scribe:scribe:1.3.2"
}
}
To learn more about these topics, check out the Gradle User Guide, and the samples in the full Gradle distribution.
If you want to add something to classpath of buildscript(build.gradle) and not the project source, then add it to buildScript closure.
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.scribe:scribe:1.3.2'
}
}
Reference : In Gradle documentation's Organizing Build Logic chapter, see the section External dependencies for the build script

Access to variables in root gradle build.gradle from subproject build.gradle?

I have a root build.gradle that contains some variables I want to have as global variables for some subprojects but not all sub projects
I created a list:
List spring_dependencies = [
"org.springframework:spring-beans:$springVersion",
"org.springframework:spring-core:$springVersion",
"org.springframework:spring-web:$springVersion",
]
I have some suprojects that do NOT use this for compilation, so I want to only add:
compile spring_dependencies
to the projects that actually need spring.
How can I accomplish this global variable sharing in gradle?
One method I have just tried (and it seems to work) is to declare another sub-project (I called it 'spring'), which has the following build.gradle:
apply plugin: 'java'
repositories {
mavenCentral()
}
dependencies {
compile "org.springframework:spring-beans:$springVersion"
compile "org.springframework:spring-core:$springVersion"
compile "org.springframework:spring-web:$springVersion"
}
Add this project in to the settings.gradle list of sub-projects, then in the build.gradle that requires the spring libraries, you can do:
apply plugin: 'java'
repositories {
mavenCentral()
}
dependencies {
compile project(':spring')
}
To extract the dependencies from your spring sub-project.
There might be a better way to achieve the same result... :-/

Resources