What is a Maven Dependency exactly? - java

I have just started to learn Spring using Maven. Can somebody clearly explain?

In your codebase, you will have a multitude of packages. Each of those packages will have a pom.xml file which have maven dependencies in there. Those are the dependencies that get pulled in when doing an 'mvn install' on that particular package. E.g. one of your packages which uses spring will probably have this :
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
Further, your package will also depend on other packages, and so will have dependencies on those packages. Each package gets a .jar file of its own when built (which contains .class files). A certain package doesn't rely on all other packages in the codebase, so it just pulls in the ones needed. These packages can be published and pulled in from a locally hosted Artifactory, and in the case of spring it probably gets pulled in from an online maven repo.
The fetched artifacts (.jar files) get put into a hidden repository folder (mine's called .m2/repository) which you can configure in your IDE, and the fetching is done smartly. If it exists already, it won't do the effort to pull in a new one. If you however do want to override the currently fetched artifact, look at this question I asked when I was struggling to understand maven myself.
Notice the < version > tag. This tells maven the version to fetch, and if it sees that version already exists (I'm not sure how it checks, it probably looks at the folder name or some file inside like MANIFEST.MF) it doesn't bother fetching it. In case you have a dependency which has frequent updates, changing this version field all the time can be bothersome, you can make it such that it fetches the latest all the time.
Hope that helps.

Related

How to find java classes that needs a dependency in maven pom.xml file

I have a Maven based project, and I use IntelliJ. The pom.xml file probably contains dependencies that I don't need. How can I find which Java files (in particular the import statements) that need a specific dependency in the pom.xml file? Alternatively, how can I find which dependencies I don't need in the pom.xml?
I have tried to comment out a dependency from pom.xml, build the project and look what breaks. In at least one case, I saw no compile time problems, but there was a runtime problem. This method is also more effort than I want.
I have also tried to find information in the IntelliJ Project explorer, section "External Libraries". But the items listed there are not always present in the pom.xml file. Each versioned item there expands to a tree with a jar file on top, and I can ask IntelliJ about the usage of the contained items. I have found the usage of some packages contained in jar files, but the number of packages to investigate simply becomes too large.
Here is a dependency that I want to know if I need or not:
<!-- https://mvnrepository.com/artifact/com.googlecode.soundlibs/mp3spi -->
<dependency>
<groupId>com.googlecode.soundlibs</groupId>
<artifactId>mp3spi</artifactId>
<version>1.9.5.4</version>
</dependency>
This particular dependency results in three items in the External Libraries list (there are two sub dependencies apparently). Asking IntelliJ for usage of these libraries, I can't find any usage in my own files. But if I remove the dependency from the pom.xml file, I get runtime problems.
Maven offers you the dependency:analyze goal which gives you the artifacts that are declared in your pom but not used by any part of your source code. Beware, though, that there may be dependencies that are only used at runtime.

How to properly use any Java API

I have been trying to use the vget library/api to make my own youtube video downloader. The vget library can be found here: https://github.com/axet/vget
I have downloaded the zip on github and I imported the project into eclipse. However, I am confused to how I am supposed to properly use this API. Should I make a completely new project, and import the classes that I need or do I put my own source files in the project of the api?
I have read other threads concerning this problem. However, they all mention how a api is typically packaged in a JAR file, but in my case it is just files and classes. So I am confused to how I should properly use this api.
The vget project is a maven project. You can see that because it has a pom.xml file in the root folder of the project.
To use it, you don't even need to download the source, because the compiled jar files are already stored in the central maven repository. You can find more information about this here:
http://mvnrepository.com/artifact/com.github.axet/vget/1.1.23
(in general, you can use the http://mvnrepository.com/ site to search whether your library is available on the maven central repository. If it's even a mildly popular library, then chances are that it is)
What you need to do is to make your own project a maven project.
Here's a "5 minutes" starter guide that describes how to do that.
When you've done that, you just add the dependency on vget to your pom.xml file in the <dependencies> section:
<dependency>
<groupId>com.github.axet</groupId>
<artifactId>vget</artifactId>
<version>1.1.23</version>
</dependency>
Since you are making use of a 3rd party software, and not extending it with your own logic, the way to go is to create a new project, which references the 3rd party software.
You then construct your application and make it do whatever you need it to do. When it comes to using logic which is available within the 3rd party logic, you would then simply delegate that call to the 3rd party library.
I have seen on the link you have provided, that this is a maven project. You have to execute a maven package command, or maven install, so that the jar file will be generated.
With this jar follow the Bill's instructions, and add it as external library to your claspath.
When you do this, you will be able to invoke methods of that api.
Let us know if you need some help doing this in eclipse.
If your project is a maven project, you can solve dependencies problems just adding the dependency written on Readme file to your pom file.
The easiest and most automatic way is to use something like maven, ant, or gradle, that will automatically download and put the jars in to your classpath if they are in the central repositories. For example, in the maven configuration file(pom.xml) you can add this to the dependency list:
VGet Maven Repository
These build tools also allow you to add external jars if needed.
If
I would suggest you get familiar with Maven. At the bottom there is a Maven dependency you just have to include into your pom.xml, and then you can use the extension immediately.
Maven is a build platform which organizes your project in a technical way (convention over configuration, e.g. code is in /src/main/java, tests are in /src/test/java). The proper way is it to create a Maven project in Eclipse (you have to install the plugin and download Maven as well) and put the dependency
<dependency>
<groupId>com.github.axet</groupId>
<artifactId>vget</artifactId>
<version>1.1.23</version>
</dependency>
into your <dependencies> inside your pom.xml. After adding it, you project recognizes the additional package automatically.
Nobody tinkers by adding libraries manually. It's actually not professional to work without a build platform like Maven or Gradle.

Best way to add local dependency to Maven project

There are a lot of questions about this, but the answers seem to contradict each other. So I wanted to ask it for my version of Maven (3.0.4).
I have a JAR file that's not part of any maven repository. It's a local dependency. I understand there are two ways to add it to my Maven project.
Add it as a dependency and specify the file path in the <systemPath> property. (No other work needed.)
Create a local repository <my-project>/repo and install the JAR in this repository. Then, add the new repository in my pom.xml file and add the new dependency.
I'm curious which way is better practice? I've heard some negative things about the <systemPath> property, although that way looks faster.
The answer is, it depends...
If you add it as a system dependency it is likely to become path dependent which makes it more difficult to share among other developers. Sure you can also distribute the 3rd party jar relative to your POM via your SCM but the intention of systemPath is more for dependencies that are provided by the JDK or the VM. From the docs about systemPath:
They are usually used to tell Maven about dependencies which are provided by the JDK or the VM. Thus, system dependencies are especially useful for resolving dependencies on artifacts which are now provided by the JDK, but where available as separate downloads earlier.
To install the jar in the local repo is also not friendly for sharing. It requires all developers to "upload" the jar to their local repo before building. You can of course add a script that handles this for you but it is always easy to forget to upload and IMO a better solution is point 3 below. The local install process is described here.
If you are working in an organization where the developers share the POM you should upload the 3rd party jar to a local repository manager. That way you can easily work with the 3rd party jar as if using any other maven enabled jar. Check this link for a comprehensive list on repository managers.
To summarize, if you are sharing the POM with others I would suggest that you upload it to a local repository manager. Otherwise the second option can work for you. As a last option, I would fall back to option number 1.
Also note that this has nothing to do with which version of Maven you are running.
You can add jar to your local maven repository. Usually it located at:
$home_directory/.m2/repository
For example you have expample.jar and you want to add it to your pom as:
<dependency>
<groupId>com.example</groupId>
<artifactId>example</artifactId>
<version>1.0</version>
</dependency>
Then you must add example.jar to:
$home_directory/.m2/repository/com/example/1.0/example.jar
In my case NetBeans do it for me.
The best way I see so far is to use install:install-file goal with maven. You can use the mvn command line to execute it directly with appropriate parameters, or if you are using eclipse EE, you can do so by leveraging the embedded maven and creating a Run Configuration as follows:
Then, you include the jar as follows:
<dependency>
<groupId>mylocal.weka</groupId>
<artifactId>weka</artifactId>
<version>1.0</version>
</dependency>
Of course adjust the parameters as per your needs.
Best,
Haytham

Easy way to generate Maven dependencies in pom.xml?

I'm new to Struts and Maven, converting a Dynamic Web Project to Maven.
Under the DWP I would just drag required JAR files into WEB-INF/lib but using Maven it looks like I have to add them to pom.xml using groupId, artifactId and version.
I have no idea what these fields are for any given JAR file and have been googling around to look this up, however some simple tutorials out there use 10, 20 or 30 different jar files.
Surely, there MUST be an easier - and saner, developer-friendly - way to do this?
Those JARs are downloaded automatically from Maven Repositories, into your local repository (if they didn't exist there already).
e.g. http://mvnrepository.com/
The groupId is similar to a project prefix (e.g. javax.servlet), while the artifactId points to the JAR from that group (e.g. servlet-api). And the version is... well, the version of the JAR.
Say I want the Struts framework and API in my project. I quickly Google maven struts, and between the first results pops up this link. I pick a version, and then I look at the group and artifact id (which in this case are struts and struts).
<dependency>
<groupId>struts</groupId>
<artifactId>struts</artifactId>
<version>1.2.9</version>
</dependency>
You may find one or more implementations of the same framework, for example: from the group org.apache.struts
When your project requires a lot of JARs, then it is highly likely that some of those JAR automatically download their dependencies.
Add your struts dependency, and observe that it will automatically pull other required dependencies. In the end, you will have added about 5 JARs, tops. I can guarantee.

How do I determine the maven coordinates of this jar in a local lib directory?

I'm new to maven and am converting a java web app to maven (instead of managed by my IDE). I understand that can install the dependency locally (first choice) or declare it as a provided dependency (second choice). I read about what groupId, artifactId, and version mean. However, it doesn't explain how to determine the exact coordinates of a jar.
The jar in question (servlet-api.jar of apache-tomcat 7.0.34) for example, doesn't have a pom.xml file in the jar.
When you have a random jar file, in this case servlet-api.jar, present in some folder, you have to poke around to figure out if it is the same as some version.
One:Look inside the jar and note the date (or date range) of the files inside it. You might notice what files are in there. You might need that detail.
Two: Go to somewhere that you can look for the jar. I like http://mvnrepository.com/ where you can type in the name of the jar. "servlet-api". I found this one in about 10 seconds:
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifact>servlet-api</artifactId>
<version>6.0.36</version>
</dependency>
But its not yours. (Another 30 seconds and I found this: mvnrepository servlet-api for tomcat 7.0.34)
You can then download the one you think matches and look inside it to see if the date matches.
Its basically detective work from here. You might find the exact jar with maven 'coordinates' and you might not.
Reading the other answers reminded me that with the Java EE jars, I find it best to use a generic version for building your application. Use "provided" for the maven scope. The the container will provide the real jar and, if it isn't totally standard, you won't be using the non-standard parts because your build used the generic version.
So, for example, you might build with:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>
What I typically do is go to http://search.maven.org and look for the jars, for example: servlet-api.jar. You can also do fully qualified class name search, eg if you know inside your jar there is a class javax.servlet.http.HttpServletRequest, you can search for fc:javax.servlet.http.HttpServletRequest and it will list all jars containing this class
However keep in mind in the case of servlet-api.jar -- it shouldn't be bundled into your war/ears because it should be provided by container (tomcat in this case). Typically the best practice when creating Java EE project is to include dependency to javax.servlet:servlet-api:2.5 (or other version supported by you container) in provided scope. Hence the jars will only exist in your classpath during compile time, but at runtime it will be provided by the container
The Maven artifacts (JAR files) will be located in e.g.
~/.m2/repository/org/apache/tomcat/artifact/version/
The servlet-api.jar file will be located in ~/.m2/repository/javax/servlet/servlet-api/2.5/ if I remember correctly - given that you use version 2.5 of the servlet specification.
However, the servlet-api is always provided by the application container, hence the "provided" type of the dependency in the Maven POM.

Categories

Resources