Vaadin 12 + Gradle 5 Create executable Fat jar - java

I need to use Jetty and Vaadin and build a fat jar.
My workspace is based around Gradle 5, Its a gradle multi module project
Parent
Common-Lib
Core-Lib
Jetty+Vaadin
I followed the documentation which i found here:
https://vaadin.com/tutorials/embedded-jetty-server-in-vaadin-flow
The documentation explains how to create Jetty's WebAppContext and start Jetty Server instance all based around maven.
Expect as i said my workspace is based around gradle, so instead of copying the pom.xml i rewrote it to the gradle build script which looks as follows:
plugins {
id 'idea'
}
group = 'some.example.jetty.and.vaadin.fatjar'
version = '1.0.0'
dependencies {
implementation project(':Core-Lib')
implementation project(':Common-Lib')
compile group: 'javax.servlet', name: 'javax.servlet-api', version: '4.0.1'
compile group: 'org.eclipse.jetty', name: 'jetty-continuation', version: '9.4.14.v20181114'
compile group: 'org.eclipse.jetty.websocket', name: 'websocket-server', version: '9.4.14.v20181114'
compile group: 'org.eclipse.jetty.websocket', name: 'javax-websocket-server-impl', version: '9.4.14.v20181114'
compile group: 'com.vaadin', name: 'vaadin-core', version: '12.0.7'
}
My problem is that during the build gradle outputs a .war file. I cannot use a .war file.
This project is supposed to be a plug-in module for another application, which i do not have sources for. The application just loads a jar files from specific folder, only jar extension is supported.
My question is: How can i create standard "unshaded" uber jar/fat jar instead of .war
With the word "unshaded" i want to unpack all JAR dependencies, and repack them into the final JAR.

Related

Gradle: publish existing jar/source/javadoc to maven

I have some proprietary libraries which are used in my java project. I use gradle as build manager. I use the eclipse-ide.
Since I dont want to have any binaries in my repo, I created a custom maven repository. Prior to Gradle 6.x Gradle just downloaded the .jar file with the correct folder structure in the repository (GROUPNAME/ARTIFACT/VERSION/... .jar)
After I updated to Gradle 6.5 Gradle wanted a .pom file to specify the jar. So I created a dummy project with this build file and used the command gradle install to get the .pom file.
plugins {
id 'java-library'
id 'maven'
}
repositories {
jcenter()
}
dependencies {
api group: 'commons-codec', name: 'commons-codec', version: '1.10'
api group: 'commons-logging', name: 'commons-logging', version: '1.2'
api group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25'
api group: 'log4j', name: 'log4j', version: '1.2.17'
}
install {
repositories.mavenInstaller {
pom.version = '...'
pom.groupId = '...'
pom.artifactId = '...'
}
}
With this method I had to rename the library jar accordingly. Now I have the .pom file but missing all the md5/sha/metafile/... files which are normaly generated with the maven-publish plugin.
I either need to know how to configure my dummy project to generate the md5/sha/metafile/... without having the source code - just have the .jar/sources.jar/javadoc.jar
OR I need to know how to configure my normal build to download the javadoc/sources withouth the correct .pom file

Gradle to use a jar-with-dependencies in compile task

We have a project that make use of 'jrs-rest-java-client', version: '6.3.1'
The site we used to get the jar from has a certificate issue since September. https://jaspersoft.artifactoryonline.com
We then had to get the jar from a different site.
https://jaspersoft.jfrog.io/
The problem is that a dependency require is missing, but if we use the jar that has "-jar-with-dependencies" it is working. I tried by downloading that jar locally and changing the .gradle to use the local version.
What I would prefer is to have the build to fetch that version directly without having to download first.
How do we specify what jar to use?
dependencies {
compile fileTree(dir: 'lib',
includes: [
'ojdbc8.jar',
])
//compile group: 'com.jaspersoft', name: 'jrs-rest-java-client', version: '6.3.1'
compile group: 'com.jaspersoft', name: 'jrs-rest-java-client', version: '6.3.1', USETHISONE: 'jar-with-dependencies'
//compile files("${buildDir}/jrs-rest-java-client-6.3.1-jar-with-dependencies.jar")
}
I have now tried as suggested;
repositories {
mavenCentral()
// to handle broked jasper reports dependencies
maven {
url 'http://jasperreports.sourceforge.net/maven2'
url 'https://jaspersoft.jfrog.io/jaspersoft/third-party-ce-artifacts/'
url "https://jaspersoft.jfrog.io/jaspersoft/jaspersoft-clients-releases"
}
}
dependencies {
implementation project(':common:project-common-properties')
implementation project(':common:project-common-mail')
implementation fileTree(dir: 'lib', includes: [
'ojdbc8.jar'
])
implementation group: 'com.jaspersoft', name: 'jrs-rest-java-client', version: '6.3.1', classifier: 'jar-with-dependencies'
}
I'm still getting errors at build time...
FAILURE: Build failed with an exception.
* What went wrong:
Could not resolve all files for configuration ':services:notificationService:compileClasspath'.
> Could not find com.jaspersoft.jasperserver:jasperserver-dto:6.3.0.
Required by:
project :services:notificationService > com.jaspersoft:jrs-rest-java-client:6.3.1
That library is not required if the jrs-rest-java-client-6.3.1-jar-with-dependencies.jar is used.
Thanks all,
The solution was, as seen if the video (Thanks!)
adding a new url:
url "https://jaspersoft.jfrog.io/jaspersoft/jrs-ce-releases"
From the jfrog repo, it shows you how to do this:
compile(group: 'com.jaspersoft', name: 'jrs-rest-java-client', version: '6.3.1', classifier: 'jar-with-dependencies')
Add the repo for gradle:
repositories {
jcenter {
name "jaspersoft-releases"
url "https://jaspersoft.jfrog.io/jaspersoft/jaspersoft-clients-releases"
}
}
I'd recommend switching from compile to implementation and using a shorthand to declare the dependency:
implementation "com.jaspersoft:jrs-rest-java-client:6.3.1:jar-with-dependencies"
Give a man a fish and you feed him for a day. Teach him how to fish and you feed him for his life time.
I decided to record a short clip of how I found the appropriate repositories for the artifacts you needed, on jfrog:

IntelliJ no Main Manifest Attribute after creating jar artifact

I am trying to build an jar artefact from this repository. I imported apache commons io and org.json as libraries. When extracting the artifact I find a Manifest file which only contains the information of org.json. You can find the jar here. The manifest file in my Project is not reflected at all. Any help is appreciated. When I run the jar in console with java -jar I get the
Error: No Main Manifest Attribute in XXX.jar.
From the project you provided on github i made the following changes to make it run with java -jar. But first and foremost the project you linked on github does not build with gradle build on a fresh pull.
to make this run you need to add commons io and org.json to you build.gradle file. this makes the build.gradle file look like:
plugins {
id 'java'
}
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile group: 'commons-io', name: 'commons-io', version: '2.6'
compile group: 'org.json', name: 'json', version: '20190722'
testCompile group: 'junit', name: 'junit', version: '4.12'
}
jar {
manifest {
attributes(
'Main-Class': 'de.bergwacht.esslingen.Main'
)
}
}
your project also has alot of unused dependencies that should be removed that were creating gradle warnings.
in AnweseneheitsTableModel remove the imports:
import com.sun.org.apache.xpath.internal.operations.Bool;
in DienstprotokollInvalidArgumentException remove the imports:
import com.sun.javaws.exceptions.InvalidArgumentException;
in MainForm remove the imports:
import com.sun.org.apache.xpath.internal.operations.Bool;
import com.sun.xml.internal.fastinfoset.algorithm.BooleanEncodingAlgorithm;
at this point you can run ./gradlew jar and this will create a jar for you under build/libs
you can run that jar with java -jar build/libs/BWOrgaTool-1.0-SNAPSHOT.jar
that command will run it, it will encounter a NPE:
Exception in thread "main" java.lang.NullPointerException
at de.bergwacht.esslingen.forms.MainForm.<init>(MainForm.java:138)
at de.bergwacht.esslingen.Main.main(Main.java:42)
but thats another problem all together, you can start debugging your program at that point.

how to exclude test dependences in gradle

first, I have a project like this:
project-a
src
main
java
A.java
test
java
ATest.java
then, I have another project like this:
project-b
src
main
java
B.java
test
java
BTest.java
the build.gradle configuration, project-b dependence project-a
dependencies{
compile project(":project-a")
}
the question is BTest.java can access ATest.java, how to avoid this?
-------------------show more detail---------------
settings.gradle
rootProject.name = 'test-dependence'
include 'project-a', 'project-b'
project-b/build.gradle
dependencies {
compile project(":project-a")
testCompile group: 'junit', name: 'junit', version: '4.12'
}
Unfortunately there's a bit of an impedence mismatch between Gradle modules and IntelliJ modules since Gradle allows multiple classpaths (configurations) in a module and IntelliJ has a single classpath per module.
Basically IntelliJ will allow BTest.java to access ATest.java but if you built from command line, Gradle won't allow it.
Try the following in intellij Gradle Settings.
Preferences -> Build, Execution, Deployment -> Build Tools -> Gradle: check create separate modules per source set
Related question here

How do I include a single dependency in my JAR with Gradle?

I'm starting with Gradle and I was wondering how do I include a single dependency (TeamSpeak API in my case) into my JAR so that it could be available at the runtime.
Here is a part of my build.gradle :
apply plugin: 'java'
compileJava {
sourceCompatibility = '1.8'
options.encoding = 'UTF-8'
}
jar {
manifest {
attributes 'Class-Path': '.......'
}
from {
* What should I put here ? *
}
}
dependencies {
compile group: 'org.hibernate', name: 'hibernate-core', version: '4.3.7.Final'
compile group: 'org.spigotmc', name: 'spigot', version: '1.8-R0.1-RELEASE'
// Many other dependencies, all available at runtime...
// This one isn't. So I need to include it into my JAR :
compile group: 'com.github.theholywaffle', name: 'teamspeak3-api', version: '+'
}
Thanks for your help :)
The easiest way is to start with a separate configuration for the dependencies you want to include. I know you only asked about a single jar but this solution will work if you add more dependencies to your new configuration. Maven has a well known name for this sort of thing called provided, so that is what we will use.
configurations {
provided
// Make compile extend from our provided configuration so that things added to bundled end up on the compile classpath
compile.extendsFrom(provided)
}
dependencies {
provided group: 'org.spigotmc', name: 'spigot', version: '1.8-R0.1-RELEASE'
}
jar {
// Include all of the jars from the bundled configuration in our jar
from configurations.provided.asFileTree.files.collect { zipTree(it) }
}
Using provided as the name of the configuration is also important because when the jar gets published, any dependencies you have in the providedconfiguration will show up as provided in the POM.xml that gets published with the JAR. Maven dependency resolvers will not pull down provided dependencies and users of your jar will not end up with duplicate copies of classes on the classpath. See Maven Dependency Scopes

Categories