I've been digging into Gradle and loving it so far! I was delighted to find that apply plugin: 'eclipse' would easily generate an Eclipse project, but I'm irked by the fact that the dependency libraries show up under the root of the project in the Project Explorer view, like so:
That seems unsustainable as the list of libraries expands. Yeah, it doesn't affect the functionality, but it's sure ugly. I'd rather group them into a Libraries "folder" or something like that. Does anyone know of an easy way? I'm thinking I can use withXml to monkey with the project definition, but it seems like someone else has probably thought of this and there must be a better way.
Bonus if I can easily see the subset of libraries that get packaged in (vs e.g. testCompile or providedCompile) when using the war plugin!
If you use Gradle Plugin for Eclipse developed by Pivotal folks there is an option to use classpath container that does what you want - it replaces individual classpath entries with one (expandable).
To enable this feature Right click on the project and select 'Gradle >> Enable Dependency Management'
Related
We have a directory structure like so
java
build/build.gradle (This does NOT exist yet, but we want this)
servers
server1/build.gradle
server2/build.gradle
libraries
lib1/build.gradle
lib2/build.gradle
We have 11 servers and 14 libraries with varying uses of dependencies. EACH server is a composite build ONLY depending on libraries (we don’t allow servers to depend on each other). In this way, as our mono-repo grows, opening up server1 does NOT get slower and slower as more and more gradle code is added(ie. gradle only loads server1 and all it’s libraries and none of the other libraries OR servers are loaded keeping things FAST).
Ok, so one problem we are running into is duplication now which is why we need build/build.gradle file AND we want EVERY module in our mono repo to include that somehow for a few goals(each goal may need a different solution)
GOAL 1: To have an ext { … } section containing a Map of Strings to gradle dependencies much like so
deps = [
'web-webserver': "org.webpieces:http-webserver:${webpiecesVersion}",
'web-webserver-test': "org.webpieces:http-webserver-test:${webpiecesVersion}",
'web-devrouter': "org.webpieces:http-router-dev:${webpiecesVersion}"
]
In this way, we want ALL our projects to them import dependencies like so
compile deps['web-webserver']
GOAL 2: We want to 'include' a standard list of plugins so we are versioning all gradle plugins the same across the repo. While the above configures all jars to avoid jar hell in a mono-repo, we would like to do the same with just this section
plugins {
id 'com.github.sherter.google-java-format' version '0.9'
}
Of course, it each project may also want to add a few more plugins OR even not depend on this section(in case of an emergency and trying to just get the job done).
GOAL 3: We want checkstyle configuration (or any plugin config) to be defined the SAME for all projects (eventually!!!). We would like the checkstyle gradle to live in a common area but have all libraries somehow pull it in. Again, it would be nice for it to be optional in that, I can pull the gradle section into my build.gradle OR can create a new one in case of emergencies so I don't have to fix all projects in the monorepo right away.
IDEALLY, perhaps I kind of want configuration injection where when I run server1/build.gradle, it actually runs java/build/build.grade as it’s parent somehow but with overrides (IF I declare 'extends xxx.gradle' maybe) then all libraries it uses also use java/build/build.gradle as their parent. I am not sure this is possible or feasible. I am pretty sure 'extends xxx' doesn't exist in gradle.
Are any of these GOALS possible?
thanks,
Dean
I have been working on a monorepo with the exact same requirement as you, using gradle composite builds as well. The way we have solved this problem is by using pre compiled plugins
You need to do a new gradle project with only the code you want to share. This will create a plugin, that you can just add as a composite build and apply to the other projects.
I'm a bit confused by why you don't just use a "standard" gradle top level build file and compose the others as subprojects.
This solves all 3 of your goals
If you are concerned by build speed, you can target each server individually simply by running
./gradlew :server1:build
But if you are not able to do this for some reason you can use the apply from: syntax as described here
I've been searching around for a while and can't seem to find anything regarding this issue. I'm new to Java in general and for the last half a year I've been learning Maven. I use IntelliJ IDEA and I'm already used to the fact that it can autocomplete dependency coordinates (groupId, artifactId, version) if you sync the repository. It works nicely and it feels natural when you decide to add some dependency after the initial project generation.
Now I'm trying to switch to Gradle (which is a requirement on my new job) and I'm studying it. And I can't get over the first roadblock that I've encountered with it: there is no autocompletion and it even seems like IntelliJ IDEA's support for this kind of feature has degraded over time (I saw a video of old version of IDEA where there used to be a "Generate" -> "Add maven dependency" option, which I cannot find in the latest version). I even tried a bunch of plugins with names like "Gradle Dependency Helper" and non of them worked.
Are we supposed to type the whole dependency coordinates to add them to gradle build? Because that feels like a big downside of Gradle with IDEA. Or is there some well hidden feature that I missed?
You may manage Gradle dependencies in Intellij IDEA using View→Tool windows→Dependencies.
It allows to add or remove dependencies from dependencies section in your build.gradle and gives full-text search for available dependencies.
I've started using Gradle several months ago and I sometimes bump into a problem with my build.gradle files. For example if I add something like this to my file:
apply plugin: 'kotlin'
I can't tell what that will expand to. In my case I figured out that it pulls in the java plugin as well and the java plugin itself sets up some configuration. How do I know what these statements will expand to? Do Gradle has something like an effective build.gradle ?
Clarification: what I really wish to know is what each apply plugin X statement does behind the scenes without looking up documentations etc.
Since Gradle 2.10 you could try using gradle buildEnvironment. Also see this answer, this blog article, or the official docs.
Try gradle dependencies. The output is similar to Maven's mvn dependency:tree.
See docs here: https://docs.gradle.org/current/userguide/inspecting_dependencies.html#example_rendering_the_dependency_report_for_a_custom_configuration
You could probably list the plugins with a custom task
task pluginReport {
doLast {
allprojects.each { Project p ->
PluginContainer plugins = p.plugins
println "Project: ${p.name} has ${plugins.size()} plugins
plugins.each { Plugin plugin ->
println " - ${plugin.class.name}"
}
}
}
}
Gradle plugins, while they can exist in the form of gradle scripts, a great many of them are binary plugins: java code that happens to be executed by the jvm at build time. This means that "build.gradle" is the effective build.gradle, unless you really want to go looking at bytecode/plugin source code.
The best way to know what a plugin is bringing into your project is to read the documentation, or if insufficient documentation exists, try to reach out to the Kotlin devs/a Kotlin specific support forum.
Edit in response to clarification: No, there is no way know what a plugin is doing without looking at documentation; plugins are frequently Groovy/Java programs that run with your build. It'd be like asking your computer to surmise what "xyz.exe" does without googling or running it.
Choosing gradle plugins is a very big and deliberate choice for your build procedure, and it needs to be done carefully and with consideration for what functionality they bring and what settings to use for each plugin to ensure your build delivers to results you need. Even if we had SciFi computers that could magically say what a random binary does in plain English, you'd be better served by doing your legwork, reading the docs, and figuring out what your plugins do and how to actually use your plugins effectively anyway.
So we have a huge multi-project codebase with structure like below:
C:\Eclipse\Workspace->
AR
DC
CI
..
..
Each project has a build.gradle file which has 80% of the code same with only dependencies section changing for all the projects.
What I want to achieve:
I want to create a parent project named "BuildAllProjects" which would be the ONLY project having build.gradle, settings.gradle and gradle.properties and propose to have a properties file for mentioning the dependencies of each project, something like:
AR=j2ee,commons-lang,FW,DA,Common
DC=commons-codec,FW,DA,Common,spring-core
and then use the gradle expand[] properties to dynamically fill the dependencies for the project which I am building, so for instance, if I am building AR, I may want to run:
gradle -PAR build
which will read dependencies for "AR" from the properties and expand in the form :
dependencies {
compile name 'j2ee'
compile name 'commons-lang'
}
Do you guys think this is possible or is this the WORST way of achieving it? I am new to GRADLE overall and information provided above is based on knowledge that I have acquired in a weeks time. Please provide your suggestions to implement this at the BEST of gradle.
Thanks,
Yogendra
Layering a properties file based build language on top of Gradle's build language doesn't strike me as desirable. Instead, I recommend to focus on writing clean and DRY Gradle build scripts. You can learn more about Gradle's powerful abstraction capabilities (configuration injection, script plugins, buildSrc, custom plugins and extensions, etc.) in the Gradle User Guide.
In a typical multi-project build, subproject build scripts mostly contain dependency declarations, whereas most other configuration happens in the root build script and/or script plugins.
I'm setting up a (java) maven project that depends on a library (Jettison, among others) that is in the Maven repo. Jettison, in turn, depends on stax. I need to run a tool (Jar Jar Links) on stax (to change the namespace). How do I alter the rules for a transitive dependency in a maven project? My transitive dependencies are being included in my target folder using the copy-dependencies goal (I assume this is how things are usually done). I assume that this is the point where the plugin would be run on the transitively-generated artifact.
Extra question: I don't need this at this point but how would I go about altering the source in the transitive dependency? I can get the jar of the source with mvn dependency:sources but, from there, I'm not sure what the right approach is.
Victory!
Seems at least two people are even more clueless about Maven than me so let me explain what I'm doing before I report the fix at the bottom of this post (spoiler alert: it looks to be a bug in JarJar).
Android uses Java but its missing a lot of the java core (specifically, javax classes). The Android DEX compiler (which converts .jars to Android .dex files) won't even allow you to compile things in the java.* or javax.* namespace because it'll (usually) break stuff. However, in some (many) cases, there are routines that you might want to include -- specifically because they are used by existing libraries. The most legendary is StAX, which is why Google posted an example of how to include it here in the Dalvik repo's wiki. The example uses JarJar... with ant. Transitive dependencies are not really an issue when you aren't using a repo so they are not addressed in the wiki.
I was able to get JarJar to run on my source with Maven but without changing the namespaces in the dependencies (and transitive dependencies), that's worthless. Hence my question.
I thought that the copy-dependencies plugin might be useful for... copying the dependencies and running a transforming plugin in the process. Copying dependencies is mentioned as a step in the official "Maven in 5 minutes" doc so it seemed like a good start but maybe the the people who wrote the official docs don't know how to use it :-) . Either way, it it didn't help -- there is no simple way I could see to transform the jars as it copies.
Using the verbose spew from Maven, I was able to see that Jar Jar was in fact processing my jars properly... and then throwing out the result. It would have packaged the converted classes from the transitive dependencies in my artifact with the rest of my code but, instead, it "Excluded" them. Jar Jar parameters are basically undocumented and most of the tags aren't even listed in the docs but all of the examples I could find use a section with wild-cards that tell it what classes to hold onto. At least I thought (think?) that's what the section is for. Instead, it seems to randomly throw out stuff. Basically, the section is busted. For example, I had:
<keep>
<pattern>com.example.**</pattern>
</keep>
...thinking that this would keep classes that began with com.example. Wrong. It keeps whatever the hell it wants. I tried a million things in that spot until one worked:
<keep>
<pattern>*.**</pattern>
</keep>
This only keeps the classes I wanted -- the classes it updated and the originals of the ones that it didnt touch. Note that ** doesn't even work. This is version 1.8 of the JarJar plugin (the version most poms Ive found use).
Back to work.