Maven/Gradle working overlay example with eclipse - java

I have an EAR project which should contain one or more skinny WARs. I already tried everything to get that project working with eclipse but just couldn't make eclipse do the same as the tools(maven and gradle) do when I run them from the command line.
Are there no working examples I could use to get my projects working with eclipse? Please help me, I alread ask myself if anyone is really using these tools like I want them to for such kind of projects.

In my last project experience I have problem with supporting the maven with Eclipse. Because of problem in Eclipse m2 plugin.
So the best solution for me was build an ear from the command line by some shell scripts for example. To open project in IDE I used maven eclipse plugin, thus I generated eclipse workspace by maven.
Using Eclipse External Tools you can run shell script to build/or run your EE application from the command line pretty convenient.
The same applies to the gradle, but looks like Eclipse Gradle plugin is more stable, and now I use plugin in my Gradle project.
If it will be useful for you, you can review github test project to illustrate how to make maven multymodule war project. Also you can find short explanation how to generate eclipse workspace for this project. After workspace generated you can import as Existing Project into your workspace.

Here is a sample Ear project containing war(Refer to img below for dir structure)
MainDir contain 2 files and 1 directory called war.
File settings.gradle contains
include 'war'
File build.gradle contains
apply plugin: 'ear'
repositories {
mavenCentral()
}
dependencies {
deploy project(':war')
//earlib group: YOUR_DEPENDENCIES
}
build.gradle for war directory contains
apply plugin: 'war'
apply plugin: 'jetty' // you can call gradle jRW
repositories {
mavenCentral()
}
dependencies {
//compile group: YOUR_DEPENDENCIES
}
httpPort = 8080 //jetty start port
stopPort = 8081 //jetty stop port
File HelloWorld.java contains
public class HelloWorld {
public String getHello() {
return "Hello world!";
}
}
File index.jsp contains
<jsp:useBean id="helloWorld" class="your_package.HelloWorld"/>
<html>
<p>${helloWorld.hello}</p>
</html>
Now open cmd->MainDir(or you can search eclipse-marketplace for gradle and execute this step directly from eclipse) and type
gradle jRW//short for jettyRunWar
now open
localhost:8080/war/

Related

How to deploy 100s of jars in Jfrog Artifactory

I was in the process of converting java projects build system from Ant to Maven and there are literally 700+ dependency jar files lying in a folder without any version or package information.
I was able to figure out maven co-ordinates for 400+ of those jar files using it's hash. So for the remaining 300+ jar files I am thinking of uploading it directly to a local repo in Artifactory and then generate maven co-ordinates automatically.
As far as i have explored the only way to achieve this is to deploy/upload every jar file manually via Artifactory UI with Deploy as Maven Artifact option enabled to generate co-ordinates automatically but this is a very time consuming process (I want to do this for 300+ files).
is there any other efficient way to do it?
I see two ways to achieve what you want, unfortunately none is available "out of the box"...
Use the command line client to upload each JAR file to Artifactory.
The main command to upload is:
jfrog rt upload foo.jar maven-local-repo
See https://www.jfrog.com/confluence/display/CLI/CLI+for+JFrog+Artifactory for more details
Use a bash script to loop on the JAR files, and for each file, upload it to a separate location, generate a short pom (from a sample pom and some sed to replace groupId and artifactId with the filename) and upload it next to the JAR file.
As Artifactory provides this option over its webapp, create a Selenium client that loops on each JAR file, connects to the Artifactory UI, and uploads each file using the "Generate default POM" option.
See https://www.jfrog.com/confluence/display/JFROG/Deploying+Artifacts#DeployingArtifacts-DeployingMavenArtifacts
I'm sure you already figured out a solution, but for anyone else who has to do something similar I ended up just using gradle to do it for me. I created a bare gradle project and with the following build.gradle. It collects all the jars from the directory specified and loops through them and creates publications for each. We wanted to use the sub-folder structure as the groupId so there's a bit of logic to format that in there.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.21.0"
}
}
apply plugin: 'java'
apply plugin: 'maven-publish'
apply plugin: "com.jfrog.artifactory"
version = '0.2021.0'
ext.thirdPartyLib = fileTree(dir: "$rootDir/../extrajars", include: ['**/*.jar'])
publishing {
publications {
thirdPartyLib.each{ jar->
def fbase = jar.name.minus(".jar")
"$fbase"(MavenPublication) {
artifact jar
artifactId fbase
//the following was to use the folder structure as the groupId
def path = jar.path.minus("\\" + jar.name)
path = path.replaceAll("\\\\", ".")
path = path.replaceAll("c:/pathtoDirectory", "")
groupId = path
}
}
}
}
artifactory {
contextUrl = 'http://yourArtifactoryUrl'
publish {
repository {
repoKey='yourRepo'
username='username'
password='password'
}
defaults {
thirdPartyLib.each{ jar->
def fbase = jar.name.minus(".jar")
publications( fbase )
}
}
}
}

How to change the working directory using JavaFX with Gradle?

The title says all. How do I change the working/runtime directory when using JavaFX with Gradle in Eclipse?
Basically, I have a project that requires log4j and initiates a basic logger which uses the "logs/" directory from the place the jar is run. This directory is being made in the home of the source, but I want it to be made in the "run/" directory. I'm assuming for other files that will be created, they will also have this same issue.
My build.gradle is this:
// Plugins
plugins {
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.7'
}
// Repositories
repositories {
jcenter()
mavenCentral()
}
// Dependencies
dependencies {
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'org.apache.logging.log4j:log4j-core:2.12.0'
}
// JavaFX
javafx {
version = '12'
modules = ['javafx.controls']
}
mainClassName = 'net.protolauncher.backtest2.ProtoLauncher'
I am using Eclipse to run it, but this issue also occurs when just running the run task. I tried changing the Working Directory in the "Gradle Project" run configuration, but it didn't work at all (it just loaded forever).
To give an example, here's the directory of my source code: DirectoryX. Now, I made a folder in here called "run", like so: DirectoryX/run. When I run the program, I want my logs to go into DirectoryX/run/logs and similar files to go into the run directory. However, when running with Gradle my log files are being created in DirectoryX/logs.
This probably made no sense, but if it did, I really appreciate any help I can get.
After hours of searching online to no avail, I finally found a StackOverflow answer that solves the question. Turns out, JavaExec is a complicated thing, and what I was doing was specific to that, NOT JavaFx.

How to build distribution package in multi-module Gradle project?

I have seen this post Gradle multi project distribution but still have some doubts.
I would like to create the following project layout
root
|--lib-java-module
|--spring-boot-module
|--3PP_A_module # not java
| |-- custom scripts, config
|--3PP_B_module # not java
| |-- custom scripts, config
|--dist-module
As you might have guessed, I want the dist-module to build myapp-dist.tar.gz with libjava.jar, sprintbootapp.jar, 3pp-a.tar, 3pp-b.tar.
myapp-dist.tar.gz
libjava.jar
sprintbootapp.jar
3pp-a.tar
3pp-b.tar.
The 3pp-a-module and the 3pp-b-module only contain some configuration files and startup scripts. No java or any compiled code. How to package them individually into tar files (no compression)?
How to define dependencies in dist-module to the other modules? Is it possible to get the other modules built when build is triggered from dist-module?
Update:
I setup my test project based on #marco-r's answer and it works except for packaging the war file. Checkout the test project from github https://github.com/KiranMohan/study-spring-boot.
This is the project setup of interest.
include ':sb-2.1-multi-package', ':sb-2.1-multi-package:hello-rest-lib',
':sb-2.1-multi-package:hello-rest-standalone-jar',
':sb-2.1-multi-package:hello-rest-war'
include 'sb-2.1-3pp-resources'
include 'sb-2.1-build'
However adding hello-rest-war to sb-2.1-build.tar.gz fails.
Instead of war files, its the dependencies that are getting packaged.
dependencies {
archivesDeps project(path: ':sb-2.1-3pp-resources', configuration: 'archives')
javaDeps project(":sb-2.1-multi-package:hello-rest-war")
}
...
task copyJavaDeps(type: Copy) {
inputs.files(configurations.javaDeps)
from configurations.javaDeps
into "${ARCHIVE_DIRECTORY}/lib"
}
...
// create distribution bundle
distributions {
main {
contents {
from ARCHIVE_DIRECTORY
into "/springapp/multimodule"
}
}
}
Contents of the package
springapp/multimodule/lib/classmate-1.4.0.jar
springapp/multimodule/lib/hello-rest-lib-0.0.1-SNAPSHOT.jar
springapp/multimodule/lib/hibernate-validator-6.0.16.Final.jar
...
springapp/multimodule/lib/tomcat-embed-websocket-9.0.17.jar
springapp/multimodule/lib/validation-api-2.0.1.Final.jar
springapp/multimodule/sb-2.1-3pp-resources/config/3pp.json
How to package war file (hello-rest-war module) and without all the transitive dependencies?
This is multiple question scenario, so I am going to address it in parts.
Since all 3PP_X_module have the same building requirements create a build.gradle in each of the submodules that refer to an actual build gradle that have the common functionality required:
apply from: '../tarArtifact.gradle'
In the parent folder create the previously referred tarArtifact.gradle to have the functionality to TAR the contents of a subfolder (arbitrarily chosen as contents) of a referring subproject:
apply plugin: 'base'
task tarContents(type: Tar) {
from 'contents'
archiveName = "${project.name}.tar"
destinationDir file('build/tar')
}
artifacts {
archives file: tarContents.archivePath, type: 'tar', builtBy: tarContents
}
Since the archives configuration is wired to the output of the tarContents (builtBy: tarContents), then the archives configuration can be used to retrieve the desired TAR as the output of building this project naturally.
Create in dist-module the following build.gradle file:
apply plugin: 'distribution'
plugins.withType(DistributionPlugin) {
distTar {
compression = Compression.GZIP
extension = 'tar.gz'
}
}
configurations {
wholeProjectDist
}
dependencies {
wholeProjectDist project(path: ':3pp-a-module', configuration: 'archives')
wholeProjectDist project(path: ':3pp-b-module', configuration: 'archives')
wholeProjectDist project(':lib-java-module')
wholeProjectDist project(':spring-boot-module')
}
distributions {
main {
contents {
from configurations.wholeProjectDist
}
}
}
This gradle file includes the following:
Applies the Distribution plugin, so we can generate the final tar.gz file from the artifacts generated by all the other subprojects.
Configures the distTar task (of the DistributionPlugin plugin) to compress any generated TAR using it by using GZIP.
Creates the configuration wholeProjectDist to capture the dependencies of dist-module itself; which we will use with the distribution plugin's tasks.
Declares the dependencies of dist-module as the artifacts output by the siblings' subprojects; using the newly created wholeProjectDist.
Configures the distribution's plugin main configuration to have as contents all the files from configurations.wholeProjectDist
Create a settings.gradle file under dist-module to allow it to access its siblings modules using includeFlat:
includeFlat '3pp-a-module', '3pp-b-module', 'lib-java-module', 'spring-boot-module'
Include in the parent folder a settings.gradle file to include all children submodules (as the root project):
includeFlat '3pp-a-module', '3pp-b-module', 'lib-java-module', 'spring-boot-module'
Build the desired tar.gz files by invoking the gradle command (from the root folder):
gradle :dist-module:distTar
Hope this helps.

Gradle multi project, how to deal with different rootDirs

My company is currently switching from Ant to Gradle for its Java projects, but I am stuck with a nice clean setup. Let's say I work for a company that builds websites for clients which generally use the same root libraries (core project), but have some specific code, which is put in the sub-project. Per client, we build a new sub-project, that depends on the core project. Number of clients will increase in the future.
Currently we have three projects:
A core project. This should run individually, as we want to be able to do the unit testing seperately for this.
Two sub-projects that depend on the core project, but have some own projects that are specific to the project.
I was sucessful in converting the whole ant build into a gradle build for the core project. My idea is to have all functionality and project structure in the core, and only the extra for what is actually needed in the sub-projects.
Here is a short sample of our folder structure:
-- core
- build.gradle
- settings.gradle
-- repository (our external jars used)
-- Implementation
-- source_code
-- all the core project folders
-- Projects
-- Client A
- build.gradle
- settings.gradle
-- more project specific folders
-- Client B
- build.gradle
- settings.gradle
-- more project specific folders
I use the $rootDir variable a lot. A fraction of the core's settings.gradle looks as such:
project(':CoreProjectA').projectDir = new File(rootDir, 'Implementation/Source_code/Core/coreA')
project(':CoreProjectB').projectDir = new File(rootDir, 'Implementation/Source_code/Core/CoreB')
But with many more. Also, in the core build.gradle, I refer to our repository as such:
repositories {
//All sub-projects will now refer to the same 'libs' directory
flatDir {
dirs "$rootDir/repository/lib/jaxb"
//many more dirs here
}
}
Now this all works great when I do a gradle build from the core project.
I was planning to put the next piece of code in every client's subproject build.gradle:
apply from: '../../../build.gradle'
When I run a gradle build from Client A folder, my rootDir obviously has changed, and now, all my paths cannot be found anywhere.
Is there any way to set this up in a nice clean way? So that every future sub project added can always use the same structure? Or will I have to give each sub-project its own build.gradle and settings.gradle entirely?
I know the last option could work, but it is a lot of overhead, and just doesn't seem nice and clean to me at all..
Thanks in advance!
I recently worked on a similar configuration, so let me explain me how I build the Gradle infrastructure. Since you mentioned a lot of requirements, I hope that I'll miss any of them and you can apply my scheme to your problem.
General
We actually use build systems (like Gradle) to let them take care of any dependencies (projects, modules, tasks). So why should we define a depedency in something like a filesystem hierarchy, if we can simply define it in Gradle?
I would avoid using paths as much as possible (convention over configuration) and try to stick to Gradle projects for both the build scripts and the dependencies.
Also, if you define dependencies in your core gradle.build, you should just call this gradle file, even if you only want to build a subproject. Your apply from: '../../../build.gradle' destroys the whole Gradle logic. Instead you should use something like gradle :sub1:build to only build the first subproject.
First approach (with core as root project)
Filesystem structure:
core/
build.gradle
settings.gradle
src/
...
sub1/
src/
...
build.gradle [optional]
sub2/
src/
...
build.gradle [optional]
Core settings.gradle:
include 'sub1'
include 'sub2'
Core build.gradle:
allprojects {
apply plugin: 'java'
repositories {
// define repos for all projects
}
}
subprojects {
dependencies {
// let subprojects depend on core
compile rootProject
}
}
project(':sub1') {
// define anything you want (e.g. dependencies) just for this subproject
// alternative: use build.gradle in subproject folder
}
Second approach (all projects independent)
Filesystem structure:
core/
src/
...
build.gradle [optional]
sub1/
src/
...
build.gradle [optional]
sub2/
src/
...
build.gradle [optional]
build.gradle
settings.gradle
Root settings.gradle:
include 'core'
include 'sub1'
include 'sub2'
Root 'build.gradle'
subprojects {
apply plugin: 'java'
repositories {
// define repos for all projects
}
}
configure(subprojects.findAll {it.name != 'core'}) {
dependencies {
// Add dependency on core for sub1 and sub2
compile project(':core')
}
}
project(':sub1') {
// define anything you want (e.g. dependencies) just for this subproject
// alternative: use build.gradle in subproject folder
}
This approach provides great flexibility, since every dependency logic is handled by Gradle and you'll never have to copy anything to another position. Simply change the dependency and you are fine.
Sources
Gradle Tutorial on Multi-project Builds
Question in Gradle Forum
It looks like you have extra settings.gradle inside subprojects. That makes Gradle think the sub-project is a standalone one. If you remove settings.gradle from subprojects, Gradle will look for it up the filesystem hierarchy, will find one in core project, will create correct multimodule project and all the paths should work properly.
So, just remove extra settings.gradle files and your build will work fine. Having build.gradle in subprojects is perfectly fine.
I want to thank Nikita and especially lukegv for his detailed answer, but I went with a different approach ultimately.
I didn't want to have one main gradle build and extend it each time we have a new project. Also, I wanted to keep it simple and logical for my colleagues if they want to create a build for one of the projects.
Therefor, I kept the structure I had as described above. In the root gradle.settings but changed the
project(':CoreProjectA').projectDir = new File(rootDir, 'Implementation/Source_code/Core/coreA')
project(':CoreProjectB').projectDir = new File(rootDir, 'Implementation/Source_code/Core/CoreB')
into:
project(':CoreProjectA').projectDir = new File(customRootDir, 'Implementation/Source_code/Core/coreA')
project(':CoreProjectB').projectDir = new File(customRootDir, 'Implementation/Source_code/Core/CoreB')
In each project I have a properties.gradle with the customRootDir filled in (relatively to the projects directory).
It all works like a charm. I can go into any project folder and produce builds, while using the functionality of the root's build.gradle.

Gradle building rest spring app can't find main class

I'm trying to do a http://spring.io/guides/gs/rest-service/ tutorial, and I did everything like it is in tutorial.
When I was trying to build with gradle with the gradle.build from the tutorial gradle build failed because of missing
springBoot {
mainClass = "main.java.hello.Application"
}
I did add it and now compilation start and finish correctly, but as soon as I'm trying to do
java -jar build/libs/gs-rest-service-0.1.0.jar
It throws an error
I have no idea what to do with it. Any help?
It should be hello.Application. main/java is a part of package name / project dir structure.
When added the following piece of code to build.gradle:
springBoot {
mainClass = "hello.Application"
}
both ./gradlew clean bootRun and ./gradlew clean build with java -jar build/libs/gs-rest-service-0.1.0.jar work well.
The above error is due to the build do not includes our Web RESTful Service main application class files into the gs-rest-service-0.1.0.jar file because of the src/main/java/hello, folder is not under the gradle build scope.
In order to avoid the above error or any other errors for https://spring.io/guides/gs/rest-service/ tutorial
Please follow the steps below.
My Folder structure as follows.
C:\MyWebService\src\main\java\hello
Put your build.gradle file under your main folder e.g "MyWebService" not in your hello or any other folder hence "gradle build' will be successful.
Using DOS cmd navigate to your main folder e.g C:\MyWebService\ where src should be the first sub folder.
Run the gradle commands.
gradle
gradle tasks
gradle wrapper
gradlew clean build -- final build
or gradlew clean bootRun -- run before build
You will find your gs-rest-service-0.1.0.jar under your C:\MyWebService\build\libs folder.
Finally invoke spring web service from main folder e.g C:\MyWebService\
java -jar build/libs/gs-rest-service-0.1.0.jar
To check Spring RESTful Web Service by hitting below url in the browser, JSON data will be returned.
http://localhost:8080/greeting
{"id":1,"content":"Hello, World!"}
Now you should be successful with completing the Spring RESTful Web Service tutorial.
N.B: Please do not modify your original build.gradle file provided
on the tutorial.
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'application'
Add the above highlighted line in the build.gradle

Categories

Resources