Gradle: After conversion of maven to gradle, what are the next steps to match up files? - maven

Ive been working off the guides which mention to start by doing
gradle init
on the project. So this creates build.grade. However, the rest of the gradle file is very thinly padded. Im quite new to doing these conversions, but broadly speaking, what would be the next step to get things in harmony?

The Gradle docs lists the following features of the Maven POM conversion:
Uses effective POM and effective settings (support for POM inheritance, dependency management, properties)
Supports both single module and multimodule projects
Supports custom module names (that differ from directory names)
Generates general metadata - id, description and version
Applies maven, java and war plugins (as needed)
Supports packaging war projects as jars if needed
Generates dependencies (both external and inter-module)
Generates download repositories (inc. local Maven repository)
Adjusts Java compiler settings
Supports packaging of sources and tests
Supports TestNG runner
Generates global exclusions from Maven enforcer plugin settings
This means, every required functionality beyond these features must be added manually, either by searching and applying plugins equivalent to the ones used in Maven or by implementing the functionality on your own.

Related

How can i publish just a build script in gradle?

I want to publish a common build script which i will include across various projects in my application.
This will contain only the common set of dependencies, i.e dependencies with particular versions that will be common across all the artifacts in my enterprise application..
My applications will refer to this file from the url.
How can i achieve this?
EDIT1: my exploration in this direction is based on this answer on SO:
How to share a common build.gradle via a repository?
There are a few different options for this.
One is to publish a project with the dependencies you want to share defined as API dependencies. Projects that depend on this will inherit the dependencies.
Or you could write and publish a Gradle plugin that will configure your projects with the common dependencies. Projects can apply the plugin, and will automatically be configured in a certain way. (You don't need to publish a plugin to do this - first try creating a project-local buildSrc convention plugin.)
I would actually recommend neither of these approaches.
It's easy to get into a tangled web of dependency hell when transitive dependencies are inherited. It's likely that at some point some dependency will clash, and excluding dependencies can be a big headache, and will easily cancel out any benefit in trying to reduce a little duplication.
Additionally, it's nice when a project is explicit about its dependencies. Being able to look at a build.gradle.kts and understand exactly what dependencies are set is very convenient.
Instead, what I would recommend is controlling the versions of common dependencies in a central location. This can be achieved with the Java Platform plugin. This plugin can be applied to a single build.gradle.kts file, and it lists all versions of all possible dependencies. (It can also import existing Maven BOMs, like the Spring Boot BOM).
Now, all subprojects can add a platform dependency on the 'Java Platform' project.
dependencies {
// import the platform from a Maven repo
implementation(platform("my.company:my-shared-platform:1.2.3"))
// or import a platform from a local project
implementation(platform(":my-project:version-platform"))
// no need to define a version, if it's defined in the platform
implementation("com.fasterxml.jackson.core:jackson-databind")
}
This is the best of both worlds. Projects can be explicit about their dependencies, retain autonomy, while the versions can be aligned across independent projects.

Is it possible to force a Maven plugin to be included in a project from a dependency of that project?

I have three Java projects. The first is an application, com.foo:foo-application:1.0.0, and the second is a module used as a dependency to that application, com.foo:foo-framework:1.0.0. The third is a Maven plugin authored by our team, com.foo:foo-plugin:1.0.0.
My intention is that any project, e.g. foo-application, which uses classes available in foo-framework must also validate that it has used those classes correctly, where said validation is enforced by foo-plugin.
Is there a way to enforce this behaviour within foo-framework's POM.xml, whereby any Maven module which declares it as a dependency in its own POM will have foo-plugin executed as part of its build lifecycle?
No (at least no way that I'm aware of).
when you declare a dependency on something, youre declaring a dependency on its output artifacts (and transitively their dependencies as optionally described in that artifact's pom.xml file). There's no place in a pom file to force anything on the build importing it - the build importing it may not even be a maven build.
it appears you may be able to do something similar via other tools though - for example checkstyle supports discovering rules from dependencies on the classpath (not exactly what you want and depends on users of your library running checkstyle configured just right)

After making a Gradle groovy jar library how to make it re-usable for multiple local projects?

Here I read about how to make a Groovy library .jar ... i.e. pretty much the same as making a Groovy (standalone) project. But I'm not clear what you do then with the resultant .jar...
Say I have two Eclipse "proper"/"standalone" projects (I'm using Groovy for everything) and I want them to share a third Gradle library project of mine as a dependency, which is merely a library of classes... how are my standalone projects expected to find the latest .jar version of the library which they're both using...?
My expectation would be that somehow these versions of the library .jar would have to under GRADLE_USER_HOME (i.e. same location as all other dependency .jars).
Then I would assume that in the build.gradle of both standalone projects you'd have a line like
compile 'mylibrary:mylibrarymodule:3.+'
... of course the first part of these compile directives normally involves a "domain name in reverse" ... and this is normally used by a repository like Maven. How does it work with something which doesn't need to be published?
NB at the time of writing I don't have a Maven account as such and have no idea whether "publication" for re-use of a local common library project like this is essential or not.
Naturally, when I distribute versions of my standalone projects they will need to be packaged up with the library .jar in question.
A link to a how-to for a case like this would be more than welcome: I haven't found it under gradle.org.
If you are developing by yourself, you can use maven-publish plugin to publish your artifacts to local maven repository(you don't have to install maven for this) and on your dependent project you can simply say use mavenLocal repository for dependencies.
If you are on a company, I suggest installing a repository manager and deploy your artifacts to this repository so others can use. You can use their respective plugins to deploy easily. (Gradle Artifactory Plugin, Gradle Nexus Plugin, these are just deployment plugins, you have to setup respository manager to. There are other repository management tools also.) Doing the above process from CI server is the preferred way.
To use latest version of a dependency, you can use Gradle Versions Plugin. If the versioning happen often, using snapshot versions also a possibility.

What is the difference between an app dependency and a module dependency/plugin?

When using some 3rd party libraries, I add a dependency to my module's build.gradle file.
compile 'com.android.support:appcompat-v7:24.1.1'
Or I add a plugin
apply plugin: 'com.neenbedankt.android-apt'
Some other times, the library requires adding a dependency to my app's build.gradle file.
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
What is the difference between these dependencies and plugins?
Why can't they all be set in a single build.gradle file?
All suggestions are appreciated, I'm having trouble searching for info on this
Three things. Gradle plugin, module dependency, a build dependency which is placed on the classpath of the build tool.
A plugin is how Gradle knows what tasks to use. There are many plugins. For more info, see Gradle - Plugin Documentation
A dependency is a library that is compiled with your code. The following line makes your module depend on the Android AppCompat V7 library. For the most part, you search Maven or Jcenter for these.
compile 'com.android.support:appcompat-v7:24.1.1'
The classpath setting is needed for Gradle, not your app. For example, this allows this includes the Gradle Build Tools for Android into the classpath, and allows Gradle to build apps.
classpath 'com.android.tools.build:gradle:2.1.2'
Why can't they all be in one build.gradle file?
They probably can be. It is simply more modular to not.
I got this answer from a colleague, and this helped me understand. "A gradle plugin is like the tools you use to build the app. The dependencies are the libraries included in the app. A gradle plugin is usually the tasks - like ktlint, etc."
I didn't understand this myself so here is what i found. My answer is based on gradle build tool.
Plugins:
Add additional tasks, repositories, new DSL elements, configuration for classpaths/build/run or dependency management for subsequent development. Plugins are developed for a larger scope of development like java, kotlin or spring-boot.
Dependencies:
modules/libraries for tasks like http, serialization or database are dependencies stored remotely at repositories or locally that are needed at runTime, test or build are resolved by gradle in a configured fashion.
Sources:
Spring boot gradle plugin: https://github.com/spring-projects/spring-boot/tree/master/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin
Gradle documentation on plugins/dependencies: https://docs.gradle.org/current/userguide/plugins.html
https://docs.gradle.org/current/userguide/core_dependency_management.html
Remote repositories:
https://mvnrepository.com/
In simple words:
Plugins are used to add some additonal features to the software/tools(like Gradle). Gradle will use the added plugins at the time of building the App.
Dependecies are used to add some addtional code to your source code, so a dependency will make some extra code (like Classes in Java) in the form of library available for your source code.

Custom dependency management plugin in Gradle

How do you write a custom gradle plugin to handle dependencies in a custom module descriptor, from a custom repository? The gradle documentation says the following, but I haven't been able to find anything that tells me how.
Even if your project is using a custom dependency management system or
something like an Eclipse .classpath file as master data for
dependency management, it is very easy to write a Gradle plugin to use
this data in Gradle.
I've been maintaining a Custom Ivy resolver for ATG projects (forked from this project), but Gradle recently deprecated this with version 1.8, and I need to port the implementation to a native Gradle plugin.
Implementations of ATG use 'modules' (not unlike Gradle projects), that have a MANIFEST.MF file for a module descriptor. These files define other 'modules' that a module depends on, and also a list of paths (jars or directories) that form the (direct) classpath for the current module.
e.g.
ATG-Class-Path: lib/classes.jar lib/commons-beanutils-1.7.jar
ATG-Required: MyProj.core MyProj.integration.webservices DAF.Endeca.Assembler
Module dependencies are transitive, and may refer to custom modules or modules that sit within the ATG product installation. Hence, I need to define a custom repository that can use the ATG product installation as a source of artifacts.
Without Gradle, I need to maintain dependencies in the form of
ATG's MANIFEST.MF files
Eclipse .classpath files
Dependencies for the Ant build-script
SonarQube configurations
Since I can't get rid of the ATG MANIFEST.MF files, I would like to write a write a custom plugin to allows them to be used in Gradle builds. I can then use Gradle as my build system, which can also generate Eclipse .classpath and .project files, and run Sonar against the project.
Gradle seems to have a lot of source code, and rummaging through it for the last couple of days hasn't got me anywhere.
If someone can point me to a list of interfaces that need to be implemented to (1) implement a custom repository, and (2) implement a custom dependency resolver (to use custom files as module descriptors), that should be enough to get me started.
The Eclipse .classpath use case mentioned above can be solved by parsing that file and translating it to Gradle file dependencies. It isn't currently possible to plug in a custom repository implementation.

Resources