Local Maven Repository issue with multiple jars - java

I have local Maven repository in C:\Users\<User_Name>\.m2 directory. After getting "java.lang.NoSuchMethodError..." exception and navigating problem on the web, I see this page mentioning to remove unused jar version(s) from local repository.
My questions are:
1. When I look at C:\Users\<User_Name>\.m2\repository\org\mockito\mockito-core folder, there are 52 different version folder. I think it is similar for other jar libraries. So, should we clean unused jars periodically? Or should we keep unused versions of a jar library?
2. If I just have 3.0.0 version of mockito-core in my pom.xml, how the app use or mix another version(s) in the local repository? Normally, if I just a single mockito-core dependency in my pom.xml, may there be any problem as mentioned on that page (solving the problem after removing other jar version)?

1)
You do not need to "clean unused jars" from your local maven repo manually. How do you want to decide which jar, which version is unused? Maybe your next project will use the jar that you want to delete. Who knows.
If you have enough disk space then you can leave your local maven repo directory untouched for years. If this directory grows too big, then I suggest you delete the complete .m2 folder. Then the next time when you build a project, Maven will download automatically all dependencies that your project needs.
There is only one use-case when deleting your local maven repo can cause a headache: if you have installed some custom jars manually.
2)
It is highly possible that the different dependency versions that you see in your local Maven repo directory come from different projects that you built earlier.
Anyway, you can display your effective pon with the Apache Maven Help Plugin.

Related

how to get all dependencies of a library?

I want to use the Google Firebase Messaging library in my Android Project. But my laptop just works offline and has not any access to the internet. I want to download FirebsaeMessaging library with all it's dependencies then add those files as aar library files to my project. First I want to get list of all dependencies of that library. How can i do this without internet? Thanks.
There are two approaches in general:
You download the complete dependencies with your online system, copy them into a libs folder and then create a project where you dependent on every jar in that libs folder.
You create a maven based project, build the project so that every dependency is copied to your local repository and copy the .m2 (local repository) to your offline machine. In case you want a gradle based project, #lance-java already posted a solution to that.
The first approach has the advantage that you have an isolated project with no dependency to the internet. Everything is in your project and explicit. You would have to check in your dependencies into your source control system like in good old times.
The second approach is good, if you are working in a team on that project. The export of your dependencies hat nothing to do with the project setup itself. Every programmer would find a "normal" project setup and dependency management.
If guess, that you want to go for the 1. way. If so, I would suggest to use ivy to download the complete dependency tree. Put the ivy-X.Y.Z.jar into your project beside a script that lists all dependencies - some sort of poor mans dependency management.
Example:
$ java -jar ivy-2.5.0.jar -dependency com.google.firebase firebase-admin 6.8.1 -retrieve "libs/[artifact](-[classifier]).[ext]"
This command would download the complete dependency tree for com.google.firebase:firebase-admin:6.8.1 and store the jars without version into the libs folder.
You could use my dependency-export plugin to export dependencies to a directory using maven directory conventions. You can then use the directory as a local repository for building offline.
As of Gradle version 6.1 the dependency cache is portable meaning that you can copy the dependency cache from one machine to another and the second machine should be able build offline. Perhaps this is what you want?
See this issue

Compilation error occurs if jars are added manually in Intellij

I am using Maven in my project, and for some reasons, some additional jars should be added manually (I have followed the step like Correct way to add external jars (lib/*.jar) to an IntelliJ IDEA project).
The package can be imported successfully. However, the compilation error happens, which indicates the package does not exist and cannot find the symbol of the used object.
I have tried the following tips but it remain unchanged:
Invalid caches / restarts
reimport
delete .idea file and .iml file
The scenario is quit similar to this one : https://intellij-support.jetbrains.com/hc/en-us/community/posts/206821195--beginner-question-including-external-jar-compile-error.
Please see the following sample images. It may run successfully but cannot be compiled well.
The reason is that when you add a library manually via IntelliJ, only IntelliJ knows about them and when you compile your code using Maven, it can't be find by Maven because Maven only searches for dependencies you defined in pom.xml.
You should install your libraries in your (at least) local maven repository and add them as a normal dependency in your pom.xml. Then you don't need to add them manually in IntelliJ.
You should follow the steps mentioned at Guide to installing 3rd party JARs
Update:
Also you should note that if you're working as a team, you should install this on the local maven repository of all developers (which is not practical). The best solution is to install a Maven repository (e.g. Nexus, Artifactory or Archiva) in a server on your local network and upload your private jar files on those servers. Then all developers can define the address of the local Maven repository server in their local Maven settings and use artifacts/libraries from that servers. Plus it works as a local cache/proxy to fetch any Maven artifacts and prevents unnecessary calls to public maven repositories.

How include 3rd party jars in maven project (compile, build, package) where adding local maven repo is not an option?

We have a git project that has some 3rd party jars which are not available in any Maven repo and are in a "lib" folder in the project. I need to include them for compiling, building and then package them into the WAR in WEB-INF/lib.
I cannot add them as a local maven repo from the command line because this projects needs to be buildable for anyone cloning the repo without requiring them to run extra commands (I have no way around this requirement).
I saw some people suggesting System scope but that then Maven won't package them into your WAR:
<dependency>
<groupId>com.roufid.tutorials</groupId>
<artifactId>example-app</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${basedir}/lib/yourJar.jar</systemPath>
</dependency>
How do I get these jars to be used for compiling/inspection, building and then packaged into the WAR?
You can use :
System scope but make the packaging yourself via assembly plugin
A maven repo along with your project (i.e. maven repo on-the-fly, basically same as local repo but without having a extra moving part to worry about because this repo follows your project).
For Maven repo on-the-fly option, you can do as described here (which is, take any already existing Maven repo, which already contains your needed jars, such as your local one, put it in your project, and then reference this repo from your project using relative paths).
I'll assume you've verified that whatever mechanism you might use to distribute these jars would be in compliance with the relevant licenses. If it would, then it seems there would be little reason for the jars' creators not to provide for official Maven distribution, so your best option might be to lobby for them to do that. But if not, and yet for some reason they'll allow for you distributing the jar (either through cloning of your repo, or via a separate Maven repo you maintain):
There are several ways. I give preference to approaches that don't put the jars in the git repo.
Publish a Maven Repo
So it's possible to host a public-facing repo and serve the artifacts that way. The pom can add your public-facing repo to the build, so that those who clone can build without having to run any special commands.
Running your own repo isn't terribly difficult. The OSS versions of Nexus or Artifactory jFrog would probably be perfectly capable.
But, if we're assuming the authors' refusal to publish their own jars via Maven means they don't want them distributed that way, then there's no reason to spend much time on the details of this option. So moving on...
Distribution in the Git Repo
I guess this is what you're doing, though again if Maven distribution violates the license I'd make sure you're splitting hairs the right way in thinking that this doesn't.
So the question would be how to get Maven to deal with the artifacts distributed in this way, and again there are some options.
Your objection to putting the jars in the local repo is that it would require extra commands of the user; but actually this could be automated in the "validate" phase of the build. Binding install:install-file to the validate phase should work.
Alternately, your objection to using system scope is that the file isn't copied into the final war. You might be able to use the dependency plugin to force the issue, but I'm not sure of that. What I am sure of is you could treat the directory containing the jars as a web resource with suitable configuration in the war plugin. (You'd want it to be treated as unfiltered and to map to the WEB-INF/lib folder.)
In any case, if you distribute jars (or other large binaries) in the git repo, I strongly recommend you look at git lfs. This will require one-time configuration by each of your users, but it will prevent your repo from gradually becoming bloated and unusable.
Use forward slash (/) to backslash () in the systemPath.
<dependency>
<groupId>com.roufid.tutorials</groupId>`enter code here`
<artifactId>example-app</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${basedir}\lib\yourJar.jar</systemPath>

Eclipse detects wrong maven dependency

I faced with foggy issue.
I am novice in project. I use Eclipse. all my colleagues use IDEA. I have checkout project from svn.
I performed corresponding maven tasks for building and deploying project. all works good.
But my Eclipse shows me problem.
in code:
sceneService.uploadFile(...);
eclipse shows that sceneService hasn't uploadFile method
I began researching. I show this class on PC of my colleague. But there aren't this issue. I noticed that we use different version of jar file of sceneService class.
We use same revision of the pom.xml.
dependency for jar in my pom.xml(for my module):
<dependency>
<groupId>com.day.cq.dam</groupId>
<artifactId>cq-dam-scene7</artifactId>
<scope>provided</scope>
</dependency>
when I type alt+shift+w I see that jar contains sceneService class takes from another module.
I think there is some issue in downloading the correct jar by Maven. your local repository may contain an earlier version of the jar.
Try these commands by going to the root folder of your project from command prompt.
mvn eclipse:clean
mvn eclipse:eclipse
mvn install
if still the problem persists try deleting your local .m2 repository and again rebuilding the project
I think my earlier comments about the "provided" scope are a red herring. The actual problem is likely due to conflicting versions.
By default, Eclipse enables workspace resolution of artifacts. This means it will find artifacts to use (i.e. cq-dam-scene7) from other projects in your workspace. It will also find them in the .m2 repository as well; I'm not sure which takes precedence.
Possible routes towards a solution include:
Specify a version for your artifact. This will ensure you use the correct JAR, even if it has to be found in the local .m2 repository.
<dependency>
<groupId>com.day.cq.dam</groupId>
<artifactId>cq-dam-scene7</artifactId>
<version>1.2.3</version>
<scope>provided</scope>
</dependency>
Ensure your local cq-dam-scene7 project contains the correct code - i.e. a version with the uploadFile() method defined.
I am facing a similar issue, I have two Maven projects in workspace. Main Project is using output JAR of a Helper project as an artifact.
Now the problem is that Main project is trying to Reference JUnit library of Helper project (which has older version 4.10) instead of it's own JUnit library having version 4.12. Because of this in-correct referencing I get build errors in main project.
Only work around which I found is to close the Helper project and have only Main project open in workspace.
Possibly this is an Eclipse bug.
Delete the repository folder in .m2 (in your user dir) and let maven rebuild it in next build cycle.
It will ensure no old jars are cached locally

Switch to older version of Maven

I am trying to build a project using Maven but I don't know Maven.
Anyway I had a problem and I found in a link to use an older version of Maven. So I did, since the instructions for the project were about 2.0.9 anyway.
But now I am not sure how to proceed. I see under my user.home directory a .m2 folder with a repository directory.
Should I delete this or not?
The .m2 folder contains the downloaded artifacts and some other repository info, which do not depend on the used maven version. So you dont need to delete anything, just use the maven binary of your choice.
EDIT: the contents of the artifacts - .jars, .poms, .boms etc. are defined by the artifacts themselves which are the accesible through repositories/catalogues. The .pom of your project references the needed artifacts. The maven binary downloads the artifacts (and does many other things which are OT here) to your local cache - the .m2 directory. The point is, no matter what version of the maven binary you use, the artifacts remain the same.
You surely can delete your repository. As long as you have an internet connection maven will simply download the artifacts again. But there is nothing to be gained by the removal except a longer initial build time and some traffic.
Sometimes it does make sence to delete certain metadata from the repo, like the .lastUpdated files. It is only advisable if maven is unable to find a dependency which you know for sure is in your repository. You can then run find ./ -name "*.lastUpdated" -exec rm {} \;.

Categories

Resources