Understanding Java Artifacts and Maven - maven

I am trying to understand relationship between artifact, group, class definitions.
For example, I've seen the following artifact declaration:
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>2.53.0</version>
Is there a file associated with this artifact?
Is this enough information to pull down the file down when building your Maven Project?
Where is it getting the file from? Is it getting it from selenium, or does Maven house these artifacts, and it is getting from Maven?
Where exactly is it downloading the artifact from?
What's in the artifact file? Class definitions? Multiple classes can be defined in there, right?
Maven seems to be making a jar file. Is it compounding all the classes into that file?
Also, how is artifact file different from JAR file and can you make your own artifact file?

Is there a file associated with this artifact?
Yes, what you have posted is known as a coordinate. It references a jar named selenium-java that is in the group org.seleniumhq.selenium.
Groups, identified by the groupId component of the coordinate, are a way of namespacing artifacts within maven to prevent naming collisions.
This coordinate says that the project has a dependency on version 2.53.0 of a maven artifact named selenium-java in the group org.seleniumhq.selenium.
Is this enough information to pull down the file down when building your Maven Project?
Yes, the coordinate is how the artifact is located within the maven repository and is enough information to locate and download the artifact when building a maven project.
Where is it getting the file from? Is it getting it from selenium, or does Maven house these artifacts, and it is getting from Maven?
Where exactly is it downloading the artifact from?
Where the file is retrieved from is based on your maven configuration. By default maven will first check the local maven repository on your machine to see if the artifact has already been downloaded. If not, it will then check Maven Central.
You can also host your own maven repositories using tools such as Nexus or Artifactory that can mirror repositories on the internet such as Maven Central as well as store artifacts you create yourself that you do not with to share with others.
What's in the artifact file? Class definitions? Multiple classes can be defined in there, right?
An artifact can be any type of file. In the case of the selenium coordinate above the artifact is a jar file. There will also be a pom file associated with that coordinate that explains all of the dependencies of the selenium-java jar.
http://search.maven.org/#artifactdetails%7Corg.seleniumhq.selenium%7Cselenium-java%7C2.53.0%7Cjar
Maven seems to be making a jar file. Is it compounding all the classes into that file?
You can build normal jars or fat jars with maven. By default maven will build a normal jar. If you wish to package all of a jars dependencies within it (i.e. fat jar) you need to use a special maven plugin.
http://maven.apache.org/plugins/maven-shade-plugin/
Also, how is artifact file different from JAR file and can you make your own artifact file?
Artifact is a generic term used to describe anything you can store within a maven repository. Maven repositories can store many different types of files. In the case of this coordinate the artifact is a jar file.

Related

Why doesn't the dependency contain a jar in the maven public repository https://mvnrepository.com?

I a maven rookie and am wondering how to get a binary jar file if it is not already in the repo. Specifically i'm in need of: jackson-dataformats-text-2.13.0.jar. Do I need to build it myself? I'm used to creating a project and marking a library as a dependency and seeing the jar downloaded into my .m2 cache but all i see in my cache is:
jchan#jchan-Z170N:~/.m2/repository/com/fasterxml/jackson/dataformat/jackson-dataformats-text/2.13.0$ ls
jackson-dataformats-text-2.13.0.jar.lastUpdated jackson-dataformats-text-2.13.0.pom.sha1
jackson-dataformats-text-2.13.0.pom _remote.repositories
Can someone advise how I am to get a built version of the jar from maven central?
We are still maintaining our ant build and I need the jar file for this. (i know i know, ancient stuff but team is not ready to port just yet).
parent pom don't contain jar file
This is the reason why no bundle link is present on the official public maven repository https://mvnrepository.com
The maven dependency is not a jar, is a parent. So the extension is: .pom which is just a plain pom.xml
Parent dependencies don't contain compiled class like .jar.
In your specific case, there are another dependencies who contains jars:
https://repo1.maven.org/maven2/com/fasterxml/jackson/dataformat/jackson-dataformat-yaml/2.13.0/
https://repo1.maven.org/maven2/com/fasterxml/jackson/dataformat/jackson-dataformat-xml/2.13.0/
advice
Check what classes do you need on your ant project and search if exist a jar (with the classes you need) on https://mvnrepository.com
Another option is to get all the dependencies from pom :
https://repo1.maven.org/maven2/com/fasterxml/jackson/dataformat/jackson-dataformats-text/2.9.0/jackson-dataformats-text-2.9.0.pom and download them into your ant project. In theory is the same of add the parent pom in a maven project

JAR file is corrupted (+missing source, javadoc) pushing maven artifact from BinTray to JCenter

I have some maven artifacts on bintray new for our current release that need adding to JCenter before they can be synced from BinTray to Maven Central. (We have other artifacts already in place)
However some of these artifacts are throwing errors when trying to add to JCenter that I don't agree with :-)
For example
JAR file is corrupted.
A binary file (jar, aar, wat, apk) should be part of the package.
Could not validate jar file.
Package should include sources as part of the package.
This particular jar looks ok for me. I download from BinTray (in case it was indeed corrupted on the upload)
* It's entirely readable - not corrupted
* It includes a regular jar, which has other jars and class files included
* It also includes a 'sources' jar and 'javadoc' jar -- which we added a few releases ago when manually syncing to maven central.
The contents of the package on bintray are:
ui-chassis-spring-1.3-javadoc.jar
ui-chassis-spring-1.3-sources.jar
ui-chassis-spring-1.3.jar
This appears to be suitable for maven central. It follows the pattern also documented at https://maven.apache.org/plugins/maven-deploy-plugin/examples/deploying-sources-javadoc.html
I did see a prior question opened where the resolution was to include sources in the main jar, but I disagree with this approach. Normally sources are download (for example by an IDE such as IntelliJ) on demand
Is there any way to get more detailed information? Is the validation on JCenter incorrect?
[ Ref: Github issue - https://github.com/odpi/egeria/issues/2499 ]

How to include csjdbc.jar as part of maven dependency?

I have been looking for a dependency for csjdbc.jar in Maven repository so that I can build my app using maven and retrieve that jar on the fly. However, I cannot find a dependency in Maven repository related to that jar. Can anyone help, please?
Hopefully you have already resolved this issue.
csjdbc.jar is not listed in maven repositories. If you have composite software installed you can copy the jar from
~\Composite Software\CIS 6.1.0\apps\jdbc\lib
directory to your local machine's maven repository like below with proper versioning:
C:\maven\repository\composite\csjdbc\6.1\csjdbc-6.1.jar
(I have 6.1 jar)

Difference between projectHelper.attachArtifact and project.getArtifact().setFile

I'm currently facing an issue with the execution of my MUnit tests using the command line.
I'm facing a problem of "duplicate project artifact assignment" Using version 1.2 of mule-domain-maven-plugin that was fixed here with version 1.3. Removing this line of code causes FileNotFoundException on mule-domain-config.xml when running my MUnit.
After decompiling the code, I can see that 1.2 (which works with my MUnits), has 2 lines of code :
this.projectHelper.attachArtifact(this.project, "zip", domain);
this.project.getArtifact().setFile(domain);
I can see that 1.3 has only this line :
this.projectHelper.attachArtifact(this.project, "zip", domain);
Does anybody know the difference between this.projectHelper.attachArtifact(this.project, "zip", domain); and this.project.getArtifact().setFile(domain); and how to resolve this issue?
The difference is the same as the difference between the main artifact and attached artifacts.
First of all, an artifact is, put simply, an object containing the Maven coordinates pointing to it (group id / artifact id / version / classifier / type), a repository where to resolve it or where it was resolved, and a file, which is the actual concrete file to use / download / upload.
Except for POM projects, a Maven project generates a single main artifact. It depends on its packaging; for example a project with a packaging of jar will create a main JAR artifact whose file contains all the classes of your project, and a project with a packaging of war will create the web application. Furthermore, the project itself is tied to its POM file; this means that a project, not only has a file for its main artifact, but also has reference to the POM file that created it. It is only for projects of packaging pom that no main artifact will be created; this is because such projects are parent or aggregator projects, containing build logic to be shared between multiple projects, but they do not produce a main deliverable.
In addition to this, a project has attached, or secondary, artifacts. They correspond to additional artifacts that are also generated during the build of a project, and differ from the main one by their classifier and/or type, and, naturally, their actual file. Those additional artifacts are installed and deployed alongside the main one. As an example, a typical project of packaging jar would also generate its Javadoc and Sources as a JAR file as attached artifacts having the classifier javadoc and sources. It follows that a project of packaging pom can only have attached artifacts, since it has no main artifact. Finally, it is perfectly allowed to have a project without attached artifacts; only the main one (or none at all in case of a pom project) would get deployed.
Inside a Maven plugin, all those considerations comes down to the following:
The main artifact of a project is retrieved with project.getArtifact(), as an Artifact.
project.getArtifact().setFile(...) sets the actual file of the main artifact of the project. Again, for a project of packaging jar, this would be the actual JAR file that was generated on-disk. Concrete example: it is what the Maven JAR plugin does.
The MavenProjectHelper component is used to attach artifacts to the project. projectHelper.attachArtifact(project, "zip", file); would attach an artifact of type ZIP to the given project, with no classifier, and whose file is the given file. There is an overload to attach an artifact with a classifier. Concrete example: it is what the Maven Assembly Plugin does when it is configured to attach the artifacts it produces.
project.setFile(file) sets the POM file of the Maven project that created it.
To give examples, we can consider the artifacts deployed under org.mule.tools.maven in Central. Under the artifact id mule-maven-plugin, there are multiple files:
mule-maven-plugin-2.1.jar is the main artifact file,
which was created by the POM file mule-maven-plugin-2.1.pom,
while mule-maven-plugin-2.1-javadoc.jar and mule-maven-plugin-2.1-sources.jar are attached with their respective classifier.
As second example, consider the artifact id mule-esb-maven-tools. The only file deployed (except for the hash files) is mule-esb-maven-tools-1.1.pom. This is perfectly normal since it's a POM project, so it has no main artifact (there are no JARs or other deployed); there's only the POM file of the project, with no attached artifacts.

How do I add an artifact to a local maven repository so that it will properly reference its own set of dependencies?

I am developing an application that depends on a number of legacy JAR files and I want the project to build straight out of version control without other users having to install these JARs in their local repository. I cannot add them to the corporate repository so I have created a repository that is local to this project and I have added these JARs to that repository using maven-install-plugin:install-file and setup the repository entry in the POM file so it knows to search the local repository.
This works exactly the way I want...up to a point. The problem is that most of these legacy JAR files have their own set of dependencies. I would like for them to work just like other artifacts that have their own set of dependencies so that maven can resolve everything and include all the necessary files but I can't find a way to do this with any maven-install-plugin:install-file options (or any other maven commands/plugins). I am pretty new at maven so I am probably just ignorant on this point.
As a work around, I attempted to go into the local repository directory and manually edit the POM file for the artifact to include the dependencies. This didn't cause any errors but it is also not pulling in those dependencies.
Can someone out there give me a clue?
The maven-install-plugin:install-file goal has a pomFile attribute. You can use this to specify a POM file for your legacy jar. You would create a POM file that points to all of the dependencies by artifactId in the <dependencies> section. If you have a remote nexus repository you can use the admin screen for the repository to deploy a jar.
Once you edit POM files in your project specific repository, host it as maven repo using Maven Repository Managers (like sonatype nexus). Add your project nexus repo as one of the maven repo in project pom.xml as below
<repositories>
<repository>
<id>my-project-mvn-repo</id>
<name>my-project-mvn-repo</name>
<url>http://<your project maven repo URL here></url>
</repository>
<repositories>
Now all developers should be able to make build. The legacy jar files POM contains dependency. Maven should take care of automatically pulling dependent jars on developer's workspace.

Resources