Custom Gradle plugin jar - adding transient dependencies to classpath - gradle

I have created a custom gradle plugin that has transient dependencies. The plugin is working fine and I am outputting the archives to a local maven repo, which again is all working fine. The output directory contains both the pom and jar files.
I want to be able to distribute the plugin between the projects without dependency on the local repo, and without setting up a remote private repo. The obvious choice here is to distibute the jar file between projects, however this requires me to then manually add the transient dependencies of the plugin to a project's classpath.
My questions is how can I distribute a gradle plugin as a jar and have it include transient dependencies without having to manually add those dependencies to a new projects classpath?
Without adding to the classpath I am seeing the following error:
Error:(4, 0) Unable to load class 'x'.
Possible causes for this unexpected error include: Gradle's dependency cache may be corrupt (this sometimes occurs after a network connection timeout.).
The state of a Gradle build process (daemon) may be corrupt. Stopping all Gradle daemons may solve this problem.
Your project may be using a third-party plugin which is not compatible with the other plugins in the project or the version of Gradle requested by the project. In the case of corrupt Gradle processes, you can also try closing the IDE and then killing all Java processes.

Related

Hot reloading a multi-module spring boot application with gradle

I'm trying to convert a project from maven to gradle, but I'm having trouble getting hot reloading to work the same way. I can't show the actual project so I've created two identical very simple projects. One with maven one with gradle. These projects contain two modules:
project
|____api
|____lib
The /api module contains a spring-boot app which depends on code from the /lib module
In the maven project I can change code in either of these modules and recompile either with my IDE (intellij) or with the maven cli and spring-boot-devtools will hot reload the application. However in the gradle version it only successfully hot reloads code that has changed in the /api module.
From what I gathered this seems like a classpath issue. If you run gradle or maven in debug mode it prints out the classpath it passes when it starts the application. Maven includes <project_dir>/lib/target/classes/kotlin/main. However gradle only includes <project_dir>/lib/build/libs/lib.jar
I'm very new to gradle to I might have some of the build configuration messed up. Here are the two project repo's:
Maven: https://github.com/Perry-Olsson/mvn-hot-reload
Gradle: https://github.com/Perry-Olsson/gradle-hot-reload

Error: DefaultOperationDescriptor#2b878eea already available in Android Studio

Failed to complete Gradle Execution
When I try to Sync Gradle with Project Files, the error mentioned below appears
Android Studio version that I am using is 3.0.1, Gradle Build 4.1-all.zip
FYI, I have already tried ->Build->Clean Project and Invalidate Cache & Restart and one more thing is that there is no error in my code.
Message Error:
Information:Gradle tasks [:app:generateDebugSources, :app:generateDebugAndroidTestSources, :app:mockableAndroidJar]
Error:Failed to complete Gradle execution.
Cause:
Operation org.gradle.tooling.internal.provider.events.DefaultOperationDescriptor#86028ba already available.
BUILD SUCCESSFUL in 8s
Information:1 error
Information:0 warnings
But When I try to Run on my Emulator
The error below appears
Message Error At Run Time
Information:Gradle tasks [:app:assembleDebug]
E:\Android Game App\app\build.gradle
Error:(1, 1) A problem occurred evaluating project ':Android Game App:app'.
Failed to apply plugin [id 'com.android.application']
Due to a limitation of Gradle new variant-aware dependency management, loading the Android Gradle plugin in different class loaders leads to a build error.
This can occur when the buildscript classpaths that contain the Android Gradle plugin in sub-projects, or included projects in the case of composite builds, are set differently.
To resolve this issue, add the Android Gradle plugin to only the buildscript classpath of the top-level build.gradle file.
In the case of composite builds, also make sure the build script classpaths that contain the Android Gradle plugin are identical across the main and included projects.
If you are using a version of Gradle that has fixed the issue, you can disable this check by setting android.enableBuildScriptClasspathCheck=false in the gradle.properties file.
To learn more about this issue, go to https://d.android.com/r/tools/buildscript-classpath-check.html.
Information:BUILD FAILED in 16s
Information:1 error
Information:0 warnings
Information:See complete output in console
Nothing found on Google! Any help would be highly encouraged???
The key to the problem is this line. Maybe due to a project.all in root build.gradle or you are using composite builds.
This can occur when the build script classpaths that contain the Android Gradle plugin in sub-projects,
or included projects in the case of composite builds, are set differently.
that mean in all yours build.gradle you have more than one this line
buildscript {
dependencies {
classpath "com.android.tools.build:gradle:x.y.z"
}
}
what this means is that with the introduction of Android Gradle Plugin 3.Y.Z and the new way of handling dependencies,
if you mix in the same project 2 projects with different plugin version (one with a 2.3 and other with 3.0.1) you will get dragons while compiling.
And this error it's a way to force developer to check it and opt-out once detected and solved.
how to solve it, first ensure you don't use a android gradle plugin below 3.0.1 and use the new dependencies configurations, and add this property on every gradle.properties you have.
android.enableBuildScriptClasspathCheck=false
with that you can now compile
one example could be found at realm sample repo they use a allprojects block that include android gradle plugin on every module. and solve it adding previus gradle property at root gradle.properties

Intellij: How to add module compile output to web-inf/classes in stead of web-inf/lib?

I'm using maven to set up a war project in IntelliJ and run in it GlassFish. The war project depends on several other modules. When I run the project in debug mode, hot deploying codechanges of the changes results in NoClassDefFound exceptions. I found out that IntelliJ tries to redeploy the module jar but GlassFish keeps a lock on it so it fails. All the classes in that module are now unavailable, causing these NoClassDefFound exceptions.
IntelliJ generates the artifacts this way: the dependent modules are all added as jar dependencies as if they were external dependencies:
Now, when I remove the jar dependencies, IntelliJ tells me it found some missing dependencies and proposes a fix to add the missing dependencies.
Fixing those dependencies will add the module compile output to the WEB-INF\classes folder.
Once deployed, IntelliJ has no problem anymore hot-deploying changed classes to GlassFish since there's no jar to keep a lock on.
Problem
Every time I make a change to any pom.xml, IntelliJ refreshes the artifacts automatically, which is fine: I definitely want to see those changes appear in the artifact. However, all modules are added as jar dependencies again.
Question
How can I make sure that IntelliJ adds the compile output of project modules to WEB-INF\classes and not to WEB-INF\lib?
I found this question but it has two problems:
There are many module dependencies so if possible I'd like to avoid specifying them all one by one in the unpack goal
IntelliJ seems to ignore this. When I add that configuration and while it works perfectly in a maven commandline build, IntelliJ still refuses to add the module compile output to the WEB-INF\classes dir
I found a bugreport that asks about the same thing but for me it's hard to believe there's no way to solve this problem. Other webapp developers using IntelliJ must have this same issue, making it difficult to hot-deploy code changes, unless I did something wrong in my pom configuration.

Maven WAR Plugin / Jenkins repository connector: Omitting transitive dependencies?

Situation
I have a multi-module Maven project. In it, I have several JAR artefacts, it then gets assembled as a WAR file. Thus, the WAR artefact depends on all kinds of JAR artefacts (it also has a WAR overlay), most of them with scope "compile".
Build and deployment to a repository are fine. But when I try to retrieve the WAR artefact, I have issues. previously, I used a simple wget to retrieve it from the Nexus API, but I wanted to try the Jenkins Repository Connector - not the least reason being that it actually shows a list of available versions.
I configure a repository in
Manage Jenkins -> Configure System -> Artifact Resolver
with the URL for our repo:
http://$NEXUS/nexus/content/repositories/releases/
then in the job, i add a parameter:
Maven Repository Artifact
and use the repository configured above, then i add
Artifact Resolver
as a build step and set it up.
Problem
I am not even sure on which side this should be solved: When I run the job to try to get the WAR file from the nexus, it also starts trying to retrieve all kinds of transitive dependencies (some of which are unaccessible to this user) and fails. What I need is just the WAR file. No transitive dependencies (since they're already packaged in the WAR).
The Repository Connector plugin doesn't seem to have a switch for this, and the Maven side it's probably perfectly OK to include those dependencies in the output POM.
Question
What can I do to either stop the repository connector from retrieving transitive dependencies or retrieve the WAR artefact in a different way? Also interesting for me (but a bit broad as a question) would be general ideas about doing this kind of workflow. E.g., does anyone use other ways of deploying the WAR into their Nexus?
i submitted a patch to the repository connector plugin.
my fork:
https://github.com/rmalchow/repository-connector-plugin
working on getting it to be merged:
https://github.com/jenkinsci/repository-connector-plugin/pull/10

Fetch all dependencies, put them in a new local Maven repository using Gradle

I have a Gradle project with several subprojects and many, many dependencies. I would like to have a simple way to tell Gradle to download all dependencies (including those under buildscript!) and put them in a local Maven/Ivy repository for later use. The Gradle script should then be able to pull all dependencies from the local repository.
Background: I need to build the application on a server which has absolutely no access to any public Maven repositories, so all dependencies must already be present on the host. I've tried a flat directory, but I have not found it easy to resolve the transitive dependencies, and managing them by hand is not an option. Copying the Gradle cache did not work, either.
Can anyone suggest something? Thanks.
I found a solution, namely to install Apache Archive (http://archiva.apache.org/) locally and set it up as a proxy. Then I copied the entire installation to the target-server and disabled the remote repositories. The dependencies could then be fetched locally.

Resources