Maven does not resolve correct SNAPSHOT dependencies - java

I will be quick. My maven version is 3.5.0. I'm using some libraries in my web applications. The libraries are installed separately and deployed in an artifactory instance.
I have the following pom (part of):
<project>
....
<properties>
<process.domain.common.version>0.0.1-SNAPSHOT</process.domain.common.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.intersoft</groupId>
<artifactId>process.domain.common</artifactId>
<version>${process.domain.common.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.intersoft</groupId>
<artifactId>process.domain.common</artifactId>
</dependency>
</dependencies>
</project>
but in the libs, Maven puts this library:
process.domain.common-0.0.1-20190319.151024-3.jar
instead of this:
process.domain.common-0.0.1-SNAPSHOT.jar
My dependencies are resolved from artifactory. Why does Maven put this temporary library with timestamp name instead of the SNAPSHOT? This behavior does not happen in all resolved libraries.

Finally, i found the solution.
The solution is to add maven war plugin in your pom.xml of the war project:
<properties>
<version.war.plugin>2.5</version.war.plugin>
</properties>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>${version.war.plugin}</version>
<configuration>
<warName>${project.artifactId}</warName>
</configuration>
</plugin>
</plugins>
</build>
Proof:
WEB-INF/lib without the war plugin:
WEB-INF/lib with the war plugin:

Maven append the current date to snapshots for compare the snapshot version from your local repository and the snapshot version from remote repository and evaluate if is required download remoting jar, because that downloading 0.0.1-SNAPSHOT today might give a different file than downloading it yesterday or tomorrow.

If you build a Snapshot locally, it is just build with the name 0.0.1-SNAPSHOT. If you deploy it to Artifactory, it gets an internal timestamp version number like the one you mentioned.
When you download it again, Artifactory gives you the latest timestamp.
So locally, you sometimes have a -SNAPSHOT version and sometimes a timestamp version. The exact rule how the artifact in the war is named is unclear to me, but whether you have timestamped version or not, you should be fine.

Related

how do I tell maven 3.6.3 to get latest version of artifact from custom repository

I need to download the latest version of artifact from custom repository rather than maven repository.(Download a latest single artifact from the custom repository)
I followed the how do i tell maven to get latest version of artifact from custom nexus repository.
How do I tell Maven to use the latest version of a dependency?
https://www.baeldung.com/maven-dependency-latest-version
<dependencies>
<dependency>
<groupId>com.LDBS</groupId>
<artifactId>LDBS</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>org.demo.repo</id>
<url>http://demoRepo/dependencies</url>
</repository>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.7</version>
</plugin>
</plugins>
After including the version plugin (mvn versions:display-dependency-updates) I am able to see the latest new version
But I can't download that version to my local repo using following commands
mvn versions:use-releases
mvn versions:use-next-releases
Still I am only getting the old snapshot version not the latest version jars from my custom repo. Eclipse mavendependencies too referring the old snapshots because latest version are not downloaded in local repo
Any one please advise

maven war plugin does not forget about old files and dependencies and creates a war that contains removed files and dependencies

Hello I'm having a weird problem about war creation.
I use maven-war-plugin (tried with 3.1.0, 3.2.0, and 2.6). When I run war:war (or mvn clean package, or similars) the war is created but I noticed that it is like it always packages all the files and dependencies it encountered in the history of the project. I noticed this because the war file is always getting bigger and by opening it I see there are a lot of dependencies that I declared on the pom but now they are removed, and most importantly there are classes I deleted from the project! I even tried to start a new project and the result does not change.
I guess I'm using this badly... Is there something I should do to let him "forget" about the history and force it to consider the project "as it is" when creating a war?
Thanks for the help!
PS:
I always clean and compile before running war:war;
I work with IntelliJ IDEA Community 2017.3
using jdk 1.7 because of technical constraints.
Just for completeness, there is my pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>sduca-consumer-listener</groupId>
<artifactId>sduca-consumer-listener</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<webappDirectory>/sduca</webappDirectory>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- Using Spring 4 because of jdk 1.7 -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
</project>
EDIT1: I tried to change versions of maven-war-plugin, maven-compiler-plugin, and Maven itself, but nothing changes.
EDIT2: I tried changing the output directory, no changes. I tried to change version of the dependencies and as "expected" now the war includes both versions, becoming bigger and bigger...
EDIT3: I reinstalled IntelliJ IDEA, upgrading to the latest version. Nothing changes, it has only reset the content of the package, but it still "keep track" of the content and dependencies and still includes removed stuff on the package when creating a new one.
EDIT4: I've started using mvn clean compile war:war instead of mvn clean package and at first things started working, but then the problem of the existing old files returned. However, I find out that if I manually remove the exceding resources and *.class from the war it looks it works (at least it's deployed).
It's just a trick worked for me many times,
Backup your dependencies from pom.xml and delete it.
Do a clean build, it will show errors in all Java classes. Also delete the previous war.
Now, replace those backed up dependencies and clean build the webapp again. All errors will be disappeared and war file will be as expected.

Running Tomcat Maven plugin with added project provided dependency

Need to be pointed in the right direction on this perhaps, but if I add a "provided" dependency that is not included in the tomcat set of provided dependencies, running tomcat7:run from within eclipse fails with a classnotfoundexception on the class from the provided scope jar.
It needs to "provided" because it's a custom jar from a separate project that I've run mvn install on and for production am copying the jar to the $CATALINA_BASE/shared directory so that it's available (as a singleton) across applications/webapps.
<dependency>
<groupId>IndexFileAccessTracker</groupId>
<artifactId>IndexFileAccessTracker</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
Only way I see (with my limited knowledge of Maven and the Tomcat7 plugin) is to change the scope to compile when running tomcat from the plugin in Eclipse and then change the scope back to provided when running the package goal.
Are there solutions to this? I tried adding the dependency to the the tomcat maven plugin (keeping the main maven dependency as provided but got the same class not found error:
<!-- For Maven Tomcat Plugin -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<path>/CounterWebApp</path>
</configuration>
<dependencies>
<dependency>
<groupId>IndexFileAccessTracker</groupId>
<artifactId>IndexFileAccessTracker</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
</plugin>
Again, it needs to be provided in the main Maven dependency because I don't want it included in the deployed WAR.
Resolved by using profiles, similar to https://stackoverflow.com/a/5951630
...
</dependencies>
<profiles>
<profile>
<id>runineclipse</id>
<dependencies>
<dependency>
<groupId>IndexFileAccessTracker</groupId>
<artifactId>IndexFileAccessTracker</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
</profile>
</profiles>
<build>
...
Then in my run/debug configuration just added runineclipse to the Profiles: box.
(On a side note, to do step through debugging I had to manually add the project to the Source tab.)
The build configuration was just the same package in the Goals: box; and I left the original dependency to have scope provided.
The tomcat7-maven-plugin and its run goal
Requires dependency resolution of artifacts in scope: test
Everythig that is on the compile classpath is also on the test classpath.
Thats why it is working with scope compile.
So the solution in your case would be to mark your dependency as test what even is (imo) semantically correct.
This will make the library available at local test-time, but not in the final artifact.

Maven Profile in different dependencies

I have a Maven module with two different database profiles.
<profile>
<id>db-localhost-oracle</id>
<dependencies>
<dependency>
<groupId>ojdbc6</groupId>
<artifactId>ojdbc6</artifactId>
</dependency>
</dependencies>
<properties>
<db.driver>oracle.jdbc.driver.OracleDriver</db.driver>
<db.dialect>no.jbv.sergej.util.FixedOracle10gDialect</db.dialect>
<db.url>jdbc:oracle:thin:#//localhost:1521/xe</db.url>
<db.hbm2ddl>update</db.hbm2ddl>
</properties>
</profile>
<profile>
<id>db-localhost-mysql</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
<properties>
<db.driver>com.mysql.jdbc.Driver</db.driver>
<db.dialect>org.hibernate.dialect.MySQL5Dialect</db.dialect>
<db.url>jdbc:mysql://localhost/${mysql.schema}</db.url>
<db.hbm2ddl>update</db.hbm2ddl>
</properties>
</profile>
When is run maven install with "db-localhost-mysql" it includes the "mysql-connector-java" jar file in lib directory. Now I do clean install with "db-localhost-oracle" and it includes the both "mysql-connector-java" and "ojdbc6" jars in the lib directory.
How can I make it like, if I build with one profile maven automatically remove the jars for other profile?
Your problem does not match what should happen in practice. Your profile definition sounds about right to me:
mvn clean install will enable the db-localhost-mysql (as it is marked as to be activated by default) and it will add mysql-connector-java. The same will happen if you run mvn clean install -Pdb-localhost-mysql
mvn clean install -Pdb-localhost-oracle will add the ojdbc6 driver. The mysql profile will not be enabled (as it is triggered only if no profile is explicitly active).
That does not mean your current dependency hierarchy hasn't already one of those jars. It might come as a transitive dependency. To isolate this case and know which project needs to be fixed run mvn dependency:tree -Pdb-localhost-oracle to look at your dependencies hierarchy when the mysql profile is not enabled.
I assume you download your downloaded dependencies using maven-dependency-plugin somewhere outside your target dir (${basedir}/lib).
If that is the case, you would need to include your lib dir inside your clean definition (see http://maven.apache.org/plugins/maven-clean-plugin/examples/delete_additional_files.html):
<build>
[...]
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.5</version>
<configuration>
<filesets>
<fileset>
<directory>lib</directory>
</fileset>
</filesets>
</configuration>
</plugin>
[...]
</build>
However: Please consider doing it differently:
do not have your regular build change anything outside the target directory, if possible (which would have prevented your problem in first place), instead download to something like target/lib
Please do not use profiles to change the outcome of your build. This is dangerous. (see http://www.blackbuild.com/how-to-really-use-maven-profiles-without-endangering-your-karma/ for an extended explanation)
If you want different outcame consider Maven Assemblies.

Maven2: can we have dependency for a plugin thats used in the build section

I am using a project's open source that consists of a set a parent POM and
several children POM. Those children POM represent libraries, arch-types and
a plug-in. This plugin depends on various of these children modules and is
used within the section of dependent projects like mine.I have imported
this Maven project to my Eclipse workspace.
In my own project's POM (also in Eclipse) I can reference those modules via
dependencies without a problem. However I would also like to use the plug-in in
the build section but it cannot be used due to the following Maven2 error:
Project build error: Unresolveable build extension: Plugin org.grouplens.lenskit:lenskit-eval-maven-plugin:2.1-SNAPSHOT or one of its dependencies could not be resolved: Could not find artifact org.grouplens.lenskit:lenskit-eval-maven-plugin:jar:2.1-SNAPSHOT
This is because I am accessing the POM's directly via Eclipse's "resolve dependencies
from workspace projects" and of course this snapshot version has not been deployed to
a repository so this is the only way I can actually use it.
I tried:
Add any of the dependencies of lenskit-eval-maven-plugin:
Their are several but I just added the only one of the project's
module (others include stuff like maven-plugin-api):
<dependency>
<groupId>org.grouplens.lenskit</groupId>
<artifactId>lenskit-test</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
placing a dependency for that plugin module before using the module in the section
<dependency>
<groupId>org.grouplens.lenskit</groupId>
<artifactId>lenskit-eval-maven-plugin</artifactId>
<version>${lenskit.version}</version>
</dependency>
adding a dependencies in the plug-in itself so:
<build>
<plugins>
<plugin>
<artifactId>lenskit-eval-maven-plugin</artifactId>
<groupId>org.grouplens.lenskit</groupId>
<!-- TODO -->
<version>${lenskit.version}</version>
<extensions>true</extensions>
<dependencies>
<dependency>
<groupId>org.grouplens.lenskit</groupId>
<artifactId>lenskit-eval-maven-plugin</artifactId>
<version>${lenskit.version}</version>
</dependency>
</dependencies>
And using (0), (1) and (2) at the same time
Ok, so I realize that attempt (2) is pushing it. So my question is: is their
any way I can use a plug-in in the build section that is also a dependency?
If so how? If the use of solution (1) is correct, could this be an issue with
Eclipse's method of resolving to local workspace first?
TIA
There is no existing artifact for maven2 from its default repo. Try adding explicit repo or this plugin is not suitable for maven2 (check this for maven3, I dont have any problems).
In maven central you will not find any snapshot version of such things only release. In your case you need to use a different version of the plugin like this:
<groupId>org.grouplens.lenskit</groupId>
<artifactId>lenskit-eval-maven-plugin</artifactId>
<version>2.0.2</version>
which is of Sep. 2013...
The thing which you mentioned in your question like this:
<build>
<plugins>
<plugin>
<artifactId>lenskit-eval-maven-plugin</artifactId>
<groupId>org.grouplens.lenskit</groupId>
<!-- TODO -->
<version>${lenskit.version}</version>
<extensions>true</extensions>
<dependencies>
<dependency>
<groupId>org.grouplens.lenskit</groupId>
<artifactId>lenskit-eval-maven-plugin</artifactId>
<version>${lenskit.version}</version>
</dependency>
</dependencies
does not make sense, cause you define a plugin where you like to add the same plugin onto the classpath of the plugin.
The only thing which will bring you to solve the problem is using the right version like this:
<build>
<plugins>
<plugin>
<artifactId>lenskit-eval-maven-plugin</artifactId>
<groupId>org.grouplens.lenskit</groupId>
<!-- TODO -->
<version>2.0.2</version>
<extensions>true</extensions>
<...>
</plugin>
...
</plugins>
</build>
You might need to add a <pluginRepository> in your settings.xml or in POM for your snapshot version of the plugin, because plugins are not being searched in normal repositories.
UPDATE
Your local maven repo is an auto-created cached version of online repos under $HOME/.m2/repository.
-SNAPSHOT versions which are deployed to Central repo are usually stored on some other address, which must be explicitly set. Adding this should help to use the snapshot version if you don't have this in your POM/settings.xml:
<pluginRepositories>
<pluginRepository>
<id>sonatype-snapshots</id>
<releases><enabled>false</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</pluginRepository>
</pluginRepositories>

Categories