How to shorten Gradle dependency cache folder names? - java

Is there a way to configure Gradle to shorten the folder names of its cached dependencies?
From the Gradle user guide it does not appear its possible, but figured to check with others.
My use case is because using the 'idea' Gradle plugin it helps with settings up Module dependencies. A problem arises when the Module classpath becomes 'too long' for cmd.exe (I'm not trying to discuss these limitations). Idea loads the project just fine, but its unable to run my program since it states the classpath is too long.
Since this is not an Idea problem, I figured it would be lovely if there was a way Gradle could cache deps using shorter folder names.
Example
from: C:\.gradle\caches\modules-2\files-2\com.google.application\application\2.0\SVABNSAVSASAMNVSMAVSASN\application.jar
Options 1 To: C:\.gradle\caches\modules-2\files-2\c.g.a\a\2.0\SVABNSAVSASAMNVSMAVSASN\application.jar
Options 2 To: C:\.gradle\caches\modules-2\files-2\co.go.ap\ap\2.0\[tinyurl-equivalent]\application.jar
Options 3 To: C:\.g\c\m-2\f-2\c.g.a\a\2.0\[tinyurl-equivalent]\application.jar
Options 4 To: C:\.g\[tinyurl-equivalent]\application.jar
I do know that Idea does recognize the long classpath and prompts to enabled Dynamic Classpaths, but this has been known to cause other problems (some invoked apps cannot see the full classpath) and therefore I'd like to avoid this Idea option.

As of Gradle 2.1, shortening dependency cache paths isn't supported. There are ideas around symlinking or copying dependencies into the project, but nothing concrete has materialized.

Related

Gradle: Add dependency of subproject as dependency of the root project

We are running our Java EE applications in WAS 8.5 and Gradle 5.* to build them.
In the past we packaged our .war application in an .ear archive, which we then deployed on our server. We had to separate our libraries from our applications and include them as shared libraries, because in our experience it made deploying much slower and in some cases used up all system memory, crashing the server.
After some experimentation, we realized that we don't need to extract the dependencies into shared libraries, because we can include them in the lib folder of our .ear archive.
Currently, we get this done by defining the dependencies of our .war application as compileOnly and redefining them as earlib in the root project (which generates the .ear archive). I'm looking for a way to automate this procedure.
The script I used looks something like this:
project.configurations.named('deploy').getAllDependencies().withType(ProjectDependency.class).forEach({dependency ->
project.configurations.named('earlib').getAllDependencies()
.addAll(dependency.dependentProject.configurations.named('earlib').getAllDependencies())
})
// This loosely resembles the actual code I used. The thought process is right, it just might have a couple syntax errors.
// Obviously, I defined an `earlib` configuration in the subproject
I tried running this code in the configuration phase, as well as in the doFirst{} section of the ear task. They all had different problems.
The former didn't work, because it seems like in the configuration phase when this code ran, the dependencies weren't configured yet.
The latter didn't work, because I can't just add dependencies during runtime (thinking back, it sounds ridiculous that I even tried it).
My question is: Can I find a phase in the build lifecycle, where I can find and modify the dependencies? Is there another workaround to solve my problem?
The technical answer to your questions is that you can use either:
A configuration.incoming.beforeResolve hook to do it last minute, only when the configuration really needs to be resolved.
Use an afterEvaluate block, assuming all the other dependencies are not defined in an afterEvaluate themselves.
However, the right solution would be to leverage the dependency management engine of Gradle and effectively declare that your root project, the one building the EAR, has dependencies on the specific configurations of the subprojects.
Not knowing your full setup and details, I believe the above would still be the more correct solution, though you may have to filter the subproject artifacts from the resulting graph.
Ideas on how this works in recent Gradle version: https://docs.gradle.org/6.2/userguide/cross_project_publications.html Most of the things explained there should work with the latest 5.x versions.

With Buildship 2 subprojects are not linked as Project Dependencies

For several months we've been using Buildship 1.X plus some manual .launch/tasks to build our Eclipse/WTP config files per development environment. I am currently attempting to migrate to using Buildship 2 (which I'm hoping will rid us of the need for the manual bits.)
However, when I import the projects (which have 0 eclipse config files at this point) via the buildship/gradle import, the subprojects are included via 'Libraries' rather than as 'Projects' (see image below.) In contrast, if I use gradle's eclipse task to generate the eclipse config files (i.e. .classpath) then the configuration ends up as I would expect it to be. Is this a current limitation of Buildship, or do I need to do something differently in my gradle files to coerce Buildship to bring them in as Projects?
Ultimately I don't know that I should care about this difference, but I do know that I'm getting compiler errors saying classes from the subprojects are missing from the classpath. As long as I can fix that issue, I'm perfectly happy.
Potentially helpful info
settings.gradle:
rootProject.name = 'projectroot'
include 'Project2.0'
project(':Project2.0').name = 'projectx'
include 'the-platform'
include 'the-platform:central-repo:central-repo-common'
include 'the-platform:central-repo:central-repo-model'
include 'the-platform:central-repo:central-repo-persist'
include 'the-platform:central-repo:central-repo-service'
Project2.0/build.gradle (snippet):
dependencies {
...
compile project(':the-platform:central-repo:central-repo-common')
compile project(':the-platform:central-repo:central-repo-model')
compile project(':the-platform:central-repo:central-repo-persist')
compile project(':the-platform:central-repo:central-repo-service')
...
}
Hmmm, nevermind. My intuition about the difference between the behavior of buildship vs the eclipse plugin to gradle being responsible for my classpath issues was incorrect. Something else (as yet unexplained) must've been the issue as it is working correctly now.

Failed make using IntelliJ, JBoss due to multiple configuration issues including Pom.xml

Introduction
I have inherited a project that I am able to build using the maven command mvn clean install -DskipTests. However, I am not able to make using the inteliJ button. I am able to deploy the project using Remote debugging but I am not able to hotswap new code in/out due to make not working.
Errors during make
When I run make I get a series of errors such as:
Older Maven Version
I have been told to use an older version of maven, specifically 3.0.3 .
I have gone to the settings for the current project and manually set maven 3.0.3 as the default.
Question 1) Is there a chance this does not apply to the sub directories? Should I change my system path variable and set the old maven as the system default?
Red Highlighting in POM.XML
I am seeing that InteliJ is highlighting a pom.xml in one of the sub-modules for errors. This code has been committed by colleagues so it is strange that there would be errors.
and
and
Question 2) Could Maven be the issue here? Or could there legitimately be an error in the POM.xml?
Maven > Reimport does not solve the issue
Additionally, running Maven > re-import does not solve the issue.
Updating Indices
I tried selecting the proposed option to Update Maven Indices. This has brought up the following dialogs and is downloading in the background from both the maven servers but also a private artifactory.
The indices were taking too long to update so I invalidated the cache/restarted and will try again as proposed # Intelli J IDEA takes forever to update indices .
Summary of Questions
Question 1) Is there a chance this does not apply to the sub directories? Should I change my system path variable and set the old maven as the system default?
Question 2) Could Maven be the issue here? Or could there legitimately be an error in the POM.xml?
Update
Indices finished downloading after some time.
I removed some of the problematic entries in the pom.xml and the project now is not red-underlying the various packages that they do not exist.
I am starting to believe the pom.xmlwas problematic. However, if someone downloads the dependencies/indices, then the problem no longer appears.
Update - Remove Module
I talked with a colleague and he said the specific modules are no longer used (even if they do include faulty pom.xml files). I was told to right click the module and select "remove module". This pretty much stopped the problem.
I talked with a colleague and he said the specific modules are no longer used (even if they do include faulty pom.xml files). I was told to right click the module and select "remove module". This pretty much stopped the problem.

Issues excluding transitive dependency of project reference from eclipse class path

I have several gradle projects in my eclipse workspace. For the sake of simplicity I'm only really interested in 2 of them, let's just use A and B for this.
So the problem I'm having is that Project A has an included dependency on JBoss, which pulls in javax validation-api 1.0.0.GA, and Project B has a dependency on javax validation-api 1.1.0.Final. Since Gradle itself resolves the conflict by using the newer library first, B is happy when built by gradle. But Eclipse itself includes errors which are very distracting while editing.
The correct version of the validation-api jar ends up in B's class path but the problem is that the Gradle IDE plugin changes the project(':A') dependency to a project reference, and Eclipse seems to give the project reference precedence over the external jar. So the old jar is preferred by extension.
I tried adding { exclude module: 'validation-api' } in B's build.gradle for the dependency on A which works according to the output of 'gradle dependencies', however since Eclipse just gets as far as making it a project reference, it won't exclude the jar and the problem remains.
Also per this question I tried adding { transitive = false } and the same thing happens. I don't think even the hack posed there would work for me since the .classpath contains a single reference to the Gradle container so there's nothing to remove.
I've managed to get around this by explicitly including a reference to the correct version of the jar from my gradle cache and then moving it above the Gradle Classpath Container so that eclipse sees that version first.
My question is: Is there a better/more generic way to do this? Preferably one that I can commit to source control without breaking other people's builds or requiring them to manually modify paths or properties somewhere? There is another project with what appears to be a similar issue so something I can fix in the build.gradle file would be awesome.
Worst case scenario, I could probably switch to IntelliJ if that behaves itself better than the Eclipse-Gradle integration?
These kind of transitive dependency issues are long-standing problem with Gradle Eclipse integration (both in STS tooling and also commandline generated .classpath metadata from Gradle's Eclipse plugin. The problem is the way that Eclipse computes transitive classpaths.
Only recently we found a reasonable solution to this problem. Actually there are now two solutions, one better than the other but depending on your situation you might want to use either of them.
The first solution is a bug fix that changes the classpath order of project dependencies so that they are no longer 'preferred' over jar dependencies PR-74. To get this fix you may need to install gradle tooling from a snapshot update site because the fix went in after 3.6.3.
This solution doesn't fix the real problem (you still have the 'wrong' stuff on the classpath) but just makes it less likely to cause real problem in your projects.
The second solution is to enable use of the 'Custom Tooling API model' PR-55 introduced in STS 3.6.3. This is a bit experimental and only works for recent version of Gradle, at least 1.12 but probably better to use 2.x. It also only works for projects that have 'Dependency management' enabled (if not enabled you are using the .classpath generated by Gradle's eclipse plugin which has the same 'broken' classpath issues as the STS tooling).
The 'custom tooling model' is really the better solution in principle as it fixes the way gradle classpath get mapped to eclipse projects so that project dependencies are no longer exported and each project gets its own classpath considering dependencies conflict resolution.
To enable this go to "Window >> Preferences >> Gradle" and enable checkbox "Use Custom Tooling Model".

Changing package names before building in Bamboo

I recently discovered that BlackBerry treats all classes with the same fully-qualified name as identical--regardless of whether they are in entirely different apps or not--causing apps that use different versions of our shared libraries to break when they are installed on the same phone.
To solve this problem, we are planning on changing the package names to include a version number, then building. Can someone explain how, using Bamboo, I can insert a step in our build process that:
changes certain packages names
replaces all code references to the old package name with references to the new package name?
A great tool that is made especially for the task of changing the fully qualified names of Java classes in jar files is jarjar. It can be used easily from within Ant, or alternatively from a shell script.
I have never used Bamboo - I assume, it should work there, too. Of course, there may be some special restrictions in that environment (concerning bytecode manipulation), I don't know about (?)
I'm not familiar with Bamboo and you did not include much information about your build system. If you are using maven, you could use the shade plugin:
This plugin provides the capability to package the artifact in an uber-jar, including its dependencies and to shade - i.e. rename - the packages of some of the dependencies.
The second example here shows how to configure package renaming. The resulting jar file would then have to be processed by rapc as in Chris Lerchers comment to his answer. It should be possible to also integrate this in a maven build using the exec plugin.

Categories