How do you build a .jar that contains external .jar dependencies? - java

I'm using the Microsoft JDBC Driver 4.1 to connect to SQL Server. In Eclipse I have added the .jar file to the class path of my project ( C:\Program Files\Microsoft JDBC Driver 4.1 for SQL Server\sqljdbc_4.1\enu\sqljdbc41.jar).
I've added this .jar to a folder called lib in my project and am trying to have this .jar added as part of my .jar:
repositories {
mavenCentral()
}
dependencies {
compile files('lib/sqljdbc41.jar')
testCompile group: 'junit', name: 'junit', version: '4.+'
}
However, sqljdbc41.jar is not included in my .jar. Am I missing something?

You have to create a (application) distribution to package your libraries and application jar in a folder: http://gradle.org/docs/current/userguide/application_plugin.html
Alternatively you can use a plugin like https://github.com/johnrengelman/shadow to create a self-contained uberjar.

Thanks chromanoid. I was able to solve the problem two ways. First I placed the sqljdbc41.jar in a new folder called lib in my project. Solution 1 was to create an application distribution:
apply plugin:'application'
apply plugin: 'java'
mainClassName = "main.java.application.Main"
repositories {
mavenCentral()
}
dependencies {
runtime files('lib/sqljdbc41.jar')
testCompile group: 'junit', name: 'junit', version: '4.+'
}
You can then create a distribution using the distZip task. Solution 2 was to create a fat jar.
apply plugin: 'java'
repositories {
mavenCentral()
}
configurations {
provided
compile.extendsFrom provided
}
dependencies {
runtime files('lib/sqljdbc41.jar')
testCompile group: 'junit', name: 'junit', version: '4.+'
}
jar {
dependsOn configurations.runtime
from {
(configurations.runtime - configurations.provided).collect {
it.isDirectory() ? it : zipTree(it)
}
} {
exclude "META-INF/*.SF"
exclude "META-INF/*.DSA"
exclude "META-INF/*.RSA"
}
}
and use the build task.

Related

Could not get unknown property "runtime" Gradle 7.0

I switched to gradle 7.0 recently and now cannot build my projects jar, with the error
Could not get unknown property 'runtime' for configuration container of type org.gradle.api.internal.artifacts.configurations.DefaultConfigurationContainer.
`
Here is my build.gradle:
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'application'
repositories {
mavenCentral()
}
dependencies {
implementation group: 'org.glassfish.jersey.containers', name: 'jersey-container-servlet-core', version: '2.7'
implementation group: 'org.eclipse.jetty.aggregate', name: 'jetty-all', version: '9.3.0.M1'
//
implementation 'javax.xml.bind:jaxb-api:2.3.0'
// testImplementation group: 'junit', name: 'junit', version: '4.11'
implementation group: 'org.json', name: 'json', version: '20200518'
implementation group: 'com.jolbox', name: 'bonecp', version: '0.8.0.RELEASE'
implementation group: 'mysql', name: 'mysql-connector-java', version: '8.0.22'
implementation group: 'com.fasterxml.jackson.jaxrs', name: 'jackson-jaxrs-json-provider', version: '2.12.0'
implementation "org.slf4j:slf4j-simple:1.7.9"
}
version = '1.0'
jar {
manifest {
attributes(
'Main-Class': 'classes.RestServer',
)
}
}
task fatJar(type: Jar) {
manifest.from jar.manifest
classifier = 'all'
from {
configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) }
} {
exclude "META-INF/.SF"
exclude "META-INF/.DSA"
exclude "META-INF/*.RSA"
}
with jar
}
artifacts {
archives fatJar
}
Gradle removed the runtime configuration after Gradle 6.x.
You can either change your fatJar task in build.gradle to refer to runtimeConfiguration (as per the Java plugin documentation):
task fatJar(type: Jar) {
manifest.from jar.manifest
classifier = 'all'
from {
// change here: runtimeClasspath instead of runtime
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
} {
exclude "META-INF/.SF"
exclude "META-INF/.DSA"
exclude "META-INF/*.RSA"
}
with jar
}
Alternatively use a plugin that deals with fat jar building for you. I've tried Shadow a few years ago. This should also take care of files with the same names from different jars (like META-INF/LICENSE) that you may run into with your approach.
Support for runtime configuration has been stopped gradle-7.0, so configurations.runtime is not working.
Task copyAllDependencies worked for me in gradle-7.0.
Here is the example to copy dependencies into ${buildDir}/output/libs:
Add following to build.gradle.
task copyAllDependencies(type: Copy) {
from configurations.compileClasspath
into "${buildDir}/output/libs"
}
build.dependsOn(copyAllDependencies)
I hope it helps.

Gradle jar will run inside of intellij but not outside as a standalone

After building my gradle jar within intellij, my project will run perfectly fine. If I try to then move that jar to my desktop and run it using the command "java -jar ProjectName.jar" it throws and error "Cannot find or load main class main"
I'm painfully aware that this question has been asked multiple times on this website as I've spent hours trying to fix it. Ever since I reinstalled Intellij I have been having this issue. I've tried making a fat jar and excluding META-INF, I tried creating a whole new project and creating a jar within that project. I also tried to use a recent iteration of this project which did run as a standalone and had no luck.
build.gradle
plugins {
id 'java'
}
group 'PantryDatabase'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile(
[group: 'com.google.cloud', name: 'google-cloud-bigquery', version: '1.74.0'],
[group: 'com.jfoenix', name: 'jfoenix', version: '9.0.8'],
[group: 'me.xdrop', name: 'fuzzywuzzy', version: '1.2.0']
)
}
jar {
manifest {
attributes 'Main-Class': "Main"
}
from configurations.runtime.collect { zipTree(it) }
}
task customFatJar(type: Jar) {
baseName = 'Pantry_Database'
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}
with jar
exclude "META-INF/*.SF"
exclude "META-INF/*.DSA"
exclude "META-INF/*.RSA"
manifest {
attributes 'Main-Class': 'Main'
}
}
Class Files: https://imgur.com/gallery/HbGJPgr
Error Message: https://imgur.com/gallery/KkHNfas

Gradle jar does not include Guava Preconditions

I have the following build.gradle file for my project
apply plugin: 'java'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile 'com.google.guava:guava:23.6-jre';
testCompile group: 'junit', name: 'junit', version: '4.12'
}
jar {
manifest {
attributes 'Main-Class': 'Runner.ClientRunner'
}
}
However, when I run "gradle jar" and attempt to run the given jar, I get the error:
java.lang.NoClassDefFoundError: com/google/common/base/Preconditions
I can't seem to nail down what I've done wrong here, guava is included in the dependencies for gradle and the jar file appears to build fine otherwise (it only crashes when it gets to the first class that depends on guava). Any assistance appreciated.
If it helps I'm doing this from IntelliJ.
I solved my problem using the solution at https://discuss.gradle.org/t/how-to-include-dependencies-in-jar/19571
My build.gradle now looks like
apply plugin: 'java'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
configurations {
// configuration that holds jars to include in the jar
extraLibs
}
dependencies {
compile 'com.google.guava:guava:23.6-jre';
extraLibs group: 'com.google.guava', name: 'guava', version: '23.6-jre'
testCompile group: 'junit', name: 'junit', version: '4.12'
configurations.compile.extendsFrom(configurations.extraLibs)
}
jar {
manifest {
attributes 'Main-Class': 'Runner.ClientRunner'
}
from {
configurations.extraLibs.collect { it.isDirectory() ? it : zipTree(it) }
}
}

Add dependency jar files from outside of root project in Gradle

I would like to add jar files outside of root project in build.gradle.
I knew I can add jar files under root project.
Example:
dependencies {
compile fileTree('MyLibs')
}
It will include all jar files under root.Project.name/MyLibs
What I want is including my jar files are outside of root.Project.name directory.
Example: On my MacOSX
/Users/MyJava/MyLibs/alllibs.jar
I did try the following so far:
dependencies {
compile fileTree('/Users/MyJava/MyLibs')
}
But it doesn't work.
All the above jars files are inside my local file system(My MacOSX).
Here is my full build.gradle file if are wondering.
group 'try_gradle'
version '1.0-SNAPSHOT'
apply plugin: 'java'
sourceCompatibility = 1.5
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.11'
}
dependencies {
compile fileTree('/Users/MyJava/MyLibs')
}

Gradle: How to use one-jar output as input for launch4j

I'd like to create a exe file, without having to put all required libraries beside the exe.
Formerly with ant I created a self-contained jar file with one-jar and then wrapped this into a exe file with launch4j.
Gradle has plugins for both and standalone both work very well with almost no configuration.
But how can I manage to use the created one-jar as the input for launch4j?
This is my current buildfile:
apply plugin: 'java'
apply plugin: 'launch4j'
apply plugin: 'gradle-one-jar'
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'edu.sc.seis.gradle:launch4j:1.0.6'
classpath 'com.github.rholder:gradle-one-jar:1.0.4'
}
}
launch4j {
mainClassName = "de.my.umkopierer.Umkopierer"
launch4jCmd = "C:/Program Files (x86)/Launch4j/launch4j"
jar = "lib/Umkopierer-1.0.jar"
headerType = "console"
dontWrapJar = false
}
sourceCompatibility = 1.7
version = '1.0'
jar {
manifest {
attributes 'Implementation-Title': 'Umkopierer', 'Implementation-Version': version
}
}
repositories {
mavenCentral()
}
dependencies {
compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
compile 'com.google.guava:guava:18.0'
compile 'com.fasterxml.jackson.core:jackson-core:2.4.4'
compile 'com.fasterxml.jackson.datatype:jackson-datatype-jdk7:2.4.4'
compile 'com.fasterxml.jackson.core:jackson-databind:2.4.4'
testCompile group: 'junit', name: 'junit', version: '4.+'
}
task oneJar(type: OneJar) {
mainClass = "de.stiffi.umkopierer.Umkopierer"
}
I solved this by making the launch4j task 'createExe' dependent on the onejar/fatjar (or any other fat jar creation method). E.g.:
tasks.createExe.dependsOn('oneJar')
task launch4j(overwrite: true, dependsOn: ['createExe']){
}
Also I think that your gradle build file should contain a main class attribute like
manifest {
attributes 'Main-Class':'com.example.MyMainClass'
}
(at least that's the case if you are using the fatjar gradle plugin).

Categories