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

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).

Related

Gradle dependencies not being exported to runnable jar by eclipse

I am trying to export my gradle eclipse project to a runnable jar, however it's dependencies are not being bundled into the runnable jar itself.
I file -> export -> runnable jar -> Extract required libraries into generated jar.
They are correctly exported if I manually do "add external jar" from the configure build path option, however I want to do this via gradle, and they are not correctly exported without the manual add.
I have tried to do a gradlew clean, and gradlew build. I have refreshed my gradle dependencies, and I have rebuilt the project, as well as cleaned it via the eclipse project -> clean option.
Below is my build.gradle file:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.1.4.RELEASE")
}
}
plugins {
id 'java'
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-activemq")
testCompile group: 'junit', name: 'junit', version: '4.12'
compile 'org.json:json:20171018'
compile 'org.mongodb:mongo-java-driver:3.6.4'
compile group: 'com.github.jai-imageio', name: 'jai-imageio-core', version: '1.4.0'
compile files ('../libs/CommonUtils.jar')
compile files ('../libs/UMS.jar')
compile files ('../libs/Cache.jar')
}
jar {
from { configurations.runtime.collect { zipTree(it) } }
}
When I look into the jar generated, I see that it doesn't contain the dependencies inside it, and when I go to run the jar via java -jar jar.jar, I get a NoClassDefFound error. I want to get all my gradle dependencies bundled into a runnable jar so I can do a java -jar jar.jar and have my jar run as if I had hit run in the eclipse editor.
The build tools itself will create the runnable jar.
gradle clean
gradle taskName
Project Jar will be created under folder :
$project/build/libs/ folder.

Query for Gradle dependency for WAR plugin

I am new to Gradle. With Gradle 3.5, I am trying to create a war build from a java project. Below is my gradle file content.
apply plugin: 'war'
buildDir = "${rootProject.ext.buildGradle}/${project.name}"
def buildClassesDir = buildDir.getAbsolutePath() + '/classes/main'
configurations {
localLibraries
}
task copyNonJava(type: Copy, dependsOn: compileJava) {
from ('src/main/java') {
exclude '**/*.java'
include '**/*.properties'
}
from ('resources') {
include 'default_content.properties'
}
into buildClassesDir
includeEmptyDirs = false
}
task bundleJar (type: Jar, dependsOn: ['compileJava', 'copyNonJava']) {
baseName archivesBaseName
from buildClassesDir
}
task bundleWar (type: War, dependsOn: ['bundleJar']) {
baseName = project.name
from 'web'
webXml = file( 'resources/WEB-INF/web.xml' )
classpath = configurations.localLibraries
}
dependencies {
compile group: 'com.system', name: 'core', version: rootProject.version, changing: true
compile group: 'com.system', name: 'core-ui', version: rootProject.version, changing: true
compile group: 'com.persistence', name: 'persistence', version: '1.0'
compile group: 'com.surveys', name: 'survey', version: '1.0'
localLibraries fileTree("lib") {
exclude 'spring*'
}
}
When I generate war build, it adds jar files under WEB-INF/lib directory. But along with those jar files I want jar files from com.system group and jar file generated from bundleJar task. How can I achieve this?
Libraries from the compile configuration are included in classpath by default but classpath = configurations.localLibraries overrides the default value.
Instead of overriding the default classpath (classpath = ... effectively means setClasspath(...)) you can append additional files to it:
task bundleWar (type: War, dependsOn: ['bundleJar']) {
baseName = project.name
from 'web'
webXml = file( 'resources/WEB-INF/web.xml' )
classpath configurations.localLibraries
classpath bundleJar.archivePath
}
Thank you for the response on this. Really appreciate.
I have figured out a way from this. Learned that gradle follows some directory conventions so make changes to directory structure supported by gradle and made changes to the gradle script.
Here is working gradle script:
apply plugin: 'war'
buildDir = "${rootProject.ext.buildGradle}/${project.name}"
def buildClassesDir = buildDir.getAbsolutePath() + '/classes/main'
configurations {
localLibraries
}
task bundleJar (type: Jar, dependsOn: ['compileJava']) {
baseName archivesBaseName
from buildClassesDir
}
task bundleWar (type: War, dependsOn: ['bundleJar']) {
dependsOn = [ 'bundleJar' ]
baseName = project.name
from 'web'
webXml = file( 'resources/WEB-INF/web.xml' )
}
dependencies {
compile group: 'com.system', name: 'core', version: rootProject.version, changing: true
compile group: 'com.system', name: 'core-ui', version: rootProject.version, changing: true
compile group: 'com.persistence', name: 'persistence', version: '1.0'
compile group: 'com.surveys', name: 'survey', version: '1.0'
// Replace this and make sure all necessary jar dependencies are been fetched from repository instead from file system
/*localLibraries fileTree("lib") {
exclude 'spring*'
}*/
}

add jar dynamically in to running java project(Main project)

I need to add jar generated from running application into same application classpath.
Flow - i have generated set of class files(packaged as jar) from WSDL using axis 2 from java .Now i need to access the .class file in generated jar on same java project.
I have used Build Tool Gradle
Here is my code , to build jar for generated set of java files.
buildscript {
ext {
springBootVersion = '1.5.2.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
sourceCompatibility = 1.8
bootRepackage {
enabled = false
}
sourceSets {
compile fileTree(dir:'C://Users//10Decoders//Downloads//axis2-1.7.4-bin//axis2-1.7.4//lib',include: '*.jar')
preBuildSources
main {
java {
srcDirs = ['../'+customProp]
println "sourceSets -- > DONE ---"+customProp
}
}
}
task copypackage(type: Copy){
println "COpy Jar to package - > "
into customProp
from customProp+'/src/'
}
jar {
archiveName = customProp+'.jar'
destinationDir = projectDir
println "JAR BUILD---- > "
}
}
task mydatafile(dependsOn:build){
println "COpy Jar to claspath - > "+customProp
doLast{
copy{
into "../"
from customProp+'.jar'
}
}
}
build.dependsOn copypackage
Another Gradle file to build jar for current java application(Which has main function)
Build.script 2
buildscript {
ext {
springBootVersion = '1.5.2.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
dependencies {
compile 'org.springframework:spring-support:2.0.8'
compile 'org.springframework:spring-aop:4.1.2.RELEASE'
compile 'org.springframework:spring-beans:4.1.2.RELEASE'
compile 'org.springframework:spring-context:4.1.2.RELEASE'
compile 'org.springframework:spring-core:4.1.2.RELEASE'
compile 'com.squareup.okio:okio:1.11.0'
compile 'com.squareup.okhttp3:okhttp:3.6.0'
compile 'org.json:json:20160810'
compile 'mysql:mysql-connector-java:5.1.38'
compile 'org.apache.commons:commons-dbcp2:2.0.1'
compile group: 'org.hibernate.javax.persistence', name: 'hibernate-jpa-2.0-api', version: '1.0.1.Final'
compile group: 'log4j', name: 'log4j', version: '1.2.17'
compile('org.springframework.boot:spring-boot-starter-jdbc')
compile group: 'com.predic8', name: 'soa-model-core', version: '1.5.4'
// https://mvnrepository.com/artifact/wsdl4j/wsdl4j
compile group: 'wsdl4j', name: 'wsdl4j', version: '1.6.2'
// https://mvnrepository.com/artifact/org.reflections/reflections
compile group: 'org.reflections', name: 'reflections', version: '0.9.5-RC2'
}
jar {
archiveName = 'batch.jar'
destinationDir = projectDir
manifest {
attributes (
'Main-Class': 'com.wsdl.migration.SpringWsdlFieldIdentification',
'Class-Path': 'testAPP.jar mydata/'+customProp+'.jar'
)
}
}
task copyLibs(type: Copy){
println "buildDir- > "+buildDir
}
build.dependsOn copyLibs
Here customProp is variable to get the jar name dynamically while run the gradle build.(gradle build -P customProp=XXXXtask ).
BottomLine : I cannot able to access the classes from the dynamically generate jar.So the Question becomes - How can i add the jar file into running application on runtime??.Thanks in advance.

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')
}

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

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.

Categories