Gradle Dependency Management - Transitive Dependency Version Incorrect - intellij-idea

I have two projects edited in IntelliJ IDEA 2016 that use Gradle dependency management: project A and project B.
Project A defines a compile scope dependency for elasticsearch as:
compile 'org.elasticsearch:elasticsearch:2.3.1'
Project B declares a compile scope dependency for project A, as so:
compile 'com.mycompany:elasticsearch-common:2.3.1'
I would expect, in the Gradle tool window in IntelliJ IDEA 2016, for project B to see:
...
com.mycompany:elasticsearch-common:2.3.1 (Compile)
org.elasticsearch:elasticsearch:2.3.1 (Compile)
...
Instead I see:
...
com.mycompany:elasticsearch-common:2.3.1 (Compile)
org.elasticsearch:elasticsearch:1.5.2 (Compile)
...
No other dependency in project B depends on elasticsearch, so it's not being overridden by another dependency declaration.
Indeed, the pom.xml on our nexus for project A has this:
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>2.3.1</version>
<scope>compile</scope>
</dependency>
So why is IntelliJ reporting the transitive version for elasticsearch as being 1.5.2?
What I've tried:
Deleting .idea and .gradle inside project B directory
Deleting gradle caches
Invalidating caches and restarting in IntelliJ
Swearing
Drinking lots of tea
Asking friends and colleagues
Emailing Oprah
Reverting to IntelliJ 15 when all of this was fine (now no longer is)
Going to the toilet (related to 5) and hoping it magically fixes itself when I get back
None of the above work.
What does work is specifying the elasticsearch:2.3.1 dependency specifically in project B, but doesn't that negate the entire reason for transitive dependencies?
Any help is appreciated.
Update 1
As suggested by LanceJava in the comments, I ran gradle dependencies to see what was happening.
This shows that it's specifically downgrading it:
org.elasticsearch:elasticsearch:2.3.1 -> 1.5.2
When I ran gradle dependencyInsight on that dependency it came up with:
:dependencyInsight
com.mycompany:elasticsearch-common:2.3.1 (selected by rule)
\--- compile
org.elasticsearch:elasticsearch:1.5.2 (selected by rule)
org.elasticsearch:elasticsearch:2.3.1 -> 1.5.2
\--- com.mycompany:elasticsearch-common:2.3.1
\--- compile
Anyone have any ideas why this is happening?
Update 2
This seems to have the answer: https://discuss.gradle.org/t/excluded-dependence-comes-back-when-spring-boot-plugin-is-applied/17945/2
It seems that the gradle spring-boot plugin likes to take over a bit and enforce it's own dependency versions (even though I'm not using a spring-boot-starter that is using spring-data).
I fixed this by adding:
ext[elasticsearch.version] = '2.3.1'
to my build.gradle file.

What wasn't made clear in the question was that this project was using the spring-boot gradle plugin, which enforces certain versions of libraries, and was force-downgrading my elasicsearch version to keep it in line with it's spring-data requirements (even though I wasn't using spring-data in my project).
I discovered this by executing:
gradle dependencyInsight --dependency elasticsearch --configuration compile
which at the time came out as:
org.elasticsearch:elasticsearch:1.5.2 (selected by rule)
org.elasticsearch:elasticsearch:2.3.1 -> 1.5.2
\--- com.mycompany:elasticsearch-common:2.3.1
\--- runtime
I learnt that the (selected by rule) part meant that something was programatically selecting that particular version. That narrowed it down to being a plugin.
I was only using 4 plugins, being:
java
maven
idea
spring-boot
and the only plugin I hadn't used elsewhere (and therefore hadn't suffered this problem elsewhere) was spring-boot.
Once I commented this plugin out, I could see that the dependency was correct.
At this point I learnt that I needed to explicitly specify the version I wanted to use by:
ext[elasticsearch.version] = '2.3.1'
Sorted. More tea for me!

Related

Syntax highlight for Kotlin-script files in Idea

I migrated my Gradle project config for Kotlin-script usage: now I have both build.gradle and build.gradle.kts and can switch between them configuring settings.gradle:
project(':myProject').buildFileName='build.gradle.kts'
The issue is kts build.gradle.kts is not properly highlited: it does not resolve dependencies, says version = 123 is not a valid word and so on.
I use Idea Ultimate 2017.1.3 and kotlin-plugin 1.1.2. What's the issue? Deleting build.gradle doesn't help either.
gradle-script-kotlin project files are highlited correctly.
The issue probably was I used incorrect gradle version. I recreated the project specifying gradle version 3.5 and now it works fine. Probably I should use gradle wrapper to prevent the same issue occurence on other developers' machines.

IntelliJ OSGi dependency resolution

I've been searching for quite a while now, no result:
Working on an OSGi project with IntelliJ, how can I make IntelliJ resolve dependencies, as specified in MANIFEST.MF, to other bundles in the same project other than from the specified OSGi framework (a.k.a. "target platform")?
Edit:
Let's say I have a bundle com.example.projecta with the following manifest:
...
Require-Bundle: com.example.projectb;bundle-version="1.0.0"
...
and my modules look like this:
com.example.projecta
com.example.projectb (1.0.0)
How do I make IntelliJ resolve the dependency to com.example.projectb by reading the manifest, not by adding the depedency manually?
IntelliJ IDEA cannot do that, unfortunately. That would require some kind of repository (like Maven, but for bundles).

Mule Maven tests throw ClassNotFoundException all of a sudden

All of a sudden all my Mule Maven projects are throwing this error when running mvn clean test:
java.lang.NoClassDefFoundError: org/apache/commons/cli/ParseException
at org.mule.tck.junit4.AbstractMuleTestCase.(AbstractMuleTestCase.java:71)
I can add a dependency for it, but I shoudln't really have to.
Nothings changed in my code. I am using Mule 3.4
You need commons-cli.jar in your classpath, add this Maven dependency to your pom
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.1</version>
</dependency>
Update: OP's code was fixed after adding commons-cli 1.1 dependency.
Issue description and how to fix it: http://ricston.com/blog/mule-classnotfoundexception-tests-commons-cli/
In a nutshell, you probably have an incorrect JAR named commons-cli-1.2. Delete that and rerun your maven build. You should be good after that.
If the follogin dependency in available in the POM. it should be working fine.
<dependency>
<groupId>org.mule.tests</groupId>
<artifactId>mule-tests-functional</artifactId>
<version>3.4.0</version>
<scope>test</scope>
</dependency>
Then use mvn clean compile to update the dependency.
mvn eclipse:clean eclipse:eclipse clean compile
Hope this helps.
Maven behaviour isn't reproducible from one run to the next: apart from generic network problems and repository corruption problems, anything might be updated automatically at any time, breaking any step of the execution, even if you don't change any of your files.
Your error message about a class in some Apache Commons library suggests a disagreement between the version of that library Mule should be using (one that has the ParseException class) and the library version it actually loads (without the class and causing the exception).
Plausible version mismatch scenarios include an update to a buggy new version of Mule (maybe only to a wrong or corrupted POM) which specifies an incompatible library version, or a random upgrade or downgrade of the latest library version in your repository as a consequence of adding or updating something unrelated to Mule.
Analysis suggestions:
What plugins in your Maven repository have a snapshot version? Which ones of these snapshots were updated around the time the error first appeared?
Which library jars, and which versions, include the ParseException class? What depends on specific versions or on the latest version of those jars?

What is the Ivy equivalent of Maven's versions:display-dependency-updates?

I have an ivy.xml file where I specify my dependencies explicitly. Is there any functionality built into Ivy that will let me discover or automatically update my dependencies which are out of date?
I don't want to use latest.release because I want a completely stable and reproducible build. But every once in a while I'll want to update some dependencies and at the same time it would be good to answer the question, which other dependencies are out of date?
Like you, I only use dynamic versions for in-house dependencies. When upgrading, at the start of a new development phase, I would use one of the repository search tools to discover new versions of 3rd party libraries:
http://mvnrepository.com/
http://mavencentral.sonatype.com/
As I'm sure you're aware, another problem is that upgrading dependencies can often lead to an involuntary upgrade of your transitive dependencies....
What I'd suggest is to generate an ivy dependency report and use this to review your code's module usage. I find this very useful especially considering that some 3rd party Maven modules are not well behaved and will import many unnecessary libraries onto my classpath.
The following is an example of my standard dependencies target:
<target name='dependencies' description='Resolve project dependencies and set classpaths'>
<ivy:resolve/>
<ivy:report todir='${ivy.reports}' graph='false' xml='false'/>
<ivy:cachepath pathid="compile.path" conf="compile"/>
<ivy:cachepath pathid="provided.path" conf="provided"/>
<ivy:cachepath pathid="runtime.path" conf="runtime"/>
<ivy:cachepath pathid="test.path" conf="test"/>
</target>
Hope this helps.... If you find a way to automatically manage this I'd be interested.
One workaround is to use ivy:makepom and then run mvn versions:display-dependency-updates using the generated pom.
I'm not sure if this is the best solution or not, but you can create a configuration (e.g., "checklatest") that asks for the latest versions, then run a report against that.
For example, in your ivy.xml file:
...
<dependencies>
....
<dependency org="somegroup" name="somename"
rev="latest.release" conf="checklatest->default"/>
</dependencies>
and then run an ant task that uses the task for that configuration.
Even there, it isn't necessarily going to pick up the latest version -- e.g., Apache's commons-httpclient eventually got incorporated into the httpcomponents project, so a request for the latest "commons-httpclient" in group "commons-httpclient" will only find version 3.1. But if you look at the publication date on the report Ivy generates, it should be fairly clear that something happened, when the latest publication is 2007. At that point, you would have to investigate.
checkdepsupdate is the rough equivalent in Ivy.
It gives you output like:
[ivy:checkdepsupdate] com.sun.mail#javax.mail 1.5.4 -> 1.6.2
[ivy:checkdepsupdate] commons-codec#commons-codec 1.10 -> 1.11
[ivy:checkdepsupdate] org.apache.commons#commons-compress 1.12 -> 1.18
[ivy:checkdepsupdate] commons-dbutils#commons-dbutils 1.5 -> 1.7
[ivy:checkdepsupdate] commons-io#commons-io 2.4 -> 2.6
[ivy:checkdepsupdate] org.apache.commons#commons-lang3 3.6 -> 3.8.1
[ivy:checkdepsupdate] org.apache.commons#commons-text 1.1 -> 1.6
[ivy:checkdepsupdate] org.apache.poi#poi 3.13 -> 4.0.0

Resolving maven dependencies

Inovking maven2 goal mvn dependency:list on an artifact pom causes to download the whole dependent artifact packages. I think only those pom files are necessary for resolving dependencies. Aren't they?
On the dependecy plugin documentation you can read that dependency:list is an alias for dependency:resolve. What you need is dependency:tree which :
Displays the dependency tree for this project.
Even with dependency:tree you will have to download dependencies.
From Arnaud Héritier (developer on Maven Project)
This is a problem in maven core which doesn't allow in 2.x to resolve dependencies without downloading artifacts.
Each mojo (plug-in in the Apache Maven) has a functionality description. See all dependency plugin functionality.
I am working with the current edition of Maven (the plug-in that shipped with Eclipse Neon), and I'm still working to get my head around how to make it do all the magical things it is claimed to be able to do.
I have the screen pictured below, in which the dependency highlighted in the left pane is unresolved.
!Dependency tree, showing missing dependency1
I thought that selecting (executing) the Update Project item off the project's context menu, as shown in the following image, would resolve it, but it left me with three errors, all, one way or another, the result of a missing dependency.
!Maven fly-out menu in project context menu2
By examining the file system, I have confirmed that the dependency is, in fact, absent.
Color me confused; why didn't that action download the missing dependency?