I'm working on a project in Intellij IDEA which is divided into several Maven modules. Moreover I configured these modules as WAR artifacts, so they can be deployed to a Tomcat 8 independently. During development I recognized a behavior I couldn't solve so far: If I add/remove a dependency in a module's pom.xml these changes are not considered in the lib-directory of my final artifact, leading to ClassNotFoundExceptions on server startup and so on. The only solution that came up to me is to fix these changes in my artifact settings manually, which works but seems not very handy to me. Is there any way to configure IntelliJ to synchronize an atrifact's lib folder with Maven dependencies automatically?
Sorry in case of duplication. I already found questions related to this one, but these solutions as well as the JetBrains docs have not been successful so far.
Thank for helping me!
Finally got it. The problem arises if you create WAR artifacts 'manually'. Because IntelliJ uses pom.xml to configure artifacts automatically, including war makes IDEA creating all necessary artifacts for you. These are always up to date with your Maven dependencies.
Related
I use both Intellij IDEA (2018.3.5) & Eclipse IDEs, but I prefer Intellij. I have a maven based Java project with multiple poms. I added some dependencies to one of the pom files. I need to find out if there are any dependency conflicts which could prevent the build from running when its deployed, and then exclude them. I tried the steps given below to find conflicts which could cause problems. Are they enough or do I need to do more ?
Check if there are any compile time dependency conflicts with mvn clean install -DskipTests. Build was successful with no errors.
Check if Intellij shows no problems under File > Project Structure > Problems. There are no problems.
I also saw the dependency tree with mvn dependency:tree -Dverbose. It has a lot of "omitted for duplicate" and "omitted for conflict with" items, but the build was successful. I don't see any errors though. Does this mean that everything is okay or do I have to do something more about these conflicts ?
The best way to tell if everything is fine with your application is to have good tests.
However normally one doesn't exclude transitive dependencies from project's <dependency> libraries. Doing it can potentially break the dependency in a subtle and hard to notice way. It's usually safer to remove the whole <dependency>.
There are few scenario when one should use <exclude>:
Dealing with incompatible transitive dependencies between different libraries e.g. A requires library C-1.0 but library B requires library C-2.0 while C-1.0 and C-2.0 can't coexist on the classpath.
Having transitive dependencies already provided by system e.g. deploying to Tomcat with additional JARs in the TOMCAT_HOME/lib directory.
If you decide to exclude a dependency it's important that you check the final artifact because sometimes plugins do weird things e.g. there were versions of maven-assembly-plugin affected by a bug that resulted in different dependencies being resolved during shaded JAR creation than maven-dependency-plugin used for compilation.
That looks easy enough: search the net in which package they are, copy the dependency into your pom.xml and here you go!
But I didn't didn't anything that I could use as a dependency.
Not much of a surprise, other people had the same problem, and solutions can found here https://stackoverflow.com/a/29270114/4142984 in combination with https://stackoverflow.com/a/15692230/4142984 .
In other words, those solutions suggest to get the jar manually and hard-link it in you build-path. It worked, though.
But isn't maven supposed to do that?
Question is: what did I miss, to tell maven to do this.
And I'm using maven with eclipse, just in case this would make a difference.
The links you provided suggest adding a JAR to your project CLASSPATH. That's not using Maven.
If you want to have Maven manage that dependency, and it's not in a Maven Central repo, you need to do an mvn install to your enterprise or local Maven repository.
I'm not if this Maven plugin is what you need. Maybe you can consider that as well.
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".
We use maven-release-plugin to release our maven components to repository(ies). However, some of these components use ranges on some of our dependencies. We want this because some of the dependencies are released often (Snapshots are not an option)
When we use release plugin the ranges are checked into scm and deployed to our maven repo. This doesn't make any sense since unresolved pom files in the maven repository could (and will) ensure that other build change for one build to another.
We tried using release:prepare-with-pom, but the just makes a new pom file that is committed to scm (release-pom.xml). The original pom with ranges is still deployed to the repo.
As another snag we would like to keep the ranges for the next development release. So our head/trunk should not b resolved.
I have this feeling that we are going about this the wrong way.
Can anyone please help us to solve our problem? If there are other ways to do this we would appreciate your suggestions.
I have stumbled upon two known maven release plugin bugs. Please see the following bug reports:
MRELEASE-618
MRELEASE-727
These are scheduled to be release in version 2.2.3 or 2.3 of maven-release-plugin
Edit as response to posted comments:
I agree that it is not obvious why these bugs solves my problem. I'll try to elaborate.
To get the release plugin to use the resolved pom file and deploy it you need to first use release:prepare-with-pom and then release:perform. If you want perform to deploy the resolved pom file you need to set the pomFileName in config to release-pom.xml. If not it deployes the unresolved pom.xml. Deployed pom files with ranges is not a good idea. This is why the 618 is needed.
The 727 is needed because the release-pom.xml is only checked in on the tag. When doing a release:perform your tag is checked out in the target directory. Because og the bug the plugin is looking for the release-pom.xml in the module root directory and comes up empty. This could also possibly go wrong without the pomFileName config, but less likely.
Ranges is generally a bad idea in Maven because it is buggy and because Maven does not by default deploy the resolved pom files. If Maven always deployed resolved pom files ranges would be a good idea.
Last month I asked this question because I couldn't get the EhCache jar to pull down into my local Maven cache using the M2E Eclipse plugin.
Now, I am trying to convert several EhCache/Terracotta POM files into Ivy XML files (using the IvyConvertPom task (which works perfectly fine for every other POM in my local repository - and there are hundreds) and it is choking, stating:
impossible convert given pom file to ivy file: java.io.IOException: Impossible to load parent for file:/C:/Users/myUser/jars/net/sf/ehcache/ehcache-terracotta-root/2.5.0/ehcache-terracotta-root-2.5.0.pom. Parent=org.terracotta.forge#forge-parent;2.3 from=C:/Users/myUser/jars\net\sf\ehcache\ehcache-terracotta-root\2.5.0\ehcache-terracotta-root-2.5.0.pom to=C:/Users/myUser/jars\net\sf\ehcache\ehcache-terracotta-root\2.5.0\ivy.xml
Could not find artifact for C:/Users/myUser\jars\net\sf\ehcache\ehcache-terracotta-root\2.5.0\ehcache-terracotta-root-2.5.0.pom
This is happening for all of the following EhCache/Terracotta artifacts:
net\sf\ehcache\ehcache-terracotta\2.4.7\ehcache-terracotta-2.4.7.pom
net\sf\ehcache\ehcache-terracotta\2.5.0\ehcache-terracotta-2.5.0.pom
net\sf\ehcache\ehcache-terracotta-root\2.4.7\ehcache-terracotta-root-2.4.7.pom
net\sf\ehcache\ehcache-terracotta-root\2.5.0\ehcache-terracotta-root-2.5.0.pom
I'm not sure if this issue is related to the issue I had last month, or if the developers over at EhCache just have a non-standard way of writing their POMs, but this is twice now where Maven (IvyConvertPom uses Maven XSLT under the hood) has choked on doing something with their jars.
Does anything jump out at anybody as being obvious? Otherwise I have to debug Ivy code, which sounds like a painful way to wrap up a Wednesday. I'll do it if I have to, but thought I'd ask here first in case I was missing something glaring.
Thanks in advance!
I think the problem is that ivy can't resolve org.terracotta.forge#forge-parent;2.3
I'm not expert in ivy or IvyConvertPom, but I think you might need to somehow compel ivy into using the terracotta maven repository:
http://repo.terracotta.org/maven2/
I think I reproduced this problem locally and ran ant with "-d" and I could see it try all the standard maven repos out there, but not all terracotta artifacts are on maven central.
I have no idea how to inform ivy about other repos though, hopefully you know that bit of the puzzle
The ehcache versions prior to 2.9.0 have declared terracotta artifacts as a managed dependency supplied by the specific maven repository.
A fix for this bug has made it to ehcache project on Feb 6, 2015 where it became a jar dependency instead.