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

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.

Related

Fat JAR with Kotlin and Apache Spark 2.3

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.

How to solve NoMethodError that arises due to using a same library with two different versions using gradle or anything else?

I have two dependencies that use a same library but with different versions and I get NoMethodError. I am not sure how to solve it using gradle or anything else? Any help would be great
group 'com.hello'
version '1.0-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'idea'
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
compile 'org.slf4j:slf4j-log4j12:1.7.12'
compile group: 'org.apache.spark', name: 'spark-core_2.11', version: '2.0.1'
compile group: 'org.apache.spark', name: 'spark-streaming_2.11', version: '2.0.1'
compile group: 'org.apache.spark', name: 'spark-streaming-kafka-0-10_2.11', version: '2.0.1'
compile group:'org.apache.kafka', name: 'kafka-clients', version: '0.10.1.0'
compile group: 'com.datastax.spark', name: 'spark-cassandra-connector_2.11', version: '2.0.0-M3'
compile group: 'com.github.brainlag', name: 'nsq-client', version: '1.0.0.RC2'
compile group: 'com.google.code.gson', name: 'gson', version: '2.7'
}
task buildStreamingJar(type: Jar) {
if(project.hasProperty("jarname")) {
def fullyQualifiedPackageName = ""
def jarname = project.getProperty("jarname")
if (jarname.equalsIgnoreCase("SparkDriver1")) {
fullyQualifiedPackageName = "com.hello.streamprocessing.app.SparkDriver1"
}
if (jarname.equalsIgnoreCase("SparkDriver2")) {
fullyQualifiedPackageName = "com.hello.streamprocessing.app.SparkDriver2"
}
baseName = project.name + "-$jarname" + "-stream"
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
zip64 true
from sourceSets.test.output
manifest {
attributes 'Main-Class': fullyQualifiedPackageName
}
exclude 'META-INF/.RSA', 'META-INF/.SF', 'META-INF/*.DSA'
}
}
so what is happening here is that in my dependencies spark-core_2.11 uses
com.google.guava:14.0.1 and nsq-client uses com.google.guava:19.0
which is leading to the following error.
Exception in thread "main" java.lang.NoSuchMethodError: com.google.common.collect.Sets.newConcurrentHashSet()Ljava/util/Set;
at com.github.brainlag.nsq.NSQProducer.(NSQProducer.java:22)
at com.hello.streamprocessing.app.SparkDriver2.main(SparkDriver2.java:37)
I need to use this build.gradle file to build a FAT Uber jar so I can use it with spark-submit
Basically you can't really solve this, if either spark-core or nsq-client is using features of guava that or not present in one version or the other. You can run gradlew dependencies which will show you how gradle resolves the version conflict on guava. By default it will choose version 19.0 as its the newer version. Your best chance is to use versions of your libraries that are dependent on the same version of guava. That is either to downgrade nsq-client or upgrade spark-core if possible.
You can exclude the transitive dependency to guava like this:
dependencies {
...
compile (group: 'com.github.brainlag', name: 'nsq-client', version: '1.0.0.RC2') {
exclude group: 'com.google.guava', module: 'guava'
}
...
}
However this will only work if nsq-client is not relying on features only present in version 19.0 of guava as mentioned above.
Sadly this is a common problem especially with the guava library as it is used in nearly every project and the developers don't care a lot about a stable API of their library.
Your best bet is probably to try excluding guava from spark-core and give it a try and, if it's not working, to exclude it from nsq-client and give it a try. But even if it seems to be working at a first glance odds are good (or actually bad in your case), that you will run into similar problems during runtime of your application.
If the above is not working, you could still fork nsq-client and replace the problematic parts with something compatible to guava 14.0.1. I don't really like this option but if the developers of nsq-client are nice they might accept your change...
One of the dependencies lib is not being downloaded. Use the latest lib of both. Use can as well use this:
repositories {
mavenCentral()
}
configurations {
compile
}
dependencies {
compile 'dependency repo1'
compile 'dependency repo2'
}
task libs(type: Sync) {
from configurations.compile
into "$buildDir/libs"
}
This will help download both dependencies.

Where do i add my dependencies? In which build.gradle to put them?

I am requested to add a few dependencies. I know They should be added on build.gradle, but in the dependencies section is written:
dependencies {
classpath 'com.android.tools.build:gradle:1.3.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
I am new to android so from my small experience and googling there are supposed to be two build.gradle files, and only in one of them I should add dependencies, but I can not find an extra build.gradle file!?
I will be happy for help! Where should I add my dependencies and where did my second build.gradle disappear?
Gradle is a bit of an odd tool.
https://docs.gradle.org/current/userguide/artifact_dependencies_tutorial.html
They state here how it works. There is only one build.gradle per project that will pull and manage dependencies for you.
Android Studio extends this. There is one 'main' build.gradle for the entire project, and then for each submodule there is a build.gradle since they are run as separate programs. in the master project build.gradle, put dependencies that effect everything you are doing in the build process, and then for each module dependencies specific for those modules. That's what it's saying.
http://developer.android.com/tools/building/configuring-gradle.html
**EDIT: **
Android Studio docs:
Declare dependencies
The app module in this example declares three dependencies:
dependencies {
// Module dependency
compile project(":lib")
// Remote binary dependency
compile 'com.android.support:appcompat-v7:19.0.1'
// Local binary dependency
compile fileTree(dir: 'libs', include: ['*.jar']) }
Each of these dependencies is described below. The build system adds all the compile
dependencies to the compilation classpath and includes them in the
final package.
Gradle docs:
Example 7.1. Declaring dependencies
build.gradle
apply plugin: 'java'
repositories {
mavenCentral()
}
dependencies {
compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final'
testCompile group: 'junit', name: 'junit', version: '4.+'
}
Dependencies can be listed in a bunch of different ways.

Gradle - build jar which includes both .class and .java files?

I'm using android studio + gradle. I have a module that is a plain standalone java app. Is there a way I can package that module into a .jar file that includes both its compiled .class files, and its source .java files? By default it looks like android studio is only including .class files for me.
I was originally doing this using Eclipse (export as a jar), but can't figure out how to do the equivalent with android studio.
---- EDIT -----
This is my current build.gradle file, but it still outputs a jar that only includes the .class files:
apply plugin: 'java'
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
}
task sourcesJar(type: Jar) {
from sourceSets.main.java.srcDirs
classifier = 'sources'
}
artifacts {
archives sourcesJar
}
Thanks
It is most common to publish a separate sources JAR from compiled classes.
To do that in Gradle, add this to your Gradle build:
task sourcesJar(type: Jar) {
from android.sourceSets.main.java.srcDirs
classifier = 'sources'
}
artifacts {
archives sourcesJar
}

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